From ba193547d402e8aebe138bcfe0c71c4051340de8 Mon Sep 17 00:00:00 2001 From: Vladyslav Mustafin Date: Tue, 14 Jan 2020 14:24:40 +0200 Subject: [PATCH 01/19] #2 [SDL-0234] Proxy Library RPC Generation * Added `lib/rpc_spec` submodule pointed to `master` branch of `smartdevicelink/rpc_spec` repository * Created `Proxy RPC Generator` based on Python 3.5 and linked with parser from the `lib/rpc_spec` submodule * Added `README.md` with usage description and transformation rules for Proxy RPC Generator --- .gitignore | 8 +- .gitmodules | 4 + generator/README.md | 1533 +++++++++++++++++ generator/__init__.py | 0 generator/generator.py | 436 +++++ generator/mapping.json | 140 ++ generator/paths.ini | 11 + generator/requirements.txt | 5 + generator/templates/base_struct_function.js | 76 + generator/templates/base_template.js | 43 + generator/templates/enum_template.js | 70 + generator/templates/function_template.js | 7 + .../scripts/FunctionID_keyForValue.js | 8 + generator/templates/scripts/PutFileRequest.js | 18 + generator/templates/scripts/fullAppID.js | 49 + generator/templates/struct_template.js | 6 + generator/test/__init__.py | 0 generator/test/runner.py | 41 + .../test/test_code_format_and_quality.py | 36 + generator/test/test_enums.py | 65 + generator/test/test_functions.py | 269 +++ generator/test/test_structs.py | 37 + generator/transformers/__init__.py | 0 generator/transformers/common_producer.py | 301 ++++ generator/transformers/enums_producer.py | 94 + generator/transformers/functions_producer.py | 51 + generator/transformers/generate_error.py | 12 + generator/transformers/structs_producer.py | 37 + lib/rpc_spec | 1 + 29 files changed, 3357 insertions(+), 1 deletion(-) create mode 100644 .gitmodules create mode 100644 generator/README.md create mode 100644 generator/__init__.py create mode 100644 generator/generator.py create mode 100644 generator/mapping.json create mode 100644 generator/paths.ini create mode 100644 generator/requirements.txt create mode 100644 generator/templates/base_struct_function.js create mode 100644 generator/templates/base_template.js create mode 100644 generator/templates/enum_template.js create mode 100644 generator/templates/function_template.js create mode 100644 generator/templates/scripts/FunctionID_keyForValue.js create mode 100644 generator/templates/scripts/PutFileRequest.js create mode 100644 generator/templates/scripts/fullAppID.js create mode 100644 generator/templates/struct_template.js create mode 100644 generator/test/__init__.py create mode 100644 generator/test/runner.py create mode 100755 generator/test/test_code_format_and_quality.py create mode 100644 generator/test/test_enums.py create mode 100644 generator/test/test_functions.py create mode 100644 generator/test/test_structs.py create mode 100644 generator/transformers/__init__.py create mode 100644 generator/transformers/common_producer.py create mode 100644 generator/transformers/enums_producer.py create mode 100644 generator/transformers/functions_producer.py create mode 100644 generator/transformers/generate_error.py create mode 100644 generator/transformers/structs_producer.py create mode 160000 lib/rpc_spec diff --git a/.gitignore b/.gitignore index e8f5dc71..0777ec2a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,9 @@ **/node_modules/ *.log -.env \ No newline at end of file +.*env* +.idea +*__pycache__ +.DS_Store +*htmlcov +*.coverage +*.pytest_cache \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..816169a9 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "lib/rpc_spec"] + path = lib/rpc_spec + url = git@github.com:smartdevicelink/rpc_spec.git + branch = master diff --git a/generator/README.md b/generator/README.md new file mode 100644 index 00000000..de48273f --- /dev/null +++ b/generator/README.md @@ -0,0 +1,1533 @@ +# Proxy Library RPC Generator + +## Overview + +This script provides the possibility to auto-generate JavaScript code based on a given SDL MOBILE_API XML specification. + +## Requirements + +The script requires Python 3.5 pre-installed in the system. This is the minimal Python 3 version that has not reached the end-of-life (https://devguide.python.org/devcycle/#end-of-life-branches). + +Some required libraries are described in `requirements.txt` and should be pre-installed by the command: +```shell script +pip install -r requirements.txt +``` +Please also make sure before usage the 'lib/rpc_spec' Git submodule is successfully initialized, because the script uses the XML parser provided there. + +## Usage +```shell script +usage: generator.py [-h] [-v] [-xml SOURCE_XML] [-xsd SOURCE_XSD] + [-d OUTPUT_DIRECTORY] [-t [TEMPLATES_DIRECTORY]] + [-r REGEX_PATTERN] [--verbose] [-e] [-s] [-m] [-y] [-n] + +Proxy Library RPC Generator + +optional arguments: + -h, --help show this help message and exit + -v, --version print the version and exit + -xml SOURCE_XML, --source-xml SOURCE_XML, --input-file SOURCE_XML + should point to MOBILE_API.xml + -xsd SOURCE_XSD, --source-xsd SOURCE_XSD + -d OUTPUT_DIRECTORY, --output-directory OUTPUT_DIRECTORY + define the place where the generated output should be + placed + -t [TEMPLATES_DIRECTORY], --templates-directory [TEMPLATES_DIRECTORY] + path to directory with templates + -r REGEX_PATTERN, --regex-pattern REGEX_PATTERN + only elements matched with defined regex pattern will + be parsed and generated + --verbose display additional details like logs etc + -e, --enums only specified elements will be generated, if present + -s, --structs only specified elements will be generated, if present + -m, -f, --functions only specified elements will be generated, if present + -y, --overwrite force overwriting of existing files in output + directory, ignore confirmation message + -n, --skip skip overwriting of existing files in output + directory, ignore confirmation message +``` + +# JavaScript ES6 Transformation rules + +## Overview +These are the general transformation rules for RPC classes of SDL JavaScript Suite Library. The description of base classes, already included in the library, is not provided here, for details please view the source code. + +The JSDoc is used for inline documentation of generated code. All non-XML values should follow Architecture & Contribution Guidelines (GUIDELINES.md) + +These rules based on the current `develop` branch state (commit:`c5b3b448e008dadc9a5b66addde17633ac957700`) of [`smartdevicelink/sdl_javascript_suite`](https://github.com/smartdevicelink/sdl_javascript_suite) repository. + +## The License Header +All files should start from the comment with the license information. + +```javascript +/* +* Copyright (c) [year], SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ +``` +Where `[year]` in the copyright line is the current year. + +## `` +Each Enum class should be stored as a single script file in the folder named `enums` and the name of the script file should be equal to the value from the `"name"` attribute of `` followed by the extension `.js`. + +Example: +```shell script +enums/ImageType.js +``` +The script should import the base Enum class and the produced class should extend it. The name of the class is the value from the `"name"` attribute of ``. The constructor has no params and should call `super()`. + +The class should have the next JSDoc comment: +```javascript +/** + * [decription] + * @typedef {Enum} [enum_name] + * @property {Object} _MAP + */ +``` +Where `[description]` is `` of the current ``, if exists, and `[enum_name]` is the value of the `"name"` attribute. + +The constructor should have the next JSDoc comment: +```javascript +/** + * @constructor + */ +``` + +Example: +```javascript +import { Enum } from '_path_to_base_classes_/Enum.js'; + +/** + * Contains information about the type of image. + * @typedef {Enum} ImageType + * @property {Object} _MAP + */ +class ImageType extends Enum { + + /** + * @constructor + */ + constructor() { + super(); + } +} +``` +The set of `` should be mapped to the frozen object and put into the private static property `_MAP`. + +The following list are general rules for keys and values of this object: + +1. The `"name"` attribute is the base value for both the key and the value of the mapped object. +2. In case if the `"internal_name"` attribute exists, this should be used for the key instead of the `"name"` attribute. +3. In case if the `"value"` attribute exists, this attribute should be used for the value instead of the `"name"` attribute. +4. In case if the `"hexvalue"` attribute exists, this attribute should be used for the value instead of the `"value"` and `"name"` attributes. +5. Uses of the "sync" prefix shall be replaced with "sdl" (where it would not break functionality). E.g. `SyncMsgVersion -> SdlMsgVersion`. This applies to member variables and their accessors. The key used when creating the RPC message JSON should match that of the RPC Spec. +6. The `_MAP` keys and static getters of the `FunctionID` enum shall not include the ID suffix. e.g. `RegisterAppInterfaceID -> RegisterAppInterface`. + +According to ES6 standard, static (class-side) data properties and prototype data properties must be defined outside of the ClassBody declaration. + +Example: +```javascript +ImageType._MAP = Object.freeze({ + 'STATIC': 'STATIC', + 'DYNAMIC': 'DYNAMIC', +}); +``` + +For each `` the static getter method should be defined in the class. The name of the getter is the `"internal_name"` or `"name"` attribute value, the same as `_MAP` keys. The returned value is the value from the frozen object described above taken by the corresponding key. + +The getter should have the next JSDoc comment: +```javascript +/** + * [decription] + * @return {[enum_type]} + */ +``` +Where `[description]` is `` of the current ``, if exists, and `[enum_type]` is the one of `String` or `Number`. + +Example: +```javascript +/** + * @return {String} + */ +static get STATIC() { + return ImageType._MAP.STATIC; +} + +/** + * @return {String} + */ +static get DYNAMIC() { + return ImageType._MAP.DYNAMIC; +} +``` +The base Enum class requires subclasses to override and implement the `valueForKey` method with one parameter named `"key"`. This implementation should return a given enumeration **`value`** if the provided **`key`** exists in the collection (otherwise `null`) using the _valueForKey(key) private method found in the base Enum class. + +This method should have the next JSDoc comment: +```javascript +/** + * A method for subclasses to implement that does what _keyForValue does + * @param key - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ +``` + +Example: +```javascript +/** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ +static valueForKey (key) { + return ImageType._valueForKey(key, ImageType._MAP); +} +``` +Also the base Enum class requires subclasses to override and implement the `keyForValue` method with one parameter named `"value"`. This implementation should return a given enumeration **`key`** if the provided **`value`** exists in the collection (otherwise `null`) using the __keyForValue(value) private method found in the base Enum class. + +This method should have the next JSDoc comment: +```javascript +/** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ +``` + +Example: +```javascript +/** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ +static keyForValue (value) { + return ImageType._keyForValue(value, ImageType._MAP); +} +``` +After the `_MAP` definition, the script should export the produced class. + +Example: +```javascript +export { ImageType }; +``` + +### Below are examples of `` with different `` attributes + + +#### Example with only `"name"` attribute: + +XML: +```xml + + Contains information about the type of image. + + + +``` + +The Output: +```javascript +/* +* Copyright (c) 2019, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { Enum } from '_path_to_base_classes_/Enum.js'; + +/** + * Contains information about the type of image. + * @typedef {Enum} ImageType + * @property {Object} _MAP + */ +class ImageType extends Enum { + /** + * @constructor + */ + constructor () { + super(); + } + + /** + * @return {String} + */ + static get STATIC () { + return ImageType._MAP.STATIC; + } + + /** + * @return {String} + */ + static get DYNAMIC () { + return ImageType._MAP.DYNAMIC; + } + + /** + * Get the value for the given enum key + * @param value - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + static valueForKey (key) { + return ImageType._valueForKey(key, ImageType._MAP); + } + + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + static keyForValue (value) { + return ImageType._keyForValue(value, ImageType._MAP); + } +} + +ImageType._MAP = Object.freeze({ + 'STATIC': 'STATIC', + 'DYNAMIC': 'DYNAMIC', +}); + +export { ImageType }; +``` + +#### Example with `"internal_name"` and `"name"` attribute: + +XML: +```xml + + Contains information about the VR capabilities. + + +``` + +The Output: +```javascript +/* +* Copyright (c) 2019, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { Enum } from '_path_to_base_classes_/Enum.js'; + +/** + * Contains information about the VR capabilities. + * @typedef {Enum} VrCapabilities + * @property {Object} _MAP + */ +class VrCapabilities extends Enum { + constructor () { + super(); + } + + /** + * @return {String} + */ + static get VR_TEXT () { + return VrCapabilities._MAP.VR_TEXT; + } + + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + static valueForKey (key) { + return VrCapabilities._valueForKey(key, VrCapabilities._MAP); + } + + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + static keyForValue (value) { + return VrCapabilities._keyForValue(value, VrCapabilities._MAP); + } +} + +VrCapabilities._MAP = Object.freeze({ + 'VR_TEXT': 'TEXT', +}); + +export { VrCapabilities }; +``` + +#### Example with `"value"` attribute: + +XML: +```xml + + + The default window is a main window pre-created on behalf of the app. + + + The primary widget of the app. + + +``` + +The Output: +```javascript +/* +* Copyright (c) 2019, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ +import { Enum } from '_path_to_base_classes_/Enum.js'; + +/** + * @typedef {Enum} PredefinedWindows + * @property {Object} _MAP + */ +class PredefinedWindows extends Enum { + /** + * @constructor + */ + constructor () { + super(); + } + + /** + * The primary widget of the app. + * @return {Number} + */ + static get PRIMARY_WIDGET () { + return PredefinedWindows._MAP.PRIMARY_WIDGET; + } + + /** + * The default window is a main window pre-created on behalf of the app. + * @return {Number} + */ + static get DEFAULT_WINDOW () { + return PredefinedWindows._MAP.DEFAULT_WINDOW; + } + + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + static valueForKey (key) { + return PredefinedWindows._valueForKey(key, PredefinedWindows._MAP); + } + + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + static keyForValue (value) { + return PredefinedWindows._keyForValue(value, PredefinedWindows._MAP); + } +} + +PredefinedWindows._MAP = Object.freeze({ + 'PRIMARY_WIDGET': 1, + 'DEFAULT_WINDOW': 0, +}); + +export { PredefinedWindows }; +``` + +#### Example with `"hexvalue"` attribute: + +XML: +```xml + + Enumeration linking function names with function IDs in SmartDeviceLink protocol. Assumes enumeration starts at value 0. + + + + +``` + +The Output: +```javascript +/* +* Copyright (c) 2019, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ +import { Enum } from '_path_to_base_classes_/Enum.js'; + +/** + * Enumeration linking function names with function IDs in SmartDeviceLink protocol. Assumes enumeration starts at value 0. + * @typedef {Enum} FunctionID + * @property {Object} _MAP + */ +class FunctionID extends Enum { + /** + * @constructor + */ + constructor () { + super(); + } + + /** + * @return {Number} + */ + static get RESERVED () { + return FunctionID._MAP.RESERVED; + } + + /** + * @return {Number} + */ + static get RegisterAppInterface () { + return FunctionID._MAP.RegisterAppInterface; + } + + /** + * @return {Number} + */ + static get Slider () { + return FunctionID._MAP.Slider; + } + + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + static valueForKey (key) { + return FunctionID._valueForKey(key, FunctionID._MAP); + } + + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + static keyForValue (value) { + return FunctionID._keyForValue(value, FunctionID._MAP); + } +} + +FunctionID._MAP = Object.freeze({ + 'RESERVED': 0x0, + 'RegisterAppInterface': 0x1, + 'Slider': 0x1A, +}); + +export { FunctionID }; +``` + +## `` +Each Struct class should be stored as a single script file in the folder named `structs` and the name of the script file should be equal to the value from the `"name"` attribute of `` following by the extension `.js`. + +Example: +```shell script +structs/VehicleDataResult.js +``` + +The script should import the base `RpcStruct` class and the produced class should extend it. The name of the class is the value from the `"name"` attribute of ``. + +The script should also import any Enum and Struct classes, that are used in the represented structure. + +The constructor has one parameter named `parameters` to pass the JavaScript object with initial values of the represented structure and should call `super(parameters)` to pass this object into the base class. + +The class should have the next JSDoc comment: +```javascript +/** + * [decription] + */ +``` +Where `[description]` is `` of the current ``, if exists. + +The constructor should have the next JSDoc comment: +```javascript +/** + * @constructor + */ +``` + +Example: +```javascript +import { RpcStruct } from '_path_to_base_classes_/RpcStruct.js'; +import { VehicleDataType } from '../enums/VehicleDataType.js'; +import { VehicleDataResultCode } from '../enums/VehicleDataResultCode.js'; + +/** + * Individual published data request result + */ +class VehicleDataResult extends RpcStruct { + + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } +} +``` + +The set of `` should be mapped to the static properties of the new class by following rules: + +1. The name of the property is the `SCREAMING_SNAKE_CASE` formatted value of the `"name"` attribute of `` with the `KEY_` prefix. +2. The value of the property is the value of the `"name"` attribute of `` +3. Uses of the "sync" prefix shall be replaced with "sdl" (where it would not break functionality). E.g. `KEY_SYNC_MSG_VERSION -> KEY_SDL_MSG_VERSION`. This applies to member variables and their accessors. The key used when creating the RPC message JSON should match that of the RPC Spec. + +According to ES6 standard, static (class-side) data properties and prototype data properties must be defined outside of the ClassBody declaration. + +Example: +```javascript +VehicleDataResult.KEY_DATA_TYPE = 'dataType'; +VehicleDataResult.KEY_RESULT_CODE = 'resultCode'; +VehicleDataResult.KEY_OEM_CUSTOM_DATA_TYPE = 'oemCustomDataType'; +``` + +For each `` the getter and setter methods should be defined in the class: + +1. The name of the getter is the `PascalCase` formatted value of the `"name"` attribute with the `get` prefix, for the setter the prefix should be `set`. +2. Uses of the "sync" prefix shall be replaced with "sdl" (where it would not break functionality). E.g. `SyncMsgVersion -> SdlMsgVersion`. This applies to member variables and their accessors. The key used when creating the RPC message JSON should match that of the RPC Spec. +3. If the `` has the `"type"` attribute value as one of `Boolean`, `Float`, `Integer`, `String`: + * The getter should call and return the result of the `this.getParameter` method, where the single parameter is the value of the corresponding static property described above; + * The setter should call the `this.setParameter` method, where the first parameter is the value of the corresponding static property described above, the second is the value passed into setter; + * The setter should return `this` instance to support the chaining. +4. If the `` has the `"type"` attribute value as the one of `` or `` name: + * The getter should call and return the result of the `this.getObject` method, where the first parameter is the corresponding Struct or Enum class, the second is the value of the corresponding static property described above; + * The setter should validate the received value by calling the `this.validateType` method, where the fist parameter is the Struct or Enum class corresponding to the `"type"` attribute value of ``, the second is the value itself; + * The setter should call the `this.setParameter` method, where the first parameter is the value of the corresponding static property described above, the second is the value passed into setter; + * The setter should return `this` instance to support the chaining. + +The setter should have the next JSDoc comment: +```javascript +/** + * @param {[param_type]} [value_name] [decription] + * @return {[struct_name]} + */ +``` +Where `[param_type]` is the `"type"` attribute, `[value_name]` is the lowercase last part of the `"name"` attribute, `[description]` is `` of the current ``, if exists, and `[struct_name]` is the `"name"` attribute of the current Struct. + +The getter should have the next JSDoc comment: +```javascript +/** + * @return {[param_type]} + */ +``` +Where `[param_type]` is the `"type"` attribute of the current ``. + + +Examples: +```javascript +/** + * @param {VehicleDataType} type Defined published data element type. + * @return {VehicleDataResult} + */ +setDataType(type) { + this.validateType(VehicleDataType, type); + this.setParameter(VehicleDataResult.KEY_DATA_TYPE, type); + return this; +} + +/** + * @return {VehicleDataType} + */ +getDataType() { + return this.getObject(VehicleDataType, VehicleDataResult.KEY_DATA_TYPE); +} + +/** + * @param {String} type Type of requested oem specific parameter + * @return {VehicleDataResult} + */ +setOemCustomDataType(type) { + this.setParameter(VehicleDataResult.KEY_OEM_CUSTOM_DATA_TYPE, type); + return this; +} + +/** + * @return {String} + */ +getOemCustomDataType() { + return this.getParameter(VehicleDataResult.KEY_OEM_CUSTOM_DATA_TYPE); +} +``` + +After the static properties definition, the script should export the produced class. + +Example: +```javascript +export { VehicleDataResult }; +``` + +### Below is the full example of the Struct class with simple and Enum parameters inside: + +XML: +```xml + + Individual published data request result + + Defined published data element type. + + + Published data result code. + + + Type of requested oem specific parameter + + +``` + +The Output: +```javascript +/* +* Copyright (c) 2019, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '_path_to_base_classes_/RpcStruct.js'; +import { VehicleDataType } from '../enums/VehicleDataType.js'; +import { VehicleDataResultCode } from '../enums/VehicleDataResultCode.js'; + +/** + * Individual published data request result + */ +class VehicleDataResult extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {VehicleDataType} type - Defined published data element type. + * @return {VehicleDataResult} + */ + setDataType (type) { + this.validateType(VehicleDataType, type); + this.setParameter(VehicleDataResult.KEY_DATA_TYPE, type); + return this; + } + + /** + * @return {VehicleDataType} + */ + getDataType () { + return this.getObject(VehicleDataType, VehicleDataResult.KEY_DATA_TYPE); + } + + /** + * @param {VehicleDataResultCode} code - Published data result code. + * @return {VehicleDataResult} + */ + setResultCode (code) { + this.validateType(VehicleDataResultCode, code); + this.setParameter(VehicleDataResult.KEY_RESULT_CODE, code); + return this; + } + + /** + * @return {VehicleDataResultCode} + */ + getResultCode () { + return this.getObject(VehicleDataResultCode, VehicleDataResult.KEY_RESULT_CODE); + } + + /** + * @param {String} type - Type of requested oem specific parameter + * @return {VehicleDataResult} + */ + setOemCustomDataType (type) { + this.setParameter(VehicleDataResult.KEY_OEM_CUSTOM_DATA_TYPE, type); + return this; + } + + /** + * @return {String} + */ + getOemCustomDataType () { + return this.getParameter(VehicleDataResult.KEY_OEM_CUSTOM_DATA_TYPE); + } +} + +VehicleDataResult.KEY_DATA_TYPE = 'dataType'; +VehicleDataResult.KEY_RESULT_CODE = 'resultCode'; +VehicleDataResult.KEY_OEM_CUSTOM_DATA_TYPE = 'oemCustomDataType'; + +export { VehicleDataResult }; +``` + +## `` + +Each Function class should be stored as a single script file in the folder named `messages` and the name of the script is the value from the `"name"` attribute of `` (followed by additional suffix `Response` if the `"messagetype"` attribute is set to `response`) followed by the extension `.js`. + +Example: +```shell script +messages/AddCommand.js +messages/AddCommandResponse.js +messages/OnLanguageChange.js +``` + +There are some prerequisites for the Function class: + +1. Based on the value of the `"messagetype"` attribute of ``, the script should import the base class `RpcRequest`, `RpcResponse` or `RpcNotification` class and the produced class should extend the imported base class. +2. The script should import `enums/FunctionID.js` to get the `functionID` hex value of the current RPC function. The key of the required `` of `FunctionID` enum is the value of the `"functionID"` attribute of ``. +3. The script should import all Enum and Struct classes, that are used by the representing function. +4. The name of the class is the value from the `"name"` attribute of `` (followed by additional suffix `Response` if the `"messagetype"` attribute is set to `response`), e.g. `AddCommand`, `AddCommandResponse`, `OnLanguageChange`. +5. The constructor has one parameter named `store` to pass the JavaScript object with initial values of the function params and should call `super(store)` to pass this object into the parent class. +6. The constructor should call `this.setFunctionName` method with the correspond `FunctionID` value described in the point 2, e.g. `FunctionID.AddCommandID`. + +The class should have the next JSDoc comment: +```javascript +/** + * [decription] + */ +``` +Where `[description]` is `` of the current ``, if exists. + +The constructor should have the next JSDoc comment: +```javascript +/** + * @constructor + */ +``` + +Example: +```javascript +import { RpcRequest } from '_path_to_base_classes_/RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; +import { Image } from '../enums/Image.js'; +import { MenuParams } from '../enums/MenuParams.js'; + +/** + * Adds a command to the in application menu. Either menuParams or vrCommands must be provided. + */ +class AddCommand extends RpcRequest { + + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.AddCommandID); + } +} +``` + +Example: +```javascript +import { RpcResponse } from '_path_to_base_classes_/RpcResponse.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +class AddCommandResponse extends RpcResponse { + + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.AddCommandID); + } +} +``` + +Example: +```javascript +import { RpcNotification } from '_path_to_base_classes_/RpcNotification.js'; +import { FunctionID } from '../enums/FunctionID.js'; +import { Language } from '../enums/Language.js'; +import { MenuParams } from '../enums/MenuParams.js'; + +class OnLanguageChange extends RpcNotification { + + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnLanguageChangeID); + } +} +``` + +The set of `` should be mapped to the static properties of the new class by following rules: + +1. The name of the property is the `SCREAMING_SNAKE_CASE` formatted value of the `"name"` attribute of `` with the `KEY_` prefix. +2. Uses of the "sync" prefix shall be replaced with "sdl" (where it would not break functionality). E.g. `SyncMsgVersion -> SdlMsgVersion`. This applies to member variables and their accessors. The key used when creating the RPC message JSON should match that of the RPC Spec. +3. The value of the property is the value of the "name" attribute of +4. The exclusion are `` with name `success`, `resultCode` and `info` of `` with the attribute `messagetype="response"`, in this case they should be omitted. + +According to ES6 standard, static (class-side) data properties and prototype data properties must be defined outside of the ClassBody declaration. + +Example: +```javascript +AddCommand.KEY_CMD_ID = 'cmdID'; +OnLanguageChange. KEY_LANGUAGE = 'language'; +OnLanguageChange.KEY_HMI_DISPLAY_LANGUAGE = 'hmiDisplayLanguage'; +``` + +For each `` the getter and setter methods should be defined in the class: + +1. The name of the getter is the `PascalCase` formatted value of the `"name"` attribute with the `get` prefix, for the setter the prefix should be `set`. +2. If the `` has the `"type"` attribute value as one of `Boolean`, `Float`, `Integer`, `String`: + * The getter should call and return the result of the `this.getParameter` method, where the single parameter is the value of the corresponding static property described above; + * The setter should call the `this.setParameter` method, where the first parameter is the value of the corresponding static property described above, the second is the value passed into setter; + * The setter should return `this` instance to support the chaining. +3. If the `` has the `"type"` attribute value as the one of `` or `` name: + * The getter should call and return the result of the `this.getObject` method, where the first parameter is the corresponding Struct or Enum class, the second is the value of the corresponding static property described above; + * The setter should validate the received value by calling the `this.validateType` method, where the fist parameter is the Struct or Enum class corresponding to the `"type"` attribute value of ``, the second is the value itself; + * The setter should call the `this.setParameter` method, where the first parameter is the value of the corresponding static property described above, the second is the value passed into setter; + * The setter should return `this` instance to support the chaining. +4. The exclusion are `` with name `success`, `resultCode` and `info` of `` with the attribute `messagetype="response"`, in this case they should be omitted. + +The setter should have the next JSDoc comment: +```javascript +/** + * @param {[param_type]} [value_name] [decription] + * @return {[struct_name]} + */ +``` +Where `[param_type]` is the `"type"` attribute, `[value_name]` is the lowercase last part of the `"name"` attribute, `[description]` is `` of the current ``, if exists, and `[struct_name]` is the `"name"` attribute of the current Struct. + +The getter should have the next JSDoc comment: +```javascript +/** + * @return {[param_type]} + */ +``` +Where `[param_type]` is the `"type"` attribute of the current ``. + +Example: +```javascript +/** + * @param {Number} cmdid unique ID of the command to add. + * @return {AddCommand} + */ +setCmdID(id) { + this.setParameter(AddCommand.KEY_CMD_ID, id); + return this; +} + +/** + * @return {Number} + */ +getCmdID() { + return this.getParameter(AddCommand.KEY_CMD_ID); +} + +/** + * @param {MenuParams} params Optional sub value containing menu parameters + * @return {AddCommand} + */ +setMenuParams(menuParams) { + this.validateType(MenuParams, menuParams); + this.setParameter(AddCommand.KEY_MENU_PARAMS, menuParams); + return this; +} + +/** + * @return {MenuParams} + */ +getMenuParams() { + return this.getObject(MenuParams, AddCommand.KEY_MENU_PARAMS); +} + +/** + * @param {Language} language Current display language + * @return {OnLanguageChange} + */ +setHmiDisplayLanguage(language) { + this.validateType(Language, language); + this.setParameter(OnLanguageChange.KEY_HMI_DISPLAY_LANGUAGE, language); + return this; +} + +/** + * @return {Language} + */ +getHmiDisplayLanguage() { + return this.getObject(Language, OnLanguageChange.KEY_HMI_DISPLAY_LANGUAGE); +} +``` + +After the static properties definition, the script should export the produced class. + +Example: +```javascript +export { AddCommand }; +``` + +### Below are full examples for Request, Response and Notification. +#### Request Example: + +XML: +```xml + + + Adds a command to the in application menu. + Either menuParams or vrCommands must be provided. + + + + unique ID of the command to add. + + + + Optional sub value containing menu parameters + + + + + An array of strings to be used as VR synonyms for this command. + If this array is provided, it may not be empty. + + + + + + Image struct determining whether static or dynamic icon. + If omitted on supported displays, no (or the default if applicable) icon shall be displayed. + + + + +``` + +The Output: +```javascript +/* +* Copyright (c) 2019, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '_path_to_base_classes_/RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; +import { Image } from '../structs/Image.js'; +import { MenuParams } from '../structs/MenuParams.js'; + +/** + * Adds a command to the in application menu. Either menuParams or vrCommands must be provided. + */ +class AddCommand extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.AddCommand); + } + + /** + * @param {Number} id - unique ID of the command to add. + * @return {AddCommand} + */ + setCmdID (id) { + this.setParameter(AddCommand.KEY_CMD_ID, id); + return this; + } + + /** + * @return {Number} + */ + getCmdID () { + return this.getParameter(AddCommand.KEY_CMD_ID); + } + + /** + * @param {MenuParams} params - Optional sub value containing menu parameters + * @return {AddCommand} + */ + setMenuParams (params) { + this.validateType(MenuParams, params); + this.setParameter(AddCommand.KEY_MENU_PARAMS, params); + return this; + } + + /** + * @return {MenuParams} + */ + getMenuParams () { + return this.getObject(MenuParams, AddCommand.KEY_MENU_PARAMS); + } + + /** + * @param {Array} commands - An array of strings to be used as VR synonyms for this command. If this array + * is provided, it may not be empty. + * @return {AddCommand} + */ + setVrCommands (commands) { + this.setParameter(AddCommand.KEY_VR_COMMANDS, commands); + return this; + } + + /** + * @return {Array} + */ + getVrCommands () { + return this.getParameter(AddCommand.KEY_VR_COMMANDS); + } + + /** + * @param {Image} icon - Image struct determining whether static or dynamic icon. If omitted on supported displays, + * no (or the default if applicable) icon shall be displayed. + * @return {AddCommand} + */ + setCmdIcon (icon) { + this.validateType(Image, icon); + this.setParameter(AddCommand.KEY_CMD_ICON, icon); + return this; + } + + /** + * @return {Image} + */ + getCmdIcon () { + return this.getObject(Image, AddCommand.KEY_CMD_ICON); + } +} + +AddCommand.KEY_CMD_ID = 'cmdID'; +AddCommand.KEY_MENU_PARAMS = 'menuParams'; +AddCommand.KEY_VR_COMMANDS = 'vrCommands'; +AddCommand.KEY_CMD_ICON = 'cmdIcon'; + +export { AddCommand }; +``` + +#### Response Example: + +> Please pay attention that no other parameters for this example except "info", "success" and "resultCode", thus they were omitted and only the constructor and other parameters are present) + +XML: +```xml + + + true if successful; false, if failed + + + + See Result + + + + + + + + + + + + + + + + + Provides additional human readable info regarding the result. + + + + + ID of the choice that was selected in response to PerformInteraction. + Only is valid if general result is "success:true". + + + + + + Manually entered text selection, e.g. through keyboard + Can be returned in lieu of choiceID, depending on trigger source + + + + + + See TriggerSource + Only is valid if resultCode is SUCCESS. + + + + +``` + +The Output: +```javascript +/* +* Copyright (c) 2019, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcResponse } from '_path_to_base_classes_/RpcResponse.js'; +import { FunctionID } from '../enums/FunctionID.js'; +import { TriggerSource } from '../enums/TriggerSource.js'; + +class PerformInteractionResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.PerformInteraction); + } + + /** + * @param {Number} id - ID of the choice that was selected in response to PerformInteraction. Only is valid if + * general result is "success:true". + * @return {PerformInteractionResponse} + */ + setChoiceID (id) { + this.setParameter(PerformInteractionResponse.KEY_CHOICE_ID, id); + return this; + } + + /** + * @return {Number} + */ + getChoiceID () { + return this.getParameter(PerformInteractionResponse.KEY_CHOICE_ID); + } + + /** + * @param {String} entry - Manually entered text selection, e.g. through keyboard Can be returned in lieu of + * choiceID, depending on trigger source + * @return {PerformInteractionResponse} + */ + setManualTextEntry (entry) { + this.setParameter(PerformInteractionResponse.KEY_MANUAL_TEXT_ENTRY, entry); + return this; + } + + /** + * @return {String} + */ + getManualTextEntry () { + return this.getParameter(PerformInteractionResponse.KEY_MANUAL_TEXT_ENTRY); + } + + /** + * @param {TriggerSource} source - See TriggerSource Only is valid if resultCode is SUCCESS. + * @return {PerformInteractionResponse} + */ + setTriggerSource (source) { + this.validateType(TriggerSource, source); + this.setParameter(PerformInteractionResponse.KEY_TRIGGER_SOURCE, source); + return this; + } + + /** + * @return {TriggerSource} + */ + getTriggerSource () { + return this.getObject(TriggerSource, PerformInteractionResponse.KEY_TRIGGER_SOURCE); + } +} + +PerformInteractionResponse.KEY_CHOICE_ID = 'choiceID'; +PerformInteractionResponse.KEY_MANUAL_TEXT_ENTRY = 'manualTextEntry'; +PerformInteractionResponse.KEY_TRIGGER_SOURCE = 'triggerSource'; + +export { PerformInteractionResponse }; +``` +#### Notification Example: +XML: +```xml + + + Current SDL voice engine (VR+TTS) language + + + Current display language + + +``` +The Output: +```javascript +/* +* Copyright (c) 2019, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcNotification } from '_path_to_base_classes_/RpcNotification.js'; +import { FunctionID } from '../enums/FunctionID.js'; +import { Language } from '../enums/Language.js'; + +class OnLanguageChange extends RpcNotification { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.OnLanguageChange); + } + + /** + * @param {Language} language - Current SDL voice engine (VR+TTS) language + * @return {OnLanguageChange} + */ + setLanguage (language) { + this.validateType(Language, language); + this.setParameter(OnLanguageChange.KEY_LANGUAGE, language); + return this; + } + + /** + * @return {Language} + */ + getLanguage () { + return this.getObject(Language, OnLanguageChange.KEY_LANGUAGE); + } + + /** + * @param {Language} language - Current display language + * @return {OnLanguageChange} + */ + setHmiDisplayLanguage (language) { + this.validateType(Language, language); + this.setParameter(OnLanguageChange.KEY_HMI_DISPLAY_LANGUAGE, language); + return this; + } + + /** + * @return {Language} + */ + getHmiDisplayLanguage () { + return this.getObject(Language, OnLanguageChange.KEY_HMI_DISPLAY_LANGUAGE); + } +} + +OnLanguageChange.KEY_LANGUAGE = 'language'; +OnLanguageChange.KEY_HMI_DISPLAY_LANGUAGE = 'hmiDisplayLanguage'; + +export { OnLanguageChange }; +``` diff --git a/generator/__init__.py b/generator/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/generator/generator.py b/generator/generator.py new file mode 100644 index 00000000..b6588500 --- /dev/null +++ b/generator/generator.py @@ -0,0 +1,436 @@ +"""This is main runner of generator + +""" + +import logging +import re +import sys +from argparse import ArgumentParser +from collections import namedtuple +from inspect import getfile +from json import JSONDecodeError, loads +from os.path import basename +from pprint import pformat +from time import sleep +from xml.etree.ElementTree import ParseError as XMLSchemaError + +from jinja2 import Environment, FileSystemLoader, TemplateNotFound, UndefinedError +from pathlib2 import Path +from xmlschema import XMLSchema + +ROOT = Path(__file__).absolute().parents[0] + +sys.path.append(ROOT.parents[0].joinpath('lib/rpc_spec/InterfaceParser').as_posix()) + +try: + from parsers.sdl_rpc_v2 import Parser + from parsers.parse_error import ParseError as InterfaceError + from model.interface import Interface + from transformers.generate_error import GenerateError + from transformers.common_producer import InterfaceProducerCommon + from transformers.enums_producer import EnumsProducer + from transformers.functions_producer import FunctionsProducer + from transformers.structs_producer import StructsProducer +except ModuleNotFoundError as message: + print('%s.\nprobably you did not initialize submodule', message) + sys.exit(1) + + +class Generator: + """ + This class contains only technical features, as follow: + - parsing command-line arguments, or evaluating required Paths interactively; + - calling parsers to get Model from xml; + - calling producers to transform initial Model to dict used in jinja2 templates + Not required to be covered by unit tests cause contains only technical features. + """ + + def __init__(self): + self.logger = logging.getLogger(self.__class__.__name__) + self._env = None + + @property + def env(self): + """ + :return: jinja2 Environment + """ + return self._env + + @env.setter + def env(self, value): + """ + :param value: path with directory with templates + :return: jinja2 Environment + """ + if not Path(value).exists(): + self.logger.critical('Directory with templates not found %s', value) + sys.exit(1) + else: + self._env = Environment(loader=FileSystemLoader(value)) + + @property + def get_version(self): + """ + :return: current version of Generator + """ + return InterfaceProducerCommon.version + + def config_logging(self, verbose): + """ + Configure logging + :param verbose: boolean + """ + handler = logging.StreamHandler() + handler.setFormatter(logging.Formatter(fmt='%(asctime)s - %(name)s - %(levelname)s - %(message)s', + datefmt='%m-%d %H:%M')) + if verbose: + handler.setLevel(logging.DEBUG) + self.logger.setLevel(logging.DEBUG) + else: + handler.setLevel(logging.ERROR) + self.logger.setLevel(logging.ERROR) + logging.getLogger().handlers.clear() + root_logger = logging.getLogger() + root_logger.addHandler(handler) + + def evaluate_source_xml_xsd(self, xml, xsd): + """ + :param xml: path to MOBILE_API.xml file + :param xsd: path to .xsd file (optional) + :return: validated path to .xsd file + """ + if not Path(xml).exists(): + self.logger.critical('File not found: %s', xml) + sys.exit(1) + + if xsd and Path(xsd).exists(): + return xsd + + replace = xml.replace('.xml', '.xsd') + if xsd and not Path(xsd).exists(): + self.logger.critical('File not found: %s', xsd) + sys.exit(1) + elif not xsd and not Path(replace).exists(): + self.logger.critical('File not found: %s', replace) + sys.exit(1) + else: + return replace + + def evaluate_output_directory(self, output_directory): + """ + :param output_directory: path to output_directory + :return: validated path to output_directory + """ + if output_directory.startswith('/'): + path = Path(output_directory).absolute().resolve() + else: + path = ROOT.joinpath(output_directory).resolve() + if not path.exists(): + self.logger.warning('Directory not found: %s, trying to create it', path) + try: + path.mkdir(parents=True, exist_ok=True) + except OSError as message1: + self.logger.critical('Failed to create directory %s, %s', path.as_posix(), message1) + sys.exit(1) + return path + + def get_parser(self): + """ + Parsing command-line arguments, or evaluating required Paths interactively. + :return: an instance of argparse.ArgumentParser + """ + + if len(sys.argv) == 2 and sys.argv[1] in ('-v', '--version'): + print(self.get_version) + sys.exit(0) + + Paths = namedtuple('Paths', 'name path') + xml = Paths('source_xml', ROOT.parents[0].joinpath('lib/rpc_spec/MOBILE_API.xml')) + required_source = not xml.path.exists() + + out = Paths('output_directory', ROOT.parents[0].joinpath('lib/js/src/rpc')) + output_required = not out.path.exists() + + parser = ArgumentParser(description='Proxy Library RPC Generator') + parser.add_argument('-v', '--version', action='store_true', help='print the version and exit') + parser.add_argument('-xml', '--source-xml', '--input-file', required=required_source, + help='should point to MOBILE_API.xml') + parser.add_argument('-xsd', '--source-xsd', required=False) + parser.add_argument('-d', '--output-directory', required=output_required, + help='define the place where the generated output should be placed') + parser.add_argument('-t', '--templates-directory', nargs='?', default=ROOT.joinpath('templates').as_posix(), + help='path to directory with templates') + parser.add_argument('-r', '--regex-pattern', required=False, + help='only elements matched with defined regex pattern will be parsed and generated') + parser.add_argument('--verbose', action='store_true', help='display additional details like logs etc') + parser.add_argument('-e', '--enums', required=False, action='store_true', + help='only specified elements will be generated, if present') + parser.add_argument('-s', '--structs', required=False, action='store_true', + help='only specified elements will be generated, if present') + parser.add_argument('-m', '-f', '--functions', required=False, action='store_true', + help='only specified elements will be generated, if present') + parser.add_argument('-y', '--overwrite', action='store_true', + help='force overwriting of existing files in output directory, ignore confirmation message') + parser.add_argument('-n', '--skip', action='store_true', + help='skip overwriting of existing files in output directory, ignore confirmation message') + + args, unknown = parser.parse_known_args() + + if unknown: + self.logger.critical('found unknown arguments: %s', ' '.join(unknown)) + parser.print_help(sys.stderr) + sys.exit(1) + + if args.skip and args.overwrite: + self.logger.critical('please select only one option skip or overwrite') + sys.exit(1) + + if not args.enums and not args.structs and not args.functions: + args.enums = args.structs = args.functions = True + + for intermediate in (xml, out): + if not getattr(args, intermediate.name) and intermediate.path.exists(): + while True: + try: + confirm = input('Confirm default path {} for {} Y/Enter = yes, N = no' + .format(intermediate.path, intermediate.name)) + if confirm.lower() == 'y' or not confirm: + self.logger.warning('%s set to %s', intermediate.name, intermediate.path) + setattr(args, intermediate.name, intermediate.path.as_posix()) + sleep(0.05) + break + if confirm.lower() == 'n': + self.logger.warning('provide argument %s', intermediate.name) + sys.exit(1) + except KeyboardInterrupt: + print('\nThe user interrupted the execution of the program') + sys.exit(1) + + self.config_logging(args.verbose) + + args.source_xsd = self.evaluate_source_xml_xsd(args.source_xml, args.source_xsd) + + args.output_directory = self.evaluate_output_directory(args.output_directory) + + self.env = args.templates_directory + + self.logger.info('parsed arguments:\n%s', pformat((vars(args)))) + return args + + def versions_compatibility_validating(self): + """version of generator script requires the same or lesser version of parser script. + if the parser script needs to fix a bug (and becomes, e.g. 1.0.1) and the generator script stays at 1.0.0. + As long as the generator script is the same or greater major version, it should be parsable. + This requires some level of backward compatibility. E.g. they have to be the same major version. + + """ + + regex = r'(\d+\.\d+).(\d)' + + parser_origin = Parser().get_version + parser_split = re.findall(regex, parser_origin).pop() + generator_split = re.findall(regex, self.get_version).pop() + + parser_major = float(parser_split[0]) + generator_major = float(generator_split[0]) + + if parser_major > generator_major: + self.logger.critical('Generator (%s) requires the same or lesser version of Parser (%s)', + self.get_version, parser_origin) + sys.exit(1) + + self.logger.info('Parser type: %s, version %s,\tGenerator version %s', + basename(getfile(Parser().__class__)), parser_origin, self.get_version) + + def get_paths(self, file_name=ROOT.joinpath('paths.ini')): + """ + :param file_name: path to file with Paths + :return: namedtuple with Paths to key elements + """ + fields = ('path_to_enum_class', 'path_to_struct_class', 'path_to_request_class', 'path_to_response_class', + 'path_to_notification_class', 'enums_dir_name', 'structs_dir_name', 'functions_dir_name') + intermediate = {} + try: + with file_name.open('r') as file: + for line in file: + if line.startswith('#'): + self.logger.warning('commented property %s, which will be skipped', line.strip()) + continue + if re.match(r'^(\w+)\s?=\s?(.+)', line): + if len(line.split('=')) > 2: + self.logger.critical('can not evaluate value, too many separators %s', str(line)) + sys.exit(1) + name, var = line.partition('=')[::2] + if name.strip() in intermediate: + self.logger.critical('duplicate key %s', name) + sys.exit(1) + intermediate[name.strip().lower()] = var.strip() + except FileNotFoundError as message1: + self.logger.critical(message1) + sys.exit(1) + + for line in fields: + if line not in intermediate: + self.logger.critical('in %s missed fields: %s ', file, str(line)) + sys.exit(1) + + Paths = namedtuple('Paths', ' '.join(fields)) + return Paths(**intermediate) + + def get_mappings(self, file_name=ROOT.joinpath('mapping.json')): + """ + The key name in *.json is equal to property named in jinja2 templates + :param file_name: path to file with manual mappings + :return: dictionary with custom manual mappings + """ + + try: + with file_name.open('r') as file: + intermediate = file.readlines() + return loads(''.join(intermediate)) + except (FileNotFoundError, JSONDecodeError) as message1: + self.logger.error(message1) + return {} + + def write_file(self, file_name, template, data): + """ + Calling producer/transformer instance to transform initial Model to dict used in jinja2 templates. + Applying transformed dict to jinja2 templates and writing to appropriate file + :param file_name: output js file + :param template: name of template + :param data: transformed moder ready for apply to Jinja2 template + """ + try: + render = self.env.get_template(template).render(data) + with file_name.open('w', encoding='utf-8') as file: + file.write(render) + except (TemplateNotFound, UndefinedError) as message1: + self.logger.error('skipping %s, template not found %s', file_name.as_posix(), message1) + + def process(self, directory, skip, overwrite, items, transformer): + """ + Process each item from initial Model. According to provided arguments skipping, overriding or asking what to to. + :param directory: output directory for writing output files + :param skip: if file exist skip it + :param overwrite: if file exist overwrite it + :param items: elements initial Model + :param transformer: producer/transformer instance + """ + + directory.mkdir(parents=True, exist_ok=True) + template = type(items[0]).__name__.lower() + '_template.js' + for item in items: + data = transformer.transform(item) + file = directory.joinpath(data['file_name'] + '.js') + if file.is_file(): + if skip: + self.logger.info('Skipping %s', file) + continue + if overwrite: + self.logger.info('Overriding %s', file) + self.write_file(file, template, data) + else: + while True: + try: + confirm = input('File already exists {}. Overwrite? Y/Enter = yes, N = no\n'.format(file)) + if confirm.lower() == 'y' or not confirm: + self.logger.info('Overriding %s', file) + self.write_file(file, template, data) + break + if confirm.lower() == 'n': + self.logger.info('Skipping %s', file) + break + except KeyboardInterrupt: + print('\nThe user interrupted the execution of the program') + sys.exit(1) + else: + self.logger.info('Writing new %s', file) + self.write_file(file, template, data) + + def parser(self, xml, xsd, pattern=None): + """ + Validate xml to match with xsd. Calling parsers to get Model from xml. If provided pattern, filtering Model. + :param xml: path to MOBILE_API.xml + :param xsd: path to MOBILE_API.xsd + :param pattern: regex-pattern from command-line arguments to filter element from initial Model + :return: initial Model + """ + self.logger.info('''Validating XML and generating model with following parameters: + Source xml : %s + Source xsd : %s''', xml, xsd) + + try: + schema = XMLSchema(xsd) + if not schema.is_valid(xml): + raise GenerateError(schema.validate(xml)) + interface = Parser().parse(xml) + except (InterfaceError, XMLSchemaError, GenerateError) as message1: + self.logger.critical('Invalid XML file content: %s, %s', xml, message1) + sys.exit(1) + + enum_names = tuple(interface.enums.keys()) + struct_names = tuple(interface.structs.keys()) + + if pattern: + intermediate = {} + intermediate.update({'params': interface.params}) + for kind, content in vars(interface).items(): + if kind == 'params': + continue + for name, item in content.items(): + if re.match(pattern, item.name): + self.logger.info('%s/%s match with %s', kind, item.name, pattern) + if kind in intermediate: + intermediate[kind].update({name: item}) + else: + intermediate.update({kind: {name: item}}) + interface = Interface(**intermediate) + + self.logger.debug({'enums': tuple(interface.enums.keys()), + 'structs': tuple(interface.structs.keys()), + 'functions': tuple(map(lambda i: i.function_id.name, interface.functions.values())), + 'params': interface.params}) + return enum_names, struct_names, interface + + @staticmethod + def evaluate_instance_directory(dir_name): + """ + :param dir_name: property from paths.ini (ENUMS|STRUCTS|FUNCTIONS)_DIR_NAME + :return: substring after double dot + """ + pattern = re.search(r'^([./]*)(.+)', dir_name) + if pattern: + return pattern.group(2) + raise GenerateError('Can not evaluate directory {}'.format(dir_name)) + + def main(self): + """ + Entry point for parser and generator + :return: None + """ + args = self.get_parser() + + self.versions_compatibility_validating() + + enum_names, struct_names, interface = self.parser(xml=args.source_xml, xsd=args.source_xsd, + pattern=args.regex_pattern) + + paths = self.get_paths() + mappings = self.get_mappings() + + if args.enums and interface.enums: + directory = args.output_directory.joinpath(self.evaluate_instance_directory(paths.enums_dir_name)) + self.process(directory, args.skip, args.overwrite, tuple(interface.enums.values()), + EnumsProducer(paths, mappings)) + if args.structs and interface.structs: + directory = args.output_directory.joinpath(self.evaluate_instance_directory(paths.structs_dir_name)) + self.process(directory, args.skip, args.overwrite, tuple(interface.structs.values()), + StructsProducer(paths, enum_names, struct_names, mappings)) + if args.functions and interface.functions: + directory = args.output_directory.joinpath(self.evaluate_instance_directory(paths.functions_dir_name)) + self.process(directory, args.skip, args.overwrite, tuple(interface.functions.values()), + FunctionsProducer(paths, enum_names, struct_names, mappings)) + + +if __name__ == '__main__': + Generator().main() diff --git a/generator/mapping.json b/generator/mapping.json new file mode 100644 index 00000000..05fa6c5b --- /dev/null +++ b/generator/mapping.json @@ -0,0 +1,140 @@ +{ + "enums": { + "DisplayType": { + "params_additional": [ + { + "key": "TESTING", + "value": "'TESTING'" + } + ] + } + }, + "structs": { + "DisplayCapabilities": { + "graphicSupported": { + "methods": { + "method_title": "GraphicsSupported", + "key": "KEY_GRAPHICS_SUPPORTED" + }, + "params": { + "key": "KEY_GRAPHICS_SUPPORTED" + } + } + }, + "Grid": { + "col": { + "methods": { + "method_title": "Column", + "key": "KEY_COLUMN" + }, + "params": { + "key": "KEY_COLUMN" + } + }, + "colspan": { + "methods": { + "method_title": "ColumnSpan", + "key": "KEY_COLUMN_SPAN" + }, + "params": { + "key": "KEY_COLUMN_SPAN" + } + }, + "rowspan": { + "methods": { + "method_title": "RowSpan", + "key": "KEY_ROW_SPAN" + }, + "params": { + "key": "KEY_ROW_SPAN" + } + }, + "levelspan": { + "methods": { + "method_title": "LevelSpan", + "key": "KEY_LEVEL_SPAN" + }, + "params": { + "key": "KEY_LEVEL_SPAN" + } + } + }, + "TextField": { + "name": { + "methods": { + "method_title": "TextFieldName" + } + } + }, + "RGBColor": { + "red": { + "methods": { + "method_title": "RedValue" + } + }, + "green": { + "methods": { + "method_title": "GreenValue" + } + }, + "blue": { + "methods": { + "method_title": "BlueValue" + } + } + } + }, + "functions": { + "SetAppIconRequest": { + "syncFileName": { + "methods": { + "method_title": "FileName", + "key": "KEY_FILE_NAME" + }, + "params": { + "key": "KEY_FILE_NAME" + } + } + }, + "RegisterAppInterfaceResponse": { + "supportedDiagModes": { + "methods": { + "key": "KEY_SUPPORTED_DIAG_MODE" + }, + "params": { + "key": "KEY_SUPPORTED_DIAG_MODE" + } + } + }, + "RegisterAppInterfaceRequest": { + "appID": { + "-methods": {} + }, + "fullAppID": { + "script": "templates/scripts/fullAppID.js" + }, + "params_additional": [ + { + "key": "APP_ID_MAX_LENGTH", + "value": 10 + } + ] + }, + "PutFileRequest": { + "syncFileName": { + "methods": { + "method_title": "FileName", + "key": "KEY_FILE_NAME" + }, + "params": { + "key": "KEY_FILE_NAME" + } + }, + "script": "templates/scripts/PutFileRequest.js" + }, + "OnHMIStatus": { + "name": "OnHmiStatus", + "file_name": "OnHmiStatus" + } + } +} diff --git a/generator/paths.ini b/generator/paths.ini new file mode 100644 index 00000000..c3a4c167 --- /dev/null +++ b/generator/paths.ini @@ -0,0 +1,11 @@ +#sdl_javascript_suite/lib/js/util/ +PATH_TO_ENUM_CLASS = ../../util/Enum.js + +#sdl_javascript_suite/lib/js/rpc/ +PATH_TO_STRUCT_CLASS = ../RpcStruct.js +PATH_TO_REQUEST_CLASS = ../RpcRequest.js +PATH_TO_RESPONSE_CLASS = ../RpcResponse.js +PATH_TO_NOTIFICATION_CLASS = ../RpcNotification.js +ENUMS_DIR_NAME = ../enums +STRUCTS_DIR_NAME = ../structs +FUNCTIONS_DIR_NAME = ../messages \ No newline at end of file diff --git a/generator/requirements.txt b/generator/requirements.txt new file mode 100644 index 00000000..ffc507da --- /dev/null +++ b/generator/requirements.txt @@ -0,0 +1,5 @@ +xmlschema +Jinja2 +coverage +pathlib2 +pylint \ No newline at end of file diff --git a/generator/templates/base_struct_function.js b/generator/templates/base_struct_function.js new file mode 100644 index 00000000..7853c7ec --- /dev/null +++ b/generator/templates/base_struct_function.js @@ -0,0 +1,76 @@ +{% extends 'base_template.js' %} + +{% block typedef %} +{%- if description is defined or deprecated is defined %} +/** + {% if description is defined -%} + {% for d in description -%} + * {{d}} + {% endfor -%} + {% endif -%} + {% if deprecated is defined -%} + * @deprecated + {% endif -%} + */ +{%- endif %} +{%- endblock %} +{% block body %} + /** + {% if deprecated is defined -%} + * @deprecated + {% endif -%} + * @constructor + */ +{%- block constructor %} +{% endblock -%} + {% if scripts is defined -%} + {% for s in scripts %} +{{s|indent(4,True)}} + {% endfor -%} + {% endif -%} + {% for e in methods %} + {% set l = e.type|length + e.param_name|length + 13 -%} + /** + {% if deprecated is defined -%} + * @deprecated + {% endif -%} + {% if not e.description -%} + * @param {{'%s%s%s %s'|format('{', e.type, '}', e.param_name)}} + {% else -%} + * {% for d in e.description -%} + {% if loop.index == 1 -%} + @param {{'%s%s%s %s - %s'|format('{', e.type, '}', e.param_name, d)}} + {% else -%} + * {{d|indent(l,True)}} + {% endif -%} {% endfor -%} + {% endif -%} + * @return {{'%s%s%s'|format('{', name, '}')}} + */ + set{{e.method_title}} ({{e.param_name}}) { + {%- if e.external and 'Array' not in e.type %} + this.validateType({{e.external}}, {{e.param_name}}); + {%- endif %} + this.setParameter({{name}}.{{e.key}}, {{e.param_name}}); + return this; + } + + /** + {% if deprecated is defined -%} + * @deprecated + {% endif -%} + * @return {{'%s%s%s'|format('{', e.type, '}')}} + */ + get{{e.method_title}} () { + {%- if e.external %} + return this.getObject({{e.external}}, {{name}}.{{e.key}}); + {%- else %} + return this.getParameter({{name}}.{{e.key}}); + {%- endif %} + } +{% endfor %} +{%- endblock %} +{% block properties %} +{%- for e in params %} +{{name}}.{{e.key}} = {{e.value}}; +{%- endfor %} +{%- endblock %} \ No newline at end of file diff --git a/generator/templates/base_template.js b/generator/templates/base_template.js new file mode 100644 index 00000000..8246cbf6 --- /dev/null +++ b/generator/templates/base_template.js @@ -0,0 +1,43 @@ +/* +* Copyright (c) {{year}}, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ +{% for e in imports %} +import {{'%s %s %s'|format('{', e.what, '}')}} from '{{e.wherefrom}}'; +{%- endfor %} +{% block typedef %}{% endblock %} +class {{name}} extends {{extend}} { +{%- block body %} +{% endblock -%} +} +{% block properties %} +{% endblock %} + +export {{'%s %s %s'|format('{', name, '}')}}; diff --git a/generator/templates/enum_template.js b/generator/templates/enum_template.js new file mode 100644 index 00000000..afe46a5e --- /dev/null +++ b/generator/templates/enum_template.js @@ -0,0 +1,70 @@ +{% extends 'base_template.js' %} +{% block typedef %} +/** + {% if description is defined -%} + {% for d in description -%} + * {{d}} + {% endfor -%} + {% endif -%} + {% if deprecated is defined -%} + * @deprecated + {% endif -%} + * @typedef {{'%s%s%s %s'|format('{', extend, '}', name)}} + * @property {Object} _MAP + */ +{%- endblock %} +{% block body %} + /** + {%- if deprecated is defined %} + * @deprecated + {%- endif %} + * @constructor + */ + constructor () { + super(); + } + {%- for e in methods %} + + /** + {%- if deprecated is defined %} + * @deprecated + {%- endif %} + {%- for d in e.description %} + * {{d}} + {%- endfor %} + * @return {{'%s%s%s'|format('{', e.type, '}')}} + */ + static get {{e.method_title}} () { + return {{name}}._MAP.{{e.method_title}}; + } + {%- endfor %} +{% if scripts is defined -%} + {%- for s in scripts %} +{{s|indent(4,True)}} + {%- endfor %} +{% endif %} + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + static valueForKey (key) { + return {{name}}._valueForKey(key, {{name}}._MAP); + } + + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + static keyForValue (value) { + return {{name}}._keyForValue(value, {{name}}._MAP); + } +{% endblock %} +{% block properties %} +{{name}}._MAP = Object.freeze({ +{%- for e in params %} + '{{e.key}}': {{e.value}}, +{%- endfor %} +}); +{%- endblock %} \ No newline at end of file diff --git a/generator/templates/function_template.js b/generator/templates/function_template.js new file mode 100644 index 00000000..549751c6 --- /dev/null +++ b/generator/templates/function_template.js @@ -0,0 +1,7 @@ +{% extends 'base_struct_function.js' %} +{% block constructor %} + constructor (store) { + super(store); + this.setFunctionName(FunctionID.{{ func }}); + } +{% endblock %} \ No newline at end of file diff --git a/generator/templates/scripts/FunctionID_keyForValue.js b/generator/templates/scripts/FunctionID_keyForValue.js new file mode 100644 index 00000000..95d2d7e8 --- /dev/null +++ b/generator/templates/scripts/FunctionID_keyForValue.js @@ -0,0 +1,8 @@ +/** + * Returns the key of the map with the corresponding value + * @param {Number} value + * @return {null|String} - Returns null if not found + */ +static keyForValue (value) { + return FunctionID.keyForValueInternal(value, FunctionID._MAP); +} \ No newline at end of file diff --git a/generator/templates/scripts/PutFileRequest.js b/generator/templates/scripts/PutFileRequest.js new file mode 100644 index 00000000..33b771e0 --- /dev/null +++ b/generator/templates/scripts/PutFileRequest.js @@ -0,0 +1,18 @@ +// ------ Not part of the RPC spec itself ----- + +/** + * @param {Uint8Array} fileData + * @return {PutFile} + */ +setFileData(fileData) { + this.setBulkData(fileData); + return this; +} +/** + * @return {Uint8Array} + */ +getFileData() { + return this.getBulkData(); +} + +//----------------- END ----------------------- \ No newline at end of file diff --git a/generator/templates/scripts/fullAppID.js b/generator/templates/scripts/fullAppID.js new file mode 100644 index 00000000..bfd44e71 --- /dev/null +++ b/generator/templates/scripts/fullAppID.js @@ -0,0 +1,49 @@ +/** + * @param {String} fullAppId + * @return {RegisterAppInterface} + */ +setFullAppId (fullAppId) { + this.validateType(String, fullAppId); + + if (fullAppId !== null) { + fullAppId = fullAppId.toLowerCase(); + this.setParameter(RegisterAppInterface.KEY_FULL_APP_ID, fullAppId); + let appID; + if (fullAppId.length <= RegisterAppInterface.APP_ID_MAX_LENGTH) { + appID = fullAppId; + } else { + appID = fullAppId.replace('-', '').substring(0, RegisterAppInterface.APP_ID_MAX_LENGTH); + } + this._setAppId(appID); + } else { + this.setParameter(RegisterAppInterface.KEY_FULL_APP_ID, null); + } + + return this; +} + +/** + * @return {String} the app id + */ +getFullAppId () { + return this.getParameter(RegisterAppInterface.KEY_FULL_APP_ID); +} + +/** + * @param {String} appId - This method should not be accessed directly by developers. Only set the full ID and this + * param will be set. + * @return {RegisterAppInterface} + */ +_setAppId (appId) { + this.validateType(String, appId); + + this.setParameter(RegisterAppInterface.KEY_APP_ID, appId); + return this; +} + +/** + * @return {String} the app id + */ +getAppId () { + return this.getParameter(RegisterAppInterface.KEY_APP_ID); +} \ No newline at end of file diff --git a/generator/templates/struct_template.js b/generator/templates/struct_template.js new file mode 100644 index 00000000..d8027553 --- /dev/null +++ b/generator/templates/struct_template.js @@ -0,0 +1,6 @@ +{% extends 'base_struct_function.js' %} +{% block constructor %} + constructor (parameters) { + super(parameters); + } +{% endblock %} diff --git a/generator/test/__init__.py b/generator/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/generator/test/runner.py b/generator/test/runner.py new file mode 100644 index 00000000..c2b0ebab --- /dev/null +++ b/generator/test/runner.py @@ -0,0 +1,41 @@ +"""Main entry point to run all tests + +""" + +import sys +from pathlib import Path +from unittest import TestLoader, TestSuite, TextTestRunner + +PATH = Path(__file__).absolute() + +sys.path.append(PATH.parents[2].joinpath('lib/rpc_spec/InterfaceParser').as_posix()) +sys.path.append(PATH.parents[1].as_posix()) + +try: + from test_enums import TestEnumsProducer + from test_functions import TestFunctionsProducer + from test_structs import TestStructsProducer + from test_code_format_and_quality import CodeFormatAndQuality +except ModuleNotFoundError as message: + print('{}.\nProbably you did not initialize submodule'.format(message)) + sys.exit(1) + + +def main(): + """ + Main entry point to run all tests + """ + suite = TestSuite() + + suite.addTests(TestLoader().loadTestsFromTestCase(TestFunctionsProducer)) + suite.addTests(TestLoader().loadTestsFromTestCase(TestEnumsProducer)) + suite.addTests(TestLoader().loadTestsFromTestCase(TestStructsProducer)) + suite.addTests(TestLoader().loadTestsFromTestCase(CodeFormatAndQuality)) + + runner = TextTestRunner(verbosity=2) + test_result = runner.run(suite) + print(test_result) + + +if __name__ == '__main__': + main() diff --git a/generator/test/test_code_format_and_quality.py b/generator/test/test_code_format_and_quality.py new file mode 100755 index 00000000..45b12ca5 --- /dev/null +++ b/generator/test/test_code_format_and_quality.py @@ -0,0 +1,36 @@ +"""Interface model unit test + +""" + +import unittest +from os import walk +from os.path import join +from pathlib import Path + +from pylint.lint import Run + + +class CodeFormatAndQuality(unittest.TestCase): + MINIMUM_SCORE = 9 + + def setUp(self): + """Searching for all python files to be checked + + """ + self.list_of_files = [] + for (directory, _, filenames) in walk(Path(__file__).absolute().parents[1].as_posix()): + self.list_of_files += [join(directory, file) for file in filenames + if file.endswith('.py') and not file.startswith('test')] + self.list_of_files.append('--max-line-length=120') + + def test_check(self): + """Performing checks by PyLint + + """ + results = Run(self.list_of_files, do_exit=False) + score = results.linter.stats['global_note'] + self.assertGreaterEqual(score, self.MINIMUM_SCORE) + + +if __name__ == "__main__": + unittest.main() diff --git a/generator/test/test_enums.py b/generator/test/test_enums.py new file mode 100644 index 00000000..2eb50f2f --- /dev/null +++ b/generator/test/test_enums.py @@ -0,0 +1,65 @@ +from collections import namedtuple +from datetime import date +from unittest import TestCase + +from transformers.enums_producer import EnumsProducer +from model.enum import Enum +from model.enum_element import EnumElement + + +class TestEnumsProducer(TestCase): + def setUp(self): + self.maxDiff = None + Prop = namedtuple('Prop', 'enums_dir_name structs_dir_name path_to_enum_class') + paths = Prop(enums_dir_name='../enums', + structs_dir_name='../structs', + path_to_enum_class='../../util/Enum.js') + self.producer = EnumsProducer(paths) + + def test_FunctionID(self): + item = Enum(name='FunctionID', elements={ + 'RESERVED': EnumElement(name='RESERVED', value=0), + 'RegisterAppInterfaceID': EnumElement(name='RegisterAppInterfaceID', hexvalue=1), + 'PerformAudioPassThruID': EnumElement(name='PerformAudioPassThruID', hexvalue=10) + }) + expected = { + 'name': 'FunctionID', + 'imports': [self.producer.imports(what='Enum', wherefrom='../../util/Enum.js')], + 'methods': [self.producer.methods(origin='RESERVED', + method_title='RESERVED', + description=[], type='Number'), + self.producer.methods(origin='RegisterAppInterfaceID', + method_title='RegisterAppInterface', + description=[], type='Number'), + self.producer.methods(origin='PerformAudioPassThruID', + method_title='PerformAudioPassThru', + description=[], type='Number')], + 'params': [self.producer.params(key='RESERVED', value=0), + self.producer.params(key='RegisterAppInterface', value='0x01'), + self.producer.params(key='PerformAudioPassThru', value='0x10')], + 'extend': 'Enum' + } + result = self.producer.transform(item) + self.assertEqual(expected['name'], result['name']) + self.assertListEqual(sorted(expected['imports']), sorted(result['imports'])) + self.assertListEqual(sorted(expected['methods']), sorted(result['methods'])) + self.assertListEqual(sorted(expected['params']), sorted(result['params'])) + self.assertEqual(expected['extend'], result['extend']) + + def test_Result(self): + item = Enum(name='Result', elements={ + 'SUCCESS': EnumElement(name='SUCCESS') + }) + expected = { + 'year': date.today().year, + 'name': 'Result', + 'file_name': 'Result', + 'imports': [self.producer.imports(what='Enum', wherefrom='../../util/Enum.js')], + 'methods': tuple([self.producer.methods(origin='SUCCESS', + method_title='SUCCESS', + description=[], type='String')]), + 'params': tuple([self.producer.params(key='SUCCESS', value="'SUCCESS'")]), + 'extend': 'Enum' + } + result = self.producer.transform(item) + self.assertEqual(expected, result) diff --git a/generator/test/test_functions.py b/generator/test/test_functions.py new file mode 100644 index 00000000..1cffd645 --- /dev/null +++ b/generator/test/test_functions.py @@ -0,0 +1,269 @@ +from collections import namedtuple +from unittest import TestCase + +from transformers.functions_producer import FunctionsProducer +from model.array import Array +from model.boolean import Boolean +from model.enum import Enum +from model.enum_element import EnumElement +from model.function import Function +from model.integer import Integer +from model.param import Param +from model.string import String +from model.struct import Struct + + +class TestFunctionsProducer(TestCase): + def setUp(self): + self.maxDiff = None + Prop = namedtuple('Prop', + 'functions_dir_name enums_dir_name structs_dir_name path_to_request_class ' + 'path_to_response_class path_to_notification_class') + paths = Prop(functions_dir_name='../messages', + enums_dir_name='../enums', + structs_dir_name='../structs', + path_to_request_class='../RpcRequest.js', + path_to_response_class='../RpcResponse.js', + path_to_notification_class='../RpcNotification.js') + + mapping = {"functions": { + "RegisterAppInterfaceRequest": { + "syncMsgVersion": { + "imports": { + "what": "SdlMsgVersion", + "wherefrom": "../structs/SdlMsgVersion.js" + }, + "methods": { + "method_title": "SdlMsgVersion", + "external": "SdlMsgVersion", + "key": "KEY_SDL_MSG_VERSION", + "type": "SdlMsgVersion" + }, + "params": { + "key": "KEY_SDL_MSG_VERSION" + } + }, + "fullAppID": { + "script": "templates/scripts/fullAppID.js" + }, + "params_additional": [ + { + "key": "APP_ID_MAX_LENGTH", + "value": 10 + } + ] + }, + "RegisterAppInterfaceResponse": { + "script": "templates/scripts/notExist.js" + }, + "PutFileRequest": { + "script": "templates/scripts/PutFileRequest.js" + }}} + + enum_names = ('FileType', 'Language') + struct_names = ('SyncMsgVersion', 'TemplateColorScheme', 'TTSChunk', 'Choice') + self.producer = FunctionsProducer(paths, enum_names, struct_names, mapping) + + def test_RegisterAppInterfaceRequest(self): + item = Function(name='RegisterAppInterface', function_id=Enum(name='RegisterAppInterfaceID'), + message_type=EnumElement(name='request'), params= + { + 'syncMsgVersion': Param(name='syncMsgVersion', param_type= + Struct(name='SyncMsgVersion', description=['Specifies the'], members={ + 'majorVersion': Param(name='majorVersion', param_type=Integer()) + }), description=['See SyncMsgVersion']), + 'fullAppID': Param(name='fullAppID', description=['ID used'], param_type=String()), + 'dayColorScheme': Param(name='dayColorScheme', param_type= + Struct(name='TemplateColorScheme', description= + ['\n A color scheme for all display layout templates.\n '])), + 'ttsName': Param(name='ttsName', description=['\n TTS string for'], param_type= + Array(element_type=Struct(name='TTSChunk', description=['A TTS chunk']))) + }) + expected = { + 'name': 'RegisterAppInterface', + 'imports': [self.producer.imports(what='SdlMsgVersion', wherefrom='../structs/SdlMsgVersion.js'), + self.producer.imports(what='TemplateColorScheme', + wherefrom='../structs/TemplateColorScheme.js'), + self.producer.imports(what='TTSChunk', wherefrom='../structs/TTSChunk.js'), + self.producer.imports(what='RpcRequest', wherefrom='../RpcRequest.js'), + self.producer.imports(what='FunctionID', wherefrom='../enums/FunctionID.js')], + 'methods': [self.producer.methods(origin='syncMsgVersion', key='KEY_SDL_MSG_VERSION', + method_title='SdlMsgVersion', external='SdlMsgVersion', + description=['See SyncMsgVersion'], param_name='version', + type='SdlMsgVersion'), + self.producer.methods(origin='fullAppID', key='KEY_FULL_APP_ID', method_title='FullAppID', + external=None, description=['ID used'], param_name='id', type='String'), + self.producer.methods(origin='dayColorScheme', key='KEY_DAY_COLOR_SCHEME', param_name='scheme', + method_title='DayColorScheme', external='TemplateColorScheme', + description=['A color scheme for all display layout templates.'], + type='TemplateColorScheme'), + self.producer.methods(origin='ttsName', key='KEY_TTS_NAME', param_name='name', + method_title='TtsName', external='TTSChunk', + description=['TTS string for'], type='Array')], + 'params': [self.producer.params(key='APP_ID_MAX_LENGTH', value=10), + self.producer.params(key='KEY_SDL_MSG_VERSION', value="'syncMsgVersion'"), + self.producer.params(key='KEY_FULL_APP_ID', value="'fullAppID'"), + self.producer.params(key='KEY_DAY_COLOR_SCHEME', value="'dayColorScheme'"), + self.producer.params(key='KEY_TTS_NAME', value="'ttsName'")], + 'scripts': [self.producer.get_file_content('templates/scripts/fullAppID.js')], + 'func': 'RegisterAppInterface', + 'extend': 'RpcRequest' + } + result = self.producer.transform(item) + self.assertEqual(expected['name'], result['name']) + self.assertListEqual(sorted(expected['imports']), sorted(result['imports'])) + self.assertListEqual(sorted(expected['methods']), sorted(result['methods'])) + self.assertListEqual(sorted(expected['params']), sorted(result['params'])) + self.assertEqual(expected['func'], result['func']) + self.assertEqual(expected['extend'], result['extend']) + + def test_RegisterAppInterfaceResponse(self): + item = Function(name='RegisterAppInterface', function_id=Enum(name='RegisterAppInterfaceID'), + description=['The response '], + message_type=EnumElement(name='response'), params= + { + 'success': Param(name='success', param_type=Boolean(), description=[' true if ']), + 'language': Param(name='language', param_type= + Enum(name='Language', elements={ + 'EN-US': EnumElement(name='EN-US', description=['English - US']) + }), description=['The currently']), + 'supportedDiagModes': Param(name='supportedDiagModes', param_type= + Array(element_type=Integer()), description=['\n Specifies the'], ) + }) + expected = { + 'name': 'RegisterAppInterfaceResponse', + 'imports': [self.producer.imports(what='Language', wherefrom='../enums/Language.js'), + self.producer.imports(what='RpcResponse', wherefrom='../RpcResponse.js'), + self.producer.imports(what='FunctionID', wherefrom='../enums/FunctionID.js')], + 'methods': [self.producer.methods(origin='language', key='KEY_LANGUAGE', + method_title='Language', external='Language', + description=['The currently'], param_name='language', + type='Language'), + self.producer.methods(origin='supportedDiagModes', key='KEY_SUPPORTED_DIAG_MODES', + method_title='SupportedDiagModes', external=None, + description=['Specifies the'], param_name='modes', + type='Array')], + 'params': [self.producer.params(key='KEY_LANGUAGE', value="'language'"), + self.producer.params(key='KEY_SUPPORTED_DIAG_MODES', value="'supportedDiagModes'")], + 'description': ['The response'], + 'func': 'RegisterAppInterface', + 'extend': 'RpcResponse' + } + result = self.producer.transform(item) + self.assertEqual(expected['name'], result['name']) + self.assertListEqual(sorted(expected['imports']), sorted(result['imports'])) + self.assertListEqual(sorted(expected['methods']), sorted(result['methods'])) + self.assertListEqual(sorted(expected['params']), sorted(result['params'])) + self.assertEqual(expected['description'], result['description']) + self.assertEqual(expected['func'], result['func']) + self.assertEqual(expected['extend'], result['extend']) + + def test_UnregisterAppInterfaceRequest(self): + item = Function(name='UnregisterAppInterface', function_id=Enum(name='UnregisterAppInterfaceID'), + message_type=EnumElement(name='request'), params={}) + expected = { + 'name': 'UnregisterAppInterface', + 'imports': [self.producer.imports(what='RpcRequest', wherefrom='../RpcRequest.js'), + self.producer.imports(what='FunctionID', wherefrom='../enums/FunctionID.js')], + 'func': 'UnregisterAppInterface', + 'extend': 'RpcRequest' + } + result = self.producer.transform(item) + self.assertEqual(expected['name'], result['name']) + self.assertListEqual(sorted(expected['imports']), sorted(result['imports'])) + self.assertEqual(expected['func'], result['func']) + self.assertEqual(expected['extend'], result['extend']) + + def test_PutFileRequest(self): + item = Function(name='PutFile', function_id=Enum(name='PutFileID'), description=['\n Used to'], + message_type=EnumElement(name='request'), params= + { + 'fileType': Param(name='fileType', param_type= + Enum(name='FileType', description=['Enumeration listing'], elements={ + 'AUDIO_MP3': EnumElement(name='AUDIO_MP3') + }), description=['Selected file type.']) + }) + expected = { + 'name': 'PutFile', + 'imports': [self.producer.imports(what='FileType', wherefrom='../enums/FileType.js'), + self.producer.imports(what='RpcRequest', wherefrom='../RpcRequest.js'), + self.producer.imports(what='FunctionID', wherefrom='../enums/FunctionID.js')], + 'methods': [self.producer.methods(origin='fileType', key='KEY_FILE_TYPE', + method_title='FileType', external='FileType', + description=['Selected file type.'], param_name='type', + type='FileType')], + 'params': [self.producer.params(key='KEY_FILE_TYPE', value="'fileType'")], + 'description': ['Used to'], + 'scripts': [self.producer.get_file_content('templates/scripts/PutFileRequest.js')], + 'func': 'PutFile', + 'extend': 'RpcRequest' + } + result = self.producer.transform(item) + self.assertEqual(expected['name'], result['name']) + self.assertListEqual(sorted(expected['imports']), sorted(result['imports'])) + self.assertListEqual(sorted(expected['methods']), sorted(result['methods'])) + self.assertListEqual(sorted(expected['params']), sorted(result['params'])) + self.assertEqual(expected['description'], result['description']) + self.assertSequenceEqual(expected['scripts'], result['scripts']) + self.assertEqual(expected['func'], result['func']) + self.assertEqual(expected['extend'], result['extend']) + + def test_OnEncodedSyncPDataNotification(self): + item = Function(name='OnEncodedSyncPData', function_id=Enum(name='OnEncodedSyncPDataID'), + description=['\n Callback including \n'], + message_type=EnumElement(name='notification'), params= + { + 'URL': Param(name='URL', param_type=String(), description=['\n If ']) + }) + expected = { + 'name': 'OnEncodedSyncPData', + 'imports': [self.producer.imports(what='RpcNotification', wherefrom='../RpcNotification.js'), + self.producer.imports(what='FunctionID', wherefrom='../enums/FunctionID.js')], + 'methods': [self.producer.methods(origin='URL', key='KEY_URL', + method_title='URL', external=None, + description=['If'], param_name='url', + type='String')], + 'params': [self.producer.params(key='KEY_URL', value="'URL'")], + 'description': ['Callback including'], + 'func': 'OnEncodedSyncPData', + 'extend': 'RpcNotification' + } + result = self.producer.transform(item) + self.assertEqual(expected['name'], result['name']) + self.assertListEqual(sorted(expected['imports']), sorted(result['imports'])) + self.assertListEqual(sorted(expected['methods']), sorted(result['methods'])) + self.assertListEqual(sorted(expected['params']), sorted(result['params'])) + self.assertEqual(expected['description'], result['description']) + self.assertEqual(expected['func'], result['func']) + self.assertEqual(expected['extend'], result['extend']) + + def test_CreateInteractionChoiceSetRequest(self): + item = Function(name='CreateInteractionChoiceSet', function_id=Enum(name='CreateInteractionChoiceSetID'), + description=['creates interaction'], + message_type=EnumElement(name='request'), params= + { + 'choiceSet': Param(name='choiceSet', param_type= + Array(element_type=Struct(name='Choice', description=['A choice is an option given to ']))) + }) + expected = { + 'name': 'CreateInteractionChoiceSet', + 'imports': [self.producer.imports(what='Choice', wherefrom='../structs/Choice.js'), + self.producer.imports(what='RpcRequest', wherefrom='../RpcRequest.js'), + self.producer.imports(what='FunctionID', wherefrom='../enums/FunctionID.js')], + 'methods': [self.producer.methods(origin='choiceSet', key='KEY_CHOICE_SET', + method_title='ChoiceSet', external='Choice', + description=['A choice is an option given to'], param_name='set', + type='Array')], + 'params': [self.producer.params(key='KEY_CHOICE_SET', value="'choiceSet'")], + 'description': ['creates interaction'], + 'func': 'CreateInteractionChoiceSet', + 'extend': 'RpcRequest' + } + result = self.producer.transform(item) + self.assertEqual(expected['name'], result['name']) + self.assertListEqual(sorted(expected['imports']), sorted(result['imports'])) + self.assertListEqual(sorted(expected['methods']), sorted(result['methods'])) + self.assertListEqual(sorted(expected['params']), sorted(result['params'])) + self.assertEqual(expected['description'], result['description']) + self.assertEqual(expected['func'], result['func']) + self.assertEqual(expected['extend'], result['extend']) diff --git a/generator/test/test_structs.py b/generator/test/test_structs.py new file mode 100644 index 00000000..8b174c7c --- /dev/null +++ b/generator/test/test_structs.py @@ -0,0 +1,37 @@ +from collections import namedtuple +from datetime import date +from unittest import TestCase + +from transformers.structs_producer import StructsProducer +from model.param import Param +from model.struct import Struct + + +class TestStructsProducer(TestCase): + def setUp(self): + self.maxDiff = None + Prop = namedtuple('Prop', 'structs_dir_name enums_dir_name path_to_struct_class') + paths = Prop(enums_dir_name='../enums', + structs_dir_name='../structs', + path_to_struct_class='../RpcStruct.js') + + self.producer = StructsProducer(paths, (), ('Image',)) + + def test_SoftButton(self): + item = Struct(name='SoftButton', members={ + 'image': Param(name='image', param_type=Struct(name='Image'), description=['Optional image']), + }) + expected = { + 'year': date.today().year, + 'name': 'SoftButton', + 'file_name': 'SoftButton', + 'imports': [self.producer.imports(what='Image', wherefrom='./Image.js'), + self.producer.imports(what='RpcStruct', wherefrom='../RpcStruct.js')], + 'methods': tuple([self.producer.methods(description=['Optional image'], external='Image', + key='KEY_IMAGE', method_title='Image', + origin='image', param_name='image', type='Image')]), + 'params': tuple([self.producer.params(key='KEY_IMAGE', value="'image'")]), + 'extend': 'RpcStruct' + } + result = self.producer.transform(item) + self.assertEqual(expected, result) diff --git a/generator/transformers/__init__.py b/generator/transformers/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/generator/transformers/common_producer.py b/generator/transformers/common_producer.py new file mode 100644 index 00000000..d5e57bca --- /dev/null +++ b/generator/transformers/common_producer.py @@ -0,0 +1,301 @@ +""" +Common transformation +""" + +import logging +import re +import textwrap +from abc import ABC +from collections import namedtuple, OrderedDict +from datetime import date +from pathlib import Path + +from model.array import Array +from model.double import Double +from model.enum import Enum +from model.function import Function +from model.integer import Integer +from model.struct import Struct +from transformers.generate_error import GenerateError + + +class InterfaceProducerCommon(ABC): + """ + Common transformation + """ + version = '1.0.0' + + def __init__(self, container_name, enums_dir_name, structs_dir_name, + enum_names=(), struct_names=(), mapping=OrderedDict()): + self.logger = logging.getLogger(self.__class__.__name__) + self.container_name = container_name + self.enum_names = list(map(lambda e: self.replace_sync(e), enum_names)) + self.struct_names = list(map(lambda e: self.replace_sync(e), struct_names)) + self.enums_dir = enums_dir_name + self.structs_dir = structs_dir_name + self.mapping = mapping + + @property + def get_version(self): + """ + :return: current version of Generator + """ + return self.version + + @property + def imports(self): + """ + :return: namedtuple imports(what='', wherefrom='') + """ + return namedtuple('Imports', 'what wherefrom') + + @property + def methods(self): + """ + :return: namedtuple methods( + origin='', key='', method_title='', external='', description='', param_name='', type='',) + """ + return namedtuple('Methods', 'origin key method_title external description param_name type') + + @property + def params(self): + """ + :return: namedtuple params(key='', value='') + """ + return namedtuple('Params', 'key value') + + @staticmethod + def replace_sync(name): + """ + :param name: string with item name + :return: string with replaced 'sync' to 'Sdl' + """ + if name: + return re.sub(r'^(s|S)ync(.+)$', r'\1dl\2', name) + return name + + def transform(self, item) -> dict: + """ + :param item: particular element from initial Model + :return: dictionary to be applied to jinja2 template + """ + imports = {} + methods = {} + params = {} + + for param in getattr(item, self.container_name).values(): + if isinstance(item, Function) and item.message_type.name == 'response' and \ + param.name in ('success', 'resultCode', 'info'): + self.logger.warning('%s of type %s/%s - skip parameter "%s"', + item.name, type(item).__name__, item.message_type.name, param.name) + continue + + _import, _methods, _params = self.common_flow(param, type(item)) + + if _import: + imports.update(_import) + if _methods: + methods.update({param.name: _methods}) + params.update({param.name: _params}) + + name = self.replace_sync(item.name) + render = {'year': date.today().year, + 'file_name': name, + 'name': name, + 'imports': [self.imports(what=k, wherefrom=v) for k, v in imports.items()], + 'methods': methods, + 'params': params} + + if getattr(item, 'description', None): + render.update({'description': textwrap.wrap(self.extract_description(item.description), 116)}) + if item.deprecated: + render.update({'deprecated': item.deprecated}) + + self.custom_mapping(render, item) + + render.update({'params': tuple(render['params'].values())}) + render.update({'methods': tuple(render['methods'].values())}) + + return render + + def custom_mapping(self, render, item): + """ + :param render: dictionarry with data ready to apply to Jinja2 template + :param item: original item from parsed model + :return: + """ + if isinstance(item, Function): + mapping_name = item.name + item.message_type.name.capitalize() + else: + mapping_name = item.name + + if mapping_name not in self.mapping: + return + custom = self.mapping[mapping_name] + + if 'params_additional' in custom: + for param in custom['params_additional']: + render['params'].update({param['key']: self.params(**param)}) + del custom['params_additional'] + if 'script' in custom: + script = self.get_file_content(custom['script']) + if script: + if 'script' in render: + render['scripts'].append(script) + else: + render['scripts'] = [script] + del custom['script'] + + for name, mapping in custom.copy().items(): + for sub_name, sub_mapping in mapping.copy().items(): + if sub_name == '-methods': + del render['methods'][name] + del custom[name]['-methods'] + if sub_name == 'script': + script = self.get_file_content(sub_mapping) + if script: + if 'script' in render: + render['scripts'].append(script) + else: + render['scripts'] = [script] + del custom[name]['script'] + if sub_name in render and name in render[sub_name]: + render[sub_name][name] = render[sub_name][name]._replace(**sub_mapping) + del custom[name][sub_name] + if not custom[name]: + del custom[name] + + render.update(custom) + + def common_flow(self, param, item_type): + """ + Main transformation flow, for Struct and Function + :param param: sub-element (Param, FunctionParam) of element from initial Model + :param item_type: type of parent element from initial Model + :return: tuple with 3 element, which going to be applied to jinja2 template + """ + name, description = self.extract_name_description(param) + type_name = self.extract_type(param) + imports = None + if name: + if name in self.enum_names: + imports = {name: '{}/{}.js'.format(self.enums_dir, name)} + elif name in self.struct_names: + if item_type is Struct: + import_path = '.' + else: + import_path = self.structs_dir + imports = {name: '{}/{}.js'.format(import_path, name)} + param_name = self.replace_sync(param.name) + key = self.key(param_name) + + short_name = re.sub(r'(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])', '=^.^=', param_name) \ + .split('=^.^=').pop().lower() + description = textwrap.wrap(description, 100 - len(type_name) - len(short_name)) + title = param_name[:1].upper() + param_name[1:] + + methods = self.methods(origin=param.name, key=key, method_title=title, external=name, description=description, + param_name=short_name, type=type_name) + params = self.params(key=key, value="'{}'".format(param.name)) + return imports, methods, params + + def extract_imports(self, extend): + """ + Extract imports from property PATH_TO_(STRUCT|REQUEST|RESPONSE|NOTIFICATION)_CLASS + :param extend: property to be evaluated and converted to self.imports + :return: self.imports + """ + tmp = re.match(r'.+/(.+).js', extend) + if tmp: + return self.imports(what=tmp.group(1), wherefrom=extend) + raise GenerateError('Can not extract imports from {}'.format(extend)) + + @staticmethod + def key(param: str): + """ + Convert param string to uppercase and inserting underscores + :param param: camel case string + :return: string in uppercase with underscores + """ + if re.match(r'^[A-Z_]+$', param): + return 'KEY_' + param + return 'KEY_' + re.sub(r'([a-z]|[A-Z]{2,})([A-Z]|\d$)', r'\1_\2', param).upper() + + @staticmethod + def ending_cutter(name: str): + """ + If string not contains only uppercase letters and end with 'ID' deleting 'ID' from end of string + :param name: string to evaluate and deleting 'ID' from end of string + :return: if match cut string else original string + """ + if name.endswith('ID') and re.match(r'^(?=\w+[A-Z])(?=\w+[a-z])\w+$', name): + return name[:-2] + return name + + @staticmethod + def extract_description(description): + """ + Evaluate, align and delete @TODO + :param description: list with description + :return: evaluated string + """ + return re.sub(r'(\s{2,}|\n|\[@TODO.+)', ' ', ''.join(description)).strip() if description else '' + + def extract_name_description(self, param): + """ + Extracting and evaluating name, description from appropriate place + :param param: sub-element (Param, FunctionParam) of element from initial Model + :return: tuple with 2 element (name, description) + """ + name = None + description = None + if getattr(param, 'description', None): + description = param.description + + if getattr(param, 'primary_name', None): + name = param.primary_name + elif getattr(param, 'param_type', None): + if getattr(param.param_type, 'name', None): + name = param.param_type.name + if not description and getattr(param.param_type, 'description', None): + description = param.param_type.description + elif getattr(param.param_type, 'element_type', None) and \ + getattr(param.param_type.element_type, 'name', None): + name = param.param_type.element_type.name + if not description and getattr(param.param_type.element_type, 'description', None): + description = param.param_type.element_type.description + + return self.replace_sync(name), self.extract_description(description) + + def extract_type(self, param): + """ + Evaluate and extract type + :param param: sub-element (Param, FunctionParam) of element from initial Model + :return: string with sub-element type + """ + + def evaluate(instance): + if isinstance(instance, (Struct, Enum)): + return instance.name + if isinstance(instance, (Integer, Double)): + return 'Number' + return type(instance).__name__ + + if isinstance(param.param_type, Array): + return 'Array<{}>'.format(evaluate(param.param_type.element_type)) + return self.replace_sync(evaluate(param.param_type)) + + def get_file_content(self, file_name: str): + """ + Used for getting content of custom scripts used in custom mapping + :param file_name: relational path custom scripts + :return: string with content of custom scripts + """ + file_name = Path(__file__).absolute().parents[1].joinpath(file_name) + try: + with file_name.open('r') as file: + intermediate = file.readlines() + return ''.join(intermediate) + except FileNotFoundError as message: + self.logger.error(message) + return '' diff --git a/generator/transformers/enums_producer.py b/generator/transformers/enums_producer.py new file mode 100644 index 00000000..6852ac8e --- /dev/null +++ b/generator/transformers/enums_producer.py @@ -0,0 +1,94 @@ +""" +Enums transformation +""" + +import logging +import textwrap +from collections import namedtuple + +from model.enum import Enum +from model.enum_element import EnumElement +from transformers.common_producer import InterfaceProducerCommon + + +class EnumsProducer(InterfaceProducerCommon): + """ + Enums transformation + """ + + def __init__(self, paths, mapping=None): + super(EnumsProducer, self).__init__( + container_name='elements', + enums_dir_name=paths.enums_dir_name, + structs_dir_name=paths.structs_dir_name, + mapping=mapping['enums'] if mapping and 'enums' in mapping else {}) + self.logger = logging.getLogger(self.__class__.__name__) + self.enum_class = paths.path_to_enum_class + + @property + def methods(self): + """ + Override + :return: namedtuple methods(origin='', method_title='', description='', type='') + """ + return namedtuple('Methods', 'origin method_title description type') + + def transform(self, item: Enum) -> dict: + """ + Override + :param item: particular element from initial Model + :return: dictionary to be applied to jinja2 template + """ + tmp = super(EnumsProducer, self).transform(item) + what_where = self.extract_imports(self.enum_class) + tmp.update({'extend': what_where.what}) + tmp['imports'].append(what_where) + return tmp + + def common_flow(self, param: EnumElement, item_type=None): + """ + Override + Main transformation flow, for Enum + :param param: sub-element (EnumElement) of element from initial Model + :param item_type: not used + :return: tuple with 3 element, which going to be applied to jinja2 template + """ + (name, description) = self.extract_name_description(param) + type_name = self.extract_type(param) + description = textwrap.wrap(description, 117 - len(type_name)) + name = self.ending_cutter(name) + + methods = self.methods(origin=param.name, method_title=name, description=description, type=type_name) + params = self.extract_param(param) + + imports = None + return imports, methods, params + + def extract_param(self, param: EnumElement) -> namedtuple: + """ + Evaluate and extract params + :param param: sub-element (EnumElement) of element from initial Model + :return: self.params + """ + if getattr(param, 'hexvalue', None) is not None: + if len(str(param.hexvalue)) > 1: + value = '0x{}'.format(param.hexvalue) + else: + value = '0x0{}'.format(param.hexvalue) + elif getattr(param, 'value', None) is not None: + value = param.value + else: + value = "'{}'".format(param.name) + return self.params(key=self.ending_cutter(param.primary_name), value=value) + + @staticmethod + def extract_type(param: EnumElement) -> str: + """ + Override + Evaluate and extract type + :param param: sub-element (EnumElement) of element from initial Model + :return: string with sub-element type + """ + if getattr(param, 'hexvalue', None) is not None or getattr(param, 'value', None) is not None: + return 'Number' + return 'String' diff --git a/generator/transformers/functions_producer.py b/generator/transformers/functions_producer.py new file mode 100644 index 00000000..31651707 --- /dev/null +++ b/generator/transformers/functions_producer.py @@ -0,0 +1,51 @@ +""" +Functions transformation +""" +import logging + +from model.function import Function +from transformers.common_producer import InterfaceProducerCommon + + +class FunctionsProducer(InterfaceProducerCommon): + """ + Functions transformation + """ + + def __init__(self, paths, enum_names, struct_names, mapping=None): + super(FunctionsProducer, self).__init__( + container_name='params', + enums_dir_name=paths.enums_dir_name, + structs_dir_name=paths.structs_dir_name, + enum_names=enum_names, + struct_names=struct_names, + mapping=mapping['functions'] if mapping and 'functions' in mapping else {}) + self.logger = logging.getLogger(self.__class__.__name__) + self.request_class = paths.path_to_request_class + self.response_class = paths.path_to_response_class + self.notification_class = paths.path_to_notification_class + + def transform(self, item: Function) -> dict: + """ + Override + :param item: particular element from initial Model + :return: dictionary to be applied to jinja2 template + """ + render = super(FunctionsProducer, self).transform(item) + render.update({'func': self.ending_cutter(item.function_id.name)}) + if item.message_type.name == 'response': + render.update({'file_name': item.name + item.message_type.name.capitalize()}) + name = None + if item.message_type.name == 'request': + name = self.request_class + elif item.message_type.name == 'response': + name = self.response_class + render['name'] = render['name'] + 'Response' + elif item.message_type.name == 'notification': + name = self.notification_class + if name: + what_where = self.extract_imports(name) + render.update({'extend': what_where.what}) + render['imports'].append(what_where) + render['imports'].append(self.imports(what='FunctionID', wherefrom='{}/FunctionID.js'.format(self.enums_dir))) + return render diff --git a/generator/transformers/generate_error.py b/generator/transformers/generate_error.py new file mode 100644 index 00000000..3fe1a75e --- /dev/null +++ b/generator/transformers/generate_error.py @@ -0,0 +1,12 @@ +""" +Generate error. +""" + + +class GenerateError(Exception): + """Generate error. + + This exception is raised when generator is unable to create + output from given model. + + """ diff --git a/generator/transformers/structs_producer.py b/generator/transformers/structs_producer.py new file mode 100644 index 00000000..e49609db --- /dev/null +++ b/generator/transformers/structs_producer.py @@ -0,0 +1,37 @@ +""" +Structs transformation +""" + +import logging + +from model.struct import Struct +from transformers.common_producer import InterfaceProducerCommon + + +class StructsProducer(InterfaceProducerCommon): + """ + Structs transformation + """ + + def __init__(self, paths, enum_names, struct_names, mapping=None): + super(StructsProducer, self).__init__( + container_name='members', + enums_dir_name=paths.enums_dir_name, + structs_dir_name=paths.structs_dir_name, + enum_names=enum_names, + struct_names=struct_names, + mapping=mapping['structs'] if mapping and 'structs' in mapping else {}) + self.logger = logging.getLogger(self.__class__.__name__) + self.struct_class = paths.path_to_struct_class + + def transform(self, item: Struct) -> dict: + """ + Override + :param item: particular element from initial Model + :return: dictionary to be applied to jinja2 template + """ + tmp = super(StructsProducer, self).transform(item) + what_where = self.extract_imports(self.struct_class) + tmp.update({'extend': what_where.what}) + tmp['imports'].append(what_where) + return tmp diff --git a/lib/rpc_spec b/lib/rpc_spec new file mode 160000 index 00000000..c87eb000 --- /dev/null +++ b/lib/rpc_spec @@ -0,0 +1 @@ +Subproject commit c87eb000ed8860da48f840838ef4dc5da09a7541 From aa302099c0b873e43c12fa179cad2cee2a61c0a0 Mon Sep 17 00:00:00 2001 From: Vladyslav Mustafin Date: Wed, 15 Jan 2020 18:41:59 +0200 Subject: [PATCH 02/19] Pointed `lib/rpc_spec` submodule to the personal fork for testing purposes --- .gitmodules | 2 +- lib/rpc_spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 816169a9..957d3aa9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "lib/rpc_spec"] path = lib/rpc_spec - url = git@github.com:smartdevicelink/rpc_spec.git + url = git@github.com:vladmu/rpc_spec.git branch = master diff --git a/lib/rpc_spec b/lib/rpc_spec index c87eb000..3e03b65a 160000 --- a/lib/rpc_spec +++ b/lib/rpc_spec @@ -1 +1 @@ -Subproject commit c87eb000ed8860da48f840838ef4dc5da09a7541 +Subproject commit 3e03b65a8861b545389b99e33d05ae61340f3c73 From 2e90da71415a5f541e5066d6cc4f6f62097771e4 Mon Sep 17 00:00:00 2001 From: Aleksandr Mishchenko Date: Thu, 16 Jan 2020 19:42:54 +0200 Subject: [PATCH 03/19] refactoring according to comments in pull/202 --- generator/generator.py | 2 +- generator/test/test_enums.py | 4 ++-- generator/transformers/common_producer.py | 4 ++-- generator/transformers/enums_producer.py | 10 +++++----- lib/rpc_spec | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/generator/generator.py b/generator/generator.py index b6588500..e8366cba 100644 --- a/generator/generator.py +++ b/generator/generator.py @@ -396,7 +396,7 @@ def parser(self, xml, xsd, pattern=None): def evaluate_instance_directory(dir_name): """ :param dir_name: property from paths.ini (ENUMS|STRUCTS|FUNCTIONS)_DIR_NAME - :return: substring after double dot + :return: substring after float dot """ pattern = re.search(r'^([./]*)(.+)', dir_name) if pattern: diff --git a/generator/test/test_enums.py b/generator/test/test_enums.py index 2eb50f2f..7b1a86a0 100644 --- a/generator/test/test_enums.py +++ b/generator/test/test_enums.py @@ -19,8 +19,8 @@ def setUp(self): def test_FunctionID(self): item = Enum(name='FunctionID', elements={ 'RESERVED': EnumElement(name='RESERVED', value=0), - 'RegisterAppInterfaceID': EnumElement(name='RegisterAppInterfaceID', hexvalue=1), - 'PerformAudioPassThruID': EnumElement(name='PerformAudioPassThruID', hexvalue=10) + 'RegisterAppInterfaceID': EnumElement(name='RegisterAppInterfaceID', hex_value=1), + 'PerformAudioPassThruID': EnumElement(name='PerformAudioPassThruID', hex_value=10) }) expected = { 'name': 'FunctionID', diff --git a/generator/transformers/common_producer.py b/generator/transformers/common_producer.py index d5e57bca..0098f36b 100644 --- a/generator/transformers/common_producer.py +++ b/generator/transformers/common_producer.py @@ -11,7 +11,7 @@ from pathlib import Path from model.array import Array -from model.double import Double +from model.float import Float from model.enum import Enum from model.function import Function from model.integer import Integer @@ -277,7 +277,7 @@ def extract_type(self, param): def evaluate(instance): if isinstance(instance, (Struct, Enum)): return instance.name - if isinstance(instance, (Integer, Double)): + if isinstance(instance, (Integer, Float)): return 'Number' return type(instance).__name__ diff --git a/generator/transformers/enums_producer.py b/generator/transformers/enums_producer.py index 6852ac8e..86d5dc1f 100644 --- a/generator/transformers/enums_producer.py +++ b/generator/transformers/enums_producer.py @@ -70,11 +70,11 @@ def extract_param(self, param: EnumElement) -> namedtuple: :param param: sub-element (EnumElement) of element from initial Model :return: self.params """ - if getattr(param, 'hexvalue', None) is not None: - if len(str(param.hexvalue)) > 1: - value = '0x{}'.format(param.hexvalue) + if getattr(param, 'hex_value', None) is not None: + if len(str(param.hex_value)) > 1: + value = '0x{}'.format(param.hex_value) else: - value = '0x0{}'.format(param.hexvalue) + value = '0x0{}'.format(param.hex_value) elif getattr(param, 'value', None) is not None: value = param.value else: @@ -89,6 +89,6 @@ def extract_type(param: EnumElement) -> str: :param param: sub-element (EnumElement) of element from initial Model :return: string with sub-element type """ - if getattr(param, 'hexvalue', None) is not None or getattr(param, 'value', None) is not None: + if getattr(param, 'hex_value', None) is not None or getattr(param, 'value', None) is not None: return 'Number' return 'String' diff --git a/lib/rpc_spec b/lib/rpc_spec index 3e03b65a..1af08b55 160000 --- a/lib/rpc_spec +++ b/lib/rpc_spec @@ -1 +1 @@ -Subproject commit 3e03b65a8861b545389b99e33d05ae61340f3c73 +Subproject commit 1af08b558a1cf72ddf4af76a5c4190bcf27db66a From 604bc1bb1091619928045ed9d49c4ff0fb44e571 Mon Sep 17 00:00:00 2001 From: Aleksandr Mishchenko Date: Tue, 21 Jan 2020 15:36:46 +0200 Subject: [PATCH 04/19] align changes from parser rpc_spec --- lib/rpc_spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rpc_spec b/lib/rpc_spec index 1af08b55..8555a713 160000 --- a/lib/rpc_spec +++ b/lib/rpc_spec @@ -1 +1 @@ -Subproject commit 1af08b558a1cf72ddf4af76a5c4190bcf27db66a +Subproject commit 8555a7139c7b10524d98f41cef554c77746f5d6a From 8d452a64d8cdf65629f95d272812e1c360485e50 Mon Sep 17 00:00:00 2001 From: Aleksandr Mishchenko Date: Thu, 23 Jan 2020 10:34:03 +0200 Subject: [PATCH 05/19] align with rpc_spec --- lib/rpc_spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rpc_spec b/lib/rpc_spec index 8555a713..a6c66dfc 160000 --- a/lib/rpc_spec +++ b/lib/rpc_spec @@ -1 +1 @@ -Subproject commit 8555a7139c7b10524d98f41cef554c77746f5d6a +Subproject commit a6c66dfc989c2f7b94a77f8beb5d92bf1c910b9b From a227a486c6b4e9dcf15807b2b71f1a4695065f86 Mon Sep 17 00:00:00 2001 From: Aleksandr Mishchenko Date: Thu, 23 Jan 2020 11:00:09 +0200 Subject: [PATCH 06/19] minor chnages after code review --- generator/generator.py | 126 ++++++++++++++--------------------------- generator/mapping.json | 14 ----- 2 files changed, 41 insertions(+), 99 deletions(-) diff --git a/generator/generator.py b/generator/generator.py index e8366cba..8805a746 100644 --- a/generator/generator.py +++ b/generator/generator.py @@ -12,11 +12,9 @@ from os.path import basename from pprint import pformat from time import sleep -from xml.etree.ElementTree import ParseError as XMLSchemaError from jinja2 import Environment, FileSystemLoader, TemplateNotFound, UndefinedError from pathlib2 import Path -from xmlschema import XMLSchema ROOT = Path(__file__).absolute().parents[0] @@ -48,6 +46,9 @@ class Generator: def __init__(self): self.logger = logging.getLogger(self.__class__.__name__) self._env = None + self.paths_named = namedtuple('paths_named', 'path_to_enum_class path_to_struct_class path_to_request_class ' + 'path_to_response_class path_to_notification_class enums_dir_name ' + 'structs_dir_name functions_dir_name') @property def env(self): @@ -93,29 +94,6 @@ def config_logging(self, verbose): root_logger = logging.getLogger() root_logger.addHandler(handler) - def evaluate_source_xml_xsd(self, xml, xsd): - """ - :param xml: path to MOBILE_API.xml file - :param xsd: path to .xsd file (optional) - :return: validated path to .xsd file - """ - if not Path(xml).exists(): - self.logger.critical('File not found: %s', xml) - sys.exit(1) - - if xsd and Path(xsd).exists(): - return xsd - - replace = xml.replace('.xml', '.xsd') - if xsd and not Path(xsd).exists(): - self.logger.critical('File not found: %s', xsd) - sys.exit(1) - elif not xsd and not Path(replace).exists(): - self.logger.critical('File not found: %s', replace) - sys.exit(1) - else: - return replace - def evaluate_output_directory(self, output_directory): """ :param output_directory: path to output_directory @@ -206,14 +184,8 @@ def get_parser(self): print('\nThe user interrupted the execution of the program') sys.exit(1) - self.config_logging(args.verbose) - - args.source_xsd = self.evaluate_source_xml_xsd(args.source_xml, args.source_xsd) - args.output_directory = self.evaluate_output_directory(args.output_directory) - self.env = args.templates_directory - self.logger.info('parsed arguments:\n%s', pformat((vars(args)))) return args @@ -247,9 +219,7 @@ def get_paths(self, file_name=ROOT.joinpath('paths.ini')): :param file_name: path to file with Paths :return: namedtuple with Paths to key elements """ - fields = ('path_to_enum_class', 'path_to_struct_class', 'path_to_request_class', 'path_to_response_class', - 'path_to_notification_class', 'enums_dir_name', 'structs_dir_name', 'functions_dir_name') - intermediate = {} + data = {} try: with file_name.open('r') as file: for line in file: @@ -261,21 +231,20 @@ def get_paths(self, file_name=ROOT.joinpath('paths.ini')): self.logger.critical('can not evaluate value, too many separators %s', str(line)) sys.exit(1) name, var = line.partition('=')[::2] - if name.strip() in intermediate: + if name.strip() in data: self.logger.critical('duplicate key %s', name) sys.exit(1) - intermediate[name.strip().lower()] = var.strip() + data[name.strip().lower()] = var.strip() except FileNotFoundError as message1: self.logger.critical(message1) sys.exit(1) - for line in fields: - if line not in intermediate: - self.logger.critical('in %s missed fields: %s ', file, str(line)) - sys.exit(1) + missed = list(set(self.paths_named._fields) - set(data.keys())) + if missed: + self.logger.critical('in %s missed fields: %s ', file, str(missed)) + sys.exit(1) - Paths = namedtuple('Paths', ' '.join(fields)) - return Paths(**intermediate) + return self.paths_named(**data) def get_mappings(self, file_name=ROOT.joinpath('mapping.json')): """ @@ -318,8 +287,8 @@ def process(self, directory, skip, overwrite, items, transformer): """ directory.mkdir(parents=True, exist_ok=True) - template = type(items[0]).__name__.lower() + '_template.js' - for item in items: + for item in items.values(): + template = type(item).__name__.lower() + '_template.js' data = transformer.transform(item) file = directory.joinpath(data['file_name'] + '.js') if file.is_file(): @@ -347,49 +316,32 @@ def process(self, directory, skip, overwrite, items, transformer): self.logger.info('Writing new %s', file) self.write_file(file, template, data) - def parser(self, xml, xsd, pattern=None): + def filter_pattern(self, interface, pattern): """ - Validate xml to match with xsd. Calling parsers to get Model from xml. If provided pattern, filtering Model. - :param xml: path to MOBILE_API.xml - :param xsd: path to MOBILE_API.xsd + :param interface: initial Model :param pattern: regex-pattern from command-line arguments to filter element from initial Model :return: initial Model """ - self.logger.info('''Validating XML and generating model with following parameters: - Source xml : %s - Source xsd : %s''', xml, xsd) - - try: - schema = XMLSchema(xsd) - if not schema.is_valid(xml): - raise GenerateError(schema.validate(xml)) - interface = Parser().parse(xml) - except (InterfaceError, XMLSchemaError, GenerateError) as message1: - self.logger.critical('Invalid XML file content: %s, %s', xml, message1) - sys.exit(1) - enum_names = tuple(interface.enums.keys()) struct_names = tuple(interface.structs.keys()) if pattern: - intermediate = {} - intermediate.update({'params': interface.params}) - for kind, content in vars(interface).items(): - if kind == 'params': + match = {i: {} for i in vars(interface).keys()} + match['params'] = interface.params + for key, value in vars(interface).items(): + if key == 'params': continue - for name, item in content.items(): + for name, item in value.items(): if re.match(pattern, item.name): - self.logger.info('%s/%s match with %s', kind, item.name, pattern) - if kind in intermediate: - intermediate[kind].update({name: item}) + if hasattr(item, 'message_type'): + log = '{}/{} {} match with {}'.format(key, item.name, item.message_type.name.title(), + pattern) else: - intermediate.update({kind: {name: item}}) - interface = Interface(**intermediate) - - self.logger.debug({'enums': tuple(interface.enums.keys()), - 'structs': tuple(interface.structs.keys()), - 'functions': tuple(map(lambda i: i.function_id.name, interface.functions.values())), - 'params': interface.params}) + log = '{}/{} match with {}'.format(key, item.name, pattern) + self.logger.info(log) + if key in match: + match[key][name] = item + return enum_names, struct_names, Interface(**match) return enum_names, struct_names, interface @staticmethod @@ -409,26 +361,30 @@ def main(self): :return: None """ args = self.get_parser() + self.config_logging(args.verbose) + self.env = args.templates_directory self.versions_compatibility_validating() - enum_names, struct_names, interface = self.parser(xml=args.source_xml, xsd=args.source_xsd, - pattern=args.regex_pattern) - paths = self.get_paths() + + interface = Parser().parse(args.source_xml, args.source_xsd) + + enum_names, struct_names, filtered = self.filter_pattern(interface, args.regex_pattern) + mappings = self.get_mappings() - if args.enums and interface.enums: + if args.enums and filtered.enums: directory = args.output_directory.joinpath(self.evaluate_instance_directory(paths.enums_dir_name)) - self.process(directory, args.skip, args.overwrite, tuple(interface.enums.values()), + self.process(directory, args.skip, args.overwrite, filtered.enums, EnumsProducer(paths, mappings)) - if args.structs and interface.structs: + if args.structs and filtered.structs: directory = args.output_directory.joinpath(self.evaluate_instance_directory(paths.structs_dir_name)) - self.process(directory, args.skip, args.overwrite, tuple(interface.structs.values()), + self.process(directory, args.skip, args.overwrite, filtered.structs, StructsProducer(paths, enum_names, struct_names, mappings)) - if args.functions and interface.functions: + if args.functions and filtered.functions: directory = args.output_directory.joinpath(self.evaluate_instance_directory(paths.functions_dir_name)) - self.process(directory, args.skip, args.overwrite, tuple(interface.functions.values()), + self.process(directory, args.skip, args.overwrite, filtered.functions, FunctionsProducer(paths, enum_names, struct_names, mappings)) diff --git a/generator/mapping.json b/generator/mapping.json index 05fa6c5b..aa889af5 100644 --- a/generator/mapping.json +++ b/generator/mapping.json @@ -1,14 +1,4 @@ { - "enums": { - "DisplayType": { - "params_additional": [ - { - "key": "TESTING", - "value": "'TESTING'" - } - ] - } - }, "structs": { "DisplayCapabilities": { "graphicSupported": { @@ -131,10 +121,6 @@ } }, "script": "templates/scripts/PutFileRequest.js" - }, - "OnHMIStatus": { - "name": "OnHmiStatus", - "file_name": "OnHmiStatus" } } } From 3d33e2a85c24a9c668651bdde423522409ee46ae Mon Sep 17 00:00:00 2001 From: Vladyslav Mustafin Date: Fri, 24 Jan 2020 14:19:25 +0200 Subject: [PATCH 07/19] Fixed typo 'decription'->'description' --- generator/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/generator/README.md b/generator/README.md index de48273f..bfbd8480 100644 --- a/generator/README.md +++ b/generator/README.md @@ -105,7 +105,7 @@ The script should import the base Enum class and the produced class should exten The class should have the next JSDoc comment: ```javascript /** - * [decription] + * [description] * @typedef {Enum} [enum_name] * @property {Object} _MAP */ @@ -164,7 +164,7 @@ For each `` the static getter method should be defined in the class. Th The getter should have the next JSDoc comment: ```javascript /** - * [decription] + * [description] * @return {[enum_type]} */ ``` @@ -660,7 +660,7 @@ The constructor has one parameter named `parameters` to pass the JavaScript obje The class should have the next JSDoc comment: ```javascript /** - * [decription] + * [description] */ ``` Where `[description]` is `` of the current ``, if exists. @@ -724,7 +724,7 @@ For each `` the getter and setter methods should be defined in the class: The setter should have the next JSDoc comment: ```javascript /** - * @param {[param_type]} [value_name] [decription] + * @param {[param_type]} [value_name] [description] * @return {[struct_name]} */ ``` @@ -930,7 +930,7 @@ There are some prerequisites for the Function class: The class should have the next JSDoc comment: ```javascript /** - * [decription] + * [description] */ ``` Where `[description]` is `` of the current ``, if exists. @@ -1033,7 +1033,7 @@ For each `` the getter and setter methods should be defined in the class: The setter should have the next JSDoc comment: ```javascript /** - * @param {[param_type]} [value_name] [decription] + * @param {[param_type]} [value_name] [description] * @return {[struct_name]} */ ``` From 325bc234680eea4ab40e16cf9706348876eaf286 Mon Sep 17 00:00:00 2001 From: Aleksandr Mishchenko Date: Mon, 27 Jan 2020 16:57:30 +0100 Subject: [PATCH 08/19] improve manual mapping --- generator/generator.py | 1 - generator/mapping.json | 8 +- generator/mapping_example.json | 54 ++++++ generator/templates/base_template.js | 1 + .../scripts/FunctionID_keyForValue.js | 8 - generator/templates/scripts/PutFileRequest.js | 6 +- ...ppID.js => RegisterAppInterfaceRequest.js} | 0 generator/test/test_enums.py | 20 +-- generator/test/test_functions.py | 59 +++--- generator/test/test_structs.py | 10 +- generator/transformers/common_producer.py | 170 +++++++++--------- generator/transformers/enums_producer.py | 16 +- generator/transformers/functions_producer.py | 5 +- generator/transformers/structs_producer.py | 2 +- 14 files changed, 194 insertions(+), 166 deletions(-) create mode 100644 generator/mapping_example.json delete mode 100644 generator/templates/scripts/FunctionID_keyForValue.js rename generator/templates/scripts/{fullAppID.js => RegisterAppInterfaceRequest.js} (100%) diff --git a/generator/generator.py b/generator/generator.py index 8805a746..eb530c3a 100644 --- a/generator/generator.py +++ b/generator/generator.py @@ -22,7 +22,6 @@ try: from parsers.sdl_rpc_v2 import Parser - from parsers.parse_error import ParseError as InterfaceError from model.interface import Interface from transformers.generate_error import GenerateError from transformers.common_producer import InterfaceProducerCommon diff --git a/generator/mapping.json b/generator/mapping.json index aa889af5..5c1deb7a 100644 --- a/generator/mapping.json +++ b/generator/mapping.json @@ -100,15 +100,13 @@ "appID": { "-methods": {} }, - "fullAppID": { - "script": "templates/scripts/fullAppID.js" - }, - "params_additional": [ + "params": [ { "key": "APP_ID_MAX_LENGTH", "value": 10 } - ] + ], + "script": "templates/scripts/RegisterAppInterfaceRequest.js" }, "PutFileRequest": { "syncFileName": { diff --git a/generator/mapping_example.json b/generator/mapping_example.json new file mode 100644 index 00000000..3e07ac46 --- /dev/null +++ b/generator/mapping_example.json @@ -0,0 +1,54 @@ +{ + "enums": { + "AudioType": { + "not_exist": { + "any": null + }, + "PCM": { + "-methods": "any value", + "params": { + "key": "new_key", + "value": "new_value" + }, + "methods": { + "method_title": "new_key", + "description": "description", + "type": "type" + } + } + } + }, + "structs": { + "Grid": { + "script": "templates/scripts/PutFileRequest.js", + "col": { + "methods": { + "description": "new description", + "external": "external", + "param_name": "param_name", + "type": "type", + "method_title": "Column", + "key": "KEY_COLUMN" + }, + "params": { + "key": "KEY_COLUMN", + "value": "new_value" + } + } + } + }, + "functions": { + "RegisterAppInterfaceRequest": { + "appID": { + "-methods": {} + }, + "params": [ + { + "key": "APP_ID_MAX_LENGTH", + "value": 10 + } + ], + "script": "templates/scripts/RegisterAppInterfaceRequest.js" + } + } +} diff --git a/generator/templates/base_template.js b/generator/templates/base_template.js index 8246cbf6..b8058607 100644 --- a/generator/templates/base_template.js +++ b/generator/templates/base_template.js @@ -1,3 +1,4 @@ +/* eslint-disable camelcase */ /* * Copyright (c) {{year}}, SmartDeviceLink Consortium, Inc. * All rights reserved. diff --git a/generator/templates/scripts/FunctionID_keyForValue.js b/generator/templates/scripts/FunctionID_keyForValue.js deleted file mode 100644 index 95d2d7e8..00000000 --- a/generator/templates/scripts/FunctionID_keyForValue.js +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Returns the key of the map with the corresponding value - * @param {Number} value - * @return {null|String} - Returns null if not found - */ -static keyForValue (value) { - return FunctionID.keyForValueInternal(value, FunctionID._MAP); -} \ No newline at end of file diff --git a/generator/templates/scripts/PutFileRequest.js b/generator/templates/scripts/PutFileRequest.js index 33b771e0..7a3a53a9 100644 --- a/generator/templates/scripts/PutFileRequest.js +++ b/generator/templates/scripts/PutFileRequest.js @@ -4,15 +4,15 @@ * @param {Uint8Array} fileData * @return {PutFile} */ -setFileData(fileData) { +setFileData (fileData) { this.setBulkData(fileData); return this; } /** * @return {Uint8Array} */ -getFileData() { +getFileData () { return this.getBulkData(); } -//----------------- END ----------------------- \ No newline at end of file +// ----------------- END ----------------------- \ No newline at end of file diff --git a/generator/templates/scripts/fullAppID.js b/generator/templates/scripts/RegisterAppInterfaceRequest.js similarity index 100% rename from generator/templates/scripts/fullAppID.js rename to generator/templates/scripts/RegisterAppInterfaceRequest.js diff --git a/generator/test/test_enums.py b/generator/test/test_enums.py index 7b1a86a0..05106809 100644 --- a/generator/test/test_enums.py +++ b/generator/test/test_enums.py @@ -2,9 +2,9 @@ from datetime import date from unittest import TestCase -from transformers.enums_producer import EnumsProducer from model.enum import Enum from model.enum_element import EnumElement +from transformers.enums_producer import EnumsProducer class TestEnumsProducer(TestCase): @@ -24,15 +24,12 @@ def test_FunctionID(self): }) expected = { 'name': 'FunctionID', - 'imports': [self.producer.imports(what='Enum', wherefrom='../../util/Enum.js')], - 'methods': [self.producer.methods(origin='RESERVED', - method_title='RESERVED', + 'imports': {self.producer.imports(what='Enum', wherefrom='../../util/Enum.js')}, + 'methods': [self.producer.methods(method_title='RESERVED', description=[], type='Number'), - self.producer.methods(origin='RegisterAppInterfaceID', - method_title='RegisterAppInterface', + self.producer.methods(method_title='RegisterAppInterface', description=[], type='Number'), - self.producer.methods(origin='PerformAudioPassThruID', - method_title='PerformAudioPassThru', + self.producer.methods(method_title='PerformAudioPassThru', description=[], type='Number')], 'params': [self.producer.params(key='RESERVED', value=0), self.producer.params(key='RegisterAppInterface', value='0x01'), @@ -54,10 +51,9 @@ def test_Result(self): 'year': date.today().year, 'name': 'Result', 'file_name': 'Result', - 'imports': [self.producer.imports(what='Enum', wherefrom='../../util/Enum.js')], - 'methods': tuple([self.producer.methods(origin='SUCCESS', - method_title='SUCCESS', - description=[], type='String')]), + 'imports': {self.producer.imports(what='Enum', wherefrom='../../util/Enum.js')}, + 'methods': tuple([self.producer.methods(method_title='SUCCESS', + description=[], type='String')]), 'params': tuple([self.producer.params(key='SUCCESS', value="'SUCCESS'")]), 'extend': 'Enum' } diff --git a/generator/test/test_functions.py b/generator/test/test_functions.py index 1cffd645..8eb24a8f 100644 --- a/generator/test/test_functions.py +++ b/generator/test/test_functions.py @@ -1,7 +1,6 @@ from collections import namedtuple from unittest import TestCase -from transformers.functions_producer import FunctionsProducer from model.array import Array from model.boolean import Boolean from model.enum import Enum @@ -11,6 +10,7 @@ from model.param import Param from model.string import String from model.struct import Struct +from transformers.functions_producer import FunctionsProducer class TestFunctionsProducer(TestCase): @@ -29,10 +29,12 @@ def setUp(self): mapping = {"functions": { "RegisterAppInterfaceRequest": { "syncMsgVersion": { - "imports": { - "what": "SdlMsgVersion", - "wherefrom": "../structs/SdlMsgVersion.js" - }, + "imports": [ + { + "what": "SdlMsgVersion", + "wherefrom": "../structs/SdlMsgVersion.js" + } + ], "methods": { "method_title": "SdlMsgVersion", "external": "SdlMsgVersion", @@ -43,10 +45,7 @@ def setUp(self): "key": "KEY_SDL_MSG_VERSION" } }, - "fullAppID": { - "script": "templates/scripts/fullAppID.js" - }, - "params_additional": [ + "params": [ { "key": "APP_ID_MAX_LENGTH", "value": 10 @@ -81,23 +80,23 @@ def test_RegisterAppInterfaceRequest(self): }) expected = { 'name': 'RegisterAppInterface', - 'imports': [self.producer.imports(what='SdlMsgVersion', wherefrom='../structs/SdlMsgVersion.js'), + 'imports': {self.producer.imports(what='SdlMsgVersion', wherefrom='../structs/SdlMsgVersion.js'), self.producer.imports(what='TemplateColorScheme', wherefrom='../structs/TemplateColorScheme.js'), self.producer.imports(what='TTSChunk', wherefrom='../structs/TTSChunk.js'), self.producer.imports(what='RpcRequest', wherefrom='../RpcRequest.js'), - self.producer.imports(what='FunctionID', wherefrom='../enums/FunctionID.js')], - 'methods': [self.producer.methods(origin='syncMsgVersion', key='KEY_SDL_MSG_VERSION', + self.producer.imports(what='FunctionID', wherefrom='../enums/FunctionID.js')}, + 'methods': [self.producer.methods(key='KEY_SDL_MSG_VERSION', method_title='SdlMsgVersion', external='SdlMsgVersion', description=['See SyncMsgVersion'], param_name='version', type='SdlMsgVersion'), - self.producer.methods(origin='fullAppID', key='KEY_FULL_APP_ID', method_title='FullAppID', + self.producer.methods(key='KEY_FULL_APP_ID', method_title='FullAppID', external=None, description=['ID used'], param_name='id', type='String'), - self.producer.methods(origin='dayColorScheme', key='KEY_DAY_COLOR_SCHEME', param_name='scheme', + self.producer.methods(key='KEY_DAY_COLOR_SCHEME', param_name='scheme', method_title='DayColorScheme', external='TemplateColorScheme', description=['A color scheme for all display layout templates.'], type='TemplateColorScheme'), - self.producer.methods(origin='ttsName', key='KEY_TTS_NAME', param_name='name', + self.producer.methods(key='KEY_TTS_NAME', param_name='name', method_title='TtsName', external='TTSChunk', description=['TTS string for'], type='Array')], 'params': [self.producer.params(key='APP_ID_MAX_LENGTH', value=10), @@ -132,14 +131,14 @@ def test_RegisterAppInterfaceResponse(self): }) expected = { 'name': 'RegisterAppInterfaceResponse', - 'imports': [self.producer.imports(what='Language', wherefrom='../enums/Language.js'), + 'imports': {self.producer.imports(what='Language', wherefrom='../enums/Language.js'), self.producer.imports(what='RpcResponse', wherefrom='../RpcResponse.js'), - self.producer.imports(what='FunctionID', wherefrom='../enums/FunctionID.js')], - 'methods': [self.producer.methods(origin='language', key='KEY_LANGUAGE', + self.producer.imports(what='FunctionID', wherefrom='../enums/FunctionID.js')}, + 'methods': [self.producer.methods(key='KEY_LANGUAGE', method_title='Language', external='Language', description=['The currently'], param_name='language', type='Language'), - self.producer.methods(origin='supportedDiagModes', key='KEY_SUPPORTED_DIAG_MODES', + self.producer.methods(key='KEY_SUPPORTED_DIAG_MODES', method_title='SupportedDiagModes', external=None, description=['Specifies the'], param_name='modes', type='Array')], @@ -163,8 +162,8 @@ def test_UnregisterAppInterfaceRequest(self): message_type=EnumElement(name='request'), params={}) expected = { 'name': 'UnregisterAppInterface', - 'imports': [self.producer.imports(what='RpcRequest', wherefrom='../RpcRequest.js'), - self.producer.imports(what='FunctionID', wherefrom='../enums/FunctionID.js')], + 'imports': {self.producer.imports(what='RpcRequest', wherefrom='../RpcRequest.js'), + self.producer.imports(what='FunctionID', wherefrom='../enums/FunctionID.js')}, 'func': 'UnregisterAppInterface', 'extend': 'RpcRequest' } @@ -185,10 +184,10 @@ def test_PutFileRequest(self): }) expected = { 'name': 'PutFile', - 'imports': [self.producer.imports(what='FileType', wherefrom='../enums/FileType.js'), + 'imports': {self.producer.imports(what='FileType', wherefrom='../enums/FileType.js'), self.producer.imports(what='RpcRequest', wherefrom='../RpcRequest.js'), - self.producer.imports(what='FunctionID', wherefrom='../enums/FunctionID.js')], - 'methods': [self.producer.methods(origin='fileType', key='KEY_FILE_TYPE', + self.producer.imports(what='FunctionID', wherefrom='../enums/FunctionID.js')}, + 'methods': [self.producer.methods(key='KEY_FILE_TYPE', method_title='FileType', external='FileType', description=['Selected file type.'], param_name='type', type='FileType')], @@ -217,9 +216,9 @@ def test_OnEncodedSyncPDataNotification(self): }) expected = { 'name': 'OnEncodedSyncPData', - 'imports': [self.producer.imports(what='RpcNotification', wherefrom='../RpcNotification.js'), - self.producer.imports(what='FunctionID', wherefrom='../enums/FunctionID.js')], - 'methods': [self.producer.methods(origin='URL', key='KEY_URL', + 'imports': {self.producer.imports(what='RpcNotification', wherefrom='../RpcNotification.js'), + self.producer.imports(what='FunctionID', wherefrom='../enums/FunctionID.js')}, + 'methods': [self.producer.methods(key='KEY_URL', method_title='URL', external=None, description=['If'], param_name='url', type='String')], @@ -247,10 +246,10 @@ def test_CreateInteractionChoiceSetRequest(self): }) expected = { 'name': 'CreateInteractionChoiceSet', - 'imports': [self.producer.imports(what='Choice', wherefrom='../structs/Choice.js'), + 'imports': {self.producer.imports(what='Choice', wherefrom='../structs/Choice.js'), self.producer.imports(what='RpcRequest', wherefrom='../RpcRequest.js'), - self.producer.imports(what='FunctionID', wherefrom='../enums/FunctionID.js')], - 'methods': [self.producer.methods(origin='choiceSet', key='KEY_CHOICE_SET', + self.producer.imports(what='FunctionID', wherefrom='../enums/FunctionID.js')}, + 'methods': [self.producer.methods(key='KEY_CHOICE_SET', method_title='ChoiceSet', external='Choice', description=['A choice is an option given to'], param_name='set', type='Array')], diff --git a/generator/test/test_structs.py b/generator/test/test_structs.py index 8b174c7c..77de73d2 100644 --- a/generator/test/test_structs.py +++ b/generator/test/test_structs.py @@ -2,9 +2,9 @@ from datetime import date from unittest import TestCase -from transformers.structs_producer import StructsProducer from model.param import Param from model.struct import Struct +from transformers.structs_producer import StructsProducer class TestStructsProducer(TestCase): @@ -25,11 +25,11 @@ def test_SoftButton(self): 'year': date.today().year, 'name': 'SoftButton', 'file_name': 'SoftButton', - 'imports': [self.producer.imports(what='Image', wherefrom='./Image.js'), - self.producer.imports(what='RpcStruct', wherefrom='../RpcStruct.js')], + 'imports': {self.producer.imports(what='Image', wherefrom='./Image.js'), + self.producer.imports(what='RpcStruct', wherefrom='../RpcStruct.js')}, 'methods': tuple([self.producer.methods(description=['Optional image'], external='Image', - key='KEY_IMAGE', method_title='Image', - origin='image', param_name='image', type='Image')]), + key='KEY_IMAGE', method_title='Image', + param_name='image', type='Image')]), 'params': tuple([self.producer.params(key='KEY_IMAGE', value="'image'")]), 'extend': 'RpcStruct' } diff --git a/generator/transformers/common_producer.py b/generator/transformers/common_producer.py index 0098f36b..ff69645f 100644 --- a/generator/transformers/common_producer.py +++ b/generator/transformers/common_producer.py @@ -11,8 +11,8 @@ from pathlib import Path from model.array import Array -from model.float import Float from model.enum import Enum +from model.float import Float from model.function import Function from model.integer import Integer from model.struct import Struct @@ -34,6 +34,9 @@ def __init__(self, container_name, enums_dir_name, structs_dir_name, self.enums_dir = enums_dir_name self.structs_dir = structs_dir_name self.mapping = mapping + self.imports = namedtuple('Imports', 'what wherefrom') + self.methods = namedtuple('Methods', 'key method_title external description param_name type') + self.params = namedtuple('Params', 'key value') @property def get_version(self): @@ -42,28 +45,6 @@ def get_version(self): """ return self.version - @property - def imports(self): - """ - :return: namedtuple imports(what='', wherefrom='') - """ - return namedtuple('Imports', 'what wherefrom') - - @property - def methods(self): - """ - :return: namedtuple methods( - origin='', key='', method_title='', external='', description='', param_name='', type='',) - """ - return namedtuple('Methods', 'origin key method_title external description param_name type') - - @property - def params(self): - """ - :return: namedtuple params(key='', value='') - """ - return namedtuple('Params', 'key value') - @staticmethod def replace_sync(name): """ @@ -84,30 +65,24 @@ def transform(self, item) -> dict: params = {} for param in getattr(item, self.container_name).values(): - if isinstance(item, Function) and item.message_type.name == 'response' and \ - param.name in ('success', 'resultCode', 'info'): - self.logger.warning('%s of type %s/%s - skip parameter "%s"', - item.name, type(item).__name__, item.message_type.name, param.name) - continue - _import, _methods, _params = self.common_flow(param, type(item)) if _import: imports.update(_import) if _methods: - methods.update({param.name: _methods}) + methods[param.name] = _methods params.update({param.name: _params}) name = self.replace_sync(item.name) render = {'year': date.today().year, 'file_name': name, 'name': name, - 'imports': [self.imports(what=k, wherefrom=v) for k, v in imports.items()], + 'imports': {self.imports(what=k, wherefrom=v) for k, v in imports.items()}, 'methods': methods, 'params': params} if getattr(item, 'description', None): - render.update({'description': textwrap.wrap(self.extract_description(item.description), 116)}) + render.update({'description': self.extract_description(item.description, 116)}) if item.deprecated: render.update({'deprecated': item.deprecated}) @@ -118,55 +93,6 @@ def transform(self, item) -> dict: return render - def custom_mapping(self, render, item): - """ - :param render: dictionarry with data ready to apply to Jinja2 template - :param item: original item from parsed model - :return: - """ - if isinstance(item, Function): - mapping_name = item.name + item.message_type.name.capitalize() - else: - mapping_name = item.name - - if mapping_name not in self.mapping: - return - custom = self.mapping[mapping_name] - - if 'params_additional' in custom: - for param in custom['params_additional']: - render['params'].update({param['key']: self.params(**param)}) - del custom['params_additional'] - if 'script' in custom: - script = self.get_file_content(custom['script']) - if script: - if 'script' in render: - render['scripts'].append(script) - else: - render['scripts'] = [script] - del custom['script'] - - for name, mapping in custom.copy().items(): - for sub_name, sub_mapping in mapping.copy().items(): - if sub_name == '-methods': - del render['methods'][name] - del custom[name]['-methods'] - if sub_name == 'script': - script = self.get_file_content(sub_mapping) - if script: - if 'script' in render: - render['scripts'].append(script) - else: - render['scripts'] = [script] - del custom[name]['script'] - if sub_name in render and name in render[sub_name]: - render[sub_name][name] = render[sub_name][name]._replace(**sub_mapping) - del custom[name][sub_name] - if not custom[name]: - del custom[name] - - render.update(custom) - def common_flow(self, param, item_type): """ Main transformation flow, for Struct and Function @@ -191,10 +117,10 @@ def common_flow(self, param, item_type): short_name = re.sub(r'(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])', '=^.^=', param_name) \ .split('=^.^=').pop().lower() - description = textwrap.wrap(description, 100 - len(type_name) - len(short_name)) + description = self.extract_description(description, 100 - len(type_name) - len(short_name)) title = param_name[:1].upper() + param_name[1:] - methods = self.methods(origin=param.name, key=key, method_title=title, external=name, description=description, + methods = self.methods(key=key, method_title=title, external=name, description=description, param_name=short_name, type=type_name) params = self.params(key=key, value="'{}'".format(param.name)) return imports, methods, params @@ -233,13 +159,18 @@ def ending_cutter(name: str): return name @staticmethod - def extract_description(description): + def extract_description(data, length: int) -> list: """ Evaluate, align and delete @TODO - :param description: list with description + :param data: list with description + :param length: :return: evaluated string """ - return re.sub(r'(\s{2,}|\n|\[@TODO.+)', ' ', ''.join(description)).strip() if description else '' + if not data: + return [] + if isinstance(data, list): + data = ' '.join(data) + return textwrap.wrap(re.sub(r'(\s{2,}|\n|\[@TODO.+)', ' ', data).strip(), length) def extract_name_description(self, param): """ @@ -265,7 +196,7 @@ def extract_name_description(self, param): if not description and getattr(param.param_type.element_type, 'description', None): description = param.param_type.element_type.description - return self.replace_sync(name), self.extract_description(description) + return self.replace_sync(name), self.extract_description(description, 116) def extract_type(self, param): """ @@ -299,3 +230,68 @@ def get_file_content(self, file_name: str): except FileNotFoundError as message: self.logger.error(message) return '' + + def custom_mapping(self, render, item): + """ + :param render: dictionarry with data ready to apply to Jinja2 template + :param item: original item from parsed model + :return: + """ + if isinstance(item, Function): + mapping_name = item.name + item.message_type.name.capitalize() + else: + mapping_name = item.name + + if mapping_name not in self.mapping: + return + custom = self.mapping[mapping_name] + + if 'params' in custom: + for data in custom['params']: + missed = list(set(self.params._fields) - set(data.keys())) + if missed: + self.logger.warning('not valid %s', str(data)) + continue + render['params'][data['key']] = self.params(**data) + del custom['params'] + if 'script' in custom: + script = self.get_file_content(custom['script']) + if script: + render['scripts'] = [script] + del custom['script'] + + for name, mapping in custom.copy().items(): + for section, data in mapping.copy().items(): + if section == '-methods' and name in render['methods']: + redundant = list(custom[name].copy().keys()) + redundant.remove('-methods') + if redundant: + self.logger.info('%s/%s, "-methods" provided, skipping: %s', + mapping_name, name, str(redundant)) + del render['methods'][name] + del custom[name] + break + if section in render: + if section == 'imports': + for field in data: + missed = list(set(getattr(self, section)._fields) - set(field.keys())) + if missed: + self.logger.error('%s/%s/%s, redundant: %s', mapping_name, name, section, missed) + continue + render[section].add(self.imports(**field)) + elif name in render[section]: + redundant = list(set(data.keys()) - set(getattr(self, section)._fields)) + if redundant: + self.logger.error('%s/%s/%s, redundant: %s', mapping_name, name, section, redundant) + continue + if 'description' in data: + data['description'] = self.extract_description(data['description'], 116) + render[section][name] = render[section][name]._replace(**data) + else: + self.logger.warning('%s/%s not exist, skipping it.', mapping_name, name) + del custom[name][section] + else: + self.logger.warning('%s/%s/%s not exist, skipping it.', mapping_name, name, section) + del custom[name] + if name in custom and not custom[name]: + del custom[name] diff --git a/generator/transformers/enums_producer.py b/generator/transformers/enums_producer.py index 86d5dc1f..cbccde23 100644 --- a/generator/transformers/enums_producer.py +++ b/generator/transformers/enums_producer.py @@ -3,7 +3,6 @@ """ import logging -import textwrap from collections import namedtuple from model.enum import Enum @@ -24,14 +23,7 @@ def __init__(self, paths, mapping=None): mapping=mapping['enums'] if mapping and 'enums' in mapping else {}) self.logger = logging.getLogger(self.__class__.__name__) self.enum_class = paths.path_to_enum_class - - @property - def methods(self): - """ - Override - :return: namedtuple methods(origin='', method_title='', description='', type='') - """ - return namedtuple('Methods', 'origin method_title description type') + self.methods = namedtuple('Methods', 'method_title description type') def transform(self, item: Enum) -> dict: """ @@ -42,7 +34,7 @@ def transform(self, item: Enum) -> dict: tmp = super(EnumsProducer, self).transform(item) what_where = self.extract_imports(self.enum_class) tmp.update({'extend': what_where.what}) - tmp['imports'].append(what_where) + tmp['imports'].add(what_where) return tmp def common_flow(self, param: EnumElement, item_type=None): @@ -55,10 +47,10 @@ def common_flow(self, param: EnumElement, item_type=None): """ (name, description) = self.extract_name_description(param) type_name = self.extract_type(param) - description = textwrap.wrap(description, 117 - len(type_name)) + description = self.extract_description(description, 117 - len(type_name)) name = self.ending_cutter(name) - methods = self.methods(origin=param.name, method_title=name, description=description, type=type_name) + methods = self.methods(method_title=name, description=description, type=type_name) params = self.extract_param(param) imports = None diff --git a/generator/transformers/functions_producer.py b/generator/transformers/functions_producer.py index 31651707..aec2896b 100644 --- a/generator/transformers/functions_producer.py +++ b/generator/transformers/functions_producer.py @@ -31,6 +31,7 @@ def transform(self, item: Function) -> dict: :param item: particular element from initial Model :return: dictionary to be applied to jinja2 template """ + list(map(item.params.__delitem__, filter(item.params.__contains__, ['success', 'resultCode', 'info']))) render = super(FunctionsProducer, self).transform(item) render.update({'func': self.ending_cutter(item.function_id.name)}) if item.message_type.name == 'response': @@ -46,6 +47,6 @@ def transform(self, item: Function) -> dict: if name: what_where = self.extract_imports(name) render.update({'extend': what_where.what}) - render['imports'].append(what_where) - render['imports'].append(self.imports(what='FunctionID', wherefrom='{}/FunctionID.js'.format(self.enums_dir))) + render['imports'].add(what_where) + render['imports'].add(self.imports(what='FunctionID', wherefrom='{}/FunctionID.js'.format(self.enums_dir))) return render diff --git a/generator/transformers/structs_producer.py b/generator/transformers/structs_producer.py index e49609db..77a85330 100644 --- a/generator/transformers/structs_producer.py +++ b/generator/transformers/structs_producer.py @@ -33,5 +33,5 @@ def transform(self, item: Struct) -> dict: tmp = super(StructsProducer, self).transform(item) what_where = self.extract_imports(self.struct_class) tmp.update({'extend': what_where.what}) - tmp['imports'].append(what_where) + tmp['imports'].add(what_where) return tmp From b30da9358e809a1283c961c5937b641e965927ea Mon Sep 17 00:00:00 2001 From: Vladyslav Mustafin Date: Tue, 28 Jan 2020 13:40:38 +0200 Subject: [PATCH 09/19] Added `Custom mapping` section into README.md --- generator/README.md | 208 +++++++++++++++++++++++++++++++++ generator/mapping_example.json | 8 +- 2 files changed, 210 insertions(+), 6 deletions(-) diff --git a/generator/README.md b/generator/README.md index bfbd8480..82751df8 100644 --- a/generator/README.md +++ b/generator/README.md @@ -1531,3 +1531,211 @@ OnLanguageChange.KEY_HMI_DISPLAY_LANGUAGE = 'hmiDisplayLanguage'; export { OnLanguageChange }; ``` + +# Custom mapping + +## Overview + +There are cases named `edge cases` when it is not possible to get the required info from XML or some manual additions are required in generated classes. For that purpose the generator includes the custom mapping file `mapping.json` that allows to add required customizations. + +## Structure + +The customization script contains the JSON object. Below is the schema: + +```json +{ + ["enums"|"structs"|"functions"]: { + [enum_name|struct_name|function_name]: { + [element_name|param_name]: { + "-methods": {}, + "methods": { + "method_name": [custom_method_name], + "key": [custom_key_name], + "description": [custom_description] + }, + "params": { + "key": [custom_key_name] + "value": [custom_value] + }, + }, + "params_additional": [ + { + "key": [custom_param_name], + "value": [custom_param_value] + } + ], + "script": [path_to_custom_code] + } + } +} +``` + +Root keys in the structure are `"enums"`, `"structs"` and `"functions"`. The key on the next level is the corresponding name of required ``, `` or ``. On the next level, the name of `` or `` is expected. Also, at this level, it is possible to add any custom code into class from the file via the `script` key and to add custom params to class properties via an array from `params_additional` key. See the detailed description below. + +The mapping object does not provide the possibility to create brand new ``, `` or ``, and their child elements in this way. The customization is allowed only for existing XML elements, unexisting names of elements and their child elements defined int the mapping object will be ignored. + +## Adding the custom code +As described above the custom code could be added via `script` key. The value of this key should be the path to the file. The code will be included as-is directly into the class, therefore only comments and method definitions are allowed in this file. + +Example: +```json +{ + "functions": { + "PutFileRequest": { + "script": "templates/scripts/PutFileRequest.js" + } + } +} +``` + +The content of the `templates/scripts/PutFileRequest.js` file is: +```javascript +// ------ Not part of the RPC spec itself ----- + +/** + * @param {Uint8Array} fileData + * @return {PutFile} + */ +setFileData(fileData) { + this.setBulkData(fileData); + return this; +} +/** + * @return {Uint8Array} + */ +getFileData() { + return this.getBulkData(); +} + +//----------------- END ----------------------- +``` +This code will be included into `PutFileRequest` class of the `messages/PutFileRequest.js` file as-is. + +## Adding custom parameters +As described above the custom code could be added via `params` key. The value of this key should be the array of objects. Each that object should include `key` and `value` properties for defining the name and the value of the new parameter. + +Following example demonstrates the object and the code that will be generated for Enums and Structs/Functions: +```json +{ + "key": "APP_ID_MAX_LENGTH", + "value": 10 +} +``` + +In Enums this will produce the new property in the static `_MAP` object +```javascript +_EnumClass_._MAP = Object.freeze({ + // ..., + 'APP_ID_MAX_LENGTH': 10, + // ... +}); +``` + +In Structs/Functions this will produce the new static property +```javascript +// ... +_StructClass_.APP_ID_MAX_LENGTH = 10; +// ... +``` +```javascript +// ... +_FunctionClass_.APP_ID_MAX_LENGTH = 10; +// ... +``` + +## Customization the `` of `` or the `` of ``/`` +In order of this customization it is possible to change the name and description of getter/setter methods and the name and value of corresponding static property. Additionally it is possible to remove getter/setter methods. + +### Changing the name and description of getter/setter methods +To change the name and description of getter/setter methods it needs to define `methods.method_name` value. + +Example: +```json +{ + "enums": { + "AudioType": { + "PCM": { + "methods": { + "method_name": "Wave", + "description": "Linear Wave!" + } + } + } + } +} +``` + +This will replace the `PCM` method name to `Wave` and `Linear PCM.` description to `Linear Wave!`, please pay attention the `_MAP` still has the `PCM` key. +```javascript + /* + * Linear Wave! + * @return {String} + */ + static get Wave () { + return AudioType._MAP.PCM; + } +``` + +### Changing the name and value of corresponding static property +To change the name of corresponding static property it needs to define `params.key` value. + +To change the value of corresponding static property it needs to define `params.value` value. + +Example: +```json +{ + "enums": { + "AudioType": { + "PCM": { + "methods": { + "key": "Wave" + }, + "params": { + "key": "Wave", + "value": "NEW_PCM" + } + } + } + } +} +``` + +The result will the following. Please pay attention that in case if the name of the static property was changed, you should also define the same `methods.key` value, otherwise the key will be unchanged in getter/setter methods. +```javascript + +class AudioType extends Enum { +// ... + /* + * Linear PCM. + * @return {String} + */ + static get PCM () { + return AudioType._MAP.Wave; // will be old `AudioType._MAP.PCM` if `methods.key` is not defined + } +// ... +} + +AudioType._MAP = Object.freeze({ + // ..., + 'Wave': "NEW_PCM", // old key/value PCM: "PCM" + // ... +}); +``` + +### Removing getter/setter methods +To remove getter/setter methods it needs to define `-methods` key, the value of this key doesn't matter. + +Example: +```json +{ + "enums": { + "AudioType": { + "PCM": { + "-methods": {} + } + } + } +} +``` + +This will remove `static get PCM` method from the class and only the `_MAP` key/value will be generated. \ No newline at end of file diff --git a/generator/mapping_example.json b/generator/mapping_example.json index 3e07ac46..b8677260 100644 --- a/generator/mapping_example.json +++ b/generator/mapping_example.json @@ -1,11 +1,11 @@ { "enums": { "AudioType": { - "not_exist": { + "not_exist_and_will_be_ignored": { "any": null }, "PCM": { - "-methods": "any value", + "-methods": {}, "params": { "key": "new_key", "value": "new_value" @@ -13,7 +13,6 @@ "methods": { "method_title": "new_key", "description": "description", - "type": "type" } } } @@ -24,9 +23,6 @@ "col": { "methods": { "description": "new description", - "external": "external", - "param_name": "param_name", - "type": "type", "method_title": "Column", "key": "KEY_COLUMN" }, From 34ef5247b808f4866bf20eadda4358a5c23b7547 Mon Sep 17 00:00:00 2001 From: Vladyslav Mustafin Date: Tue, 28 Jan 2020 15:15:38 +0200 Subject: [PATCH 10/19] Minor fix of customization spec --- generator/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/generator/README.md b/generator/README.md index 82751df8..706c931e 100644 --- a/generator/README.md +++ b/generator/README.md @@ -1558,7 +1558,7 @@ The customization script contains the JSON object. Below is the schema: "value": [custom_value] }, }, - "params_additional": [ + "params": [ { "key": [custom_param_name], "value": [custom_param_value] @@ -1570,7 +1570,7 @@ The customization script contains the JSON object. Below is the schema: } ``` -Root keys in the structure are `"enums"`, `"structs"` and `"functions"`. The key on the next level is the corresponding name of required ``, `` or ``. On the next level, the name of `` or `` is expected. Also, at this level, it is possible to add any custom code into class from the file via the `script` key and to add custom params to class properties via an array from `params_additional` key. See the detailed description below. +Root keys in the structure are `"enums"`, `"structs"` and `"functions"`. The key on the next level is the corresponding name of required ``, `` or ``. On the next level, the name of `` or `` is expected. Also, at this level, it is possible to add any custom code into class from the file via the `script` key and to add custom params to class properties via an array from `params` key. See the detailed description below. The mapping object does not provide the possibility to create brand new ``, `` or ``, and their child elements in this way. The customization is allowed only for existing XML elements, unexisting names of elements and their child elements defined int the mapping object will be ignored. @@ -1738,4 +1738,4 @@ Example: } ``` -This will remove `static get PCM` method from the class and only the `_MAP` key/value will be generated. \ No newline at end of file +This will remove `static get PCM` method from the class and only the `_MAP` key/value will be generated. From e05d4239de294586d41239215494e1dac4d89813 Mon Sep 17 00:00:00 2001 From: Aleksandr Mishchenko Date: Wed, 29 Jan 2020 14:05:37 +0100 Subject: [PATCH 11/19] adding RpcCreator processing --- generator/generator.py | 133 ++++++++++++++------ generator/mapping_example.json | 50 -------- generator/paths.ini | 4 +- generator/templates/RpcCreator_template.js | 65 ++++++++++ generator/templates/base_struct_function.js | 46 ++++--- generator/templates/base_template.js | 13 +- generator/templates/enum_template.js | 20 ++- generator/transformers/common_producer.py | 2 +- lib/rpc_spec | 2 +- 9 files changed, 202 insertions(+), 133 deletions(-) delete mode 100644 generator/mapping_example.json create mode 100644 generator/templates/RpcCreator_template.js diff --git a/generator/generator.py b/generator/generator.py index eb530c3a..56733011 100644 --- a/generator/generator.py +++ b/generator/generator.py @@ -22,6 +22,7 @@ try: from parsers.sdl_rpc_v2 import Parser + from parsers.rpc_base import ParseError from model.interface import Interface from transformers.generate_error import GenerateError from transformers.common_producer import InterfaceProducerCommon @@ -47,7 +48,7 @@ def __init__(self): self._env = None self.paths_named = namedtuple('paths_named', 'path_to_enum_class path_to_struct_class path_to_request_class ' 'path_to_response_class path_to_notification_class enums_dir_name ' - 'structs_dir_name functions_dir_name') + 'structs_dir_name functions_dir_name rpc_creator') @property def env(self): @@ -272,8 +273,8 @@ def write_file(self, file_name, template, data): render = self.env.get_template(template).render(data) with file_name.open('w', encoding='utf-8') as file: file.write(render) - except (TemplateNotFound, UndefinedError) as message1: - self.logger.error('skipping %s, template not found %s', file_name.as_posix(), message1) + except (TemplateNotFound, UndefinedError, AttributeError) as message1: + self.logger.error('skipping %s, %s', file_name.as_posix(), message1) def process(self, directory, skip, overwrite, items, transformer): """ @@ -284,36 +285,79 @@ def process(self, directory, skip, overwrite, items, transformer): :param items: elements initial Model :param transformer: producer/transformer instance """ - directory.mkdir(parents=True, exist_ok=True) for item in items.values(): - template = type(item).__name__.lower() + '_template.js' data = transformer.transform(item) - file = directory.joinpath(data['file_name'] + '.js') - if file.is_file(): - if skip: - self.logger.info('Skipping %s', file) - continue - if overwrite: - self.logger.info('Overriding %s', file) - self.write_file(file, template, data) - else: - while True: - try: - confirm = input('File already exists {}. Overwrite? Y/Enter = yes, N = no\n'.format(file)) - if confirm.lower() == 'y' or not confirm: - self.logger.info('Overriding %s', file) - self.write_file(file, template, data) - break - if confirm.lower() == 'n': - self.logger.info('Skipping %s', file) - break - except KeyboardInterrupt: - print('\nThe user interrupted the execution of the program') - sys.exit(1) + if 'template' in data: + template = data['template'] + else: + template = type(item).__name__.lower() + '_template.js' + file = directory.joinpath(data['name'] + '.js') + self.process_common(skip, overwrite, file, template, data) + + def process_function_name(self, file, dir_name, skip, overwrite, functions, transformer, mappings): + """ + :param file: + :param dir_name: + :param skip: + :param overwrite: + :param functions: + :param transformer: + :param mappings: + :return: + """ + creator = namedtuple('creator', 'name type') + data = {'name': file.stem, 'imports': [], 'cases': []} + for item in functions.values(): + kind = item.message_type.name.upper() + if kind == 'RESPONSE': + name = item.name + kind.capitalize() else: - self.logger.info('Writing new %s', file) + name = item.name + key = item.name + kind.capitalize() + if key in mappings and 'name' in mappings[key]: + name = mappings[key]['name'] + + if kind != 'RESPONSE': + data['cases'].append(creator(name, kind)) + data['imports'].append(transformer.imports(what=name, wherefrom='{}/{}.js'.format(dir_name, name))) + + self.process_common(skip, overwrite, file, file.stem + '_template.js', data) + + def process_common(self, skip, overwrite, file, template, data): + """ + :param skip: + :param overwrite: + :param file: + :param template: + :param data: + :return: + """ + if file.is_file(): + if skip: + self.logger.info('Skipping %s', file.name) + return + if overwrite: + self.logger.info('Overriding %s', file.name) self.write_file(file, template, data) + else: + while True: + try: + confirm = input('File already exists {}. Overwrite? Y/Enter = yes, N = no\n' + .format(file.name)) + if confirm.lower() == 'y' or not confirm: + self.logger.info('Overriding %s', file.name) + self.write_file(file, template, data) + break + if confirm.lower() == 'n': + self.logger.info('Skipping %s', file.name) + break + except KeyboardInterrupt: + print('\nThe user interrupted the execution of the program') + sys.exit(1) + else: + self.logger.info('Writing new %s', file.name) + self.write_file(file, template, data) def filter_pattern(self, interface, pattern): """ @@ -321,27 +365,31 @@ def filter_pattern(self, interface, pattern): :param pattern: regex-pattern from command-line arguments to filter element from initial Model :return: initial Model """ - enum_names = tuple(interface.enums.keys()) - struct_names = tuple(interface.structs.keys()) + names = tuple(interface.enums.keys()) + tuple(interface.structs.keys()) if pattern: match = {i: {} for i in vars(interface).keys()} match['params'] = interface.params + empty = True for key, value in vars(interface).items(): if key == 'params': continue for name, item in value.items(): if re.match(pattern, item.name): if hasattr(item, 'message_type'): - log = '{}/{} {} match with {}'.format(key, item.name, item.message_type.name.title(), - pattern) + log = '{}/{} {} match with {}'.format( + key, item.name, item.message_type.name.title(), pattern) else: log = '{}/{} match with {}'.format(key, item.name, pattern) self.logger.info(log) if key in match: match[key][name] = item - return enum_names, struct_names, Interface(**match) - return enum_names, struct_names, interface + empty = False + if empty: + self.logger.warning('no one match with %s', pattern) + sys.exit(0) + return Interface(**match), names + return interface, names @staticmethod def evaluate_instance_directory(dir_name): @@ -367,9 +415,13 @@ def main(self): paths = self.get_paths() - interface = Parser().parse(args.source_xml, args.source_xsd) + try: + interface = Parser().parse(args.source_xml, args.source_xsd) + except ParseError as error1: + self.logger.error(error1) + sys.exit(1) - enum_names, struct_names, filtered = self.filter_pattern(interface, args.regex_pattern) + filtered, names = self.filter_pattern(interface, args.regex_pattern) mappings = self.get_mappings() @@ -380,11 +432,14 @@ def main(self): if args.structs and filtered.structs: directory = args.output_directory.joinpath(self.evaluate_instance_directory(paths.structs_dir_name)) self.process(directory, args.skip, args.overwrite, filtered.structs, - StructsProducer(paths, enum_names, struct_names, mappings)) + StructsProducer(paths, names, mappings)) if args.functions and filtered.functions: + transformer = FunctionsProducer(paths, names, mappings) directory = args.output_directory.joinpath(self.evaluate_instance_directory(paths.functions_dir_name)) - self.process(directory, args.skip, args.overwrite, filtered.functions, - FunctionsProducer(paths, enum_names, struct_names, mappings)) + self.process(directory, args.skip, args.overwrite, filtered.functions, transformer) + self.process_function_name(args.output_directory.joinpath(paths.rpc_creator), paths.functions_dir_name, + args.skip, args.overwrite, interface.functions, transformer, + mappings.get('functions', {})) if __name__ == '__main__': diff --git a/generator/mapping_example.json b/generator/mapping_example.json deleted file mode 100644 index b8677260..00000000 --- a/generator/mapping_example.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "enums": { - "AudioType": { - "not_exist_and_will_be_ignored": { - "any": null - }, - "PCM": { - "-methods": {}, - "params": { - "key": "new_key", - "value": "new_value" - }, - "methods": { - "method_title": "new_key", - "description": "description", - } - } - } - }, - "structs": { - "Grid": { - "script": "templates/scripts/PutFileRequest.js", - "col": { - "methods": { - "description": "new description", - "method_title": "Column", - "key": "KEY_COLUMN" - }, - "params": { - "key": "KEY_COLUMN", - "value": "new_value" - } - } - } - }, - "functions": { - "RegisterAppInterfaceRequest": { - "appID": { - "-methods": {} - }, - "params": [ - { - "key": "APP_ID_MAX_LENGTH", - "value": 10 - } - ], - "script": "templates/scripts/RegisterAppInterfaceRequest.js" - } - } -} diff --git a/generator/paths.ini b/generator/paths.ini index c3a4c167..d16c3d9e 100644 --- a/generator/paths.ini +++ b/generator/paths.ini @@ -8,4 +8,6 @@ PATH_TO_RESPONSE_CLASS = ../RpcResponse.js PATH_TO_NOTIFICATION_CLASS = ../RpcNotification.js ENUMS_DIR_NAME = ../enums STRUCTS_DIR_NAME = ../structs -FUNCTIONS_DIR_NAME = ../messages \ No newline at end of file +FUNCTIONS_DIR_NAME = ../messages + +RPC_CREATOR = RpcCreator.js \ No newline at end of file diff --git a/generator/templates/RpcCreator_template.js b/generator/templates/RpcCreator_template.js new file mode 100644 index 00000000..4306ffa6 --- /dev/null +++ b/generator/templates/RpcCreator_template.js @@ -0,0 +1,65 @@ +{% extends 'base_template.js' %} + +{%- block imports %} +// messages +{{-super()}} +// other +import { RpcType } from './enums/RpcType.js'; +import { FunctionID } from './enums/FunctionID.js'; +import { JsonRpcMarshaller } from './../util/JsonRpcMarshaller.js'; +import { BinaryFrameHeader } from './../protocol/BinaryFrameHeader.js'; + +{% endblock -%} +{%- block body %} + /** + * Converts an SdlPacket to an RpcMessage + * @param {SdlPacket} sdlPacket + * @return {RpcMessage} + */ + static construct (sdlPacket) { + const payload = sdlPacket.getPayload(); + const binaryFrameHeader = BinaryFrameHeader.fromBinaryHeader(payload); + + let message; + const rpcType = binaryFrameHeader.getRpcType(); + const rpcName = RpcType.keyForValue(rpcType); + const correlationId = binaryFrameHeader.getCorrelationId(); + const functionId = binaryFrameHeader.getFunctionId(); + const functionName = FunctionID.keyForValue(functionId); + const bulkData = binaryFrameHeader.getBulkData(); + const jsonData = binaryFrameHeader.getJsonData(); + const params = { + parameters: JsonRpcMarshaller.unmarshall(jsonData), + }; + + switch (functionId) { + {%- for item in cases %} + case FunctionID.{{item.name}}: + if (rpcType === RpcType.{{item.type}}) { + message = new {{item.name}}(params); + } {% if item.type == 'REQUEST' -%} + else if (rpcType === RpcType.RESPONSE) { + message = new {{item.name}}Response(params); + } + {%- endif %} + break; + {%- endfor %} + default: + message = null; + } + + if (message === null || message === undefined) { // informs of missing classes + console.warn(`RpcCreator couldn't construct an RPC for the ${functionName} ${rpcName}`); + return null; + } + + if (rpcType === RpcType.REQUEST || rpcType === RpcType.RESPONSE) { + message.setCorrelationId(correlationId); + } + if (bulkData) { + message.setBulkData(bulkData); + } + + return message; + } +{% endblock -%} \ No newline at end of file diff --git a/generator/templates/base_struct_function.js b/generator/templates/base_struct_function.js index 7853c7ec..9a909a88 100644 --- a/generator/templates/base_struct_function.js +++ b/generator/templates/base_struct_function.js @@ -23,34 +23,32 @@ */ {%- block constructor %} {% endblock -%} - {% if scripts is defined -%} - {% for s in scripts %} -{{s|indent(4,True)}} - {% endfor -%} + {%- if script is defined %} +{{script|indent(4,True)}} {% endif -%} - {% for e in methods %} - {% set l = e.type|length + e.param_name|length + 13 -%} + {% for method in methods %} + {% set len = method.type|length + method.param_name|length + 13 -%} /** {% if deprecated is defined -%} * @deprecated {% endif -%} - {% if not e.description -%} - * @param {{'%s%s%s %s'|format('{', e.type, '}', e.param_name)}} + {% if not method.description -%} + * @param {{'%s%s%s %s'|format('{', method.type, '}', method.param_name)}} {% else -%} - * {% for d in e.description -%} + * {% for d in method.description -%} {% if loop.index == 1 -%} - @param {{'%s%s%s %s - %s'|format('{', e.type, '}', e.param_name, d)}} + @param {{'%s%s%s %s - %s'|format('{', method.type, '}', method.param_name, d)}} {% else -%} - * {{d|indent(l,True)}} + * {{d|indent(len,True)}} {% endif -%} {% endfor -%} {% endif -%} * @return {{'%s%s%s'|format('{', name, '}')}} */ - set{{e.method_title}} ({{e.param_name}}) { - {%- if e.external and 'Array' not in e.type %} - this.validateType({{e.external}}, {{e.param_name}}); + set{{method.method_title}} ({{method.param_name}}) { + {%- if method.external %} + this.validateType({{method.external}}, {{method.param_name}}{{ ', true' if '[]' in method.type }}); {%- endif %} - this.setParameter({{name}}.{{e.key}}, {{e.param_name}}); + this.setParameter({{name}}.{{method.key}}, {{method.param_name}}); return this; } @@ -58,19 +56,19 @@ {% if deprecated is defined -%} * @deprecated {% endif -%} - * @return {{'%s%s%s'|format('{', e.type, '}')}} + * @return {{'%s%s%s'|format('{', method.type, '}')}} */ - get{{e.method_title}} () { - {%- if e.external %} - return this.getObject({{e.external}}, {{name}}.{{e.key}}); + get{{method.method_title}} () { + {%- if method.external %} + return this.getObject({{method.external}}, {{name}}.{{method.key}}); {%- else %} - return this.getParameter({{name}}.{{e.key}}); + return this.getParameter({{name}}.{{method.key}}); {%- endif %} } -{% endfor %} +{% endfor -%} {%- endblock %} -{% block properties %} -{%- for e in params %} -{{name}}.{{e.key}} = {{e.value}}; +{% block properties -%} +{% for param in params %} +{{name}}.{{param.key}} = {{param.value}}; {%- endfor %} {%- endblock %} \ No newline at end of file diff --git a/generator/templates/base_template.js b/generator/templates/base_template.js index b8058607..a690ff56 100644 --- a/generator/templates/base_template.js +++ b/generator/templates/base_template.js @@ -30,15 +30,16 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ -{% for e in imports %} -import {{'%s %s %s'|format('{', e.what, '}')}} from '{{e.wherefrom}}'; +{% block imports -%} +{% for _import in imports %} +import {{'%s %s %s'|format('{', _import.what, '}')}} from '{{_import.wherefrom}}'; {%- endfor %} -{% block typedef %}{% endblock %} -class {{name}} extends {{extend}} { +{% endblock -%} +{% block typedef -%}{%- endblock %} +class {{name}}{{' extends '+ extend if extend}} { {%- block body %} {% endblock -%} } -{% block properties %} -{% endblock %} +{% block properties -%}{%- endblock %} export {{'%s %s %s'|format('{', name, '}')}}; diff --git a/generator/templates/enum_template.js b/generator/templates/enum_template.js index afe46a5e..948c1831 100644 --- a/generator/templates/enum_template.js +++ b/generator/templates/enum_template.js @@ -23,25 +23,23 @@ constructor () { super(); } - {%- for e in methods %} + {%- for method in methods %} /** {%- if deprecated is defined %} * @deprecated {%- endif %} - {%- for d in e.description %} + {%- for d in method.description %} * {{d}} {%- endfor %} - * @return {{'%s%s%s'|format('{', e.type, '}')}} + * @return {{'%s%s%s'|format('{', method.type, '}')}} */ - static get {{e.method_title}} () { - return {{name}}._MAP.{{e.method_title}}; + static get {{method.method_title}} () { + return {{name}}._MAP.{{method.method_title}}; } {%- endfor %} -{% if scripts is defined -%} - {%- for s in scripts %} -{{s|indent(4,True)}} - {%- endfor %} +{% if script is defined %} +{{script|indent(4,True)}} {% endif %} /** * Get the value for the given enum key @@ -63,8 +61,8 @@ {% endblock %} {% block properties %} {{name}}._MAP = Object.freeze({ -{%- for e in params %} - '{{e.key}}': {{e.value}}, +{%- for param in params %} + '{{param.key}}': {{param.value}}, {%- endfor %} }); {%- endblock %} \ No newline at end of file diff --git a/generator/transformers/common_producer.py b/generator/transformers/common_producer.py index ff69645f..576150a5 100644 --- a/generator/transformers/common_producer.py +++ b/generator/transformers/common_producer.py @@ -213,7 +213,7 @@ def evaluate(instance): return type(instance).__name__ if isinstance(param.param_type, Array): - return 'Array<{}>'.format(evaluate(param.param_type.element_type)) + return self.replace_sync(evaluate(param.param_type.element_type)) + '[]' return self.replace_sync(evaluate(param.param_type)) def get_file_content(self, file_name: str): diff --git a/lib/rpc_spec b/lib/rpc_spec index a6c66dfc..a6dc295d 160000 --- a/lib/rpc_spec +++ b/lib/rpc_spec @@ -1 +1 @@ -Subproject commit a6c66dfc989c2f7b94a77f8beb5d92bf1c910b9b +Subproject commit a6dc295d040531077705d96406e5cbe759c38df4 From 6821ddf3b76676107acd0c94030bc3a45e36712b Mon Sep 17 00:00:00 2001 From: Aleksandr Mishchenko Date: Wed, 29 Jan 2020 15:13:24 +0100 Subject: [PATCH 12/19] adding RpcCreator.js: year in Copyright --- generator/generator.py | 3 ++- generator/mapping.json | 21 ++++++++++++++++++++ generator/templates/RpcCreator_template.js | 1 - generator/transformers/common_producer.py | 13 +++++++----- generator/transformers/functions_producer.py | 5 ++--- generator/transformers/structs_producer.py | 5 ++--- 6 files changed, 35 insertions(+), 13 deletions(-) diff --git a/generator/generator.py b/generator/generator.py index 56733011..7e087b54 100644 --- a/generator/generator.py +++ b/generator/generator.py @@ -7,6 +7,7 @@ import sys from argparse import ArgumentParser from collections import namedtuple +from datetime import date from inspect import getfile from json import JSONDecodeError, loads from os.path import basename @@ -307,7 +308,7 @@ def process_function_name(self, file, dir_name, skip, overwrite, functions, tran :return: """ creator = namedtuple('creator', 'name type') - data = {'name': file.stem, 'imports': [], 'cases': []} + data = {'name': file.stem, 'imports': [], 'cases': [], 'year': date.today().year, } for item in functions.values(): kind = item.message_type.name.upper() if kind == 'RESPONSE': diff --git a/generator/mapping.json b/generator/mapping.json index 5c1deb7a..0d46ccf5 100644 --- a/generator/mapping.json +++ b/generator/mapping.json @@ -1,4 +1,16 @@ { + "enums": { + "FunctionID": { + "OnHMIStatusID": { + "methods": { + "method_title": "OnHmiStatus" + }, + "params": { + "key": "OnHmiStatus" + } + } + } + }, "structs": { "DisplayCapabilities": { "graphicSupported": { @@ -75,6 +87,15 @@ } }, "functions": { + "OnHMIStatusNotification": { + "name": "OnHmiStatus", + "file_name": "OnHmiStatus", + "hmiLevel": { + "methods": { + "method_title": "HMILevel" + } + } + }, "SetAppIconRequest": { "syncFileName": { "methods": { diff --git a/generator/templates/RpcCreator_template.js b/generator/templates/RpcCreator_template.js index 4306ffa6..72974a0f 100644 --- a/generator/templates/RpcCreator_template.js +++ b/generator/templates/RpcCreator_template.js @@ -8,7 +8,6 @@ import { RpcType } from './enums/RpcType.js'; import { FunctionID } from './enums/FunctionID.js'; import { JsonRpcMarshaller } from './../util/JsonRpcMarshaller.js'; import { BinaryFrameHeader } from './../protocol/BinaryFrameHeader.js'; - {% endblock -%} {%- block body %} /** diff --git a/generator/transformers/common_producer.py b/generator/transformers/common_producer.py index 576150a5..f2faae69 100644 --- a/generator/transformers/common_producer.py +++ b/generator/transformers/common_producer.py @@ -26,11 +26,10 @@ class InterfaceProducerCommon(ABC): version = '1.0.0' def __init__(self, container_name, enums_dir_name, structs_dir_name, - enum_names=(), struct_names=(), mapping=OrderedDict()): + names=(), mapping=OrderedDict()): self.logger = logging.getLogger(self.__class__.__name__) self.container_name = container_name - self.enum_names = list(map(lambda e: self.replace_sync(e), enum_names)) - self.struct_names = list(map(lambda e: self.replace_sync(e), struct_names)) + self.names = list(map(lambda e: self.replace_sync(e), names)) self.enums_dir = enums_dir_name self.structs_dir = structs_dir_name self.mapping = mapping @@ -104,9 +103,9 @@ def common_flow(self, param, item_type): type_name = self.extract_type(param) imports = None if name: - if name in self.enum_names: + if isinstance(param, Enum): imports = {name: '{}/{}.js'.format(self.enums_dir, name)} - elif name in self.struct_names: + elif isinstance(param, Struct): if item_type is Struct: import_path = '.' else: @@ -261,6 +260,8 @@ def custom_mapping(self, render, item): del custom['script'] for name, mapping in custom.copy().items(): + if not isinstance(mapping, dict): + continue for section, data in mapping.copy().items(): if section == '-methods' and name in render['methods']: redundant = list(custom[name].copy().keys()) @@ -295,3 +296,5 @@ def custom_mapping(self, render, item): del custom[name] if name in custom and not custom[name]: del custom[name] + + render.update(custom) diff --git a/generator/transformers/functions_producer.py b/generator/transformers/functions_producer.py index aec2896b..8acc231f 100644 --- a/generator/transformers/functions_producer.py +++ b/generator/transformers/functions_producer.py @@ -12,13 +12,12 @@ class FunctionsProducer(InterfaceProducerCommon): Functions transformation """ - def __init__(self, paths, enum_names, struct_names, mapping=None): + def __init__(self, paths, names, mapping=None): super(FunctionsProducer, self).__init__( container_name='params', enums_dir_name=paths.enums_dir_name, structs_dir_name=paths.structs_dir_name, - enum_names=enum_names, - struct_names=struct_names, + names=names, mapping=mapping['functions'] if mapping and 'functions' in mapping else {}) self.logger = logging.getLogger(self.__class__.__name__) self.request_class = paths.path_to_request_class diff --git a/generator/transformers/structs_producer.py b/generator/transformers/structs_producer.py index 77a85330..7028eadc 100644 --- a/generator/transformers/structs_producer.py +++ b/generator/transformers/structs_producer.py @@ -13,13 +13,12 @@ class StructsProducer(InterfaceProducerCommon): Structs transformation """ - def __init__(self, paths, enum_names, struct_names, mapping=None): + def __init__(self, paths, names, mapping=None): super(StructsProducer, self).__init__( container_name='members', enums_dir_name=paths.enums_dir_name, structs_dir_name=paths.structs_dir_name, - enum_names=enum_names, - struct_names=struct_names, + names=names, mapping=mapping['structs'] if mapping and 'structs' in mapping else {}) self.logger = logging.getLogger(self.__class__.__name__) self.struct_class = paths.path_to_struct_class From f3f56567069cbc71bd89fafac5d722dc9594ac80 Mon Sep 17 00:00:00 2001 From: Aleksandr Mishchenko Date: Wed, 29 Jan 2020 16:11:46 +0100 Subject: [PATCH 13/19] updating auto-tests --- generator/test/test_functions.py | 17 +++------ generator/test/test_structs.py | 2 +- generator/transformers/common_producer.py | 40 ++++++++++++++------ generator/transformers/enums_producer.py | 2 +- generator/transformers/functions_producer.py | 2 +- generator/transformers/structs_producer.py | 2 +- 6 files changed, 38 insertions(+), 27 deletions(-) diff --git a/generator/test/test_functions.py b/generator/test/test_functions.py index 8eb24a8f..74a5c67b 100644 --- a/generator/test/test_functions.py +++ b/generator/test/test_functions.py @@ -29,12 +29,6 @@ def setUp(self): mapping = {"functions": { "RegisterAppInterfaceRequest": { "syncMsgVersion": { - "imports": [ - { - "what": "SdlMsgVersion", - "wherefrom": "../structs/SdlMsgVersion.js" - } - ], "methods": { "method_title": "SdlMsgVersion", "external": "SdlMsgVersion", @@ -59,9 +53,8 @@ def setUp(self): "script": "templates/scripts/PutFileRequest.js" }}} - enum_names = ('FileType', 'Language') - struct_names = ('SyncMsgVersion', 'TemplateColorScheme', 'TTSChunk', 'Choice') - self.producer = FunctionsProducer(paths, enum_names, struct_names, mapping) + names = ('FileType', 'Language', 'SyncMsgVersion', 'TemplateColorScheme', 'TTSChunk', 'Choice') + self.producer = FunctionsProducer(paths, names, mapping) def test_RegisterAppInterfaceRequest(self): item = Function(name='RegisterAppInterface', function_id=Enum(name='RegisterAppInterfaceID'), @@ -98,7 +91,7 @@ def test_RegisterAppInterfaceRequest(self): type='TemplateColorScheme'), self.producer.methods(key='KEY_TTS_NAME', param_name='name', method_title='TtsName', external='TTSChunk', - description=['TTS string for'], type='Array')], + description=['TTS string for'], type='TTSChunk[]')], 'params': [self.producer.params(key='APP_ID_MAX_LENGTH', value=10), self.producer.params(key='KEY_SDL_MSG_VERSION', value="'syncMsgVersion'"), self.producer.params(key='KEY_FULL_APP_ID', value="'fullAppID'"), @@ -141,7 +134,7 @@ def test_RegisterAppInterfaceResponse(self): self.producer.methods(key='KEY_SUPPORTED_DIAG_MODES', method_title='SupportedDiagModes', external=None, description=['Specifies the'], param_name='modes', - type='Array')], + type='Number[]')], 'params': [self.producer.params(key='KEY_LANGUAGE', value="'language'"), self.producer.params(key='KEY_SUPPORTED_DIAG_MODES', value="'supportedDiagModes'")], 'description': ['The response'], @@ -252,7 +245,7 @@ def test_CreateInteractionChoiceSetRequest(self): 'methods': [self.producer.methods(key='KEY_CHOICE_SET', method_title='ChoiceSet', external='Choice', description=['A choice is an option given to'], param_name='set', - type='Array')], + type='Choice[]')], 'params': [self.producer.params(key='KEY_CHOICE_SET', value="'choiceSet'")], 'description': ['creates interaction'], 'func': 'CreateInteractionChoiceSet', diff --git a/generator/test/test_structs.py b/generator/test/test_structs.py index 77de73d2..c5110a29 100644 --- a/generator/test/test_structs.py +++ b/generator/test/test_structs.py @@ -15,7 +15,7 @@ def setUp(self): structs_dir_name='../structs', path_to_struct_class='../RpcStruct.js') - self.producer = StructsProducer(paths, (), ('Image',)) + self.producer = StructsProducer(paths, ['Image'], {}) def test_SoftButton(self): item = Struct(name='SoftButton', members={ diff --git a/generator/transformers/common_producer.py b/generator/transformers/common_producer.py index f2faae69..324d62f6 100644 --- a/generator/transformers/common_producer.py +++ b/generator/transformers/common_producer.py @@ -92,6 +92,33 @@ def transform(self, item) -> dict: return render + def extract_imports(self, param, item_type): + """ + :param param: + :param item_type: + :return: + """ + + def evaluate(element): + if isinstance(element, (Struct, Enum)): + return self.replace_sync(element.name), type(element) + return None, None + + if isinstance(param.param_type, Array): + type_origin, kind = evaluate(param.param_type.element_type) + else: + type_origin, kind = evaluate(param.param_type) + + if type_origin in self.names: + if kind is Enum: + return {type_origin: '{}/{}.js'.format(self.enums_dir, type_origin)} + elif kind is Struct: + if item_type is Struct: + import_path = '.' + else: + import_path = self.structs_dir + return {type_origin: '{}/{}.js'.format(import_path, type_origin)} + def common_flow(self, param, item_type): """ Main transformation flow, for Struct and Function @@ -101,16 +128,7 @@ def common_flow(self, param, item_type): """ name, description = self.extract_name_description(param) type_name = self.extract_type(param) - imports = None - if name: - if isinstance(param, Enum): - imports = {name: '{}/{}.js'.format(self.enums_dir, name)} - elif isinstance(param, Struct): - if item_type is Struct: - import_path = '.' - else: - import_path = self.structs_dir - imports = {name: '{}/{}.js'.format(import_path, name)} + imports = self.extract_imports(param, item_type) param_name = self.replace_sync(param.name) key = self.key(param_name) @@ -124,7 +142,7 @@ def common_flow(self, param, item_type): params = self.params(key=key, value="'{}'".format(param.name)) return imports, methods, params - def extract_imports(self, extend): + def prepare_imports(self, extend): """ Extract imports from property PATH_TO_(STRUCT|REQUEST|RESPONSE|NOTIFICATION)_CLASS :param extend: property to be evaluated and converted to self.imports diff --git a/generator/transformers/enums_producer.py b/generator/transformers/enums_producer.py index cbccde23..f268b414 100644 --- a/generator/transformers/enums_producer.py +++ b/generator/transformers/enums_producer.py @@ -32,7 +32,7 @@ def transform(self, item: Enum) -> dict: :return: dictionary to be applied to jinja2 template """ tmp = super(EnumsProducer, self).transform(item) - what_where = self.extract_imports(self.enum_class) + what_where = self.prepare_imports(self.enum_class) tmp.update({'extend': what_where.what}) tmp['imports'].add(what_where) return tmp diff --git a/generator/transformers/functions_producer.py b/generator/transformers/functions_producer.py index 8acc231f..13836ba2 100644 --- a/generator/transformers/functions_producer.py +++ b/generator/transformers/functions_producer.py @@ -44,7 +44,7 @@ def transform(self, item: Function) -> dict: elif item.message_type.name == 'notification': name = self.notification_class if name: - what_where = self.extract_imports(name) + what_where = self.prepare_imports(name) render.update({'extend': what_where.what}) render['imports'].add(what_where) render['imports'].add(self.imports(what='FunctionID', wherefrom='{}/FunctionID.js'.format(self.enums_dir))) diff --git a/generator/transformers/structs_producer.py b/generator/transformers/structs_producer.py index 7028eadc..f5c90cf6 100644 --- a/generator/transformers/structs_producer.py +++ b/generator/transformers/structs_producer.py @@ -30,7 +30,7 @@ def transform(self, item: Struct) -> dict: :return: dictionary to be applied to jinja2 template """ tmp = super(StructsProducer, self).transform(item) - what_where = self.extract_imports(self.struct_class) + what_where = self.prepare_imports(self.struct_class) tmp.update({'extend': what_where.what}) tmp['imports'].add(what_where) return tmp From 904a7c56a2f227099502e4cbef10cf6499a03463 Mon Sep 17 00:00:00 2001 From: Aleksandr Mishchenko Date: Wed, 29 Jan 2020 16:29:05 +0100 Subject: [PATCH 14/19] Trailing spaces not allowed in RpcCreator --- generator/templates/RpcCreator_template.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/generator/templates/RpcCreator_template.js b/generator/templates/RpcCreator_template.js index 72974a0f..394ab7ed 100644 --- a/generator/templates/RpcCreator_template.js +++ b/generator/templates/RpcCreator_template.js @@ -36,8 +36,7 @@ import { BinaryFrameHeader } from './../protocol/BinaryFrameHeader.js'; case FunctionID.{{item.name}}: if (rpcType === RpcType.{{item.type}}) { message = new {{item.name}}(params); - } {% if item.type == 'REQUEST' -%} - else if (rpcType === RpcType.RESPONSE) { + }{% if item.type == 'REQUEST' %} else if (rpcType === RpcType.RESPONSE) { message = new {{item.name}}Response(params); } {%- endif %} From dd8291c99128528a9df039ec4a867197ff4d0146 Mon Sep 17 00:00:00 2001 From: Aleksandr Mishchenko Date: Wed, 29 Jan 2020 17:59:46 +0100 Subject: [PATCH 15/19] resolving issue with GenericResponseResponce --- generator/generator.py | 44 +++++++++++++--------- generator/templates/RpcCreator_template.js | 6 +-- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/generator/generator.py b/generator/generator.py index 7e087b54..9d79e27e 100644 --- a/generator/generator.py +++ b/generator/generator.py @@ -9,6 +9,7 @@ from collections import namedtuple from datetime import date from inspect import getfile +from itertools import groupby from json import JSONDecodeError, loads from os.path import basename from pprint import pformat @@ -307,21 +308,28 @@ def process_function_name(self, file, dir_name, skip, overwrite, functions, tran :param mappings: :return: """ - creator = namedtuple('creator', 'name type') + if dir_name.startswith('..'): + dir_name = dir_name[1:] + + creator = namedtuple('creator', 'function_name class_name type') data = {'name': file.stem, 'imports': [], 'cases': [], 'year': date.today().year, } - for item in functions.values(): - kind = item.message_type.name.upper() - if kind == 'RESPONSE': - name = item.name + kind.capitalize() - else: - name = item.name - key = item.name + kind.capitalize() - if key in mappings and 'name' in mappings[key]: - name = mappings[key]['name'] - if kind != 'RESPONSE': - data['cases'].append(creator(name, kind)) - data['imports'].append(transformer.imports(what=name, wherefrom='{}/{}.js'.format(dir_name, name))) + grouped = [{'name': k, 'type': [x for x in v]} for k, v in groupby(functions.values(), key=lambda x: x.name)] + + for item in grouped: + name = item['name'] + for func in item['type']: + kind = func.message_type.name.capitalize() + if kind == 'Response': + name += kind + key = name + kind + if key in mappings and 'name' in mappings[key]: + name = mappings[key]['name'] + data['imports'].append(transformer.imports(what=name, wherefrom='{}/{}.js'.format(dir_name, name))) + if kind != 'Response': + data['cases'].append(creator(name, name, kind.upper())) + elif kind == 'Response' and len(item['type']) == 1: + data['cases'].append(creator(item['name'], name, kind.upper())) self.process_common(skip, overwrite, file, file.stem + '_template.js', data) @@ -426,6 +434,7 @@ def main(self): mappings = self.get_mappings() + functions_transformer = FunctionsProducer(paths, names, mappings) if args.enums and filtered.enums: directory = args.output_directory.joinpath(self.evaluate_instance_directory(paths.enums_dir_name)) self.process(directory, args.skip, args.overwrite, filtered.enums, @@ -435,12 +444,11 @@ def main(self): self.process(directory, args.skip, args.overwrite, filtered.structs, StructsProducer(paths, names, mappings)) if args.functions and filtered.functions: - transformer = FunctionsProducer(paths, names, mappings) directory = args.output_directory.joinpath(self.evaluate_instance_directory(paths.functions_dir_name)) - self.process(directory, args.skip, args.overwrite, filtered.functions, transformer) - self.process_function_name(args.output_directory.joinpath(paths.rpc_creator), paths.functions_dir_name, - args.skip, args.overwrite, interface.functions, transformer, - mappings.get('functions', {})) + self.process(directory, args.skip, args.overwrite, filtered.functions, functions_transformer) + self.process_function_name(args.output_directory.joinpath(paths.rpc_creator), paths.functions_dir_name, + args.skip, args.overwrite, interface.functions, functions_transformer, + mappings.get('functions', {})) if __name__ == '__main__': diff --git a/generator/templates/RpcCreator_template.js b/generator/templates/RpcCreator_template.js index 394ab7ed..0ad53233 100644 --- a/generator/templates/RpcCreator_template.js +++ b/generator/templates/RpcCreator_template.js @@ -33,11 +33,11 @@ import { BinaryFrameHeader } from './../protocol/BinaryFrameHeader.js'; switch (functionId) { {%- for item in cases %} - case FunctionID.{{item.name}}: + case FunctionID.{{item.function_name}}: if (rpcType === RpcType.{{item.type}}) { - message = new {{item.name}}(params); + message = new {{item.class_name}}(params); }{% if item.type == 'REQUEST' %} else if (rpcType === RpcType.RESPONSE) { - message = new {{item.name}}Response(params); + message = new {{item.class_name}}Response(params); } {%- endif %} break; From e0eac24a61b2a973a9ebd73c20742417852b2a18 Mon Sep 17 00:00:00 2001 From: Aleksandr Mishchenko Date: Thu, 30 Jan 2020 13:44:04 +0100 Subject: [PATCH 16/19] handle exeption in xsd --- lib/rpc_spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rpc_spec b/lib/rpc_spec index a6dc295d..8bda2918 160000 --- a/lib/rpc_spec +++ b/lib/rpc_spec @@ -1 +1 @@ -Subproject commit a6dc295d040531077705d96406e5cbe759c38df4 +Subproject commit 8bda29189ca7f6e81d285d6aab9768cd83b93a14 From ae6dd2b368be63c22e15585a545614e7ca9e0e20 Mon Sep 17 00:00:00 2001 From: Aleksandr Mishchenko Date: Fri, 31 Jan 2020 10:54:21 +0100 Subject: [PATCH 17/19] applying changes requested in review --- .eslintrc | 4 +- generator/README.md | 6 +-- generator/mapping.json | 66 ----------------------- generator/test/test_functions.py | 6 +-- generator/transformers/common_producer.py | 2 +- 5 files changed, 9 insertions(+), 75 deletions(-) diff --git a/.eslintrc b/.eslintrc index 2e74b787..f1c54506 100644 --- a/.eslintrc +++ b/.eslintrc @@ -40,7 +40,7 @@ "curly": [ "error" ], "dot-notation": [ "error" ], "eqeqeq": [ "error" ], - "id-length": [ "error" ], + "id-length": [ "error", { "exceptions": ["x", "y"] } ], "indent": [ "error", 4, @@ -53,7 +53,7 @@ "error", "unix" ], - "new-cap": [ "error", { + "new-cap": [ "error", { "newIsCapExceptions": ["tClass"] }], "no-case-declarations": [ "error" ], diff --git a/generator/README.md b/generator/README.md index 706c931e..84124498 100644 --- a/generator/README.md +++ b/generator/README.md @@ -1549,7 +1549,7 @@ The customization script contains the JSON object. Below is the schema: [element_name|param_name]: { "-methods": {}, "methods": { - "method_name": [custom_method_name], + "method_title": [custom_method_title], "key": [custom_key_name], "description": [custom_description] }, @@ -1647,7 +1647,7 @@ _FunctionClass_.APP_ID_MAX_LENGTH = 10; In order of this customization it is possible to change the name and description of getter/setter methods and the name and value of corresponding static property. Additionally it is possible to remove getter/setter methods. ### Changing the name and description of getter/setter methods -To change the name and description of getter/setter methods it needs to define `methods.method_name` value. +To change the name and description of getter/setter methods it needs to define `methods.method_title` value. Example: ```json @@ -1656,7 +1656,7 @@ Example: "AudioType": { "PCM": { "methods": { - "method_name": "Wave", + "method_title": "Wave", "description": "Linear Wave!" } } diff --git a/generator/mapping.json b/generator/mapping.json index 0d46ccf5..2f928fea 100644 --- a/generator/mapping.json +++ b/generator/mapping.json @@ -1,28 +1,5 @@ { - "enums": { - "FunctionID": { - "OnHMIStatusID": { - "methods": { - "method_title": "OnHmiStatus" - }, - "params": { - "key": "OnHmiStatus" - } - } - } - }, "structs": { - "DisplayCapabilities": { - "graphicSupported": { - "methods": { - "method_title": "GraphicsSupported", - "key": "KEY_GRAPHICS_SUPPORTED" - }, - "params": { - "key": "KEY_GRAPHICS_SUPPORTED" - } - } - }, "Grid": { "col": { "methods": { @@ -60,42 +37,9 @@ "key": "KEY_LEVEL_SPAN" } } - }, - "TextField": { - "name": { - "methods": { - "method_title": "TextFieldName" - } - } - }, - "RGBColor": { - "red": { - "methods": { - "method_title": "RedValue" - } - }, - "green": { - "methods": { - "method_title": "GreenValue" - } - }, - "blue": { - "methods": { - "method_title": "BlueValue" - } - } } }, "functions": { - "OnHMIStatusNotification": { - "name": "OnHmiStatus", - "file_name": "OnHmiStatus", - "hmiLevel": { - "methods": { - "method_title": "HMILevel" - } - } - }, "SetAppIconRequest": { "syncFileName": { "methods": { @@ -107,16 +51,6 @@ } } }, - "RegisterAppInterfaceResponse": { - "supportedDiagModes": { - "methods": { - "key": "KEY_SUPPORTED_DIAG_MODE" - }, - "params": { - "key": "KEY_SUPPORTED_DIAG_MODE" - } - } - }, "RegisterAppInterfaceRequest": { "appID": { "-methods": {} diff --git a/generator/test/test_functions.py b/generator/test/test_functions.py index 74a5c67b..eaa1ffaf 100644 --- a/generator/test/test_functions.py +++ b/generator/test/test_functions.py @@ -97,7 +97,7 @@ def test_RegisterAppInterfaceRequest(self): self.producer.params(key='KEY_FULL_APP_ID', value="'fullAppID'"), self.producer.params(key='KEY_DAY_COLOR_SCHEME', value="'dayColorScheme'"), self.producer.params(key='KEY_TTS_NAME', value="'ttsName'")], - 'scripts': [self.producer.get_file_content('templates/scripts/fullAppID.js')], + 'script': self.producer.get_file_content('templates/scripts/fullAppID.js'), 'func': 'RegisterAppInterface', 'extend': 'RpcRequest' } @@ -186,7 +186,7 @@ def test_PutFileRequest(self): type='FileType')], 'params': [self.producer.params(key='KEY_FILE_TYPE', value="'fileType'")], 'description': ['Used to'], - 'scripts': [self.producer.get_file_content('templates/scripts/PutFileRequest.js')], + 'script': self.producer.get_file_content('templates/scripts/PutFileRequest.js'), 'func': 'PutFile', 'extend': 'RpcRequest' } @@ -196,7 +196,7 @@ def test_PutFileRequest(self): self.assertListEqual(sorted(expected['methods']), sorted(result['methods'])) self.assertListEqual(sorted(expected['params']), sorted(result['params'])) self.assertEqual(expected['description'], result['description']) - self.assertSequenceEqual(expected['scripts'], result['scripts']) + self.assertSequenceEqual(expected['script'], result['script']) self.assertEqual(expected['func'], result['func']) self.assertEqual(expected['extend'], result['extend']) diff --git a/generator/transformers/common_producer.py b/generator/transformers/common_producer.py index 324d62f6..a894e68e 100644 --- a/generator/transformers/common_producer.py +++ b/generator/transformers/common_producer.py @@ -274,7 +274,7 @@ def custom_mapping(self, render, item): if 'script' in custom: script = self.get_file_content(custom['script']) if script: - render['scripts'] = [script] + render['script'] = script del custom['script'] for name, mapping in custom.copy().items(): From 59df96aeebd4bb6295a4cddaa29e53784b07cca9 Mon Sep 17 00:00:00 2001 From: Aleksandr Mishchenko Date: Fri, 31 Jan 2020 13:04:31 +0100 Subject: [PATCH 18/19] updating .eslintrc --- .eslintrc | 2 +- generator/templates/base_struct_function.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.eslintrc b/.eslintrc index f1c54506..19bdf662 100644 --- a/.eslintrc +++ b/.eslintrc @@ -40,7 +40,7 @@ "curly": [ "error" ], "dot-notation": [ "error" ], "eqeqeq": [ "error" ], - "id-length": [ "error", { "exceptions": ["x", "y"] } ], + "id-length": [ "error", { "exceptions": ["x", "y", "c"] } ], "indent": [ "error", 4, diff --git a/generator/templates/base_struct_function.js b/generator/templates/base_struct_function.js index 9a909a88..6eaaa4f7 100644 --- a/generator/templates/base_struct_function.js +++ b/generator/templates/base_struct_function.js @@ -25,7 +25,7 @@ {% endblock -%} {%- if script is defined %} {{script|indent(4,True)}} - {% endif -%} +{% endif -%} {% for method in methods %} {% set len = method.type|length + method.param_name|length + 13 -%} /** From cb105180c4065f0f8d115ff9f588aae73d41076f Mon Sep 17 00:00:00 2001 From: Christopher Rokita Date: Fri, 31 Jan 2020 11:24:37 -0500 Subject: [PATCH 19/19] Add generated files and update the library and example apps --- .gitmodules | 2 +- examples/js/hello-sdl/index.html | 2 +- examples/node/hello-sdl/index.js | 2 +- lib/js/app.js | 578 +- lib/js/dist/SDL.js | 4 +- .../src/manager/lifecycle/LifecycleManager.js | 8 +- lib/js/src/rpc/RpcCreator.js | 682 +- lib/js/src/rpc/enums/AmbientLightStatus.js | 135 + lib/js/src/rpc/enums/AppHMIType.js | 29 +- .../enums/AppInterfaceUnregisteredReason.js | 167 + lib/js/src/rpc/enums/AppServiceType.js | 94 + .../src/rpc/enums/AudioStreamingIndicator.js | 108 + lib/js/src/rpc/enums/AudioStreamingState.js | 30 +- lib/js/src/rpc/enums/AudioType.js | 31 +- lib/js/src/rpc/enums/BitsPerSample.js | 35 +- lib/js/src/rpc/enums/ButtonEventMode.js | 88 + lib/js/src/rpc/enums/ButtonName.js | 37 +- lib/js/src/rpc/enums/ButtonPressMode.js | 90 + lib/js/src/rpc/enums/CarModeStatus.js | 103 + lib/js/src/rpc/enums/CharacterSet.js | 50 +- lib/js/src/rpc/enums/CompassDirection.js | 135 + lib/js/src/rpc/enums/ComponentVolumeStatus.js | 119 + lib/js/src/rpc/enums/DefrostZone.js | 102 + lib/js/src/rpc/enums/DeliveryMode.js | 95 + lib/js/src/rpc/enums/DeviceLevelStatus.js | 119 + lib/js/src/rpc/enums/Dimension.js | 98 + lib/js/src/rpc/enums/Direction.js | 86 + lib/js/src/rpc/enums/DisplayMode.js | 94 + lib/js/src/rpc/enums/DisplayType.js | 43 +- lib/js/src/rpc/enums/DistanceUnit.js | 86 + .../src/rpc/enums/DriverDistractionState.js | 87 + .../src/rpc/enums/ECallConfirmationStatus.js | 127 + .../rpc/enums/ElectronicParkBrakeStatus.js | 115 + lib/js/src/rpc/enums/EmergencyEventType.js | 127 + lib/js/src/rpc/enums/FileType.js | 37 +- lib/js/src/rpc/enums/FuelCutoffStatus.js | 95 + lib/js/src/rpc/enums/FuelType.js | 123 + lib/js/src/rpc/enums/FunctionID.js | 559 +- lib/js/src/rpc/enums/GlobalProperty.js | 143 + lib/js/src/rpc/enums/HMILevel.js | 30 +- lib/js/src/rpc/enums/HmiZoneCapabilities.js | 32 +- lib/js/src/rpc/enums/HybridAppPreference.js | 95 + lib/js/src/rpc/enums/IgnitionStableStatus.js | 95 + lib/js/src/rpc/enums/IgnitionStatus.js | 119 + lib/js/src/rpc/enums/ImageFieldName.js | 102 +- lib/js/src/rpc/enums/ImageType.js | 30 +- lib/js/src/rpc/enums/InteractionMode.js | 102 + lib/js/src/rpc/enums/KeyboardEvent.js | 111 + lib/js/src/rpc/enums/KeyboardLayout.js | 95 + lib/js/src/rpc/enums/KeypressMode.js | 99 + lib/js/src/rpc/enums/Language.js | 247 +- lib/js/src/rpc/enums/LayoutMode.js | 118 + lib/js/src/rpc/enums/LightName.js | 478 + lib/js/src/rpc/enums/LightStatus.js | 118 + lib/js/src/rpc/enums/MaintenanceModeStatus.js | 103 + lib/js/src/rpc/enums/MassageCushion.js | 111 + lib/js/src/rpc/enums/MassageMode.js | 95 + lib/js/src/rpc/enums/MassageZone.js | 89 + lib/js/src/rpc/enums/MediaClockFormat.js | 43 +- lib/js/src/rpc/enums/MediaType.js | 102 + lib/js/src/rpc/enums/MenuLayout.js | 87 + lib/js/src/rpc/enums/MetadataType.js | 43 +- lib/js/src/rpc/enums/ModuleType.js | 118 + lib/js/src/rpc/enums/NavigationAction.js | 127 + lib/js/src/rpc/enums/NavigationJunction.js | 146 + lib/js/src/rpc/enums/PRNDL.js | 204 + lib/js/src/rpc/enums/PermissionStatus.js | 103 + .../rpc/enums/PowerModeQualificationStatus.js | 103 + lib/js/src/rpc/enums/PowerModeStatus.js | 143 + lib/js/src/rpc/enums/PredefinedLayout.js | 255 + lib/js/src/rpc/enums/PredefinedWindows.js | 88 + lib/js/src/rpc/enums/PrerecordedSpeech.js | 30 +- lib/js/src/rpc/enums/PrimaryAudioSource.js | 167 + lib/js/src/rpc/enums/RadioBand.js | 94 + lib/js/src/rpc/enums/RadioState.js | 102 + lib/js/src/rpc/enums/RequestType.js | 247 + lib/js/src/rpc/enums/Result.js | 87 +- lib/js/src/rpc/enums/SamplingRate.js | 36 +- lib/js/src/rpc/enums/SeatMemoryActionType.js | 97 + lib/js/src/rpc/enums/ServiceUpdateReason.js | 117 + lib/js/src/rpc/enums/SoftButtonType.js | 30 +- lib/js/src/rpc/enums/SpeechCapabilities.js | 29 +- lib/js/src/rpc/enums/SupportedSeat.js | 91 + lib/js/src/rpc/enums/SystemAction.js | 34 +- lib/js/src/rpc/enums/SystemCapabilityType.js | 127 + lib/js/src/rpc/enums/SystemContext.js | 36 +- lib/js/src/rpc/enums/TBTState.js | 151 + lib/js/src/rpc/enums/TPMS.js | 142 + lib/js/src/rpc/enums/TemperatureUnit.js | 86 + lib/js/src/rpc/enums/TextAlignment.js | 43 +- lib/js/src/rpc/enums/TextFieldName.js | 189 +- lib/js/src/rpc/enums/TimerMode.js | 97 + lib/js/src/rpc/enums/TouchType.js | 102 + lib/js/src/rpc/enums/TriggerSource.js | 95 + lib/js/src/rpc/enums/TurnSignal.js | 107 + lib/js/src/rpc/enums/UpdateMode.js | 116 + .../src/rpc/enums/VehicleDataActiveStatus.js | 111 + .../src/rpc/enums/VehicleDataEventStatus.js | 111 + .../enums/VehicleDataNotificationStatus.js | 103 + lib/js/src/rpc/enums/VehicleDataResultCode.js | 152 + lib/js/src/rpc/enums/VehicleDataStatus.js | 95 + lib/js/src/rpc/enums/VehicleDataType.js | 328 + lib/js/src/rpc/enums/VentilationMode.js | 102 + lib/js/src/rpc/enums/VideoStreamingCodec.js | 75 +- .../src/rpc/enums/VideoStreamingProtocol.js | 67 +- lib/js/src/rpc/enums/VideoStreamingState.js | 30 +- lib/js/src/rpc/enums/VrCapabilities.js | 29 +- lib/js/src/rpc/enums/WarningLightStatus.js | 103 + lib/js/src/rpc/enums/WayPointType.js | 87 + lib/js/src/rpc/enums/WindowType.js | 89 + lib/js/src/rpc/enums/WiperStatus.js | 191 + lib/js/src/rpc/enums/messageType.js | 95 + lib/js/src/rpc/messages/AddCommand.js | 81 +- lib/js/src/rpc/messages/AddCommandResponse.js | 18 +- lib/js/src/rpc/messages/AddSubMenu.js | 144 + lib/js/src/rpc/messages/AddSubMenuResponse.js | 48 + lib/js/src/rpc/messages/Alert.js | 235 + lib/js/src/rpc/messages/AlertManeuver.js | 87 + .../src/rpc/messages/AlertManeuverResponse.js | 48 + lib/js/src/rpc/messages/AlertResponse.js | 67 + lib/js/src/rpc/messages/ButtonPress.js | 122 + .../src/rpc/messages/ButtonPressResponse.js | 48 + lib/js/src/rpc/messages/CancelInteraction.js | 88 + .../rpc/messages/CancelInteractionResponse.js | 51 + lib/js/src/rpc/messages/ChangeRegistration.js | 155 + .../messages/ChangeRegistrationResponse.js | 48 + lib/js/src/rpc/messages/CloseApplication.js | 51 + .../rpc/messages/CloseApplicationResponse.js | 48 + .../messages/CreateInteractionChoiceSet.js | 88 + .../CreateInteractionChoiceSetResponse.js | 48 + lib/js/src/rpc/messages/CreateWindow.js | 155 + .../src/rpc/messages/CreateWindowResponse.js | 48 + lib/js/src/rpc/messages/DeleteCommand.js | 68 + .../src/rpc/messages/DeleteCommandResponse.js | 48 + lib/js/src/rpc/messages/DeleteFile.js | 69 + lib/js/src/rpc/messages/DeleteFileResponse.js | 69 + .../messages/DeleteInteractionChoiceSet.js | 69 + .../DeleteInteractionChoiceSetResponse.js | 48 + lib/js/src/rpc/messages/DeleteSubMenu.js | 68 + .../src/rpc/messages/DeleteSubMenuResponse.js | 48 + lib/js/src/rpc/messages/DeleteWindow.js | 69 + .../src/rpc/messages/DeleteWindowResponse.js | 48 + lib/js/src/rpc/messages/DiagnosticMessage.js | 102 + .../rpc/messages/DiagnosticMessageResponse.js | 65 + lib/js/src/rpc/messages/DialNumber.js | 69 + lib/js/src/rpc/messages/DialNumberResponse.js | 48 + lib/js/src/rpc/messages/EncodedSyncPData.js | 69 + .../rpc/messages/EncodedSyncPDataResponse.js | 48 + lib/js/src/rpc/messages/EndAudioPassThru.js | 51 + .../rpc/messages/EndAudioPassThruResponse.js | 48 + .../rpc/messages/GenericResponseResponse.js | 52 + lib/js/src/rpc/messages/GetAppServiceData.js | 90 + .../rpc/messages/GetAppServiceDataResponse.js | 72 + .../src/rpc/messages/GetCloudAppProperties.js | 68 + .../messages/GetCloudAppPropertiesResponse.js | 70 + lib/js/src/rpc/messages/GetDTCs.js | 85 + lib/js/src/rpc/messages/GetDTCsResponse.js | 84 + lib/js/src/rpc/messages/GetFile.js | 139 + lib/js/src/rpc/messages/GetFileResponse.js | 122 + .../rpc/messages/GetInteriorVehicleData.js | 107 + .../messages/GetInteriorVehicleDataConsent.js | 84 + .../GetInteriorVehicleDataConsentResponse.js | 67 + .../GetInteriorVehicleDataResponse.js | 90 + .../src/rpc/messages/GetSystemCapability.js | 89 + .../messages/GetSystemCapabilityResponse.js | 69 + lib/js/src/rpc/messages/GetVehicleData.js | 561 + .../rpc/messages/GetVehicleDataResponse.js | 595 + lib/js/src/rpc/messages/GetWayPoints.js | 71 + .../src/rpc/messages/GetWayPointsResponse.js | 67 + lib/js/src/rpc/messages/ListFiles.js | 52 + lib/js/src/rpc/messages/ListFilesResponse.js | 87 + .../messages/OnAppInterfaceUnregistered.js | 67 + lib/js/src/rpc/messages/OnAppServiceData.js | 72 + lib/js/src/rpc/messages/OnAudioPassThru.js | 51 + lib/js/src/rpc/messages/OnButtonEvent.js | 107 + lib/js/src/rpc/messages/OnButtonPress.js | 107 + lib/js/src/rpc/messages/OnCommand.js | 84 + .../src/rpc/messages/OnDriverDistraction.js | 109 + lib/js/src/rpc/messages/OnEncodedSyncPData.js | 105 + lib/js/src/rpc/messages/OnHashChange.js | 70 + lib/js/src/rpc/messages/OnHmiStatus.js | 130 +- .../src/rpc/messages/OnInteriorVehicleData.js | 69 + lib/js/src/rpc/messages/OnKeyboardInput.js | 90 + lib/js/src/rpc/messages/OnLanguageChange.js | 45 +- .../src/rpc/messages/OnPermissionsChange.js | 87 + lib/js/src/rpc/messages/OnRCStatus.js | 107 + .../rpc/messages/OnSystemCapabilityUpdated.js | 70 + lib/js/src/rpc/messages/OnSystemRequest.js | 178 + lib/js/src/rpc/messages/OnTBTClientState.js | 70 + lib/js/src/rpc/messages/OnTouchEvent.js | 89 + lib/js/src/rpc/messages/OnVehicleData.js | 598 + lib/js/src/rpc/messages/OnWayPointChange.js | 70 + .../messages/PerformAppServiceInteraction.js | 119 + .../PerformAppServiceInteractionResponse.js | 65 + .../src/rpc/messages/PerformAudioPassThru.js | 198 + .../messages/PerformAudioPassThruResponse.js | 48 + lib/js/src/rpc/messages/PerformInteraction.js | 241 + .../messages/PerformInteractionResponse.js | 103 + lib/js/src/rpc/messages/PublishAppService.js | 72 + .../rpc/messages/PublishAppServiceResponse.js | 72 + lib/js/src/rpc/messages/PutFile.js | 132 +- lib/js/src/rpc/messages/PutFileResponse.js | 37 +- lib/js/src/rpc/messages/ReadDID.js | 85 + lib/js/src/rpc/messages/ReadDIDResponse.js | 67 + .../src/rpc/messages/RegisterAppInterface.js | 381 +- .../messages/RegisterAppInterfaceResponse.js | 360 +- .../ReleaseInteriorVehicleDataModule.js | 84 + ...eleaseInteriorVehicleDataModuleResponse.js | 48 + .../src/rpc/messages/ResetGlobalProperties.js | 72 + .../messages/ResetGlobalPropertiesResponse.js | 48 + lib/js/src/rpc/messages/ScrollableMessage.js | 125 + .../rpc/messages/ScrollableMessageResponse.js | 48 + lib/js/src/rpc/messages/SendHapticData.js | 75 + .../rpc/messages/SendHapticDataResponse.js | 48 + lib/js/src/rpc/messages/SendLocation.js | 226 + .../src/rpc/messages/SendLocationResponse.js | 48 + lib/js/src/rpc/messages/SetAppIcon.js | 34 +- lib/js/src/rpc/messages/SetAppIconResponse.js | 22 +- .../src/rpc/messages/SetCloudAppProperties.js | 70 + .../messages/SetCloudAppPropertiesResponse.js | 51 + lib/js/src/rpc/messages/SetDisplayLayout.js | 114 + .../rpc/messages/SetDisplayLayoutResponse.js | 139 + .../src/rpc/messages/SetGlobalProperties.js | 226 + .../messages/SetGlobalPropertiesResponse.js | 48 + .../rpc/messages/SetInteriorVehicleData.js | 67 + .../SetInteriorVehicleDataResponse.js | 72 + lib/js/src/rpc/messages/SetMediaClockTimer.js | 135 + .../messages/SetMediaClockTimerResponse.js | 48 + lib/js/src/rpc/messages/Show.js | 285 +- lib/js/src/rpc/messages/ShowAppMenu.js | 69 + .../src/rpc/messages/ShowAppMenuResponse.js | 48 + lib/js/src/rpc/messages/ShowConstantTBT.js | 246 + .../rpc/messages/ShowConstantTBTResponse.js | 48 + lib/js/src/rpc/messages/ShowResponse.js | 18 +- lib/js/src/rpc/messages/Slider.js | 158 + lib/js/src/rpc/messages/SliderResponse.js | 66 + lib/js/src/rpc/messages/Speak.js | 71 + lib/js/src/rpc/messages/SpeakResponse.js | 48 + lib/js/src/rpc/messages/SubscribeButton.js | 71 + .../rpc/messages/SubscribeButtonResponse.js | 48 + .../src/rpc/messages/SubscribeVehicleData.js | 546 + .../messages/SubscribeVehicleDataResponse.js | 572 + lib/js/src/rpc/messages/SubscribeWayPoints.js | 51 + .../messages/SubscribeWayPointsResponse.js | 48 + lib/js/src/rpc/messages/SystemRequest.js | 107 + .../src/rpc/messages/SystemRequestResponse.js | 48 + .../src/rpc/messages/UnpublishAppService.js | 68 + .../messages/UnpublishAppServiceResponse.js | 51 + .../rpc/messages/UnregisterAppInterface.js | 20 +- .../UnregisterAppInterfaceResponse.js | 18 +- lib/js/src/rpc/messages/UnsubscribeButton.js | 70 + .../rpc/messages/UnsubscribeButtonResponse.js | 48 + .../rpc/messages/UnsubscribeVehicleData.js | 544 + .../UnsubscribeVehicleDataResponse.js | 572 + .../src/rpc/messages/UnsubscribeWayPoints.js | 51 + .../messages/UnsubscribeWayPointsResponse.js | 67 + lib/js/src/rpc/messages/UpdateTurnList.js | 86 + .../rpc/messages/UpdateTurnListResponse.js | 48 + lib/js/src/rpc/structs/AirbagStatus.js | 197 + lib/js/src/rpc/structs/AppInfo.js | 78 +- .../src/rpc/structs/AppServiceCapability.js | 85 + lib/js/src/rpc/structs/AppServiceData.js | 143 + lib/js/src/rpc/structs/AppServiceManifest.js | 220 + lib/js/src/rpc/structs/AppServiceRecord.js | 125 + .../rpc/structs/AppServicesCapabilities.js | 70 + .../rpc/structs/AudioControlCapabilities.js | 169 + lib/js/src/rpc/structs/AudioControlData.js | 127 + .../rpc/structs/AudioPassThruCapabilities.js | 69 +- lib/js/src/rpc/structs/BeltStatus.js | 318 + lib/js/src/rpc/structs/BodyInformation.js | 169 + lib/js/src/rpc/structs/ButtonCapabilities.js | 93 +- lib/js/src/rpc/structs/Choice.js | 171 + .../rpc/structs/ClimateControlCapabilities.js | 394 + lib/js/src/rpc/structs/ClimateControlData.js | 308 + lib/js/src/rpc/structs/CloudAppProperties.js | 170 + lib/js/src/rpc/structs/ClusterModeStatus.js | 120 + lib/js/src/rpc/structs/Coordinate.js | 80 + lib/js/src/rpc/structs/DIDResult.js | 102 + lib/js/src/rpc/structs/DateTime.js | 199 + lib/js/src/rpc/structs/DeviceInfo.js | 105 +- lib/js/src/rpc/structs/DeviceStatus.js | 240 + lib/js/src/rpc/structs/DisplayCapabilities.js | 208 +- lib/js/src/rpc/structs/DisplayCapability.js | 111 + lib/js/src/rpc/structs/ECallInfo.js | 104 + lib/js/src/rpc/structs/EmergencyEvent.js | 139 + lib/js/src/rpc/structs/EqualizerSettings.js | 100 + lib/js/src/rpc/structs/FuelRange.js | 82 + lib/js/src/rpc/structs/GPSData.js | 378 + lib/js/src/rpc/structs/Grid.js | 93 +- lib/js/src/rpc/structs/HMICapabilities.js | 109 +- lib/js/src/rpc/structs/HMIPermissions.js | 83 + .../structs/HMISettingsControlCapabilities.js | 134 + .../src/rpc/structs/HMISettingsControlData.js | 106 + lib/js/src/rpc/structs/HapticRect.js | 86 + lib/js/src/rpc/structs/HeadLampStatus.js | 99 + lib/js/src/rpc/structs/Image.js | 51 +- lib/js/src/rpc/structs/ImageField.js | 69 +- lib/js/src/rpc/structs/ImageResolution.js | 42 +- lib/js/src/rpc/structs/KeyboardProperties.js | 160 + lib/js/src/rpc/structs/LightCapabilities.js | 117 + .../rpc/structs/LightControlCapabilities.js | 102 + lib/js/src/rpc/structs/LightControlData.js | 66 + lib/js/src/rpc/structs/LightState.js | 120 + lib/js/src/rpc/structs/LocationDetails.js | 171 + .../src/rpc/structs/MassageCushionFirmness.js | 85 + lib/js/src/rpc/structs/MassageModeData.js | 87 + lib/js/src/rpc/structs/MediaServiceData.js | 295 + .../src/rpc/structs/MediaServiceManifest.js | 46 + lib/js/src/rpc/structs/MenuParams.js | 55 +- lib/js/src/rpc/structs/MetadataTags.js | 75 +- lib/js/src/rpc/structs/ModuleData.js | 200 + lib/js/src/rpc/structs/ModuleInfo.js | 74 +- lib/js/src/rpc/structs/MyKey.js | 66 + .../src/rpc/structs/NavigationCapability.js | 83 + .../src/rpc/structs/NavigationInstruction.js | 200 + .../src/rpc/structs/NavigationServiceData.js | 218 + .../rpc/structs/NavigationServiceManifest.js | 63 + lib/js/src/rpc/structs/OASISAddress.js | 199 + .../src/rpc/structs/ParameterPermissions.js | 80 + lib/js/src/rpc/structs/PermissionItem.js | 118 + lib/js/src/rpc/structs/PhoneCapability.js | 66 + .../src/rpc/structs/PresetBankCapabilities.js | 31 +- lib/js/src/rpc/structs/RGBColor.js | 64 +- .../rpc/structs/RadioControlCapabilities.js | 320 + lib/js/src/rpc/structs/RadioControlData.js | 280 + lib/js/src/rpc/structs/RdsData.js | 183 + lib/js/src/rpc/structs/Rectangle.js | 114 + .../rpc/structs/RemoteControlCapabilities.js | 184 + lib/js/src/rpc/structs/ScreenParams.js | 43 +- lib/js/src/rpc/structs/SdlMsgVersion.js | 61 +- .../rpc/structs/SeatControlCapabilities.js | 338 + lib/js/src/rpc/structs/SeatControlData.js | 329 + lib/js/src/rpc/structs/SeatLocation.js | 68 + .../src/rpc/structs/SeatLocationCapability.js | 119 + lib/js/src/rpc/structs/SeatMemoryAction.js | 99 + lib/js/src/rpc/structs/SingleTireStatus.js | 101 + lib/js/src/rpc/structs/SisData.js | 137 + lib/js/src/rpc/structs/SoftButton.js | 99 +- .../src/rpc/structs/SoftButtonCapabilities.js | 92 +- lib/js/src/rpc/structs/StartTime.js | 98 + lib/js/src/rpc/structs/StationIDNumber.js | 81 + lib/js/src/rpc/structs/SystemCapability.js | 206 + lib/js/src/rpc/structs/TTSChunk.js | 40 +- lib/js/src/rpc/structs/Temperature.js | 83 + lib/js/src/rpc/structs/TemplateColorScheme.js | 68 +- .../src/rpc/structs/TemplateConfiguration.js | 101 + lib/js/src/rpc/structs/TextField.js | 73 +- lib/js/src/rpc/structs/TireStatus.js | 177 + lib/js/src/rpc/structs/TouchCoord.js | 80 + lib/js/src/rpc/structs/TouchEvent.js | 106 + .../src/rpc/structs/TouchEventCapabilities.js | 59 +- lib/js/src/rpc/structs/Turn.js | 82 + lib/js/src/rpc/structs/VehicleDataResult.js | 104 + lib/js/src/rpc/structs/VehicleType.js | 59 +- .../rpc/structs/VideoStreamingCapability.js | 134 +- .../src/rpc/structs/VideoStreamingFormat.js | 61 +- lib/js/src/rpc/structs/VrHelpItem.js | 99 + lib/js/src/rpc/structs/WeatherAlert.js | 151 + lib/js/src/rpc/structs/WeatherData.js | 431 + lib/js/src/rpc/structs/WeatherServiceData.js | 160 + .../src/rpc/structs/WeatherServiceManifest.js | 131 + lib/js/src/rpc/structs/WindowCapability.js | 215 + .../src/rpc/structs/WindowTypeCapabilities.js | 82 + lib/node/dist/index.js | 40514 +++++++++++++--- package-lock.json | 8 +- package.json | 1 + rollup.config.js | 2 + 367 files changed, 74099 insertions(+), 9074 deletions(-) create mode 100644 lib/js/src/rpc/enums/AmbientLightStatus.js create mode 100644 lib/js/src/rpc/enums/AppInterfaceUnregisteredReason.js create mode 100644 lib/js/src/rpc/enums/AppServiceType.js create mode 100644 lib/js/src/rpc/enums/AudioStreamingIndicator.js create mode 100644 lib/js/src/rpc/enums/ButtonEventMode.js create mode 100644 lib/js/src/rpc/enums/ButtonPressMode.js create mode 100644 lib/js/src/rpc/enums/CarModeStatus.js create mode 100644 lib/js/src/rpc/enums/CompassDirection.js create mode 100644 lib/js/src/rpc/enums/ComponentVolumeStatus.js create mode 100644 lib/js/src/rpc/enums/DefrostZone.js create mode 100644 lib/js/src/rpc/enums/DeliveryMode.js create mode 100644 lib/js/src/rpc/enums/DeviceLevelStatus.js create mode 100644 lib/js/src/rpc/enums/Dimension.js create mode 100644 lib/js/src/rpc/enums/Direction.js create mode 100644 lib/js/src/rpc/enums/DisplayMode.js create mode 100644 lib/js/src/rpc/enums/DistanceUnit.js create mode 100644 lib/js/src/rpc/enums/DriverDistractionState.js create mode 100644 lib/js/src/rpc/enums/ECallConfirmationStatus.js create mode 100644 lib/js/src/rpc/enums/ElectronicParkBrakeStatus.js create mode 100644 lib/js/src/rpc/enums/EmergencyEventType.js create mode 100644 lib/js/src/rpc/enums/FuelCutoffStatus.js create mode 100644 lib/js/src/rpc/enums/FuelType.js create mode 100644 lib/js/src/rpc/enums/GlobalProperty.js create mode 100644 lib/js/src/rpc/enums/HybridAppPreference.js create mode 100644 lib/js/src/rpc/enums/IgnitionStableStatus.js create mode 100644 lib/js/src/rpc/enums/IgnitionStatus.js create mode 100644 lib/js/src/rpc/enums/InteractionMode.js create mode 100644 lib/js/src/rpc/enums/KeyboardEvent.js create mode 100644 lib/js/src/rpc/enums/KeyboardLayout.js create mode 100644 lib/js/src/rpc/enums/KeypressMode.js create mode 100644 lib/js/src/rpc/enums/LayoutMode.js create mode 100644 lib/js/src/rpc/enums/LightName.js create mode 100644 lib/js/src/rpc/enums/LightStatus.js create mode 100644 lib/js/src/rpc/enums/MaintenanceModeStatus.js create mode 100644 lib/js/src/rpc/enums/MassageCushion.js create mode 100644 lib/js/src/rpc/enums/MassageMode.js create mode 100644 lib/js/src/rpc/enums/MassageZone.js create mode 100644 lib/js/src/rpc/enums/MediaType.js create mode 100644 lib/js/src/rpc/enums/MenuLayout.js create mode 100644 lib/js/src/rpc/enums/ModuleType.js create mode 100644 lib/js/src/rpc/enums/NavigationAction.js create mode 100644 lib/js/src/rpc/enums/NavigationJunction.js create mode 100644 lib/js/src/rpc/enums/PRNDL.js create mode 100644 lib/js/src/rpc/enums/PermissionStatus.js create mode 100644 lib/js/src/rpc/enums/PowerModeQualificationStatus.js create mode 100644 lib/js/src/rpc/enums/PowerModeStatus.js create mode 100644 lib/js/src/rpc/enums/PredefinedLayout.js create mode 100644 lib/js/src/rpc/enums/PredefinedWindows.js create mode 100644 lib/js/src/rpc/enums/PrimaryAudioSource.js create mode 100644 lib/js/src/rpc/enums/RadioBand.js create mode 100644 lib/js/src/rpc/enums/RadioState.js create mode 100644 lib/js/src/rpc/enums/RequestType.js create mode 100644 lib/js/src/rpc/enums/SeatMemoryActionType.js create mode 100644 lib/js/src/rpc/enums/ServiceUpdateReason.js create mode 100644 lib/js/src/rpc/enums/SupportedSeat.js create mode 100644 lib/js/src/rpc/enums/SystemCapabilityType.js create mode 100644 lib/js/src/rpc/enums/TBTState.js create mode 100644 lib/js/src/rpc/enums/TPMS.js create mode 100644 lib/js/src/rpc/enums/TemperatureUnit.js create mode 100644 lib/js/src/rpc/enums/TimerMode.js create mode 100644 lib/js/src/rpc/enums/TouchType.js create mode 100644 lib/js/src/rpc/enums/TriggerSource.js create mode 100644 lib/js/src/rpc/enums/TurnSignal.js create mode 100644 lib/js/src/rpc/enums/UpdateMode.js create mode 100644 lib/js/src/rpc/enums/VehicleDataActiveStatus.js create mode 100644 lib/js/src/rpc/enums/VehicleDataEventStatus.js create mode 100644 lib/js/src/rpc/enums/VehicleDataNotificationStatus.js create mode 100644 lib/js/src/rpc/enums/VehicleDataResultCode.js create mode 100644 lib/js/src/rpc/enums/VehicleDataStatus.js create mode 100644 lib/js/src/rpc/enums/VehicleDataType.js create mode 100644 lib/js/src/rpc/enums/VentilationMode.js create mode 100644 lib/js/src/rpc/enums/WarningLightStatus.js create mode 100644 lib/js/src/rpc/enums/WayPointType.js create mode 100644 lib/js/src/rpc/enums/WindowType.js create mode 100644 lib/js/src/rpc/enums/WiperStatus.js create mode 100644 lib/js/src/rpc/enums/messageType.js create mode 100644 lib/js/src/rpc/messages/AddSubMenu.js create mode 100644 lib/js/src/rpc/messages/AddSubMenuResponse.js create mode 100644 lib/js/src/rpc/messages/Alert.js create mode 100644 lib/js/src/rpc/messages/AlertManeuver.js create mode 100644 lib/js/src/rpc/messages/AlertManeuverResponse.js create mode 100644 lib/js/src/rpc/messages/AlertResponse.js create mode 100644 lib/js/src/rpc/messages/ButtonPress.js create mode 100644 lib/js/src/rpc/messages/ButtonPressResponse.js create mode 100644 lib/js/src/rpc/messages/CancelInteraction.js create mode 100644 lib/js/src/rpc/messages/CancelInteractionResponse.js create mode 100644 lib/js/src/rpc/messages/ChangeRegistration.js create mode 100644 lib/js/src/rpc/messages/ChangeRegistrationResponse.js create mode 100644 lib/js/src/rpc/messages/CloseApplication.js create mode 100644 lib/js/src/rpc/messages/CloseApplicationResponse.js create mode 100644 lib/js/src/rpc/messages/CreateInteractionChoiceSet.js create mode 100644 lib/js/src/rpc/messages/CreateInteractionChoiceSetResponse.js create mode 100644 lib/js/src/rpc/messages/CreateWindow.js create mode 100644 lib/js/src/rpc/messages/CreateWindowResponse.js create mode 100644 lib/js/src/rpc/messages/DeleteCommand.js create mode 100644 lib/js/src/rpc/messages/DeleteCommandResponse.js create mode 100644 lib/js/src/rpc/messages/DeleteFile.js create mode 100644 lib/js/src/rpc/messages/DeleteFileResponse.js create mode 100644 lib/js/src/rpc/messages/DeleteInteractionChoiceSet.js create mode 100644 lib/js/src/rpc/messages/DeleteInteractionChoiceSetResponse.js create mode 100644 lib/js/src/rpc/messages/DeleteSubMenu.js create mode 100644 lib/js/src/rpc/messages/DeleteSubMenuResponse.js create mode 100644 lib/js/src/rpc/messages/DeleteWindow.js create mode 100644 lib/js/src/rpc/messages/DeleteWindowResponse.js create mode 100644 lib/js/src/rpc/messages/DiagnosticMessage.js create mode 100644 lib/js/src/rpc/messages/DiagnosticMessageResponse.js create mode 100644 lib/js/src/rpc/messages/DialNumber.js create mode 100644 lib/js/src/rpc/messages/DialNumberResponse.js create mode 100644 lib/js/src/rpc/messages/EncodedSyncPData.js create mode 100644 lib/js/src/rpc/messages/EncodedSyncPDataResponse.js create mode 100644 lib/js/src/rpc/messages/EndAudioPassThru.js create mode 100644 lib/js/src/rpc/messages/EndAudioPassThruResponse.js create mode 100644 lib/js/src/rpc/messages/GenericResponseResponse.js create mode 100644 lib/js/src/rpc/messages/GetAppServiceData.js create mode 100644 lib/js/src/rpc/messages/GetAppServiceDataResponse.js create mode 100644 lib/js/src/rpc/messages/GetCloudAppProperties.js create mode 100644 lib/js/src/rpc/messages/GetCloudAppPropertiesResponse.js create mode 100644 lib/js/src/rpc/messages/GetDTCs.js create mode 100644 lib/js/src/rpc/messages/GetDTCsResponse.js create mode 100644 lib/js/src/rpc/messages/GetFile.js create mode 100644 lib/js/src/rpc/messages/GetFileResponse.js create mode 100644 lib/js/src/rpc/messages/GetInteriorVehicleData.js create mode 100644 lib/js/src/rpc/messages/GetInteriorVehicleDataConsent.js create mode 100644 lib/js/src/rpc/messages/GetInteriorVehicleDataConsentResponse.js create mode 100644 lib/js/src/rpc/messages/GetInteriorVehicleDataResponse.js create mode 100644 lib/js/src/rpc/messages/GetSystemCapability.js create mode 100644 lib/js/src/rpc/messages/GetSystemCapabilityResponse.js create mode 100644 lib/js/src/rpc/messages/GetVehicleData.js create mode 100644 lib/js/src/rpc/messages/GetVehicleDataResponse.js create mode 100644 lib/js/src/rpc/messages/GetWayPoints.js create mode 100644 lib/js/src/rpc/messages/GetWayPointsResponse.js create mode 100644 lib/js/src/rpc/messages/ListFiles.js create mode 100644 lib/js/src/rpc/messages/ListFilesResponse.js create mode 100644 lib/js/src/rpc/messages/OnAppInterfaceUnregistered.js create mode 100644 lib/js/src/rpc/messages/OnAppServiceData.js create mode 100644 lib/js/src/rpc/messages/OnAudioPassThru.js create mode 100644 lib/js/src/rpc/messages/OnButtonEvent.js create mode 100644 lib/js/src/rpc/messages/OnButtonPress.js create mode 100644 lib/js/src/rpc/messages/OnCommand.js create mode 100644 lib/js/src/rpc/messages/OnDriverDistraction.js create mode 100644 lib/js/src/rpc/messages/OnEncodedSyncPData.js create mode 100644 lib/js/src/rpc/messages/OnHashChange.js create mode 100644 lib/js/src/rpc/messages/OnInteriorVehicleData.js create mode 100644 lib/js/src/rpc/messages/OnKeyboardInput.js create mode 100644 lib/js/src/rpc/messages/OnPermissionsChange.js create mode 100644 lib/js/src/rpc/messages/OnRCStatus.js create mode 100644 lib/js/src/rpc/messages/OnSystemCapabilityUpdated.js create mode 100644 lib/js/src/rpc/messages/OnSystemRequest.js create mode 100644 lib/js/src/rpc/messages/OnTBTClientState.js create mode 100644 lib/js/src/rpc/messages/OnTouchEvent.js create mode 100644 lib/js/src/rpc/messages/OnVehicleData.js create mode 100644 lib/js/src/rpc/messages/OnWayPointChange.js create mode 100644 lib/js/src/rpc/messages/PerformAppServiceInteraction.js create mode 100644 lib/js/src/rpc/messages/PerformAppServiceInteractionResponse.js create mode 100644 lib/js/src/rpc/messages/PerformAudioPassThru.js create mode 100644 lib/js/src/rpc/messages/PerformAudioPassThruResponse.js create mode 100644 lib/js/src/rpc/messages/PerformInteraction.js create mode 100644 lib/js/src/rpc/messages/PerformInteractionResponse.js create mode 100644 lib/js/src/rpc/messages/PublishAppService.js create mode 100644 lib/js/src/rpc/messages/PublishAppServiceResponse.js create mode 100644 lib/js/src/rpc/messages/ReadDID.js create mode 100644 lib/js/src/rpc/messages/ReadDIDResponse.js create mode 100644 lib/js/src/rpc/messages/ReleaseInteriorVehicleDataModule.js create mode 100644 lib/js/src/rpc/messages/ReleaseInteriorVehicleDataModuleResponse.js create mode 100644 lib/js/src/rpc/messages/ResetGlobalProperties.js create mode 100644 lib/js/src/rpc/messages/ResetGlobalPropertiesResponse.js create mode 100644 lib/js/src/rpc/messages/ScrollableMessage.js create mode 100644 lib/js/src/rpc/messages/ScrollableMessageResponse.js create mode 100644 lib/js/src/rpc/messages/SendHapticData.js create mode 100644 lib/js/src/rpc/messages/SendHapticDataResponse.js create mode 100644 lib/js/src/rpc/messages/SendLocation.js create mode 100644 lib/js/src/rpc/messages/SendLocationResponse.js create mode 100644 lib/js/src/rpc/messages/SetCloudAppProperties.js create mode 100644 lib/js/src/rpc/messages/SetCloudAppPropertiesResponse.js create mode 100644 lib/js/src/rpc/messages/SetDisplayLayout.js create mode 100644 lib/js/src/rpc/messages/SetDisplayLayoutResponse.js create mode 100644 lib/js/src/rpc/messages/SetGlobalProperties.js create mode 100644 lib/js/src/rpc/messages/SetGlobalPropertiesResponse.js create mode 100644 lib/js/src/rpc/messages/SetInteriorVehicleData.js create mode 100644 lib/js/src/rpc/messages/SetInteriorVehicleDataResponse.js create mode 100644 lib/js/src/rpc/messages/SetMediaClockTimer.js create mode 100644 lib/js/src/rpc/messages/SetMediaClockTimerResponse.js create mode 100644 lib/js/src/rpc/messages/ShowAppMenu.js create mode 100644 lib/js/src/rpc/messages/ShowAppMenuResponse.js create mode 100644 lib/js/src/rpc/messages/ShowConstantTBT.js create mode 100644 lib/js/src/rpc/messages/ShowConstantTBTResponse.js create mode 100644 lib/js/src/rpc/messages/Slider.js create mode 100644 lib/js/src/rpc/messages/SliderResponse.js create mode 100644 lib/js/src/rpc/messages/Speak.js create mode 100644 lib/js/src/rpc/messages/SpeakResponse.js create mode 100644 lib/js/src/rpc/messages/SubscribeButton.js create mode 100644 lib/js/src/rpc/messages/SubscribeButtonResponse.js create mode 100644 lib/js/src/rpc/messages/SubscribeVehicleData.js create mode 100644 lib/js/src/rpc/messages/SubscribeVehicleDataResponse.js create mode 100644 lib/js/src/rpc/messages/SubscribeWayPoints.js create mode 100644 lib/js/src/rpc/messages/SubscribeWayPointsResponse.js create mode 100644 lib/js/src/rpc/messages/SystemRequest.js create mode 100644 lib/js/src/rpc/messages/SystemRequestResponse.js create mode 100644 lib/js/src/rpc/messages/UnpublishAppService.js create mode 100644 lib/js/src/rpc/messages/UnpublishAppServiceResponse.js create mode 100644 lib/js/src/rpc/messages/UnsubscribeButton.js create mode 100644 lib/js/src/rpc/messages/UnsubscribeButtonResponse.js create mode 100644 lib/js/src/rpc/messages/UnsubscribeVehicleData.js create mode 100644 lib/js/src/rpc/messages/UnsubscribeVehicleDataResponse.js create mode 100644 lib/js/src/rpc/messages/UnsubscribeWayPoints.js create mode 100644 lib/js/src/rpc/messages/UnsubscribeWayPointsResponse.js create mode 100644 lib/js/src/rpc/messages/UpdateTurnList.js create mode 100644 lib/js/src/rpc/messages/UpdateTurnListResponse.js create mode 100644 lib/js/src/rpc/structs/AirbagStatus.js create mode 100644 lib/js/src/rpc/structs/AppServiceCapability.js create mode 100644 lib/js/src/rpc/structs/AppServiceData.js create mode 100644 lib/js/src/rpc/structs/AppServiceManifest.js create mode 100644 lib/js/src/rpc/structs/AppServiceRecord.js create mode 100644 lib/js/src/rpc/structs/AppServicesCapabilities.js create mode 100644 lib/js/src/rpc/structs/AudioControlCapabilities.js create mode 100644 lib/js/src/rpc/structs/AudioControlData.js create mode 100644 lib/js/src/rpc/structs/BeltStatus.js create mode 100644 lib/js/src/rpc/structs/BodyInformation.js create mode 100644 lib/js/src/rpc/structs/Choice.js create mode 100644 lib/js/src/rpc/structs/ClimateControlCapabilities.js create mode 100644 lib/js/src/rpc/structs/ClimateControlData.js create mode 100644 lib/js/src/rpc/structs/CloudAppProperties.js create mode 100644 lib/js/src/rpc/structs/ClusterModeStatus.js create mode 100644 lib/js/src/rpc/structs/Coordinate.js create mode 100644 lib/js/src/rpc/structs/DIDResult.js create mode 100644 lib/js/src/rpc/structs/DateTime.js create mode 100644 lib/js/src/rpc/structs/DeviceStatus.js create mode 100644 lib/js/src/rpc/structs/DisplayCapability.js create mode 100644 lib/js/src/rpc/structs/ECallInfo.js create mode 100644 lib/js/src/rpc/structs/EmergencyEvent.js create mode 100644 lib/js/src/rpc/structs/EqualizerSettings.js create mode 100644 lib/js/src/rpc/structs/FuelRange.js create mode 100644 lib/js/src/rpc/structs/GPSData.js create mode 100644 lib/js/src/rpc/structs/HMIPermissions.js create mode 100644 lib/js/src/rpc/structs/HMISettingsControlCapabilities.js create mode 100644 lib/js/src/rpc/structs/HMISettingsControlData.js create mode 100644 lib/js/src/rpc/structs/HapticRect.js create mode 100644 lib/js/src/rpc/structs/HeadLampStatus.js create mode 100644 lib/js/src/rpc/structs/KeyboardProperties.js create mode 100644 lib/js/src/rpc/structs/LightCapabilities.js create mode 100644 lib/js/src/rpc/structs/LightControlCapabilities.js create mode 100644 lib/js/src/rpc/structs/LightControlData.js create mode 100644 lib/js/src/rpc/structs/LightState.js create mode 100644 lib/js/src/rpc/structs/LocationDetails.js create mode 100644 lib/js/src/rpc/structs/MassageCushionFirmness.js create mode 100644 lib/js/src/rpc/structs/MassageModeData.js create mode 100644 lib/js/src/rpc/structs/MediaServiceData.js create mode 100644 lib/js/src/rpc/structs/MediaServiceManifest.js create mode 100644 lib/js/src/rpc/structs/ModuleData.js create mode 100644 lib/js/src/rpc/structs/MyKey.js create mode 100644 lib/js/src/rpc/structs/NavigationCapability.js create mode 100644 lib/js/src/rpc/structs/NavigationInstruction.js create mode 100644 lib/js/src/rpc/structs/NavigationServiceData.js create mode 100644 lib/js/src/rpc/structs/NavigationServiceManifest.js create mode 100644 lib/js/src/rpc/structs/OASISAddress.js create mode 100644 lib/js/src/rpc/structs/ParameterPermissions.js create mode 100644 lib/js/src/rpc/structs/PermissionItem.js create mode 100644 lib/js/src/rpc/structs/PhoneCapability.js create mode 100644 lib/js/src/rpc/structs/RadioControlCapabilities.js create mode 100644 lib/js/src/rpc/structs/RadioControlData.js create mode 100644 lib/js/src/rpc/structs/RdsData.js create mode 100644 lib/js/src/rpc/structs/Rectangle.js create mode 100644 lib/js/src/rpc/structs/RemoteControlCapabilities.js create mode 100644 lib/js/src/rpc/structs/SeatControlCapabilities.js create mode 100644 lib/js/src/rpc/structs/SeatControlData.js create mode 100644 lib/js/src/rpc/structs/SeatLocation.js create mode 100644 lib/js/src/rpc/structs/SeatLocationCapability.js create mode 100644 lib/js/src/rpc/structs/SeatMemoryAction.js create mode 100644 lib/js/src/rpc/structs/SingleTireStatus.js create mode 100644 lib/js/src/rpc/structs/SisData.js create mode 100644 lib/js/src/rpc/structs/StartTime.js create mode 100644 lib/js/src/rpc/structs/StationIDNumber.js create mode 100644 lib/js/src/rpc/structs/SystemCapability.js create mode 100644 lib/js/src/rpc/structs/Temperature.js create mode 100644 lib/js/src/rpc/structs/TemplateConfiguration.js create mode 100644 lib/js/src/rpc/structs/TireStatus.js create mode 100644 lib/js/src/rpc/structs/TouchCoord.js create mode 100644 lib/js/src/rpc/structs/TouchEvent.js create mode 100644 lib/js/src/rpc/structs/Turn.js create mode 100644 lib/js/src/rpc/structs/VehicleDataResult.js create mode 100644 lib/js/src/rpc/structs/VrHelpItem.js create mode 100644 lib/js/src/rpc/structs/WeatherAlert.js create mode 100644 lib/js/src/rpc/structs/WeatherData.js create mode 100644 lib/js/src/rpc/structs/WeatherServiceData.js create mode 100644 lib/js/src/rpc/structs/WeatherServiceManifest.js create mode 100644 lib/js/src/rpc/structs/WindowCapability.js create mode 100644 lib/js/src/rpc/structs/WindowTypeCapabilities.js diff --git a/.gitmodules b/.gitmodules index 957d3aa9..ba831342 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "lib/rpc_spec"] path = lib/rpc_spec - url = git@github.com:vladmu/rpc_spec.git + url = https://github.com/smartdevicelink/rpc_spec.git branch = master diff --git a/examples/js/hello-sdl/index.html b/examples/js/hello-sdl/index.html index 6ce9a4fd..9c007ab4 100644 --- a/examples/js/hello-sdl/index.html +++ b/examples/js/hello-sdl/index.html @@ -89,7 +89,7 @@ } async _onHmiStatusListener (onHmiStatus) { - const hmiLevel = onHmiStatus.getHMILevel(); + const hmiLevel = onHmiStatus.getHmiLevel(); // wait for the FULL state for more functionality if (hmiLevel === SDL.rpc.enums.HMILevel.HMI_FULL) { diff --git a/examples/node/hello-sdl/index.js b/examples/node/hello-sdl/index.js index 318c20dc..b475b3a1 100644 --- a/examples/node/hello-sdl/index.js +++ b/examples/node/hello-sdl/index.js @@ -89,7 +89,7 @@ class HelloSdl { } async _onHmiStatusListener (onHmiStatus) { - const hmiLevel = onHmiStatus.getHMILevel(); + const hmiLevel = onHmiStatus.getHmiLevel(); // wait for the FULL state for more functionality if (hmiLevel === SDL.rpc.enums.HMILevel.HMI_FULL) { diff --git a/lib/js/app.js b/lib/js/app.js index b2e0a776..3fb7ca96 100644 --- a/lib/js/app.js +++ b/lib/js/app.js @@ -51,76 +51,363 @@ import { RpcNotification } from './src/rpc/RpcNotification.js'; import { RpcRequest } from './src/rpc/RpcRequest.js'; import { RpcResponse } from './src/rpc/RpcResponse.js'; import { RpcStruct } from './src/rpc/RpcStruct.js'; +import { AmbientLightStatus } from './src/rpc/enums/AmbientLightStatus.js'; import { AppHMIType } from './src/rpc/enums/AppHMIType.js'; +import { AppInterfaceUnregisteredReason } from './src/rpc/enums/AppInterfaceUnregisteredReason.js'; +import { AppServiceType } from './src/rpc/enums/AppServiceType.js'; +import { AudioStreamingIndicator } from './src/rpc/enums/AudioStreamingIndicator.js'; import { AudioStreamingState } from './src/rpc/enums/AudioStreamingState.js'; import { AudioType } from './src/rpc/enums/AudioType.js'; import { BitsPerSample } from './src/rpc/enums/BitsPerSample.js'; +import { ButtonEventMode } from './src/rpc/enums/ButtonEventMode.js'; import { ButtonName } from './src/rpc/enums/ButtonName.js'; +import { ButtonPressMode } from './src/rpc/enums/ButtonPressMode.js'; +import { CarModeStatus } from './src/rpc/enums/CarModeStatus.js'; import { CharacterSet } from './src/rpc/enums/CharacterSet.js'; +import { CompassDirection } from './src/rpc/enums/CompassDirection.js'; +import { ComponentVolumeStatus } from './src/rpc/enums/ComponentVolumeStatus.js'; +import { DefrostZone } from './src/rpc/enums/DefrostZone.js'; +import { DeliveryMode } from './src/rpc/enums/DeliveryMode.js'; +import { DeviceLevelStatus } from './src/rpc/enums/DeviceLevelStatus.js'; +import { Dimension } from './src/rpc/enums/Dimension.js'; +import { Direction } from './src/rpc/enums/Direction.js'; +import { DisplayMode } from './src/rpc/enums/DisplayMode.js'; import { DisplayType } from './src/rpc/enums/DisplayType.js'; +import { DistanceUnit } from './src/rpc/enums/DistanceUnit.js'; +import { DriverDistractionState } from './src/rpc/enums/DriverDistractionState.js'; +import { ECallConfirmationStatus } from './src/rpc/enums/ECallConfirmationStatus.js'; +import { ElectronicParkBrakeStatus } from './src/rpc/enums/ElectronicParkBrakeStatus.js'; +import { EmergencyEventType } from './src/rpc/enums/EmergencyEventType.js'; import { FileType } from './src/rpc/enums/FileType.js'; +import { FuelCutoffStatus } from './src/rpc/enums/FuelCutoffStatus.js'; +import { FuelType } from './src/rpc/enums/FuelType.js'; import { FunctionID } from './src/rpc/enums/FunctionID.js'; +import { GlobalProperty } from './src/rpc/enums/GlobalProperty.js'; import { HMILevel } from './src/rpc/enums/HMILevel.js'; import { HmiZoneCapabilities } from './src/rpc/enums/HmiZoneCapabilities.js'; +import { HybridAppPreference } from './src/rpc/enums/HybridAppPreference.js'; +import { IgnitionStableStatus } from './src/rpc/enums/IgnitionStableStatus.js'; +import { IgnitionStatus } from './src/rpc/enums/IgnitionStatus.js'; import { ImageFieldName } from './src/rpc/enums/ImageFieldName.js'; import { ImageType } from './src/rpc/enums/ImageType.js'; +import { InteractionMode } from './src/rpc/enums/InteractionMode.js'; +import { KeyboardEvent } from './src/rpc/enums/KeyboardEvent.js'; +import { KeyboardLayout } from './src/rpc/enums/KeyboardLayout.js'; +import { KeypressMode } from './src/rpc/enums/KeypressMode.js'; import { Language } from './src/rpc/enums/Language.js'; +import { LayoutMode } from './src/rpc/enums/LayoutMode.js'; +import { LightName } from './src/rpc/enums/LightName.js'; +import { LightStatus } from './src/rpc/enums/LightStatus.js'; +import { MaintenanceModeStatus } from './src/rpc/enums/MaintenanceModeStatus.js'; +import { MassageCushion } from './src/rpc/enums/MassageCushion.js'; +import { MassageMode } from './src/rpc/enums/MassageMode.js'; +import { MassageZone } from './src/rpc/enums/MassageZone.js'; import { MediaClockFormat } from './src/rpc/enums/MediaClockFormat.js'; +import { MediaType } from './src/rpc/enums/MediaType.js'; +import { MenuLayout } from './src/rpc/enums/MenuLayout.js'; import { MetadataType } from './src/rpc/enums/MetadataType.js'; +import { ModuleType } from './src/rpc/enums/ModuleType.js'; +import { NavigationAction } from './src/rpc/enums/NavigationAction.js'; +import { NavigationJunction } from './src/rpc/enums/NavigationJunction.js'; +import { PRNDL } from './src/rpc/enums/PRNDL.js'; +import { PermissionStatus } from './src/rpc/enums/PermissionStatus.js'; +import { PowerModeQualificationStatus } from './src/rpc/enums/PowerModeQualificationStatus.js'; +import { PowerModeStatus } from './src/rpc/enums/PowerModeStatus.js'; +import { PredefinedLayout } from './src/rpc/enums/PredefinedLayout.js'; +import { PredefinedWindows } from './src/rpc/enums/PredefinedWindows.js'; import { PrerecordedSpeech } from './src/rpc/enums/PrerecordedSpeech.js'; +import { PrimaryAudioSource } from './src/rpc/enums/PrimaryAudioSource.js'; +import { RadioBand } from './src/rpc/enums/RadioBand.js'; +import { RadioState } from './src/rpc/enums/RadioState.js'; +import { RequestType } from './src/rpc/enums/RequestType.js'; import { Result } from './src/rpc/enums/Result.js'; import { RpcType } from './src/rpc/enums/RpcType.js'; import { SamplingRate } from './src/rpc/enums/SamplingRate.js'; +import { SeatMemoryActionType } from './src/rpc/enums/SeatMemoryActionType.js'; +import { ServiceUpdateReason } from './src/rpc/enums/ServiceUpdateReason.js'; import { SoftButtonType } from './src/rpc/enums/SoftButtonType.js'; import { SpeechCapabilities } from './src/rpc/enums/SpeechCapabilities.js'; +import { SupportedSeat } from './src/rpc/enums/SupportedSeat.js'; import { SystemAction } from './src/rpc/enums/SystemAction.js'; +import { SystemCapabilityType } from './src/rpc/enums/SystemCapabilityType.js'; import { SystemContext } from './src/rpc/enums/SystemContext.js'; +import { TBTState } from './src/rpc/enums/TBTState.js'; +import { TPMS } from './src/rpc/enums/TPMS.js'; +import { TemperatureUnit } from './src/rpc/enums/TemperatureUnit.js'; import { TextAlignment } from './src/rpc/enums/TextAlignment.js'; import { TextFieldName } from './src/rpc/enums/TextFieldName.js'; +import { TimerMode } from './src/rpc/enums/TimerMode.js'; +import { TouchType } from './src/rpc/enums/TouchType.js'; +import { TriggerSource } from './src/rpc/enums/TriggerSource.js'; +import { TurnSignal } from './src/rpc/enums/TurnSignal.js'; +import { UpdateMode } from './src/rpc/enums/UpdateMode.js'; +import { VehicleDataActiveStatus } from './src/rpc/enums/VehicleDataActiveStatus.js'; +import { VehicleDataEventStatus } from './src/rpc/enums/VehicleDataEventStatus.js'; +import { VehicleDataNotificationStatus } from './src/rpc/enums/VehicleDataNotificationStatus.js'; +import { VehicleDataResultCode } from './src/rpc/enums/VehicleDataResultCode.js'; +import { VehicleDataStatus } from './src/rpc/enums/VehicleDataStatus.js'; +import { VehicleDataType } from './src/rpc/enums/VehicleDataType.js'; +import { VentilationMode } from './src/rpc/enums/VentilationMode.js'; import { VideoStreamingCodec } from './src/rpc/enums/VideoStreamingCodec.js'; import { VideoStreamingProtocol } from './src/rpc/enums/VideoStreamingProtocol.js'; import { VideoStreamingState } from './src/rpc/enums/VideoStreamingState.js'; import { VrCapabilities } from './src/rpc/enums/VrCapabilities.js'; +import { WarningLightStatus } from './src/rpc/enums/WarningLightStatus.js'; +import { WayPointType } from './src/rpc/enums/WayPointType.js'; +import { WindowType } from './src/rpc/enums/WindowType.js'; +import { WiperStatus } from './src/rpc/enums/WiperStatus.js'; +import { messageType } from './src/rpc/enums/messageType.js'; import { AddCommand } from './src/rpc/messages/AddCommand.js'; import { AddCommandResponse } from './src/rpc/messages/AddCommandResponse.js'; -import { OnHmiStatus } from './src/rpc/messages/OnHmiStatus.js'; +import { AddSubMenu } from './src/rpc/messages/AddSubMenu.js'; +import { AddSubMenuResponse } from './src/rpc/messages/AddSubMenuResponse.js'; +import { Alert } from './src/rpc/messages/Alert.js'; +import { AlertManeuver } from './src/rpc/messages/AlertManeuver.js'; +import { AlertManeuverResponse } from './src/rpc/messages/AlertManeuverResponse.js'; +import { AlertResponse } from './src/rpc/messages/AlertResponse.js'; +import { ButtonPress } from './src/rpc/messages/ButtonPress.js'; +import { ButtonPressResponse } from './src/rpc/messages/ButtonPressResponse.js'; +import { CancelInteraction } from './src/rpc/messages/CancelInteraction.js'; +import { CancelInteractionResponse } from './src/rpc/messages/CancelInteractionResponse.js'; +import { ChangeRegistration } from './src/rpc/messages/ChangeRegistration.js'; +import { ChangeRegistrationResponse } from './src/rpc/messages/ChangeRegistrationResponse.js'; +import { CloseApplication } from './src/rpc/messages/CloseApplication.js'; +import { CloseApplicationResponse } from './src/rpc/messages/CloseApplicationResponse.js'; +import { CreateInteractionChoiceSet } from './src/rpc/messages/CreateInteractionChoiceSet.js'; +import { CreateInteractionChoiceSetResponse } from './src/rpc/messages/CreateInteractionChoiceSetResponse.js'; +import { CreateWindow } from './src/rpc/messages/CreateWindow.js'; +import { CreateWindowResponse } from './src/rpc/messages/CreateWindowResponse.js'; +import { DeleteCommand } from './src/rpc/messages/DeleteCommand.js'; +import { DeleteCommandResponse } from './src/rpc/messages/DeleteCommandResponse.js'; +import { DeleteFile } from './src/rpc/messages/DeleteFile.js'; +import { DeleteFileResponse } from './src/rpc/messages/DeleteFileResponse.js'; +import { DeleteInteractionChoiceSet } from './src/rpc/messages/DeleteInteractionChoiceSet.js'; +import { DeleteInteractionChoiceSetResponse } from './src/rpc/messages/DeleteInteractionChoiceSetResponse.js'; +import { DeleteSubMenu } from './src/rpc/messages/DeleteSubMenu.js'; +import { DeleteSubMenuResponse } from './src/rpc/messages/DeleteSubMenuResponse.js'; +import { DeleteWindow } from './src/rpc/messages/DeleteWindow.js'; +import { DeleteWindowResponse } from './src/rpc/messages/DeleteWindowResponse.js'; +import { DiagnosticMessage } from './src/rpc/messages/DiagnosticMessage.js'; +import { DiagnosticMessageResponse } from './src/rpc/messages/DiagnosticMessageResponse.js'; +import { DialNumber } from './src/rpc/messages/DialNumber.js'; +import { DialNumberResponse } from './src/rpc/messages/DialNumberResponse.js'; +import { EncodedSyncPData } from './src/rpc/messages/EncodedSyncPData.js'; +import { EncodedSyncPDataResponse } from './src/rpc/messages/EncodedSyncPDataResponse.js'; +import { EndAudioPassThru } from './src/rpc/messages/EndAudioPassThru.js'; +import { EndAudioPassThruResponse } from './src/rpc/messages/EndAudioPassThruResponse.js'; +import { GenericResponseResponse } from './src/rpc/messages/GenericResponseResponse.js'; +import { GetAppServiceData } from './src/rpc/messages/GetAppServiceData.js'; +import { GetAppServiceDataResponse } from './src/rpc/messages/GetAppServiceDataResponse.js'; +import { GetCloudAppProperties } from './src/rpc/messages/GetCloudAppProperties.js'; +import { GetCloudAppPropertiesResponse } from './src/rpc/messages/GetCloudAppPropertiesResponse.js'; +import { GetDTCs } from './src/rpc/messages/GetDTCs.js'; +import { GetDTCsResponse } from './src/rpc/messages/GetDTCsResponse.js'; +import { GetFile } from './src/rpc/messages/GetFile.js'; +import { GetFileResponse } from './src/rpc/messages/GetFileResponse.js'; +import { GetInteriorVehicleData } from './src/rpc/messages/GetInteriorVehicleData.js'; +import { GetInteriorVehicleDataConsent } from './src/rpc/messages/GetInteriorVehicleDataConsent.js'; +import { GetInteriorVehicleDataConsentResponse } from './src/rpc/messages/GetInteriorVehicleDataConsentResponse.js'; +import { GetInteriorVehicleDataResponse } from './src/rpc/messages/GetInteriorVehicleDataResponse.js'; +import { GetSystemCapability } from './src/rpc/messages/GetSystemCapability.js'; +import { GetSystemCapabilityResponse } from './src/rpc/messages/GetSystemCapabilityResponse.js'; +import { GetVehicleData } from './src/rpc/messages/GetVehicleData.js'; +import { GetVehicleDataResponse } from './src/rpc/messages/GetVehicleDataResponse.js'; +import { GetWayPoints } from './src/rpc/messages/GetWayPoints.js'; +import { GetWayPointsResponse } from './src/rpc/messages/GetWayPointsResponse.js'; +import { ListFiles } from './src/rpc/messages/ListFiles.js'; +import { ListFilesResponse } from './src/rpc/messages/ListFilesResponse.js'; +import { OnAppInterfaceUnregistered } from './src/rpc/messages/OnAppInterfaceUnregistered.js'; +import { OnAppServiceData } from './src/rpc/messages/OnAppServiceData.js'; +import { OnAudioPassThru } from './src/rpc/messages/OnAudioPassThru.js'; +import { OnButtonEvent } from './src/rpc/messages/OnButtonEvent.js'; +import { OnButtonPress } from './src/rpc/messages/OnButtonPress.js'; +import { OnCommand } from './src/rpc/messages/OnCommand.js'; +import { OnDriverDistraction } from './src/rpc/messages/OnDriverDistraction.js'; +import { OnEncodedSyncPData } from './src/rpc/messages/OnEncodedSyncPData.js'; +import { OnHMIStatus } from './src/rpc/messages/OnHMIStatus.js'; +import { OnHashChange } from './src/rpc/messages/OnHashChange.js'; +import { OnInteriorVehicleData } from './src/rpc/messages/OnInteriorVehicleData.js'; +import { OnKeyboardInput } from './src/rpc/messages/OnKeyboardInput.js'; import { OnLanguageChange } from './src/rpc/messages/OnLanguageChange.js'; +import { OnPermissionsChange } from './src/rpc/messages/OnPermissionsChange.js'; +import { OnRCStatus } from './src/rpc/messages/OnRCStatus.js'; +import { OnSystemCapabilityUpdated } from './src/rpc/messages/OnSystemCapabilityUpdated.js'; +import { OnSystemRequest } from './src/rpc/messages/OnSystemRequest.js'; +import { OnTBTClientState } from './src/rpc/messages/OnTBTClientState.js'; +import { OnTouchEvent } from './src/rpc/messages/OnTouchEvent.js'; +import { OnVehicleData } from './src/rpc/messages/OnVehicleData.js'; +import { OnWayPointChange } from './src/rpc/messages/OnWayPointChange.js'; +import { PerformAppServiceInteraction } from './src/rpc/messages/PerformAppServiceInteraction.js'; +import { PerformAppServiceInteractionResponse } from './src/rpc/messages/PerformAppServiceInteractionResponse.js'; +import { PerformAudioPassThru } from './src/rpc/messages/PerformAudioPassThru.js'; +import { PerformAudioPassThruResponse } from './src/rpc/messages/PerformAudioPassThruResponse.js'; +import { PerformInteraction } from './src/rpc/messages/PerformInteraction.js'; +import { PerformInteractionResponse } from './src/rpc/messages/PerformInteractionResponse.js'; +import { PublishAppService } from './src/rpc/messages/PublishAppService.js'; +import { PublishAppServiceResponse } from './src/rpc/messages/PublishAppServiceResponse.js'; import { PutFile } from './src/rpc/messages/PutFile.js'; import { PutFileResponse } from './src/rpc/messages/PutFileResponse.js'; +import { ReadDID } from './src/rpc/messages/ReadDID.js'; +import { ReadDIDResponse } from './src/rpc/messages/ReadDIDResponse.js'; import { RegisterAppInterface } from './src/rpc/messages/RegisterAppInterface.js'; import { RegisterAppInterfaceResponse } from './src/rpc/messages/RegisterAppInterfaceResponse.js'; +import { ReleaseInteriorVehicleDataModule } from './src/rpc/messages/ReleaseInteriorVehicleDataModule.js'; +import { ReleaseInteriorVehicleDataModuleResponse } from './src/rpc/messages/ReleaseInteriorVehicleDataModuleResponse.js'; +import { ResetGlobalProperties } from './src/rpc/messages/ResetGlobalProperties.js'; +import { ResetGlobalPropertiesResponse } from './src/rpc/messages/ResetGlobalPropertiesResponse.js'; +import { ScrollableMessage } from './src/rpc/messages/ScrollableMessage.js'; +import { ScrollableMessageResponse } from './src/rpc/messages/ScrollableMessageResponse.js'; +import { SendHapticData } from './src/rpc/messages/SendHapticData.js'; +import { SendHapticDataResponse } from './src/rpc/messages/SendHapticDataResponse.js'; +import { SendLocation } from './src/rpc/messages/SendLocation.js'; +import { SendLocationResponse } from './src/rpc/messages/SendLocationResponse.js'; import { SetAppIcon } from './src/rpc/messages/SetAppIcon.js'; import { SetAppIconResponse } from './src/rpc/messages/SetAppIconResponse.js'; +import { SetCloudAppProperties } from './src/rpc/messages/SetCloudAppProperties.js'; +import { SetCloudAppPropertiesResponse } from './src/rpc/messages/SetCloudAppPropertiesResponse.js'; +import { SetDisplayLayout } from './src/rpc/messages/SetDisplayLayout.js'; +import { SetDisplayLayoutResponse } from './src/rpc/messages/SetDisplayLayoutResponse.js'; +import { SetGlobalProperties } from './src/rpc/messages/SetGlobalProperties.js'; +import { SetGlobalPropertiesResponse } from './src/rpc/messages/SetGlobalPropertiesResponse.js'; +import { SetInteriorVehicleData } from './src/rpc/messages/SetInteriorVehicleData.js'; +import { SetInteriorVehicleDataResponse } from './src/rpc/messages/SetInteriorVehicleDataResponse.js'; +import { SetMediaClockTimer } from './src/rpc/messages/SetMediaClockTimer.js'; +import { SetMediaClockTimerResponse } from './src/rpc/messages/SetMediaClockTimerResponse.js'; import { Show } from './src/rpc/messages/Show.js'; +import { ShowAppMenu } from './src/rpc/messages/ShowAppMenu.js'; +import { ShowAppMenuResponse } from './src/rpc/messages/ShowAppMenuResponse.js'; +import { ShowConstantTBT } from './src/rpc/messages/ShowConstantTBT.js'; +import { ShowConstantTBTResponse } from './src/rpc/messages/ShowConstantTBTResponse.js'; import { ShowResponse } from './src/rpc/messages/ShowResponse.js'; +import { Slider } from './src/rpc/messages/Slider.js'; +import { SliderResponse } from './src/rpc/messages/SliderResponse.js'; +import { Speak } from './src/rpc/messages/Speak.js'; +import { SpeakResponse } from './src/rpc/messages/SpeakResponse.js'; +import { SubscribeButton } from './src/rpc/messages/SubscribeButton.js'; +import { SubscribeButtonResponse } from './src/rpc/messages/SubscribeButtonResponse.js'; +import { SubscribeVehicleData } from './src/rpc/messages/SubscribeVehicleData.js'; +import { SubscribeVehicleDataResponse } from './src/rpc/messages/SubscribeVehicleDataResponse.js'; +import { SubscribeWayPoints } from './src/rpc/messages/SubscribeWayPoints.js'; +import { SubscribeWayPointsResponse } from './src/rpc/messages/SubscribeWayPointsResponse.js'; +import { SystemRequest } from './src/rpc/messages/SystemRequest.js'; +import { SystemRequestResponse } from './src/rpc/messages/SystemRequestResponse.js'; +import { UnpublishAppService } from './src/rpc/messages/UnpublishAppService.js'; +import { UnpublishAppServiceResponse } from './src/rpc/messages/UnpublishAppServiceResponse.js'; import { UnregisterAppInterface } from './src/rpc/messages/UnregisterAppInterface.js'; import { UnregisterAppInterfaceResponse } from './src/rpc/messages/UnregisterAppInterfaceResponse.js'; +import { UnsubscribeButton } from './src/rpc/messages/UnsubscribeButton.js'; +import { UnsubscribeButtonResponse } from './src/rpc/messages/UnsubscribeButtonResponse.js'; +import { UnsubscribeVehicleData } from './src/rpc/messages/UnsubscribeVehicleData.js'; +import { UnsubscribeVehicleDataResponse } from './src/rpc/messages/UnsubscribeVehicleDataResponse.js'; +import { UnsubscribeWayPoints } from './src/rpc/messages/UnsubscribeWayPoints.js'; +import { UnsubscribeWayPointsResponse } from './src/rpc/messages/UnsubscribeWayPointsResponse.js'; +import { UpdateTurnList } from './src/rpc/messages/UpdateTurnList.js'; +import { UpdateTurnListResponse } from './src/rpc/messages/UpdateTurnListResponse.js'; +import { AirbagStatus } from './src/rpc/structs/AirbagStatus.js'; import { AppInfo } from './src/rpc/structs/AppInfo.js'; +import { AppServiceCapability } from './src/rpc/structs/AppServiceCapability.js'; +import { AppServiceData } from './src/rpc/structs/AppServiceData.js'; +import { AppServiceManifest } from './src/rpc/structs/AppServiceManifest.js'; +import { AppServiceRecord } from './src/rpc/structs/AppServiceRecord.js'; +import { AppServicesCapabilities } from './src/rpc/structs/AppServicesCapabilities.js'; +import { AudioControlCapabilities } from './src/rpc/structs/AudioControlCapabilities.js'; +import { AudioControlData } from './src/rpc/structs/AudioControlData.js'; import { AudioPassThruCapabilities } from './src/rpc/structs/AudioPassThruCapabilities.js'; +import { BeltStatus } from './src/rpc/structs/BeltStatus.js'; +import { BodyInformation } from './src/rpc/structs/BodyInformation.js'; import { ButtonCapabilities } from './src/rpc/structs/ButtonCapabilities.js'; +import { Choice } from './src/rpc/structs/Choice.js'; +import { ClimateControlCapabilities } from './src/rpc/structs/ClimateControlCapabilities.js'; +import { ClimateControlData } from './src/rpc/structs/ClimateControlData.js'; +import { CloudAppProperties } from './src/rpc/structs/CloudAppProperties.js'; +import { ClusterModeStatus } from './src/rpc/structs/ClusterModeStatus.js'; +import { Coordinate } from './src/rpc/structs/Coordinate.js'; +import { DIDResult } from './src/rpc/structs/DIDResult.js'; +import { DateTime } from './src/rpc/structs/DateTime.js'; import { DeviceInfo } from './src/rpc/structs/DeviceInfo.js'; +import { DeviceStatus } from './src/rpc/structs/DeviceStatus.js'; import { DisplayCapabilities } from './src/rpc/structs/DisplayCapabilities.js'; +import { DisplayCapability } from './src/rpc/structs/DisplayCapability.js'; +import { ECallInfo } from './src/rpc/structs/ECallInfo.js'; +import { EmergencyEvent } from './src/rpc/structs/EmergencyEvent.js'; +import { EqualizerSettings } from './src/rpc/structs/EqualizerSettings.js'; +import { FuelRange } from './src/rpc/structs/FuelRange.js'; +import { GPSData } from './src/rpc/structs/GPSData.js'; import { Grid } from './src/rpc/structs/Grid.js'; import { HMICapabilities } from './src/rpc/structs/HMICapabilities.js'; +import { HMIPermissions } from './src/rpc/structs/HMIPermissions.js'; +import { HMISettingsControlCapabilities } from './src/rpc/structs/HMISettingsControlCapabilities.js'; +import { HMISettingsControlData } from './src/rpc/structs/HMISettingsControlData.js'; +import { HapticRect } from './src/rpc/structs/HapticRect.js'; +import { HeadLampStatus } from './src/rpc/structs/HeadLampStatus.js'; import { Image } from './src/rpc/structs/Image.js'; import { ImageField } from './src/rpc/structs/ImageField.js'; import { ImageResolution } from './src/rpc/structs/ImageResolution.js'; +import { KeyboardProperties } from './src/rpc/structs/KeyboardProperties.js'; +import { LightCapabilities } from './src/rpc/structs/LightCapabilities.js'; +import { LightControlCapabilities } from './src/rpc/structs/LightControlCapabilities.js'; +import { LightControlData } from './src/rpc/structs/LightControlData.js'; +import { LightState } from './src/rpc/structs/LightState.js'; +import { LocationDetails } from './src/rpc/structs/LocationDetails.js'; +import { MassageCushionFirmness } from './src/rpc/structs/MassageCushionFirmness.js'; +import { MassageModeData } from './src/rpc/structs/MassageModeData.js'; +import { MediaServiceData } from './src/rpc/structs/MediaServiceData.js'; +import { MediaServiceManifest } from './src/rpc/structs/MediaServiceManifest.js'; import { MenuParams } from './src/rpc/structs/MenuParams.js'; import { MetadataTags } from './src/rpc/structs/MetadataTags.js'; +import { ModuleData } from './src/rpc/structs/ModuleData.js'; import { ModuleInfo } from './src/rpc/structs/ModuleInfo.js'; +import { MyKey } from './src/rpc/structs/MyKey.js'; +import { NavigationCapability } from './src/rpc/structs/NavigationCapability.js'; +import { NavigationInstruction } from './src/rpc/structs/NavigationInstruction.js'; +import { NavigationServiceData } from './src/rpc/structs/NavigationServiceData.js'; +import { NavigationServiceManifest } from './src/rpc/structs/NavigationServiceManifest.js'; +import { OASISAddress } from './src/rpc/structs/OASISAddress.js'; +import { ParameterPermissions } from './src/rpc/structs/ParameterPermissions.js'; +import { PermissionItem } from './src/rpc/structs/PermissionItem.js'; +import { PhoneCapability } from './src/rpc/structs/PhoneCapability.js'; import { PresetBankCapabilities } from './src/rpc/structs/PresetBankCapabilities.js'; import { RGBColor } from './src/rpc/structs/RGBColor.js'; +import { RadioControlCapabilities } from './src/rpc/structs/RadioControlCapabilities.js'; +import { RadioControlData } from './src/rpc/structs/RadioControlData.js'; +import { RdsData } from './src/rpc/structs/RdsData.js'; +import { Rectangle } from './src/rpc/structs/Rectangle.js'; +import { RemoteControlCapabilities } from './src/rpc/structs/RemoteControlCapabilities.js'; import { ScreenParams } from './src/rpc/structs/ScreenParams.js'; import { SdlMsgVersion } from './src/rpc/structs/SdlMsgVersion.js'; +import { SeatControlCapabilities } from './src/rpc/structs/SeatControlCapabilities.js'; +import { SeatControlData } from './src/rpc/structs/SeatControlData.js'; +import { SeatLocation } from './src/rpc/structs/SeatLocation.js'; +import { SeatLocationCapability } from './src/rpc/structs/SeatLocationCapability.js'; +import { SeatMemoryAction } from './src/rpc/structs/SeatMemoryAction.js'; +import { SingleTireStatus } from './src/rpc/structs/SingleTireStatus.js'; +import { SisData } from './src/rpc/structs/SisData.js'; import { SoftButton } from './src/rpc/structs/SoftButton.js'; import { SoftButtonCapabilities } from './src/rpc/structs/SoftButtonCapabilities.js'; +import { StartTime } from './src/rpc/structs/StartTime.js'; +import { StationIDNumber } from './src/rpc/structs/StationIDNumber.js'; +import { SystemCapability } from './src/rpc/structs/SystemCapability.js'; import { TTSChunk } from './src/rpc/structs/TTSChunk.js'; +import { Temperature } from './src/rpc/structs/Temperature.js'; import { TemplateColorScheme } from './src/rpc/structs/TemplateColorScheme.js'; +import { TemplateConfiguration } from './src/rpc/structs/TemplateConfiguration.js'; import { TextField } from './src/rpc/structs/TextField.js'; +import { TireStatus } from './src/rpc/structs/TireStatus.js'; +import { TouchCoord } from './src/rpc/structs/TouchCoord.js'; +import { TouchEvent } from './src/rpc/structs/TouchEvent.js'; import { TouchEventCapabilities } from './src/rpc/structs/TouchEventCapabilities.js'; +import { Turn } from './src/rpc/structs/Turn.js'; +import { VehicleDataResult } from './src/rpc/structs/VehicleDataResult.js'; import { VehicleType } from './src/rpc/structs/VehicleType.js'; import { VideoStreamingCapability } from './src/rpc/structs/VideoStreamingCapability.js'; import { VideoStreamingFormat } from './src/rpc/structs/VideoStreamingFormat.js'; +import { VrHelpItem } from './src/rpc/structs/VrHelpItem.js'; +import { WeatherAlert } from './src/rpc/structs/WeatherAlert.js'; +import { WeatherData } from './src/rpc/structs/WeatherData.js'; +import { WeatherServiceData } from './src/rpc/structs/WeatherServiceData.js'; +import { WeatherServiceManifest } from './src/rpc/structs/WeatherServiceManifest.js'; +import { WindowCapability } from './src/rpc/structs/WindowCapability.js'; +import { WindowTypeCapabilities } from './src/rpc/structs/WindowTypeCapabilities.js'; import { SdlServiceListener } from './src/session/SdlServiceListener.js'; import { SdlSession } from './src/session/SdlSession.js'; import { SdlSessionListener } from './src/session/SdlSessionListener.js'; @@ -180,80 +467,367 @@ const SDL = { RpcResponse, RpcStruct, enums: { + AmbientLightStatus, AppHMIType, + AppInterfaceUnregisteredReason, + AppServiceType, + AudioStreamingIndicator, AudioStreamingState, AudioType, BitsPerSample, + ButtonEventMode, ButtonName, + ButtonPressMode, + CarModeStatus, CharacterSet, + CompassDirection, + ComponentVolumeStatus, + DefrostZone, + DeliveryMode, + DeviceLevelStatus, + Dimension, + Direction, + DisplayMode, DisplayType, + DistanceUnit, + DriverDistractionState, + ECallConfirmationStatus, + ElectronicParkBrakeStatus, + EmergencyEventType, FileType, + FuelCutoffStatus, + FuelType, FunctionID, + GlobalProperty, HMILevel, HmiZoneCapabilities, + HybridAppPreference, + IgnitionStableStatus, + IgnitionStatus, ImageFieldName, ImageType, + InteractionMode, + KeyboardEvent, + KeyboardLayout, + KeypressMode, Language, + LayoutMode, + LightName, + LightStatus, + MaintenanceModeStatus, + MassageCushion, + MassageMode, + MassageZone, MediaClockFormat, + MediaType, + MenuLayout, MetadataType, + ModuleType, + NavigationAction, + NavigationJunction, + PRNDL, + PermissionStatus, + PowerModeQualificationStatus, + PowerModeStatus, + PredefinedLayout, + PredefinedWindows, PrerecordedSpeech, + PrimaryAudioSource, + RadioBand, + RadioState, + RequestType, Result, RpcType, SamplingRate, + SeatMemoryActionType, + ServiceUpdateReason, SoftButtonType, SpeechCapabilities, + SupportedSeat, SystemAction, + SystemCapabilityType, SystemContext, + TBTState, + TPMS, + TemperatureUnit, TextAlignment, TextFieldName, + TimerMode, + TouchType, + TriggerSource, + TurnSignal, + UpdateMode, + VehicleDataActiveStatus, + VehicleDataEventStatus, + VehicleDataNotificationStatus, + VehicleDataResultCode, + VehicleDataStatus, + VehicleDataType, + VentilationMode, VideoStreamingCodec, VideoStreamingProtocol, VideoStreamingState, VrCapabilities, + WarningLightStatus, + WayPointType, + WindowType, + WiperStatus, + messageType, }, messages: { AddCommand, AddCommandResponse, - OnHmiStatus, + AddSubMenu, + AddSubMenuResponse, + Alert, + AlertManeuver, + AlertManeuverResponse, + AlertResponse, + ButtonPress, + ButtonPressResponse, + CancelInteraction, + CancelInteractionResponse, + ChangeRegistration, + ChangeRegistrationResponse, + CloseApplication, + CloseApplicationResponse, + CreateInteractionChoiceSet, + CreateInteractionChoiceSetResponse, + CreateWindow, + CreateWindowResponse, + DeleteCommand, + DeleteCommandResponse, + DeleteFile, + DeleteFileResponse, + DeleteInteractionChoiceSet, + DeleteInteractionChoiceSetResponse, + DeleteSubMenu, + DeleteSubMenuResponse, + DeleteWindow, + DeleteWindowResponse, + DiagnosticMessage, + DiagnosticMessageResponse, + DialNumber, + DialNumberResponse, + EncodedSyncPData, + EncodedSyncPDataResponse, + EndAudioPassThru, + EndAudioPassThruResponse, + GenericResponseResponse, + GetAppServiceData, + GetAppServiceDataResponse, + GetCloudAppProperties, + GetCloudAppPropertiesResponse, + GetDTCs, + GetDTCsResponse, + GetFile, + GetFileResponse, + GetInteriorVehicleData, + GetInteriorVehicleDataConsent, + GetInteriorVehicleDataConsentResponse, + GetInteriorVehicleDataResponse, + GetSystemCapability, + GetSystemCapabilityResponse, + GetVehicleData, + GetVehicleDataResponse, + GetWayPoints, + GetWayPointsResponse, + ListFiles, + ListFilesResponse, + OnAppInterfaceUnregistered, + OnAppServiceData, + OnAudioPassThru, + OnButtonEvent, + OnButtonPress, + OnCommand, + OnDriverDistraction, + OnEncodedSyncPData, + OnHMIStatus, + OnHashChange, + OnInteriorVehicleData, + OnKeyboardInput, OnLanguageChange, + OnPermissionsChange, + OnRCStatus, + OnSystemCapabilityUpdated, + OnSystemRequest, + OnTBTClientState, + OnTouchEvent, + OnVehicleData, + OnWayPointChange, + PerformAppServiceInteraction, + PerformAppServiceInteractionResponse, + PerformAudioPassThru, + PerformAudioPassThruResponse, + PerformInteraction, + PerformInteractionResponse, + PublishAppService, + PublishAppServiceResponse, PutFile, PutFileResponse, + ReadDID, + ReadDIDResponse, RegisterAppInterface, RegisterAppInterfaceResponse, + ReleaseInteriorVehicleDataModule, + ReleaseInteriorVehicleDataModuleResponse, + ResetGlobalProperties, + ResetGlobalPropertiesResponse, + ScrollableMessage, + ScrollableMessageResponse, + SendHapticData, + SendHapticDataResponse, + SendLocation, + SendLocationResponse, SetAppIcon, SetAppIconResponse, + SetCloudAppProperties, + SetCloudAppPropertiesResponse, + SetDisplayLayout, + SetDisplayLayoutResponse, + SetGlobalProperties, + SetGlobalPropertiesResponse, + SetInteriorVehicleData, + SetInteriorVehicleDataResponse, + SetMediaClockTimer, + SetMediaClockTimerResponse, Show, + ShowAppMenu, + ShowAppMenuResponse, + ShowConstantTBT, + ShowConstantTBTResponse, ShowResponse, + Slider, + SliderResponse, + Speak, + SpeakResponse, + SubscribeButton, + SubscribeButtonResponse, + SubscribeVehicleData, + SubscribeVehicleDataResponse, + SubscribeWayPoints, + SubscribeWayPointsResponse, + SystemRequest, + SystemRequestResponse, + UnpublishAppService, + UnpublishAppServiceResponse, UnregisterAppInterface, UnregisterAppInterfaceResponse, + UnsubscribeButton, + UnsubscribeButtonResponse, + UnsubscribeVehicleData, + UnsubscribeVehicleDataResponse, + UnsubscribeWayPoints, + UnsubscribeWayPointsResponse, + UpdateTurnList, + UpdateTurnListResponse, }, structs: { + AirbagStatus, AppInfo, + AppServiceCapability, + AppServiceData, + AppServiceManifest, + AppServiceRecord, + AppServicesCapabilities, + AudioControlCapabilities, + AudioControlData, AudioPassThruCapabilities, + BeltStatus, + BodyInformation, ButtonCapabilities, + Choice, + ClimateControlCapabilities, + ClimateControlData, + CloudAppProperties, + ClusterModeStatus, + Coordinate, + DIDResult, + DateTime, DeviceInfo, + DeviceStatus, DisplayCapabilities, + DisplayCapability, + ECallInfo, + EmergencyEvent, + EqualizerSettings, + FuelRange, + GPSData, Grid, HMICapabilities, + HMIPermissions, + HMISettingsControlCapabilities, + HMISettingsControlData, + HapticRect, + HeadLampStatus, Image, ImageField, ImageResolution, + KeyboardProperties, + LightCapabilities, + LightControlCapabilities, + LightControlData, + LightState, + LocationDetails, + MassageCushionFirmness, + MassageModeData, + MediaServiceData, + MediaServiceManifest, MenuParams, MetadataTags, + ModuleData, ModuleInfo, + MyKey, + NavigationCapability, + NavigationInstruction, + NavigationServiceData, + NavigationServiceManifest, + OASISAddress, + ParameterPermissions, + PermissionItem, + PhoneCapability, PresetBankCapabilities, RGBColor, + RadioControlCapabilities, + RadioControlData, + RdsData, + Rectangle, + RemoteControlCapabilities, ScreenParams, SdlMsgVersion, + SeatControlCapabilities, + SeatControlData, + SeatLocation, + SeatLocationCapability, + SeatMemoryAction, + SingleTireStatus, + SisData, SoftButton, SoftButtonCapabilities, + StartTime, + StationIDNumber, + SystemCapability, TTSChunk, + Temperature, TemplateColorScheme, + TemplateConfiguration, TextField, + TireStatus, + TouchCoord, + TouchEvent, TouchEventCapabilities, + Turn, + VehicleDataResult, VehicleType, VideoStreamingCapability, VideoStreamingFormat, + VrHelpItem, + WeatherAlert, + WeatherData, + WeatherServiceData, + WeatherServiceManifest, + WindowCapability, + WindowTypeCapabilities, }, }, session: { diff --git a/lib/js/dist/SDL.js b/lib/js/dist/SDL.js index ef53c80e..50822e36 100644 --- a/lib/js/dist/SDL.js +++ b/lib/js/dist/SDL.js @@ -1,2 +1,2 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).SDL=t()}(this,function(){"use strict";function _typeof(e){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,t){for(var n=0;n=n())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+n().toString(16)+" bytes");return 0|e}function h(e,t){if(_.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return w(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return F(e).length;default:if(r)return w(e).length;t=(""+t).toLowerCase(),r=!0}}function E(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function p(e,t,n,r,i){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):2147483647=e.length){if(i)return-1;n=e.length-1}else if(n<0){if(!i)return-1;n=0}if("string"==typeof t&&(t=_.from(t,r)),_.isBuffer(t))return 0===t.length?-1:y(e,t,n,r,i);if("number"==typeof t)return t&=255,_.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):y(e,[t],n,r,i);throw new TypeError("val must be string, number or Buffer")}function y(e,t,n,r,i){var o,s=1,a=e.length,u=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;a/=s=2,u/=2,n/=2}function l(e,t){return 1===s?e[t]:e.readUInt16BE(t*s)}if(i){var c=-1;for(o=n;o>8,i=n%256,o.push(i),o.push(r);return o}(t,e.length-n),e,n,r)}function d(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function T(e,t,n){n=Math.min(e.length,n);for(var r=[],i=t;i>>10&1023|55296),c=56320|1023&c),r.push(c),i+=_}return function(e){var t=e.length;if(t<=P)return String.fromCharCode.apply(String,e);var n="",r=0;for(;rthis.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e=e||"utf8";;)switch(e){case"hex":return m(this,t,n);case"utf8":case"utf-8":return T(this,t,n);case"ascii":return v(this,t,n);case"latin1":case"binary":return I(this,t,n);case"base64":return d(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return O(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}.apply(this,arguments)},_.prototype.equals=function(e){if(!_.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===_.compare(this,e)},_.prototype.inspect=function(){var e="",t=U.INSPECT_MAX_BYTES;return 0t&&(e+=" ... ")),""},_.prototype.compare=function(e,t,n,r,i){if(!_.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===i&&(i=this.length),t<0||n>e.length||r<0||i>this.length)throw new RangeError("out of range index");if(i<=r&&n<=t)return 0;if(i<=r)return-1;if(n<=t)return 1;if(this===e)return 0;for(var o=(i>>>=0)-(r>>>=0),s=(n>>>=0)-(t>>>=0),a=Math.min(o,s),u=this.slice(r,i),l=e.slice(t,n),c=0;cthis.length)throw new RangeError("Attempt to write outside buffer bounds");r=r||"utf8";for(var o,s,a,u,l,c,_=!1;;)switch(r){case"hex":return g(this,e,t,n);case"utf8":case"utf-8":return l=t,c=n,Y(w(e,(u=this).length-l),u,l,c);case"ascii":return A(this,e,t,n);case"latin1":case"binary":return A(this,e,t,n);case"base64":return o=this,s=t,a=n,Y(F(e),o,s,a);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return S(this,e,t,n);default:if(_)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),_=!0}},_.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var P=4096;function v(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;ie.length)throw new RangeError("Index out of range")}function N(e,t,n,r){t<0&&(t=65535+t+1);for(var i=0,o=Math.min(e.length-n,2);i>>8*(r?i:1-i)}function b(e,t,n,r){t<0&&(t=4294967295+t+1);for(var i=0,o=Math.min(e.length-n,4);i>>8*(r?i:3-i)&255}function k(e,t,n,r){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function M(e,t,n,r,i){return i||k(e,0,n,4),o.write(e,t,n,r,23,4),n+4}function D(e,t,n,r,i){return i||k(e,0,n,8),o.write(e,t,n,r,52,8),n+8}_.prototype.slice=function(e,t){var n,r=this.length;if((e=~~e)<0?(e+=r)<0&&(e=0):r>>8):N(this,e,t,!0),t+2},_.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||R(this,e,t,2,65535,0),_.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):N(this,e,t,!1),t+2},_.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||R(this,e,t,4,4294967295,0),_.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):b(this,e,t,!0),t+4},_.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||R(this,e,t,4,4294967295,0),_.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):b(this,e,t,!1),t+4},_.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var i=Math.pow(2,8*n-1);R(this,e,t,n,i-1,-i)}var o=0,s=1,a=0;for(this[t]=255&e;++o>0)-a&255;return t+n},_.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var i=Math.pow(2,8*n-1);R(this,e,t,n,i-1,-i)}var o=n-1,s=1,a=0;for(this[t+o]=255&e;0<=--o&&(s*=256);)e<0&&0===a&&0!==this[t+o+1]&&(a=1),this[t+o]=(e/s>>0)-a&255;return t+n},_.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||R(this,e,t,1,127,-128),_.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},_.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||R(this,e,t,2,32767,-32768),_.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):N(this,e,t,!0),t+2},_.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||R(this,e,t,2,32767,-32768),_.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):N(this,e,t,!1),t+2},_.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||R(this,e,t,4,2147483647,-2147483648),_.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):b(this,e,t,!0),t+4},_.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||R(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),_.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):b(this,e,t,!1),t+4},_.prototype.writeFloatLE=function(e,t,n){return M(this,e,t,!0,n)},_.prototype.writeFloatBE=function(e,t,n){return M(this,e,t,!1,n)},_.prototype.writeDoubleLE=function(e,t,n){return D(this,e,t,!0,n)},_.prototype.writeDoubleBE=function(e,t,n){return D(this,e,t,!1,n)},_.prototype.copy=function(e,t,n,r){if(n=n||0,r||0===r||(r=this.length),t>=e.length&&(t=e.length),t=t||0,0=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t>>=0,n=void 0===n?this.length:n>>>0,"number"==typeof(e=e||0))for(o=t;o>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;o.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;o.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return o}function F(e){return r.toByteArray(B(e))}function Y(e,t,n,r){for(var i=0;i=t.length||i>=e.length);++i)t[i+n]=e[i];return i}}).call(U,K(0))},function(module,exports,__webpack_require__){(function(global,Buffer){var _t;_t=function(exports,_long,buffer){_long=_long&&_long.hasOwnProperty("default")?_long.default:_long,buffer=buffer&&buffer.hasOwnProperty("default")?buffer.default:buffer;var commonjsGlobal="undefined"!=typeof window?window:void 0!==global?global:"undefined"!=typeof self?self:{};function createCommonjsModule(e,t){return e(t={exports:{}},t.exports),t.exports}function getCjsExportFromNamespace(e){return e&&e.default||e}var map=createCommonjsModule(function(e){if(void 0!==commonjsGlobal.Map)e.exports=commonjsGlobal.Map,e.exports.Map=commonjsGlobal.Map;else{var t=function(e){this._keys=[],this._values={};for(var t=0;t>8&255,n[1]=e>>16&255,n[0]=e>>24&255,n[4]=PROCESS_UNIQUE[0],n[5]=PROCESS_UNIQUE[1],n[6]=PROCESS_UNIQUE[2],n[7]=PROCESS_UNIQUE[3],n[8]=PROCESS_UNIQUE[4],n[11]=255&t,n[10]=t>>8&255,n[9]=t>>16&255,n}},{key:"createPk",value:function(){return new i}},{key:"createFromTime",value:function(e){var t=Buffer$1.from([0,0,0,0,0,0,0,0,0,0,0,0]);return t[3]=255&e,t[2]=e>>8&255,t[1]=e>>16&255,t[0]=e>>24&255,new i(t)}},{key:"createFromHexString",value:function(e){if(void 0===e||null!=e&&24!==e.length)throw new TypeError("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters");if(hasBufferType)return new i(Buffer$1.from(e,"hex"));for(var t=new _Buffer(12),n=0,r=0;r<24;)t[n++]=decodeLookup[e.charCodeAt(r++)]<<4|decodeLookup[e.charCodeAt(r++)];return new i(t)}},{key:"isValid",value:function(e){return null!=e&&("number"==typeof e||("string"==typeof e?12===e.length||24===e.length&&checkForHexRegExp.test(e):e instanceof i||(e instanceof _Buffer&&12===e.length||!!e.toHexString&&(12===e.id.length||24===e.id.length&&checkForHexRegExp.test(e.id)))))}},{key:"fromExtendedJSON",value:function(e){return new i(e.$oid)}}]),i}();ObjectId.get_inc=deprecate$1(function(){return ObjectId.getInc()},"Please use the static `ObjectId.getInc()` instead"),ObjectId.prototype.get_inc=deprecate$1(function(){return ObjectId.getInc()},"Please use the static `ObjectId.getInc()` instead"),ObjectId.prototype.getInc=deprecate$1(function(){return ObjectId.getInc()},"Please use the static `ObjectId.getInc()` instead"),ObjectId.prototype.generate=deprecate$1(function(e){return ObjectId.generate(e)},"Please use the static `ObjectId.generate(time)` instead"),Object.defineProperty(ObjectId.prototype,"generationTime",{enumerable:!0,get:function(){return this.id[3]|this.id[2]<<8|this.id[1]<<16|this.id[0]<<24},set:function(e){this.id[3]=255&e,this.id[2]=e>>8&255,this.id[1]=e>>16&255,this.id[0]=e>>24&255}}),ObjectId.prototype[util$2.inspect.custom||"inspect"]=ObjectId.prototype.toString,ObjectId.index=~~(16777215*Math.random()),Object.defineProperty(ObjectId.prototype,"_bsontype",{value:"ObjectID"});var objectid=ObjectId;function _classCallCheck$3(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties$3(e,t){for(var n=0;n>>0,r=t.high>>>0;return n>>0>>0}function invalidErr(e,t){throw new TypeError('"'.concat(e,'" is not a valid Decimal128 string - ').concat(t))}function Decimal128(e){this.bytes=e}Decimal128.fromString=function(e){var t,n=!1,r=!1,i=!1,o=0,s=0,a=0,u=0,l=0,c=[0],_=0,f=0,h=0,E=0,p=0,y=0,g=[0,0],A=[0,0],S=0;if(7e3<=e.length)throw new TypeError(e+" not a valid Decimal128 string");var d=e.match(PARSE_STRING_REGEXP),T=e.match(PARSE_INF_REGEXP),P=e.match(PARSE_NAN_REGEXP);if(!d&&!T&&!P||0===e.length)throw new TypeError(e+" not a valid Decimal128 string");if(d){var v=d[2],I=d[4],m=d[5],O=d[6];I&&void 0===O&&invalidErr(e,"missing exponent power"),I&&void 0===v&&invalidErr(e,"missing exponent base"),void 0===I&&(m||O)&&invalidErr(e,"missing e before exponent")}if("+"!==e[S]&&"-"!==e[S]||(n="-"===e[S++]),!isDigit(e[S])&&"."!==e[S]){if("i"===e[S]||"I"===e[S])return new Decimal128(Buffer$2.from(n?INF_NEGATIVE_BUFFER:INF_POSITIVE_BUFFER));if("N"===e[S])return new Decimal128(Buffer$2.from(NAN_BUFFER))}for(;isDigit(e[S])||"."===e[S];)"."!==e[S]?(_<34&&("0"===e[S]&&!i||(i||(l=s),i=!0,c[f++]=parseInt(e[S],10),_+=1)),i&&(a+=1),r&&(u+=1),s+=1):(r&&invalidErr(e,"contains multiple periods"),r=!0),S+=1;if(r&&!s)throw new TypeError(e+" not a valid Decimal128 string");if("e"===e[S]||"E"===e[S]){var C=e.substr(++S).match(EXPONENT_REGEX);if(!C||!C[2])return new Decimal128(Buffer$2.from(NAN_BUFFER));p=parseInt(C[0],10),S+=C[0].length}if(e[S])return new Decimal128(Buffer$2.from(NAN_BUFFER));if(h=0,_){if(E=_-1,1!==(o=a))for(;"0"===e[l+o-1];)o-=1}else _=a=1,o=c[E=h=0]=0;for(p<=u&&16384>8&255,w[S++]=L.low.low>>16&255,w[S++]=L.low.low>>24&255,w[S++]=255&L.low.high,w[S++]=L.low.high>>8&255,w[S++]=L.low.high>>16&255,w[S++]=L.low.high>>24&255,w[S++]=255&L.high.low,w[S++]=L.high.low>>8&255,w[S++]=L.high.low>>16&255,w[S++]=L.high.low>>24&255,w[S++]=255&L.high.high,w[S++]=L.high.high>>8&255,w[S++]=L.high.high>>16&255,w[S++]=L.high.high>>24&255,new Decimal128(w)};var COMBINATION_MASK=31,EXPONENT_MASK=16383,COMBINATION_INFINITY=30,COMBINATION_NAN=31;Decimal128.prototype.toString=function(){for(var e,t,n,r,i,o,s=0,a=new Array(36),u=0;u>26&COMBINATION_MASK)>>3==3){if(i===COMBINATION_INFINITY)return g.join("")+"Infinity";if(i===COMBINATION_NAN)return"NaN";o=e>>15&EXPONENT_MASK,_=8+(e>>14&1)}else _=e>>14&7,o=e>>17&EXPONENT_MASK;if(l=o-EXPONENT_BIAS,y.parts[0]=(16383&e)+((15&_)<<14),y.parts[1]=t,y.parts[2]=n,y.parts[3]=r,0===y.parts[0]&&0===y.parts[1]&&0===y.parts[2]&&0===y.parts[3])p=!0;else for(h=3;0<=h;h--){var S=0,d=divideu128(y);if(y=d.quotient,S=d.rem.low)for(f=8;0<=f;f--)a[9*h+f]=S%10,S=Math.floor(S/10)}if(p)s=1,a[E]=0;else for(s=36;!a[E];)s-=1,E+=1;if(34<=(c=s-1+l)||c<=-7||0this.position)this.buffer[this.position++]=t;else if(void 0!==Buffer$3&&Buffer$3.isBuffer(this.buffer)){var n=Buffer$3.alloc(o.BUFFER_SIZE+this.buffer.length);this.buffer.copy(n,0,0,this.buffer.length),this.buffer=n,this.buffer[this.position++]=t}else{var r=null;r=isUint8Array(this.buffer)?new Uint8Array(new ArrayBuffer(o.BUFFER_SIZE+this.buffer.length)):new Array(o.BUFFER_SIZE+this.buffer.length);for(var i=0;ithis.position?t+e.length:this.position;else if(void 0!==Buffer$3&&"string"==typeof e&&Buffer$3.isBuffer(this.buffer))this.buffer.write(e,t,"binary"),this.position=t+e.length>this.position?t+e.length:this.position;else if(isUint8Array(e)||Array.isArray(e)&&"string"!=typeof e){for(var i=0;ithis.position?t:this.position}else if("string"==typeof e){for(var o=0;othis.position?t:this.position}}},{key:"read",value:function(e,t){if(t=t&&0= 5, is ".concat(i));if(t.allowObjectSmallerThanBufferSize&&e.length= bson size ").concat(i));if(!t.allowObjectSmallerThanBufferSize&&e.length!==i)throw new Error("buffer length ".concat(e.length," must === bson size ").concat(i));if(i+r>e.length)throw new Error("(bson size ".concat(i," + options.index ").concat(r," must be <= buffer length ").concat(Buffer$4.byteLength(e),")"));if(0!==e[r+i-1])throw new Error("One object, sized correctly, with a spot for an EOO, but the EOO isn't 0x00");return deserializeObject(e,r,t,n)}function deserializeObject(e,t,n,r){var i=null!=n.evalFunctions&&n.evalFunctions,o=null!=n.cacheFunctions&&n.cacheFunctions,s=null!=n.cacheFunctionsCrc32&&n.cacheFunctionsCrc32;if(!s)var a=null;var u=null==n.fieldsAsRaw?null:n.fieldsAsRaw,l=null!=n.raw&&n.raw,c="boolean"==typeof n.bsonRegExp&&n.bsonRegExp,_=null!=n.promoteBuffers&&n.promoteBuffers,f=null==n.promoteLongs||n.promoteLongs,h=null==n.promoteValues||n.promoteValues,E=t;if(e.length<5)throw new Error("corrupt bson message < 5 bytes long");var p=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(p<5||p>e.length)throw new Error("corrupt bson message");for(var y=r?[]:{},g=0;;){var A=e[t++];if(0===A)break;for(var S=t;0!==e[S]&&S=Buffer$4.byteLength(e))throw new Error("Bad BSON Document: illegal CString");var d=r?g++:e.toString("utf8",t,S);if(t=S+1,A===constants.BSON_DATA_STRING){var T=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(T<=0||T>e.length-t||0!==e[t+T-1])throw new Error("bad string length in bson");if(!validateUtf8$1(e,t,t+T-1))throw new Error("Invalid UTF-8 string in BSON document");var P=e.toString("utf8",t,t+T-1);y[d]=P,t+=T}else if(A===constants.BSON_DATA_OID){var v=Buffer$4.alloc(12);e.copy(v,0,t,t+12),y[d]=new objectid(v),t+=12}else if(A===constants.BSON_DATA_INT&&!1===h)y[d]=new int_32(e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24);else if(A===constants.BSON_DATA_INT)y[d]=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;else if(A===constants.BSON_DATA_NUMBER&&!1===h)y[d]=new double_1(e.readDoubleLE(t)),t+=8;else if(A===constants.BSON_DATA_NUMBER)y[d]=e.readDoubleLE(t),t+=8;else if(A===constants.BSON_DATA_DATE){var I=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24,m=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;y[d]=new Date(new long_1(I,m).toNumber())}else if(A===constants.BSON_DATA_BOOLEAN){if(0!==e[t]&&1!==e[t])throw new Error("illegal boolean type value");y[d]=1===e[t++]}else if(A===constants.BSON_DATA_OBJECT){var O=t,C=e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24;if(C<=0||C>e.length-t)throw new Error("bad embedded document length in bson");y[d]=l?e.slice(t,t+C):deserializeObject(e,O,n,!1),t+=C}else if(A===constants.BSON_DATA_ARRAY){var R=t,N=e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24,b=n,k=t+N;if(u&&u[d]){for(var M in b={},n)b[M]=n[M];b.raw=!0}if(y[d]=deserializeObject(e,R,b,!0),0!==e[(t+=N)-1])throw new Error("invalid array terminator byte");if(t!==k)throw new Error("corrupted array bson")}else if(A===constants.BSON_DATA_UNDEFINED)y[d]=void 0;else if(A===constants.BSON_DATA_NULL)y[d]=null;else if(A===constants.BSON_DATA_LONG){var D=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24,B=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24,L=new long_1(D,B);y[d]=f&&!0===h&&L.lessThanOrEqual(JS_INT_MAX_LONG)&&L.greaterThanOrEqual(JS_INT_MIN_LONG)?L.toNumber():L}else if(A===constants.BSON_DATA_DECIMAL128){var w=Buffer$4.alloc(16);e.copy(w,0,t,t+16),t+=16;var F=new decimal128(w);y[d]=F.toObject?F.toObject():F}else if(A===constants.BSON_DATA_BINARY){var Y=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24,U=Y,K=e[t++];if(Y<0)throw new Error("Negative binary type element size found");if(Y>Buffer$4.byteLength(e))throw new Error("Binary type size larger than document size");if(null!=e.slice){if(K===binary.SUBTYPE_BYTE_ARRAY){if((Y=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24)<0)throw new Error("Negative binary type element size found for subtype 0x02");if(U-4=e.length)throw new Error("Bad BSON Document: illegal CString");var H=e.toString("utf8",t,S);for(S=t=S+1;0!==e[S]&&S=e.length)throw new Error("Bad BSON Document: illegal CString");var x=e.toString("utf8",t,S);t=S+1;var G=new Array(x.length);for(S=0;S=e.length)throw new Error("Bad BSON Document: illegal CString");var j=e.toString("utf8",t,S);for(S=t=S+1;0!==e[S]&&S=e.length)throw new Error("Bad BSON Document: illegal CString");var $=e.toString("utf8",t,S);t=S+1,y[d]=new regexp(j,$)}else if(A===constants.BSON_DATA_SYMBOL){var z=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(z<=0||z>e.length-t||0!==e[t+z-1])throw new Error("bad string length in bson");y[d]=e.toString("utf8",t,t+z-1),t+=z}else if(A===constants.BSON_DATA_TIMESTAMP){var W=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24,X=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;y[d]=new timestamp(W,X)}else if(A===constants.BSON_DATA_MIN_KEY)y[d]=new min_key;else if(A===constants.BSON_DATA_MAX_KEY)y[d]=new max_key;else if(A===constants.BSON_DATA_CODE){var J=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(J<=0||J>e.length-t||0!==e[t+J-1])throw new Error("bad string length in bson");var Z=e.toString("utf8",t,t+J-1);if(i)if(o){var q=s?a(Z):Z;y[d]=isolateEvalWithHash(functionCache,q,Z,y)}else y[d]=isolateEval(Z);else y[d]=new code(Z);t+=J}else if(A===constants.BSON_DATA_CODE_W_SCOPE){var Q=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(Q<13)throw new Error("code_w_scope total size shorter minimum expected length");var ee=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(ee<=0||ee>e.length-t||0!==e[t+ee-1])throw new Error("bad string length in bson");var te=e.toString("utf8",t,t+ee-1),ne=t+=ee,re=e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24,ie=deserializeObject(e,ne,n,!1);if(t+=re,Q<8+re+ee)throw new Error("code_w_scope total size is to short, truncating scope");if(8+re+eee.length-t||0!==e[t+se-1])throw new Error("bad string length in bson");if(!validateUtf8$1(e,t,t+se-1))throw new Error("Invalid UTF-8 string in BSON document");var ae=e.toString("utf8",t,t+se-1);t+=se;var ue=Buffer$4.alloc(12);e.copy(ue,0,t,t+12);var le=new objectid(ue);t+=12,y[d]=new db_ref(ae,le)}}if(p!=t-E){if(r)throw new Error("corrupt array bson");throw new Error("corrupt object bson")}var ce=Object.keys(y).filter(function(e){return e.startsWith("$")}),_e=!0;if(ce.forEach(function(e){-1===["$ref","$id","$db"].indexOf(e)&&(_e=!1)}),!_e)return y;if(null==y.$id||null==y.$ref)return y;var fe=Object.assign({},y);return delete fe.$ref,delete fe.$id,delete fe.$db,new db_ref(y.$ref,y.$id,y.$db||null,fe)}function isolateEvalWithHash(functionCache,hash,functionString,object){var value=null;return null==functionCache[hash]&&(eval("value = "+functionString),functionCache[hash]=value),functionCache[hash].bind(object)}function isolateEval(functionString){var value=null;return eval("value = "+functionString),value}var deserializer=deserialize$1;function readIEEE754(e,t,n,r,i){var o,s,a="big"===n,u=8*i-r-1,l=(1<>1,_=-7,f=a?0:i-1,h=a?1:-1,E=e[t+f];for(f+=h,o=E&(1<<-_)-1,E>>=-_,_+=u;0<_;o=256*o+e[t+f],f+=h,_-=8);for(s=o&(1<<-_)-1,o>>=-_,_+=r;0<_;s=256*s+e[t+f],f+=h,_-=8);if(0===o)o=1-c;else{if(o===l)return s?NaN:1/0*(E?-1:1);s+=Math.pow(2,r),o-=c}return(E?-1:1)*s*Math.pow(2,o-r)}function writeIEEE754(e,t,n,r,i,o){var s,a,u,l="big"===r,c=8*o-i-1,_=(1<>1,h=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,E=l?o-1:0,p=l?-1:1,y=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,s=_):(s=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-s))<1&&(s--,u*=2),2<=(t+=1<=s+f?h/u:h*Math.pow(2,1-f))*u&&(s++,u/=2),_<=s+f?(a=0,s=_):1<=s+f?(a=(t*u-1)*Math.pow(2,i),s+=f):(a=t*Math.pow(2,f-1)*Math.pow(2,i),s=0)),isNaN(t)&&(a=0);8<=i;)e[n+E]=255&a,E+=p,a/=256,i-=8;for(s=s<>24&255,e[r+2]=s+1>>16&255,e[r+1]=s+1>>8&255,e[r]=s+1&255,r=r+4+s,e[r++]=0,r}function serializeNumber(e,t,n,r,i){if(Math.floor(n)===n&&n>=constants.JS_INT_MIN&&n<=constants.JS_INT_MAX)if(n>=constants.BSON_INT32_MIN&&n<=constants.BSON_INT32_MAX)e[r++]=constants.BSON_DATA_INT,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,e[r++]=255&n,e[r++]=n>>8&255,e[r++]=n>>16&255,e[r++]=n>>24&255;else if(n>=constants.JS_INT_MIN&&n<=constants.JS_INT_MAX){e[r++]=constants.BSON_DATA_NUMBER,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,writeIEEE754$1(e,n,r,"little",52,8),r+=8}else{e[r++]=constants.BSON_DATA_LONG,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0;var o=long_1.fromNumber(n),s=o.getLowBits(),a=o.getHighBits();e[r++]=255&s,e[r++]=s>>8&255,e[r++]=s>>16&255,e[r++]=s>>24&255,e[r++]=255&a,e[r++]=a>>8&255,e[r++]=a>>16&255,e[r++]=a>>24&255}else e[r++]=constants.BSON_DATA_NUMBER,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,writeIEEE754$1(e,n,r,"little",52,8),r+=8;return r}function serializeNull(e,t,n,r,i){return e[r++]=constants.BSON_DATA_NULL,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,r}function serializeBoolean(e,t,n,r,i){return e[r++]=constants.BSON_DATA_BOOLEAN,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,e[r++]=n?1:0,r}function serializeDate(e,t,n,r,i){e[r++]=constants.BSON_DATA_DATE,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0;var o=long_1.fromNumber(n.getTime()),s=o.getLowBits(),a=o.getHighBits();return e[r++]=255&s,e[r++]=s>>8&255,e[r++]=s>>16&255,e[r++]=s>>24&255,e[r++]=255&a,e[r++]=a>>8&255,e[r++]=a>>16&255,e[r++]=a>>24&255,r}function serializeRegExp(e,t,n,r,i){if(e[r++]=constants.BSON_DATA_REGEXP,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,n.source&&null!=n.source.match(regexp$1))throw Error("value "+n.source+" must not contain null bytes");return r+=e.write(n.source,r,"utf8"),e[r++]=0,n.ignoreCase&&(e[r++]=105),n.global&&(e[r++]=115),n.multiline&&(e[r++]=109),e[r++]=0,r}function serializeBSONRegExp(e,t,n,r,i){if(e[r++]=constants.BSON_DATA_REGEXP,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,null!=n.pattern.match(regexp$1))throw Error("pattern "+n.pattern+" must not contain null bytes");return r+=e.write(n.pattern,r,"utf8"),e[r++]=0,r+=e.write(n.options.split("").sort().join(""),r,"utf8"),e[r++]=0,r}function serializeMinMax(e,t,n,r,i){return null===n?e[r++]=constants.BSON_DATA_NULL:"MinKey"===n._bsontype?e[r++]=constants.BSON_DATA_MIN_KEY:e[r++]=constants.BSON_DATA_MAX_KEY,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,r}function serializeObjectId(e,t,n,r,i){if(e[r++]=constants.BSON_DATA_OID,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,"string"==typeof n.id)e.write(n.id,r,"binary");else{if(!n.id||!n.id.copy)throw new TypeError("object ["+JSON.stringify(n)+"] is not a valid ObjectId");n.id.copy(e,r,0,12)}return r+12}function serializeBuffer(e,t,n,r,i){e[r++]=constants.BSON_DATA_BINARY,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0;var o=n.length;return e[r++]=255&o,e[r++]=o>>8&255,e[r++]=o>>16&255,e[r++]=o>>24&255,e[r++]=constants.BSON_BINARY_SUBTYPE_DEFAULT,n.copy(e,r,0,o),r+=o}function serializeObject(e,t,n,r,i,o,s,a,u,l){for(var c=0;c>8&255,e[r++]=o>>16&255,e[r++]=o>>24&255,e[r++]=255&s,e[r++]=s>>8&255,e[r++]=s>>16&255,e[r++]=s>>24&255,r}function serializeInt32(e,t,n,r,i){return e[r++]=constants.BSON_DATA_INT,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,e[r++]=255&n,e[r++]=n>>8&255,e[r++]=n>>16&255,e[r++]=n>>24&255,r}function serializeDouble(e,t,n,r,i){return e[r++]=constants.BSON_DATA_NUMBER,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,writeIEEE754$1(e,n.value,r,"little",52,8),r+=8}function serializeFunction(e,t,n,r,i,o,s){e[r++]=constants.BSON_DATA_CODE,r+=s?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0;var a=normalizedFunctionString$1(n),u=e.write(a,r+4,"utf8")+1;return e[r]=255&u,e[r+1]=u>>8&255,e[r+2]=u>>16&255,e[r+3]=u>>24&255,r=r+4+u-1,e[r++]=0,r}function serializeCode(e,t,n,r,i,o,s,a,u){if(n.scope&&"object"===_typeof$3(n.scope)){e[r++]=constants.BSON_DATA_CODE_W_SCOPE,r+=u?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0;var l=r,c="string"==typeof n.code?n.code:n.code.toString();r+=4;var _=e.write(c,r+4,"utf8")+1;e[r]=255&_,e[r+1]=_>>8&255,e[r+2]=_>>16&255,e[r+3]=_>>24&255,e[r+4+_-1]=0,r=r+_+4;var f=serializeInto(e,n.scope,i,r,o+1,s,a);r=f-1;var h=f-l;e[l++]=255&h,e[l++]=h>>8&255,e[l++]=h>>16&255,e[l++]=h>>24&255,e[r++]=0}else{e[r++]=constants.BSON_DATA_CODE,r+=u?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0;var E=n.code.toString(),p=e.write(E,r+4,"utf8")+1;e[r]=255&p,e[r+1]=p>>8&255,e[r+2]=p>>16&255,e[r+3]=p>>24&255,r=r+4+p-1,e[r++]=0}return r}function serializeBinary(e,t,n,r,i){e[r++]=constants.BSON_DATA_BINARY,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0;var o=n.value(!0),s=n.position;return n.sub_type===binary.SUBTYPE_BYTE_ARRAY&&(s+=4),e[r++]=255&s,e[r++]=s>>8&255,e[r++]=s>>16&255,e[r++]=s>>24&255,e[r++]=n.sub_type,n.sub_type===binary.SUBTYPE_BYTE_ARRAY&&(s-=4,e[r++]=255&s,e[r++]=s>>8&255,e[r++]=s>>16&255,e[r++]=s>>24&255),o.copy(e,r,0,n.position),r+=n.position}function serializeSymbol(e,t,n,r,i){e[r++]=constants.BSON_DATA_SYMBOL,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0;var o=e.write(n.value,r+4,"utf8")+1;return e[r]=255&o,e[r+1]=o>>8&255,e[r+2]=o>>16&255,e[r+3]=o>>24&255,r=r+4+o-1,e[r++]=0,r}function serializeDBRef(e,t,n,r,i,o,s){e[r++]=constants.BSON_DATA_OBJECT,r+=s?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0;var a,u=r,l={$ref:n.collection||n.namespace,$id:n.oid};null!=n.db&&(l.$db=n.db);var c=(a=serializeInto(e,l=Object.assign(l,n.fields),!1,r,i+1,o))-u;return e[u++]=255&c,e[u++]=c>>8&255,e[u++]=c>>16&255,e[u++]=c>>24&255,a}function serializeInto(e,t,n,r,i,o,s,a){r=r||0,(a=a||[]).push(t);var u=r+4;if(Array.isArray(t))for(var l=0;l>8&255,e[r++]=P>>16&255,e[r++]=P>>24&255,u}var serializer=serializeInto;function _typeof$4(e){return(_typeof$4="function"==typeof Symbol&&"symbol"===_typeof(Symbol.iterator)?function(e){return _typeof(e)}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":_typeof(e)})(e)}var Buffer$6=buffer.Buffer,normalizedFunctionString$2=utils.normalizedFunctionString;function isDate$2(e){return"object"===_typeof$4(e)&&"[object Date]"===Object.prototype.toString.call(e)}function calculateObjectSize(e,t,n){var r=5;if(Array.isArray(e))for(var i=0;i=constants.JS_INT_MIN&&t<=constants.JS_INT_MAX&&t>=constants.BSON_INT32_MIN&&t<=constants.BSON_INT32_MAX?(null!=e?Buffer$6.byteLength(e,"utf8")+1:0)+5:(null!=e?Buffer$6.byteLength(e,"utf8")+1:0)+9;case"undefined":return r||!i?(null!=e?Buffer$6.byteLength(e,"utf8")+1:0)+1:0;case"boolean":return(null!=e?Buffer$6.byteLength(e,"utf8")+1:0)+2;case"object":if(null==t||"MinKey"===t._bsontype||"MaxKey"===t._bsontype)return(null!=e?Buffer$6.byteLength(e,"utf8")+1:0)+1;if("ObjectId"===t._bsontype||"ObjectID"===t._bsontype)return(null!=e?Buffer$6.byteLength(e,"utf8")+1:0)+13;if(t instanceof Date||isDate$2(t))return(null!=e?Buffer$6.byteLength(e,"utf8")+1:0)+9;if(void 0!==Buffer$6&&Buffer$6.isBuffer(t))return(null!=e?Buffer$6.byteLength(e,"utf8")+1:0)+6+t.length;if("Long"===t._bsontype||"Double"===t._bsontype||"Timestamp"===t._bsontype)return(null!=e?Buffer$6.byteLength(e,"utf8")+1:0)+9;if("Decimal128"===t._bsontype)return(null!=e?Buffer$6.byteLength(e,"utf8")+1:0)+17;if("Code"===t._bsontype)return null!=t.scope&&0>16&255,s[a++]=t>>8&255,s[a++]=255&t;2===o&&(t=l[e.charCodeAt(n)]<<2|l[e.charCodeAt(n+1)]>>4,s[a++]=255&t);1===o&&(t=l[e.charCodeAt(n)]<<10|l[e.charCodeAt(n+1)]<<4|l[e.charCodeAt(n+2)]>>2,s[a++]=t>>8&255,s[a++]=255&t);return s},t.fromByteArray=function(e){for(var t,n=e.length,r=n%3,i=[],o=0,s=n-r;o>2]+a[t<<4&63]+"==")):2==r&&(t=(e[n-2]<<8)+e[n-1],i.push(a[t>>10]+a[t>>4&63]+a[t<<2&63]+"="));return i.join("")};for(var a=[],l=[],c="undefined"!=typeof Uint8Array?Uint8Array:Array,r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i=0,o=r.length;i>18&63]+a[i>>12&63]+a[i>>6&63]+a[63&i]);return o.join("")}l["-".charCodeAt(0)]=62,l["_".charCodeAt(0)]=63},function(e,t){t.read=function(e,t,n,r,i){var o,s,a=8*i-r-1,u=(1<>1,c=-7,_=n?i-1:0,f=n?-1:1,h=e[t+_];for(_+=f,o=h&(1<<-c)-1,h>>=-c,c+=a;0>=-c,c+=r;0>1,f=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,h=r?0:o-1,E=r?1:-1,p=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,s=c):(s=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-s))<1&&(s--,u*=2),2<=(t+=1<=s+_?f/u:f*Math.pow(2,1-_))*u&&(s++,u/=2),c<=s+_?(a=0,s=c):1<=s+_?(a=(t*u-1)*Math.pow(2,i),s+=_):(a=t*Math.pow(2,_-1)*Math.pow(2,i),s=0));8<=i;e[n+h]=255&a,h+=E,a/=256,i-=8);for(s=s<>>=0)&&e<256)&&(r=s[e])?r:(n=y(e,(0|e)<0?-1:0,!0),i&&(s[e]=n),n):(i=-128<=(e|=0)&&e<128)&&(r=o[e])?r:(n=y(e,e<0?-1:0,!1),i&&(o[e]=n),n)}function p(e,t){if(isNaN(e))return t?l:S;if(t){if(e<0)return l;if(a<=e)return v}else{if(e<=-u)return I;if(u<=e+1)return P}return e<0?p(-e,t).neg():y(e%i|0,e/i|0,t)}function y(e,t,n){return new r(e,t,n)}r.fromInt=n,r.fromNumber=p,r.fromBits=y;var c=Math.pow;function _(e,t,n){if(0===e.length)throw Error("empty string");if("NaN"===e||"Infinity"===e||"+Infinity"===e||"-Infinity"===e)return S;if(t="number"==typeof t?(n=t,!1):!!t,(n=n||10)<2||36>>0:this.low},m.toNumber=function(){return this.unsigned?(this.high>>>0)*i+(this.low>>>0):this.high*i+(this.low>>>0)},m.toString=function(e){if((e=e||10)<2||36>>0).toString(e);if((o=a).isZero())return u+s;for(;u.length<6;)u="0"+u;s=""+u+s}},m.getHighBits=function(){return this.high},m.getHighBitsUnsigned=function(){return this.high>>>0},m.getLowBits=function(){return this.low},m.getLowBitsUnsigned=function(){return this.low>>>0},m.getNumBitsAbs=function(){if(this.isNegative())return this.eq(I)?64:this.neg().getNumBitsAbs();for(var e=0!=this.high?this.high:this.low,t=31;0>>31!=1||e.high>>>31!=1)&&(this.high===e.high&&this.low===e.low)},m.eq=m.equals,m.notEquals=function(e){return!this.eq(e)},m.neq=m.notEquals,m.ne=m.notEquals,m.lessThan=function(e){return this.comp(e)<0},m.lt=m.lessThan,m.lessThanOrEqual=function(e){return this.comp(e)<=0},m.lte=m.lessThanOrEqual,m.le=m.lessThanOrEqual,m.greaterThan=function(e){return 0>>0>this.high>>>0||e.high===this.high&&e.low>>>0>this.low>>>0?-1:1:this.sub(e).isNegative()?-1:1},m.comp=m.compare,m.negate=function(){return!this.unsigned&&this.eq(I)?I:this.not().add(f)},m.neg=m.negate,m.add=function(e){E(e)||(e=g(e));var t=this.high>>>16,n=65535&this.high,r=this.low>>>16,i=65535&this.low,o=e.high>>>16,s=65535&e.high,a=e.low>>>16,u=0,l=0,c=0,_=0;return c+=(_+=i+(65535&e.low))>>>16,l+=(c+=r+a)>>>16,u+=(l+=n+s)>>>16,u+=t+o,y((c&=65535)<<16|(_&=65535),(u&=65535)<<16|(l&=65535),this.unsigned)},m.subtract=function(e){return E(e)||(e=g(e)),this.add(e.neg())},m.sub=m.subtract,m.multiply=function(e){if(this.isZero())return S;if(E(e)||(e=g(e)),h)return y(h.mul(this.low,this.high,e.low,e.high),h.get_high(),this.unsigned);if(e.isZero())return S;if(this.eq(I))return e.isOdd()?I:S;if(e.eq(I))return this.isOdd()?I:S;if(this.isNegative())return e.isNegative()?this.neg().mul(e.neg()):this.neg().mul(e).neg();if(e.isNegative())return this.mul(e.neg()).neg();if(this.lt(A)&&e.lt(A))return p(this.toNumber()*e.toNumber(),this.unsigned);var t=this.high>>>16,n=65535&this.high,r=this.low>>>16,i=65535&this.low,o=e.high>>>16,s=65535&e.high,a=e.low>>>16,u=65535&e.low,l=0,c=0,_=0,f=0;return _+=(f+=i*u)>>>16,c+=(_+=r*u)>>>16,_&=65535,c+=(_+=i*a)>>>16,l+=(c+=n*u)>>>16,c&=65535,l+=(c+=r*a)>>>16,c&=65535,l+=(c+=i*s)>>>16,l+=t*u+n*a+r*s+i*o,y((_&=65535)<<16|(f&=65535),(l&=65535)<<16|(c&=65535),this.unsigned)},m.mul=m.multiply,m.divide=function(e){if(E(e)||(e=g(e)),e.isZero())throw Error("division by zero");var t,n,r;if(h)return this.unsigned||-2147483648!==this.high||-1!==e.low||-1!==e.high?y((this.unsigned?h.div_u:h.div_s)(this.low,this.high,e.low,e.high),h.get_high(),this.unsigned):this;if(this.isZero())return this.unsigned?l:S;if(this.unsigned){if(e.unsigned||(e=e.toUnsigned()),e.gt(this))return l;if(e.gt(this.shru(1)))return d;r=l}else{if(this.eq(I))return e.eq(f)||e.eq(T)?I:e.eq(I)?f:(t=this.shr(1).div(e).shl(1)).eq(S)?e.isNegative()?f:T:(n=this.sub(e.mul(t)),r=t.add(n.div(e)));else if(e.eq(I))return this.unsigned?l:S;if(this.isNegative())return e.isNegative()?this.neg().div(e.neg()):this.neg().div(e).neg();if(e.isNegative())return this.div(e.neg()).neg();r=S}for(n=this;n.gte(e);){t=Math.max(1,Math.floor(n.toNumber()/e.toNumber()));for(var i=Math.ceil(Math.log(t)/Math.LN2),o=i<=48?1:c(2,i-48),s=p(t),a=s.mul(e);a.isNegative()||a.gt(n);)a=(s=p(t-=o,this.unsigned)).mul(e);s.isZero()&&(s=f),r=r.add(s),n=n.sub(a)}return r},m.div=m.divide,m.modulo=function(e){return E(e)||(e=g(e)),h?y((this.unsigned?h.rem_u:h.rem_s)(this.low,this.high,e.low,e.high),h.get_high(),this.unsigned):this.sub(this.div(e).mul(e))},m.mod=m.modulo,m.rem=m.modulo,m.not=function(){return y(~this.low,~this.high,this.unsigned)},m.and=function(e){return E(e)||(e=g(e)),y(this.low&e.low,this.high&e.high,this.unsigned)},m.or=function(e){return E(e)||(e=g(e)),y(this.low|e.low,this.high|e.high,this.unsigned)},m.xor=function(e){return E(e)||(e=g(e)),y(this.low^e.low,this.high^e.high,this.unsigned)},m.shiftLeft=function(e){return E(e)&&(e=e.toInt()),0==(e&=63)?this:e<32?y(this.low<>>32-e,this.unsigned):y(0,this.low<>>e|this.high<<32-e,this.high>>e,this.unsigned):y(this.high>>e-32,0<=this.high?0:-1,this.unsigned)},m.shr=m.shiftRight,m.shiftRightUnsigned=function(e){if(E(e)&&(e=e.toInt()),0===(e&=63))return this;var t=this.high;return e<32?y(this.low>>>e|t<<32-e,t>>>e,this.unsigned):y(32===e?t:t>>>e-32,0,this.unsigned)},m.shru=m.shiftRightUnsigned,m.shr_u=m.shiftRightUnsigned,m.toSigned=function(){return this.unsigned?y(this.low,this.high,!1):this},m.toUnsigned=function(){return this.unsigned?this:y(this.low,this.high,!0)},m.toBytes=function(e){return e?this.toBytesLE():this.toBytesBE()},m.toBytesLE=function(){var e=this.high,t=this.low;return[255&t,t>>>8&255,t>>>16&255,t>>>24,255&e,e>>>8&255,e>>>16&255,e>>>24]},m.toBytesBE=function(){var e=this.high,t=this.low;return[e>>>24,e>>>16&255,e>>>8&255,255&e,t>>>24,t>>>16&255,t>>>8&255,255&t]},r.fromBytes=function(e,t,n){return n?r.fromBytesLE(e,t):r.fromBytesBE(e,t)},r.fromBytesLE=function(e,t){return new r(e[0]|e[1]<<8|e[2]<<16|e[3]<<24,e[4]|e[5]<<8|e[6]<<16|e[7]<<24,t)},r.fromBytesBE=function(e,t){return new r(e[4]<<24|e[5]<<16|e[6]<<8|e[7],e[0]<<24|e[1]<<16|e[2]<<8|e[3],t)}}],ak={},bk.m=_j,bk.c=ak,bk.d=function(e,t,n){bk.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:n})},bk.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return bk.d(t,"a",t),t},bk.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},bk.p="",bk(bk.s=2))}),BSON=unwrapExports(bson_common),bson=BSON.bson,Bson=function(){function e(){_classCallCheck(this,e)}return _createClass(e,null,[{key:"serialize",value:function(e){return bson.serialize(e)}},{key:"deserialize",value:function(e){return bson.deserialize(e)}}]),e}(),SdlPacket=function(){function _(){var e=0>24,l[c++]=(16711680&s)>>16,l[c++]=(65280&s)>>8,l[c++]=255&s,1>24,l[c++]=(16711680&a)>>16,l[c++]=(65280&a)>>8,l[c++]=255&a),null!==u&&0>16&255,o[a++]=r>>8&255,o[a++]=255&r;return 2==i?(r=revLookup[e.charCodeAt(t)]<<2|revLookup[e.charCodeAt(t+1)]>>4,o[a++]=255&r):1==i&&(r=revLookup[e.charCodeAt(t)]<<10|revLookup[e.charCodeAt(t+1)]<<4|revLookup[e.charCodeAt(t+2)]>>2,o[a++]=r>>8&255,o[a++]=255&r),o}function tripletToBase64(e){return lookup[e>>18&63]+lookup[e>>12&63]+lookup[e>>6&63]+lookup[63&e]}function encodeChunk(e,t,n){for(var r,i=[],o=t;o>2],i+=lookup[t<<4&63],i+="=="):2==r&&(t=(e[n-2]<<8)+e[n-1],i+=lookup[t>>10],i+=lookup[t>>4&63],i+=lookup[t<<2&63],i+="="),o.push(i),o.join("")}function read(e,t,n,r,i){var o,s,a=8*i-r-1,u=(1<>1,c=-7,_=n?i-1:0,f=n?-1:1,h=e[t+_];for(_+=f,o=h&(1<<-c)-1,h>>=-c,c+=a;0>=-c,c+=r;0>1,f=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,h=r?0:o-1,E=r?1:-1,p=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,s=c):(s=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-s))<1&&(s--,u*=2),2<=(t+=1<=s+_?f/u:f*Math.pow(2,1-_))*u&&(s++,u/=2),c<=s+_?(a=0,s=c):1<=s+_?(a=(t*u-1)*Math.pow(2,i),s+=_):(a=t*Math.pow(2,_-1)*Math.pow(2,i),s=0));8<=i;e[n+h]=255&a,h+=E,a/=256,i-=8);for(s=s<=kMaxLength())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+kMaxLength().toString(16)+" bytes");return 0|e}function internalIsBuffer(e){return!(null==e||!e._isBuffer)}function byteLength(e,t){if(internalIsBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return utf8ToBytes(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return base64ToBytes(e).length;default:if(r)return utf8ToBytes(e).length;t=(""+t).toLowerCase(),r=!0}}function slowToString(e,t,n){var r=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e=e||"utf8";;)switch(e){case"hex":return hexSlice(this,t,n);case"utf8":case"utf-8":return utf8Slice(this,t,n);case"ascii":return asciiSlice(this,t,n);case"latin1":case"binary":return latin1Slice(this,t,n);case"base64":return base64Slice(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return utf16leSlice(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function swap(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function bidirectionalIndexOf(e,t,n,r,i){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):2147483647=e.length){if(i)return-1;n=e.length-1}else if(n<0){if(!i)return-1;n=0}if("string"==typeof t&&(t=Buffer.from(t,r)),internalIsBuffer(t))return 0===t.length?-1:arrayIndexOf(e,t,n,r,i);if("number"==typeof t)return t&=255,Buffer.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):arrayIndexOf(e,[t],n,r,i);throw new TypeError("val must be string, number or Buffer")}function arrayIndexOf(e,t,n,r,i){var o,s=1,a=e.length,u=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;a/=s=2,u/=2,n/=2}function l(e,t){return 1===s?e[t]:e.readUInt16BE(t*s)}if(i){var c=-1;for(o=n;o>>10&1023|55296),c=56320|1023&c),r.push(c),i+=_}return decodeCodePointsArray(r)}Buffer.TYPED_ARRAY_SUPPORT=void 0===global$1.TYPED_ARRAY_SUPPORT||global$1.TYPED_ARRAY_SUPPORT,Buffer.poolSize=8192,Buffer._augment=function(e){return e.__proto__=Buffer.prototype,e},Buffer.from=function(e,t,n){return from(null,e,t,n)},Buffer.TYPED_ARRAY_SUPPORT&&(Buffer.prototype.__proto__=Uint8Array.prototype,Buffer.__proto__=Uint8Array),Buffer.alloc=function(e,t,n){return alloc(null,e,t,n)},Buffer.allocUnsafe=function(e){return allocUnsafe(null,e)},Buffer.allocUnsafeSlow=function(e){return allocUnsafe(null,e)},Buffer.isBuffer=isBuffer,Buffer.compare=function(e,t){if(!internalIsBuffer(e)||!internalIsBuffer(t))throw new TypeError("Arguments must be Buffers");if(e===t)return 0;for(var n=e.length,r=t.length,i=0,o=Math.min(n,r);it&&(e+=" ... ")),""},Buffer.prototype.compare=function(e,t,n,r,i){if(!internalIsBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===i&&(i=this.length),t<0||n>e.length||r<0||i>this.length)throw new RangeError("out of range index");if(i<=r&&n<=t)return 0;if(i<=r)return-1;if(n<=t)return 1;if(this===e)return 0;for(var o=(i>>>=0)-(r>>>=0),s=(n>>>=0)-(t>>>=0),a=Math.min(o,s),u=this.slice(r,i),l=e.slice(t,n),c=0;cthis.length)throw new RangeError("Attempt to write outside buffer bounds");r=r||"utf8";for(var o=!1;;)switch(r){case"hex":return hexWrite(this,e,t,n);case"utf8":case"utf-8":return utf8Write(this,e,t,n);case"ascii":return asciiWrite(this,e,t,n);case"latin1":case"binary":return latin1Write(this,e,t,n);case"base64":return base64Write(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return ucs2Write(this,e,t,n);default:if(o)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),o=!0}},Buffer.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var MAX_ARGUMENTS_LENGTH=4096;function decodeCodePointsArray(e){var t=e.length;if(t<=MAX_ARGUMENTS_LENGTH)return String.fromCharCode.apply(String,e);for(var n="",r=0;re.length)throw new RangeError("Index out of range")}function objectWriteUInt16(e,t,n,r){t<0&&(t=65535+t+1);for(var i=0,o=Math.min(e.length-n,2);i>>8*(r?i:1-i)}function objectWriteUInt32(e,t,n,r){t<0&&(t=4294967295+t+1);for(var i=0,o=Math.min(e.length-n,4);i>>8*(r?i:3-i)&255}function checkIEEE754(e,t,n,r,i,o){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function writeFloat(e,t,n,r,i){return i||checkIEEE754(e,t,n,4),write(e,t,n,r,23,4),n+4}function writeDouble(e,t,n,r,i){return i||checkIEEE754(e,t,n,8),write(e,t,n,r,52,8),n+8}Buffer.prototype.slice=function(e,t){var n,r=this.length;if((e=~~e)<0?(e+=r)<0&&(e=0):r>>8):objectWriteUInt16(this,e,t,!0),t+2},Buffer.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||checkInt(this,e,t,2,65535,0),Buffer.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):objectWriteUInt16(this,e,t,!1),t+2},Buffer.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||checkInt(this,e,t,4,4294967295,0),Buffer.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):objectWriteUInt32(this,e,t,!0),t+4},Buffer.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||checkInt(this,e,t,4,4294967295,0),Buffer.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):objectWriteUInt32(this,e,t,!1),t+4},Buffer.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var i=Math.pow(2,8*n-1);checkInt(this,e,t,n,i-1,-i)}var o=0,s=1,a=0;for(this[t]=255&e;++o>0)-a&255;return t+n},Buffer.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var i=Math.pow(2,8*n-1);checkInt(this,e,t,n,i-1,-i)}var o=n-1,s=1,a=0;for(this[t+o]=255&e;0<=--o&&(s*=256);)e<0&&0===a&&0!==this[t+o+1]&&(a=1),this[t+o]=(e/s>>0)-a&255;return t+n},Buffer.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||checkInt(this,e,t,1,127,-128),Buffer.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},Buffer.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||checkInt(this,e,t,2,32767,-32768),Buffer.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):objectWriteUInt16(this,e,t,!0),t+2},Buffer.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||checkInt(this,e,t,2,32767,-32768),Buffer.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):objectWriteUInt16(this,e,t,!1),t+2},Buffer.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||checkInt(this,e,t,4,2147483647,-2147483648),Buffer.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):objectWriteUInt32(this,e,t,!0),t+4},Buffer.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||checkInt(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),Buffer.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):objectWriteUInt32(this,e,t,!1),t+4},Buffer.prototype.writeFloatLE=function(e,t,n){return writeFloat(this,e,t,!0,n)},Buffer.prototype.writeFloatBE=function(e,t,n){return writeFloat(this,e,t,!1,n)},Buffer.prototype.writeDoubleLE=function(e,t,n){return writeDouble(this,e,t,!0,n)},Buffer.prototype.writeDoubleBE=function(e,t,n){return writeDouble(this,e,t,!1,n)},Buffer.prototype.copy=function(e,t,n,r){if(n=n||0,r||0===r||(r=this.length),t>=e.length&&(t=e.length),t=t||0,0=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t>>=0,n=void 0===n?this.length:n>>>0,"number"==typeof(e=e||0))for(o=t;o>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;o.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;o.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return o}function asciiToBytes(e){for(var t=[],n=0;n>8,i=n%256,o.push(i),o.push(r);return o}function base64ToBytes(e){return toByteArray(base64clean(e))}function blitBuffer(e,t,n,r){for(var i=0;i=t.length||i>=e.length);++i)t[i+n]=e[i];return i}function isnan(e){return e!=e}function isBuffer(e){return null!=e&&(!!e._isBuffer||isFastBuffer(e)||isSlowBuffer(e))}function isFastBuffer(e){return!!e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function isSlowBuffer(e){return"function"==typeof e.readFloatLE&&"function"==typeof e.slice&&isFastBuffer(e.slice(0,0))}var TextEncoder=function(){function e(){_classCallCheck(this,e)}return _createClass(e,null,[{key:"encode",value:function(e){for(var t=e.length,n=-1,r=[],i=0,o=0,s=0;s!==t;){if(i=e.charCodeAt(s),s+=1,55296<=i&&i<=56319){if(s===t){r[n+=1]=239,r[n+=1]=191,r[n+=1]=189;break}if(!(56320<=(o=e.charCodeAt(s))&&o<=57343)){r[n+=1]=239,r[n+=1]=191,r[n+=1]=189;continue}if(s+=1,65535<(i=1024*(i-55296)+o-56320+65536)){r[n+=1]=240|i>>>18,r[n+=1]=128|i>>>12&63,r[n+=1]=128|i>>>6&63,r[n+=1]=128|63&i;continue}}i<=127?r[n+=1]=0|i:(i<=2047?r[n+=1]=192|i>>>6:(r[n+=1]=224|i>>>12,r[n+=1]=128|i>>>6&63),r[n+=1]=128|63&i)}return r.length=n+1,r}}]),e}(),JsonRpcMarshaller=function(){function e(){_classCallCheck(this,e)}return _createClass(e,null,[{key:"marshall",value:function(e){var t=null;try{var n=function e(t){var n=t.getParameters();for(var r in n)n[r]instanceof RpcStruct&&(n[r]=e(n[r]));return n}(e),r=JSON.stringify(n);t=this._encode(r)}catch(e){console.error("Failed to encode messages to JSON.",e)}return t}},{key:"unmarshall",value:function(e){var t=null;try{var n=this._decode(e);t=JSON.parse(n)}catch(e){console.error("Failed to parse JSON",e)}return t}},{key:"_encode",value:function(e){return new Uint8Array(TextEncoder.encode(e))}},{key:"_decode",value:function(e){return Buffer.from(e).toString()}}]),e}(),BinaryFrameHeader=function(){function l(e,t,n,r){_classCallCheck(this,l),this._rpcType=e,this._functionId=t,this._correlationId=n,this._jsonSize=r,this._bulkData=null,this._jsonData=null}return _createClass(l,[{key:"assembleHeaderBytes",value:function(){var e=[],t=this._functionId,n=this._correlationId;this._rpcType;e.push((251658240&t)>>24),e.push((16711680&t)>>16),e.push((65280&t)>>8),e.push(255&t),e.push((4278190080&n)>>24),e.push((16711680&n)>>16),e.push((65280&n)>>8),e.push(255&n);var r=this._jsonSize;return e.push((4278190080&r)>>24),e.push((16711680&r)>>16),e.push((65280&r)>>8),e.push(255&r),e}},{key:"setRpcType",value:function(e){return this._rpcType=e,this}},{key:"getRpcType",value:function(){return this._rpcType}},{key:"setFunctionId",value:function(e){return this._functionId=e,this}},{key:"getFunctionId",value:function(){return this._functionId}},{key:"setCorrelationId",value:function(e){return this._correlationId=e,this}},{key:"getCorrelationId",value:function(){return this._correlationId}},{key:"setJsonSize",value:function(e){return this._jsonSize=e,this}},{key:"getJsonSize",value:function(){return this._jsonSize}},{key:"getJsonData",value:function(){return this._jsonData}},{key:"setJsonData",value:function(e){return this._jsonData=e,this}},{key:"setBulkData",value:function(e){return this._bulkData=e,this}},{key:"getBulkData",value:function(){return this._bulkData}}],[{key:"fromBinaryHeader",value:function(e){var t=e[0]>>4,n=(15&e[0])<<24;n+=(255&e[1])<<16,n+=(255&e[2])<<8,n+=255&e[3];var r=(255&e[4])<<24;r+=(255&e[5])<<16,r+=(255&e[6])<<8,r+=255&e[7];var i=(255&e[8])<<24;i+=(255&e[9])<<16,i+=(255&e[10])<<8;var o=new l(t,n,r,i+=255&e[11]),s=l.HEADER_SIZE,a=l.HEADER_SIZE+i;if(o.setJsonData(e.slice(s,a)),e.length>a){var u=e.slice(a);o.setBulkData(u)}return o}}]),l}();BinaryFrameHeader.HEADER_SIZE=12;var MessageFrameDisassembler=function(){function u(e,t,n,r,i,o,s){if(_classCallCheck(this,u),this._rpcRequest=e,this._sessionId=t,this._messageId=n,this._isEncrypted=o,!r)throw new Error("MTU must be specified.");if(this._mtu=r,!i)throw new Error("Version must be specified.");this._version=i,this._packetCallback=s}return _createClass(u,[{key:"_buildRPCMainBuffer",value:function(){var e=this._rpcRequest.getBulkData(),t=this._rpcRequest.getCorrelationId(),n=this._rpcRequest.getRPCType(),r=this._rpcRequest.getFunctionName(),i=FunctionID.valueForKey(r);if(!i)throw new Error("Failed to find function ".concat(r));var o=JsonRpcMarshaller.marshall(this._rpcRequest),s=o.length,a=new BinaryFrameHeader(n,i,t);a.setJsonData(o),a.setJsonSize(s),a.setBulkData(e);var u=a.getBulkData(),l=0;u&&(l=u.length);var c=new Uint8Array(12+s+l);return c.set(a.assembleHeaderBytes(),0),c.set(o,12),u&&c.set(u,12+s),c}},{key:"doRequest",value:function(){var e=this._version,t=FrameType.SINGLE,n=SdlPacket.SERVICE_TYPE_RPC,r=this._sessionId,i=this._messageId,o=this._isEncrypted,s=this._buildRPCMainBuffer(),a=this._mtu,u=Math.ceil(s.length/a);if(u<=1){var l=this._constructPacket(e,n,0,r,i,t,s,o);this._packetCallback(l)}else{var c=new ArrayBuffer(8),_=new DataView(c);_.setUint32(0,s.length,!1),_.setUint32(4,u,!1);var f=new Uint8Array(c),h=this._constructPacket(e,n,0,r,i,FrameType.FIRST,f,o);this._packetCallback(h),this._buildConsecutiveFrames(e,n,r,i,s,a,o)}}},{key:"_constructPacket",value:function(e,t,n,r,i,o,s,a){var u=s.length;return new SdlPacket(e,a,o,t,n,r,u,i,s,0,u)}},{key:"_buildConsecutiveFrames",value:function(e,t,n,r,i,o,s){for(var a,u=0,l=0;0!==a;){a=l+o>=i.length?0:u%255+1;var c=this._constructPacket(e,t,a,n,r,FrameType.CONSECUTIVE,i.slice(l,l+o),s);this._packetCallback(c),u++,l+=o}}}],[{key:"buildRPC",value:function(e,t,n,r,i,o,s){var a=new u(e,t,n,r,i,o,s);return a.doRequest(),a}}]),u}(),TransportListener=function(){function e(){_classCallCheck(this,e),this._onTransportConnected=null,this._onTransportDisconnected=null,this._onError=null,this._onPacketReceived=null}return _createClass(e,[{key:"setOnTransportConnected",value:function(e){return this._onTransportConnected=e,this}},{key:"setOnTransportDisconnected",value:function(e){return this._onTransportDisconnected=e,this}},{key:"setOnError",value:function(e){return this._onError=e,this}},{key:"setOnPacketReceived",value:function(e){return this._onPacketReceived=e,this}},{key:"onTransportConnected",value:function(){"function"==typeof this._onTransportConnected&&this._onTransportConnected()}},{key:"onTransportDisconnected",value:function(){"function"==typeof this._onTransportDisconnected&&this._onTransportDisconnected()}},{key:"onError",value:function(e){var t=0e.getMajor())return 1;if(this.getMajor()===e.getMajor()){if(this.getMinor()>e.getMinor())return 1;if(this.getMinor()===e.getMinor()){if(this.getPatch()>e.getPatch())return 1;if(this.getPatch()===e.getPatch())return 0}}return-1}}]),r}(),ServiceType=function(){function t(){return _classCallCheck(this,t),_possibleConstructorReturn(this,_getPrototypeOf(t).call(this))}return _inherits(t,Enum),_createClass(t,null,[{key:"valueForKey",value:function(e){return t._valueForKey(e,t._MAP)}},{key:"keyForValue",value:function(e){return t._keyForValue(e,t._MAP)}},{key:"CONTROL",get:function(){return t._MAP.CONTROL}},{key:"RPC",get:function(){return t._MAP.RPC}},{key:"AUDIO",get:function(){return t._MAP.AUDIO}},{key:"VIDEO",get:function(){return t._MAP.VIDEO}},{key:"HYBRID",get:function(){return t._MAP.HYBRID}}]),t}();ServiceType._MAP=Object.freeze({CONTROL:0,RPC:7,AUDIO:10,VIDEO:11,HYBRID:15});var MessageFrameAssembler=function(){function t(e){if(_classCallCheck(this,t),"function"!=typeof e)throw new Error("Callback not of expected type (function) for MessageFrameAssembler");this._callback=e,this._accumulator=[],this._totalConsecutiveFrames=0,this._consecutiveFramesHandledCount=0,this._consecutiveFramesDataLength=0}return _createClass(t,[{key:"handleFrame",value:function(e){var t=e.getFrameType();return t!==FrameType.FIRST&&t!==FrameType.CONSECUTIVE?this._callback(null,e):this._handleMultiFrameMessage(e)}},{key:"_handleFirstDataFrame",value:function(e){var t=e.getPayload();if(t instanceof Uint8Array!=!0||8!==t.length)throw new Error("Error handling first frame. Payload is an invalid length should be length 8.");for(var n in t)if(n<0||255>4,0===this._version?n.ERROR_STATE:(this._encryption=1==(e&n.ENCRYPTION_MASK)>>3,this._frameType=e&n.FRAME_TYPE_MASK,(this._version<1||5FrameType.CONSECUTIVE?n.ERROR_STATE:n.SERVICE_TYPE_STATE);if(t===n.SERVICE_TYPE_STATE)return this._serviceType=255&e,n.CONTROL_FRAME_INFO_STATE;if(t===n.CONTROL_FRAME_INFO_STATE){switch(this._controlFrameInfo=255&e,this._frameType){case FrameType.CONTROL:break;case FrameType.SINGLE:case FrameType.FIRST:if(0!==this._controlFrameInfo)return n.ERROR_STATE;break;case FrameType.CONSECUTIVE:break;default:return n.ERROR_STATE}return n.SESSION_ID_STATE}if(t===n.SESSION_ID_STATE)return this._sessionID=255&e,n.DATA_SIZE_1_STATE;if(t===n.DATA_SIZE_1_STATE)return this._dataLength+=(255&e)<<24,n.DATA_SIZE_2_STATE;if(t===n.DATA_SIZE_2_STATE)return this._dataLength+=(255&e)<<16,n.DATA_SIZE_3_STATE;if(t===n.DATA_SIZE_3_STATE)return this._dataLength+=(255&e)<<8,n.DATA_SIZE_4_STATE;if(t!==n.DATA_SIZE_4_STATE)return t===n.MESSAGE_1_STATE?(this._messageID+=(255&e)<<24,n.MESSAGE_2_STATE):t===n.MESSAGE_2_STATE?(this._messageID+=(255&e)<<16,n.MESSAGE_3_STATE):t===n.MESSAGE_3_STATE?(this._messageID+=(255&e)<<8,n.MESSAGE_4_STATE):t===n.MESSAGE_4_STATE?(this._messageID+=255&e,0===this._dataLength?n.FINISHED_STATE:(this._dumpSize=this._dataLength,this._payload=new Uint8Array(this._dataLength),n.DATA_PUMP_STATE)):t===n.DATA_PUMP_STATE?(this._payload[this._dataLength-this._dumpSize]=e,this._dumpSize-=1,0=n())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+n().toString(16)+" bytes");return 0|e}function h(e,t){if(c.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return b(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return U(e).length;default:if(r)return b(e).length;t=(""+t).toLowerCase(),r=!0}}function A(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function T(e,t,n,r,i){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):2147483647=e.length){if(i)return-1;n=e.length-1}else if(n<0){if(!i)return-1;n=0}if("string"==typeof t&&(t=c.from(t,r)),c.isBuffer(t))return 0===t.length?-1:f(e,t,n,r,i);if("number"==typeof t)return t&=255,c.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):f(e,[t],n,r,i);throw new TypeError("val must be string, number or Buffer")}function f(e,t,n,r,i){var a,s=1,u=e.length,o=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;u/=s=2,o/=2,n/=2}function _(e,t){return 1===s?e[t]:e.readUInt16BE(t*s)}if(i){var l=-1;for(a=n;a>8,i=n%256,a.push(i),a.push(r);return a}(t,e.length-n),e,n,r)}function I(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function p(e,t,n){n=Math.min(e.length,n);for(var r=[],i=t;i>>10&1023|55296),l=56320|1023&l),r.push(l),i+=c}return function(e){var t=e.length;if(t<=R)return String.fromCharCode.apply(String,e);var n="",r=0;for(;rthis.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e=e||"utf8";;)switch(e){case"hex":return O(this,t,n);case"utf8":case"utf-8":return p(this,t,n);case"ascii":return g(this,t,n);case"latin1":case"binary":return C(this,t,n);case"base64":return I(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return v(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}.apply(this,arguments)},c.prototype.equals=function(e){if(!c.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===c.compare(this,e)},c.prototype.inspect=function(){var e="",t=F.INSPECT_MAX_BYTES;return 0t&&(e+=" ... ")),""},c.prototype.compare=function(e,t,n,r,i){if(!c.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===i&&(i=this.length),t<0||n>e.length||r<0||i>this.length)throw new RangeError("out of range index");if(i<=r&&n<=t)return 0;if(i<=r)return-1;if(n<=t)return 1;if(this===e)return 0;for(var a=(i>>>=0)-(r>>>=0),s=(n>>>=0)-(t>>>=0),u=Math.min(a,s),o=this.slice(r,i),_=e.slice(t,n),l=0;lthis.length)throw new RangeError("Attempt to write outside buffer bounds");r=r||"utf8";for(var a,s,u,o,_,l,c=!1;;)switch(r){case"hex":return S(this,e,t,n);case"utf8":case"utf-8":return _=t,l=n,B(b(e,(o=this).length-_),o,_,l);case"ascii":return y(this,e,t,n);case"latin1":case"binary":return y(this,e,t,n);case"base64":return a=this,s=t,u=n,B(U(e),a,s,u);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return P(this,e,t,n);default:if(c)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),c=!0}},c.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var R=4096;function g(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;ie.length)throw new RangeError("Index out of range")}function m(e,t,n,r){t<0&&(t=65535+t+1);for(var i=0,a=Math.min(e.length-n,2);i>>8*(r?i:1-i)}function d(e,t,n,r){t<0&&(t=4294967295+t+1);for(var i=0,a=Math.min(e.length-n,4);i>>8*(r?i:3-i)&255}function L(e,t,n,r){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function k(e,t,n,r,i){return i||L(e,0,n,4),a.write(e,t,n,r,23,4),n+4}function M(e,t,n,r,i){return i||L(e,0,n,8),a.write(e,t,n,r,52,8),n+8}c.prototype.slice=function(e,t){var n,r=this.length;if((e=~~e)<0?(e+=r)<0&&(e=0):r>>8):m(this,e,t,!0),t+2},c.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,2,65535,0),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):m(this,e,t,!1),t+2},c.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,4,4294967295,0),c.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):d(this,e,t,!0),t+4},c.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,4,4294967295,0),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):d(this,e,t,!1),t+4},c.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var i=Math.pow(2,8*n-1);D(this,e,t,n,i-1,-i)}var a=0,s=1,u=0;for(this[t]=255&e;++a>0)-u&255;return t+n},c.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var i=Math.pow(2,8*n-1);D(this,e,t,n,i-1,-i)}var a=n-1,s=1,u=0;for(this[t+a]=255&e;0<=--a&&(s*=256);)e<0&&0===u&&0!==this[t+a+1]&&(u=1),this[t+a]=(e/s>>0)-u&255;return t+n},c.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,1,127,-128),c.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},c.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,2,32767,-32768),c.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):m(this,e,t,!0),t+2},c.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,2,32767,-32768),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):m(this,e,t,!1),t+2},c.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,4,2147483647,-2147483648),c.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):d(this,e,t,!0),t+4},c.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||D(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):d(this,e,t,!1),t+4},c.prototype.writeFloatLE=function(e,t,n){return k(this,e,t,!0,n)},c.prototype.writeFloatBE=function(e,t,n){return k(this,e,t,!1,n)},c.prototype.writeDoubleLE=function(e,t,n){return M(this,e,t,!0,n)},c.prototype.writeDoubleBE=function(e,t,n){return M(this,e,t,!1,n)},c.prototype.copy=function(e,t,n,r){if(n=n||0,r||0===r||(r=this.length),t>=e.length&&(t=e.length),t=t||0,0=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t>>=0,n=void 0===n?this.length:n>>>0,"number"==typeof(e=e||0))for(a=t;a>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;a.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;a.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return a}function U(e){return r.toByteArray(Y(e))}function B(e,t,n,r){for(var i=0;i=t.length||i>=e.length);++i)t[i+n]=e[i];return i}}).call(F,V(0))},function(module,exports,__webpack_require__){(function(global,Buffer){var iu;iu=function(exports,_long,buffer){_long=_long&&_long.hasOwnProperty("default")?_long.default:_long,buffer=buffer&&buffer.hasOwnProperty("default")?buffer.default:buffer;var commonjsGlobal="undefined"!=typeof window?window:void 0!==global?global:"undefined"!=typeof self?self:{};function createCommonjsModule(e,t){return e(t={exports:{}},t.exports),t.exports}function getCjsExportFromNamespace(e){return e&&e.default||e}var map=createCommonjsModule(function(e){if(void 0!==commonjsGlobal.Map)e.exports=commonjsGlobal.Map,e.exports.Map=commonjsGlobal.Map;else{var t=function(e){this._keys=[],this._values={};for(var t=0;t>8&255,n[1]=e>>16&255,n[0]=e>>24&255,n[4]=PROCESS_UNIQUE[0],n[5]=PROCESS_UNIQUE[1],n[6]=PROCESS_UNIQUE[2],n[7]=PROCESS_UNIQUE[3],n[8]=PROCESS_UNIQUE[4],n[11]=255&t,n[10]=t>>8&255,n[9]=t>>16&255,n}},{key:"createPk",value:function(){return new i}},{key:"createFromTime",value:function(e){var t=Buffer$1.from([0,0,0,0,0,0,0,0,0,0,0,0]);return t[3]=255&e,t[2]=e>>8&255,t[1]=e>>16&255,t[0]=e>>24&255,new i(t)}},{key:"createFromHexString",value:function(e){if(void 0===e||null!=e&&24!==e.length)throw new TypeError("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters");if(hasBufferType)return new i(Buffer$1.from(e,"hex"));for(var t=new _Buffer(12),n=0,r=0;r<24;)t[n++]=decodeLookup[e.charCodeAt(r++)]<<4|decodeLookup[e.charCodeAt(r++)];return new i(t)}},{key:"isValid",value:function(e){return null!=e&&("number"==typeof e||("string"==typeof e?12===e.length||24===e.length&&checkForHexRegExp.test(e):e instanceof i||(e instanceof _Buffer&&12===e.length||!!e.toHexString&&(12===e.id.length||24===e.id.length&&checkForHexRegExp.test(e.id)))))}},{key:"fromExtendedJSON",value:function(e){return new i(e.$oid)}}]),i}();ObjectId.get_inc=deprecate$1(function(){return ObjectId.getInc()},"Please use the static `ObjectId.getInc()` instead"),ObjectId.prototype.get_inc=deprecate$1(function(){return ObjectId.getInc()},"Please use the static `ObjectId.getInc()` instead"),ObjectId.prototype.getInc=deprecate$1(function(){return ObjectId.getInc()},"Please use the static `ObjectId.getInc()` instead"),ObjectId.prototype.generate=deprecate$1(function(e){return ObjectId.generate(e)},"Please use the static `ObjectId.generate(time)` instead"),Object.defineProperty(ObjectId.prototype,"generationTime",{enumerable:!0,get:function(){return this.id[3]|this.id[2]<<8|this.id[1]<<16|this.id[0]<<24},set:function(e){this.id[3]=255&e,this.id[2]=e>>8&255,this.id[1]=e>>16&255,this.id[0]=e>>24&255}}),ObjectId.prototype[util$2.inspect.custom||"inspect"]=ObjectId.prototype.toString,ObjectId.index=~~(16777215*Math.random()),Object.defineProperty(ObjectId.prototype,"_bsontype",{value:"ObjectID"});var objectid=ObjectId;function _classCallCheck$3(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties$3(e,t){for(var n=0;n>>0,r=t.high>>>0;return n>>0>>0}function invalidErr(e,t){throw new TypeError('"'.concat(e,'" is not a valid Decimal128 string - ').concat(t))}function Decimal128(e){this.bytes=e}Decimal128.fromString=function(e){var t,n=!1,r=!1,i=!1,a=0,s=0,u=0,o=0,_=0,l=[0],c=0,E=0,h=0,A=0,T=0,f=0,S=[0,0],y=[0,0],P=0;if(7e3<=e.length)throw new TypeError(e+" not a valid Decimal128 string");var I=e.match(PARSE_STRING_REGEXP),p=e.match(PARSE_INF_REGEXP),R=e.match(PARSE_NAN_REGEXP);if(!I&&!p&&!R||0===e.length)throw new TypeError(e+" not a valid Decimal128 string");if(I){var g=I[2],C=I[4],O=I[5],v=I[6];C&&void 0===v&&invalidErr(e,"missing exponent power"),C&&void 0===g&&invalidErr(e,"missing exponent base"),void 0===C&&(O||v)&&invalidErr(e,"missing e before exponent")}if("+"!==e[P]&&"-"!==e[P]||(n="-"===e[P++]),!isDigit(e[P])&&"."!==e[P]){if("i"===e[P]||"I"===e[P])return new Decimal128(Buffer$2.from(n?INF_NEGATIVE_BUFFER:INF_POSITIVE_BUFFER));if("N"===e[P])return new Decimal128(Buffer$2.from(NAN_BUFFER))}for(;isDigit(e[P])||"."===e[P];)"."!==e[P]?(c<34&&("0"===e[P]&&!i||(i||(_=s),i=!0,l[E++]=parseInt(e[P],10),c+=1)),i&&(u+=1),r&&(o+=1),s+=1):(r&&invalidErr(e,"contains multiple periods"),r=!0),P+=1;if(r&&!s)throw new TypeError(e+" not a valid Decimal128 string");if("e"===e[P]||"E"===e[P]){var N=e.substr(++P).match(EXPONENT_REGEX);if(!N||!N[2])return new Decimal128(Buffer$2.from(NAN_BUFFER));T=parseInt(N[0],10),P+=N[0].length}if(e[P])return new Decimal128(Buffer$2.from(NAN_BUFFER));if(h=0,c){if(A=c-1,1!==(a=u))for(;"0"===e[_+a-1];)a-=1}else c=u=1,a=l[A=h=0]=0;for(T<=o&&16384>8&255,b[P++]=K.low.low>>16&255,b[P++]=K.low.low>>24&255,b[P++]=255&K.low.high,b[P++]=K.low.high>>8&255,b[P++]=K.low.high>>16&255,b[P++]=K.low.high>>24&255,b[P++]=255&K.high.low,b[P++]=K.high.low>>8&255,b[P++]=K.high.low>>16&255,b[P++]=K.high.low>>24&255,b[P++]=255&K.high.high,b[P++]=K.high.high>>8&255,b[P++]=K.high.high>>16&255,b[P++]=K.high.high>>24&255,new Decimal128(b)};var COMBINATION_MASK=31,EXPONENT_MASK=16383,COMBINATION_INFINITY=30,COMBINATION_NAN=31;Decimal128.prototype.toString=function(){for(var e,t,n,r,i,a,s=0,u=new Array(36),o=0;o>26&COMBINATION_MASK)>>3==3){if(i===COMBINATION_INFINITY)return S.join("")+"Infinity";if(i===COMBINATION_NAN)return"NaN";a=e>>15&EXPONENT_MASK,c=8+(e>>14&1)}else c=e>>14&7,a=e>>17&EXPONENT_MASK;if(_=a-EXPONENT_BIAS,f.parts[0]=(16383&e)+((15&c)<<14),f.parts[1]=t,f.parts[2]=n,f.parts[3]=r,0===f.parts[0]&&0===f.parts[1]&&0===f.parts[2]&&0===f.parts[3])T=!0;else for(h=3;0<=h;h--){var P=0,I=divideu128(f);if(f=I.quotient,P=I.rem.low)for(E=8;0<=E;E--)u[9*h+E]=P%10,P=Math.floor(P/10)}if(T)s=1,u[A]=0;else for(s=36;!u[A];)s-=1,A+=1;if(34<=(l=s-1+_)||l<=-7||0<_){if(34this.position)this.buffer[this.position++]=t;else if(void 0!==Buffer$3&&Buffer$3.isBuffer(this.buffer)){var n=Buffer$3.alloc(a.BUFFER_SIZE+this.buffer.length);this.buffer.copy(n,0,0,this.buffer.length),this.buffer=n,this.buffer[this.position++]=t}else{var r=null;r=isUint8Array(this.buffer)?new Uint8Array(new ArrayBuffer(a.BUFFER_SIZE+this.buffer.length)):new Array(a.BUFFER_SIZE+this.buffer.length);for(var i=0;ithis.position?t+e.length:this.position;else if(void 0!==Buffer$3&&"string"==typeof e&&Buffer$3.isBuffer(this.buffer))this.buffer.write(e,t,"binary"),this.position=t+e.length>this.position?t+e.length:this.position;else if(isUint8Array(e)||Array.isArray(e)&&"string"!=typeof e){for(var i=0;ithis.position?t:this.position}else if("string"==typeof e){for(var a=0;athis.position?t:this.position}}},{key:"read",value:function(e,t){if(t=t&&0= 5, is ".concat(i));if(t.allowObjectSmallerThanBufferSize&&e.length= bson size ").concat(i));if(!t.allowObjectSmallerThanBufferSize&&e.length!==i)throw new Error("buffer length ".concat(e.length," must === bson size ").concat(i));if(i+r>e.length)throw new Error("(bson size ".concat(i," + options.index ").concat(r," must be <= buffer length ").concat(Buffer$4.byteLength(e),")"));if(0!==e[r+i-1])throw new Error("One object, sized correctly, with a spot for an EOO, but the EOO isn't 0x00");return deserializeObject(e,r,t,n)}function deserializeObject(e,t,n,r){var i=null!=n.evalFunctions&&n.evalFunctions,a=null!=n.cacheFunctions&&n.cacheFunctions,s=null!=n.cacheFunctionsCrc32&&n.cacheFunctionsCrc32;if(!s)var u=null;var o=null==n.fieldsAsRaw?null:n.fieldsAsRaw,_=null!=n.raw&&n.raw,l="boolean"==typeof n.bsonRegExp&&n.bsonRegExp,c=null!=n.promoteBuffers&&n.promoteBuffers,E=null==n.promoteLongs||n.promoteLongs,h=null==n.promoteValues||n.promoteValues,A=t;if(e.length<5)throw new Error("corrupt bson message < 5 bytes long");var T=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(T<5||T>e.length)throw new Error("corrupt bson message");for(var f=r?[]:{},S=0;;){var y=e[t++];if(0===y)break;for(var P=t;0!==e[P]&&P=Buffer$4.byteLength(e))throw new Error("Bad BSON Document: illegal CString");var I=r?S++:e.toString("utf8",t,P);if(t=P+1,y===constants.BSON_DATA_STRING){var p=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(p<=0||p>e.length-t||0!==e[t+p-1])throw new Error("bad string length in bson");if(!validateUtf8$1(e,t,t+p-1))throw new Error("Invalid UTF-8 string in BSON document");var R=e.toString("utf8",t,t+p-1);f[I]=R,t+=p}else if(y===constants.BSON_DATA_OID){var g=Buffer$4.alloc(12);e.copy(g,0,t,t+12),f[I]=new objectid(g),t+=12}else if(y===constants.BSON_DATA_INT&&!1===h)f[I]=new int_32(e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24);else if(y===constants.BSON_DATA_INT)f[I]=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;else if(y===constants.BSON_DATA_NUMBER&&!1===h)f[I]=new double_1(e.readDoubleLE(t)),t+=8;else if(y===constants.BSON_DATA_NUMBER)f[I]=e.readDoubleLE(t),t+=8;else if(y===constants.BSON_DATA_DATE){var C=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24,O=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;f[I]=new Date(new long_1(C,O).toNumber())}else if(y===constants.BSON_DATA_BOOLEAN){if(0!==e[t]&&1!==e[t])throw new Error("illegal boolean type value");f[I]=1===e[t++]}else if(y===constants.BSON_DATA_OBJECT){var v=t,N=e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24;if(N<=0||N>e.length-t)throw new Error("bad embedded document length in bson");f[I]=_?e.slice(t,t+N):deserializeObject(e,v,n,!1),t+=N}else if(y===constants.BSON_DATA_ARRAY){var D=t,m=e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24,d=n,L=t+m;if(o&&o[I]){for(var k in d={},n)d[k]=n[k];d.raw=!0}if(f[I]=deserializeObject(e,D,d,!0),0!==e[(t+=m)-1])throw new Error("invalid array terminator byte");if(t!==L)throw new Error("corrupted array bson")}else if(y===constants.BSON_DATA_UNDEFINED)f[I]=void 0;else if(y===constants.BSON_DATA_NULL)f[I]=null;else if(y===constants.BSON_DATA_LONG){var M=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24,Y=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24,K=new long_1(M,Y);f[I]=E&&!0===h&&K.lessThanOrEqual(JS_INT_MAX_LONG)&&K.greaterThanOrEqual(JS_INT_MIN_LONG)?K.toNumber():K}else if(y===constants.BSON_DATA_DECIMAL128){var b=Buffer$4.alloc(16);e.copy(b,0,t,t+16),t+=16;var U=new decimal128(b);f[I]=U.toObject?U.toObject():U}else if(y===constants.BSON_DATA_BINARY){var B=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24,F=B,V=e[t++];if(B<0)throw new Error("Negative binary type element size found");if(B>Buffer$4.byteLength(e))throw new Error("Binary type size larger than document size");if(null!=e.slice){if(V===binary.SUBTYPE_BYTE_ARRAY){if((B=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24)<0)throw new Error("Negative binary type element size found for subtype 0x02");if(F-4=e.length)throw new Error("Bad BSON Document: illegal CString");var H=e.toString("utf8",t,P);for(P=t=P+1;0!==e[P]&&P=e.length)throw new Error("Bad BSON Document: illegal CString");var w=e.toString("utf8",t,P);t=P+1;var W=new Array(w.length);for(P=0;P=e.length)throw new Error("Bad BSON Document: illegal CString");var j=e.toString("utf8",t,P);for(P=t=P+1;0!==e[P]&&P=e.length)throw new Error("Bad BSON Document: illegal CString");var x=e.toString("utf8",t,P);t=P+1,f[I]=new regexp(j,x)}else if(y===constants.BSON_DATA_SYMBOL){var z=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(z<=0||z>e.length-t||0!==e[t+z-1])throw new Error("bad string length in bson");f[I]=e.toString("utf8",t,t+z-1),t+=z}else if(y===constants.BSON_DATA_TIMESTAMP){var X=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24,$=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;f[I]=new timestamp(X,$)}else if(y===constants.BSON_DATA_MIN_KEY)f[I]=new min_key;else if(y===constants.BSON_DATA_MAX_KEY)f[I]=new max_key;else if(y===constants.BSON_DATA_CODE){var Q=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(Q<=0||Q>e.length-t||0!==e[t+Q-1])throw new Error("bad string length in bson");var q=e.toString("utf8",t,t+Q-1);if(i)if(a){var Z=s?u(q):q;f[I]=isolateEvalWithHash(functionCache,Z,q,f)}else f[I]=isolateEval(q);else f[I]=new code(q);t+=Q}else if(y===constants.BSON_DATA_CODE_W_SCOPE){var J=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(J<13)throw new Error("code_w_scope total size shorter minimum expected length");var ee=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24;if(ee<=0||ee>e.length-t||0!==e[t+ee-1])throw new Error("bad string length in bson");var te=e.toString("utf8",t,t+ee-1),ne=t+=ee,re=e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24,ie=deserializeObject(e,ne,n,!1);if(t+=re,J<8+re+ee)throw new Error("code_w_scope total size is to short, truncating scope");if(8+re+eee.length-t||0!==e[t+se-1])throw new Error("bad string length in bson");if(!validateUtf8$1(e,t,t+se-1))throw new Error("Invalid UTF-8 string in BSON document");var ue=e.toString("utf8",t,t+se-1);t+=se;var oe=Buffer$4.alloc(12);e.copy(oe,0,t,t+12);var _e=new objectid(oe);t+=12,f[I]=new db_ref(ue,_e)}}if(T!=t-A){if(r)throw new Error("corrupt array bson");throw new Error("corrupt object bson")}var le=Object.keys(f).filter(function(e){return e.startsWith("$")}),ce=!0;if(le.forEach(function(e){-1===["$ref","$id","$db"].indexOf(e)&&(ce=!1)}),!ce)return f;if(null==f.$id||null==f.$ref)return f;var Ee=Object.assign({},f);return delete Ee.$ref,delete Ee.$id,delete Ee.$db,new db_ref(f.$ref,f.$id,f.$db||null,Ee)}function isolateEvalWithHash(functionCache,hash,functionString,object){var value=null;return null==functionCache[hash]&&(eval("value = "+functionString),functionCache[hash]=value),functionCache[hash].bind(object)}function isolateEval(functionString){var value=null;return eval("value = "+functionString),value}var deserializer=deserialize$1;function readIEEE754(e,t,n,r,i){var a,s,u="big"===n,o=8*i-r-1,_=(1<>1,c=-7,E=u?0:i-1,h=u?1:-1,A=e[t+E];for(E+=h,a=A&(1<<-c)-1,A>>=-c,c+=o;0>=-c,c+=r;0>1,h=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,A=_?a-1:0,T=_?-1:1,f=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(u=isNaN(t)?1:0,s=c):(s=Math.floor(Math.log(t)/Math.LN2),t*(o=Math.pow(2,-s))<1&&(s--,o*=2),2<=(t+=1<=s+E?h/o:h*Math.pow(2,1-E))*o&&(s++,o/=2),c<=s+E?(u=0,s=c):1<=s+E?(u=(t*o-1)*Math.pow(2,i),s+=E):(u=t*Math.pow(2,E-1)*Math.pow(2,i),s=0)),isNaN(t)&&(u=0);8<=i;)e[n+A]=255&u,A+=T,u/=256,i-=8;for(s=s<>24&255,e[r+2]=s+1>>16&255,e[r+1]=s+1>>8&255,e[r]=s+1&255,r=r+4+s,e[r++]=0,r}function serializeNumber(e,t,n,r,i){if(Math.floor(n)===n&&n>=constants.JS_INT_MIN&&n<=constants.JS_INT_MAX)if(n>=constants.BSON_INT32_MIN&&n<=constants.BSON_INT32_MAX)e[r++]=constants.BSON_DATA_INT,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,e[r++]=255&n,e[r++]=n>>8&255,e[r++]=n>>16&255,e[r++]=n>>24&255;else if(n>=constants.JS_INT_MIN&&n<=constants.JS_INT_MAX){e[r++]=constants.BSON_DATA_NUMBER,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,writeIEEE754$1(e,n,r,"little",52,8),r+=8}else{e[r++]=constants.BSON_DATA_LONG,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0;var a=long_1.fromNumber(n),s=a.getLowBits(),u=a.getHighBits();e[r++]=255&s,e[r++]=s>>8&255,e[r++]=s>>16&255,e[r++]=s>>24&255,e[r++]=255&u,e[r++]=u>>8&255,e[r++]=u>>16&255,e[r++]=u>>24&255}else e[r++]=constants.BSON_DATA_NUMBER,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,writeIEEE754$1(e,n,r,"little",52,8),r+=8;return r}function serializeNull(e,t,n,r,i){return e[r++]=constants.BSON_DATA_NULL,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,r}function serializeBoolean(e,t,n,r,i){return e[r++]=constants.BSON_DATA_BOOLEAN,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,e[r++]=n?1:0,r}function serializeDate(e,t,n,r,i){e[r++]=constants.BSON_DATA_DATE,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0;var a=long_1.fromNumber(n.getTime()),s=a.getLowBits(),u=a.getHighBits();return e[r++]=255&s,e[r++]=s>>8&255,e[r++]=s>>16&255,e[r++]=s>>24&255,e[r++]=255&u,e[r++]=u>>8&255,e[r++]=u>>16&255,e[r++]=u>>24&255,r}function serializeRegExp(e,t,n,r,i){if(e[r++]=constants.BSON_DATA_REGEXP,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,n.source&&null!=n.source.match(regexp$1))throw Error("value "+n.source+" must not contain null bytes");return r+=e.write(n.source,r,"utf8"),e[r++]=0,n.ignoreCase&&(e[r++]=105),n.global&&(e[r++]=115),n.multiline&&(e[r++]=109),e[r++]=0,r}function serializeBSONRegExp(e,t,n,r,i){if(e[r++]=constants.BSON_DATA_REGEXP,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,null!=n.pattern.match(regexp$1))throw Error("pattern "+n.pattern+" must not contain null bytes");return r+=e.write(n.pattern,r,"utf8"),e[r++]=0,r+=e.write(n.options.split("").sort().join(""),r,"utf8"),e[r++]=0,r}function serializeMinMax(e,t,n,r,i){return null===n?e[r++]=constants.BSON_DATA_NULL:"MinKey"===n._bsontype?e[r++]=constants.BSON_DATA_MIN_KEY:e[r++]=constants.BSON_DATA_MAX_KEY,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,r}function serializeObjectId(e,t,n,r,i){if(e[r++]=constants.BSON_DATA_OID,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,"string"==typeof n.id)e.write(n.id,r,"binary");else{if(!n.id||!n.id.copy)throw new TypeError("object ["+JSON.stringify(n)+"] is not a valid ObjectId");n.id.copy(e,r,0,12)}return r+12}function serializeBuffer(e,t,n,r,i){e[r++]=constants.BSON_DATA_BINARY,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0;var a=n.length;return e[r++]=255&a,e[r++]=a>>8&255,e[r++]=a>>16&255,e[r++]=a>>24&255,e[r++]=constants.BSON_BINARY_SUBTYPE_DEFAULT,n.copy(e,r,0,a),r+=a}function serializeObject(e,t,n,r,i,a,s,u,o,_){for(var l=0;l<_.length;l++)if(_[l]===n)throw new Error("cyclic dependency detected");_.push(n),e[r++]=Array.isArray(n)?constants.BSON_DATA_ARRAY:constants.BSON_DATA_OBJECT,r+=o?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0;var c=serializeInto(e,n,i,r,a+1,s,u,_);return _.pop(),c}function serializeDecimal128(e,t,n,r,i){return e[r++]=constants.BSON_DATA_DECIMAL128,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,n.bytes.copy(e,r,0,16),r+16}function serializeLong(e,t,n,r,i){e[r++]="Long"===n._bsontype?constants.BSON_DATA_LONG:constants.BSON_DATA_TIMESTAMP,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0;var a=n.getLowBits(),s=n.getHighBits();return e[r++]=255&a,e[r++]=a>>8&255,e[r++]=a>>16&255,e[r++]=a>>24&255,e[r++]=255&s,e[r++]=s>>8&255,e[r++]=s>>16&255,e[r++]=s>>24&255,r}function serializeInt32(e,t,n,r,i){return e[r++]=constants.BSON_DATA_INT,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,e[r++]=255&n,e[r++]=n>>8&255,e[r++]=n>>16&255,e[r++]=n>>24&255,r}function serializeDouble(e,t,n,r,i){return e[r++]=constants.BSON_DATA_NUMBER,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0,writeIEEE754$1(e,n.value,r,"little",52,8),r+=8}function serializeFunction(e,t,n,r,i,a,s){e[r++]=constants.BSON_DATA_CODE,r+=s?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0;var u=normalizedFunctionString$1(n),o=e.write(u,r+4,"utf8")+1;return e[r]=255&o,e[r+1]=o>>8&255,e[r+2]=o>>16&255,e[r+3]=o>>24&255,r=r+4+o-1,e[r++]=0,r}function serializeCode(e,t,n,r,i,a,s,u,o){if(n.scope&&"object"===_typeof$3(n.scope)){e[r++]=constants.BSON_DATA_CODE_W_SCOPE,r+=o?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0;var _=r,l="string"==typeof n.code?n.code:n.code.toString();r+=4;var c=e.write(l,r+4,"utf8")+1;e[r]=255&c,e[r+1]=c>>8&255,e[r+2]=c>>16&255,e[r+3]=c>>24&255,e[r+4+c-1]=0,r=r+c+4;var E=serializeInto(e,n.scope,i,r,a+1,s,u);r=E-1;var h=E-_;e[_++]=255&h,e[_++]=h>>8&255,e[_++]=h>>16&255,e[_++]=h>>24&255,e[r++]=0}else{e[r++]=constants.BSON_DATA_CODE,r+=o?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0;var A=n.code.toString(),T=e.write(A,r+4,"utf8")+1;e[r]=255&T,e[r+1]=T>>8&255,e[r+2]=T>>16&255,e[r+3]=T>>24&255,r=r+4+T-1,e[r++]=0}return r}function serializeBinary(e,t,n,r,i){e[r++]=constants.BSON_DATA_BINARY,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0;var a=n.value(!0),s=n.position;return n.sub_type===binary.SUBTYPE_BYTE_ARRAY&&(s+=4),e[r++]=255&s,e[r++]=s>>8&255,e[r++]=s>>16&255,e[r++]=s>>24&255,e[r++]=n.sub_type,n.sub_type===binary.SUBTYPE_BYTE_ARRAY&&(s-=4,e[r++]=255&s,e[r++]=s>>8&255,e[r++]=s>>16&255,e[r++]=s>>24&255),a.copy(e,r,0,n.position),r+=n.position}function serializeSymbol(e,t,n,r,i){e[r++]=constants.BSON_DATA_SYMBOL,r+=i?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0;var a=e.write(n.value,r+4,"utf8")+1;return e[r]=255&a,e[r+1]=a>>8&255,e[r+2]=a>>16&255,e[r+3]=a>>24&255,r=r+4+a-1,e[r++]=0,r}function serializeDBRef(e,t,n,r,i,a,s){e[r++]=constants.BSON_DATA_OBJECT,r+=s?e.write(t,r,"ascii"):e.write(t,r,"utf8"),e[r++]=0;var u,o=r,_={$ref:n.collection||n.namespace,$id:n.oid};null!=n.db&&(_.$db=n.db);var l=(u=serializeInto(e,_=Object.assign(_,n.fields),!1,r,i+1,a))-o;return e[o++]=255&l,e[o++]=l>>8&255,e[o++]=l>>16&255,e[o++]=l>>24&255,u}function serializeInto(e,t,n,r,i,a,s,u){r=r||0,(u=u||[]).push(t);var o=r+4;if(Array.isArray(t))for(var _=0;_>8&255,e[r++]=R>>16&255,e[r++]=R>>24&255,o}var serializer=serializeInto;function _typeof$4(e){return(_typeof$4="function"==typeof Symbol&&"symbol"===_typeof(Symbol.iterator)?function(e){return _typeof(e)}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":_typeof(e)})(e)}var Buffer$6=buffer.Buffer,normalizedFunctionString$2=utils.normalizedFunctionString;function isDate$2(e){return"object"===_typeof$4(e)&&"[object Date]"===Object.prototype.toString.call(e)}function calculateObjectSize(e,t,n){var r=5;if(Array.isArray(e))for(var i=0;i=constants.JS_INT_MIN&&t<=constants.JS_INT_MAX&&t>=constants.BSON_INT32_MIN&&t<=constants.BSON_INT32_MAX?(null!=e?Buffer$6.byteLength(e,"utf8")+1:0)+5:(null!=e?Buffer$6.byteLength(e,"utf8")+1:0)+9;case"undefined":return r||!i?(null!=e?Buffer$6.byteLength(e,"utf8")+1:0)+1:0;case"boolean":return(null!=e?Buffer$6.byteLength(e,"utf8")+1:0)+2;case"object":if(null==t||"MinKey"===t._bsontype||"MaxKey"===t._bsontype)return(null!=e?Buffer$6.byteLength(e,"utf8")+1:0)+1;if("ObjectId"===t._bsontype||"ObjectID"===t._bsontype)return(null!=e?Buffer$6.byteLength(e,"utf8")+1:0)+13;if(t instanceof Date||isDate$2(t))return(null!=e?Buffer$6.byteLength(e,"utf8")+1:0)+9;if(void 0!==Buffer$6&&Buffer$6.isBuffer(t))return(null!=e?Buffer$6.byteLength(e,"utf8")+1:0)+6+t.length;if("Long"===t._bsontype||"Double"===t._bsontype||"Timestamp"===t._bsontype)return(null!=e?Buffer$6.byteLength(e,"utf8")+1:0)+9;if("Decimal128"===t._bsontype)return(null!=e?Buffer$6.byteLength(e,"utf8")+1:0)+17;if("Code"===t._bsontype)return null!=t.scope&&0>16&255,s[u++]=t>>8&255,s[u++]=255&t;2===a&&(t=_[e.charCodeAt(n)]<<2|_[e.charCodeAt(n+1)]>>4,s[u++]=255&t);1===a&&(t=_[e.charCodeAt(n)]<<10|_[e.charCodeAt(n+1)]<<4|_[e.charCodeAt(n+2)]>>2,s[u++]=t>>8&255,s[u++]=255&t);return s},t.fromByteArray=function(e){for(var t,n=e.length,r=n%3,i=[],a=0,s=n-r;a>2]+u[t<<4&63]+"==")):2==r&&(t=(e[n-2]<<8)+e[n-1],i.push(u[t>>10]+u[t>>4&63]+u[t<<2&63]+"="));return i.join("")};for(var u=[],_=[],l="undefined"!=typeof Uint8Array?Uint8Array:Array,r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i=0,a=r.length;i>18&63]+u[i>>12&63]+u[i>>6&63]+u[63&i]);return a.join("")}_["-".charCodeAt(0)]=62,_["_".charCodeAt(0)]=63},function(e,t){t.read=function(e,t,n,r,i){var a,s,u=8*i-r-1,o=(1<>1,l=-7,c=n?i-1:0,E=n?-1:1,h=e[t+c];for(c+=E,a=h&(1<<-l)-1,h>>=-l,l+=u;0>=-l,l+=r;0>1,E=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,h=r?0:a-1,A=r?1:-1,T=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(u=isNaN(t)?1:0,s=l):(s=Math.floor(Math.log(t)/Math.LN2),t*(o=Math.pow(2,-s))<1&&(s--,o*=2),2<=(t+=1<=s+c?E/o:E*Math.pow(2,1-c))*o&&(s++,o/=2),l<=s+c?(u=0,s=l):1<=s+c?(u=(t*o-1)*Math.pow(2,i),s+=c):(u=t*Math.pow(2,c-1)*Math.pow(2,i),s=0));8<=i;e[n+h]=255&u,h+=A,u/=256,i-=8);for(s=s<>>=0)&&e<256)&&(r=s[e])?r:(n=f(e,(0|e)<0?-1:0,!0),i&&(s[e]=n),n):(i=-128<=(e|=0)&&e<128)&&(r=a[e])?r:(n=f(e,e<0?-1:0,!1),i&&(a[e]=n),n)}function T(e,t){if(isNaN(e))return t?_:P;if(t){if(e<0)return _;if(u<=e)return g}else{if(e<=-o)return C;if(o<=e+1)return R}return e<0?T(-e,t).neg():f(e%i|0,e/i|0,t)}function f(e,t,n){return new r(e,t,n)}r.fromInt=n,r.fromNumber=T,r.fromBits=f;var l=Math.pow;function c(e,t,n){if(0===e.length)throw Error("empty string");if("NaN"===e||"Infinity"===e||"+Infinity"===e||"-Infinity"===e)return P;if(t="number"==typeof t?(n=t,!1):!!t,(n=n||10)<2||36>>0:this.low},O.toNumber=function(){return this.unsigned?(this.high>>>0)*i+(this.low>>>0):this.high*i+(this.low>>>0)},O.toString=function(e){if((e=e||10)<2||36>>0).toString(e);if((a=u).isZero())return o+s;for(;o.length<6;)o="0"+o;s=""+o+s}},O.getHighBits=function(){return this.high},O.getHighBitsUnsigned=function(){return this.high>>>0},O.getLowBits=function(){return this.low},O.getLowBitsUnsigned=function(){return this.low>>>0},O.getNumBitsAbs=function(){if(this.isNegative())return this.eq(C)?64:this.neg().getNumBitsAbs();for(var e=0!=this.high?this.high:this.low,t=31;0>>31!=1||e.high>>>31!=1)&&(this.high===e.high&&this.low===e.low)},O.eq=O.equals,O.notEquals=function(e){return!this.eq(e)},O.neq=O.notEquals,O.ne=O.notEquals,O.lessThan=function(e){return this.comp(e)<0},O.lt=O.lessThan,O.lessThanOrEqual=function(e){return this.comp(e)<=0},O.lte=O.lessThanOrEqual,O.le=O.lessThanOrEqual,O.greaterThan=function(e){return 0>>0>this.high>>>0||e.high===this.high&&e.low>>>0>this.low>>>0?-1:1:this.sub(e).isNegative()?-1:1},O.comp=O.compare,O.negate=function(){return!this.unsigned&&this.eq(C)?C:this.not().add(E)},O.neg=O.negate,O.add=function(e){A(e)||(e=S(e));var t=this.high>>>16,n=65535&this.high,r=this.low>>>16,i=65535&this.low,a=e.high>>>16,s=65535&e.high,u=e.low>>>16,o=0,_=0,l=0,c=0;return l+=(c+=i+(65535&e.low))>>>16,_+=(l+=r+u)>>>16,o+=(_+=n+s)>>>16,o+=t+a,f((l&=65535)<<16|(c&=65535),(o&=65535)<<16|(_&=65535),this.unsigned)},O.subtract=function(e){return A(e)||(e=S(e)),this.add(e.neg())},O.sub=O.subtract,O.multiply=function(e){if(this.isZero())return P;if(A(e)||(e=S(e)),h)return f(h.mul(this.low,this.high,e.low,e.high),h.get_high(),this.unsigned);if(e.isZero())return P;if(this.eq(C))return e.isOdd()?C:P;if(e.eq(C))return this.isOdd()?C:P;if(this.isNegative())return e.isNegative()?this.neg().mul(e.neg()):this.neg().mul(e).neg();if(e.isNegative())return this.mul(e.neg()).neg();if(this.lt(y)&&e.lt(y))return T(this.toNumber()*e.toNumber(),this.unsigned);var t=this.high>>>16,n=65535&this.high,r=this.low>>>16,i=65535&this.low,a=e.high>>>16,s=65535&e.high,u=e.low>>>16,o=65535&e.low,_=0,l=0,c=0,E=0;return c+=(E+=i*o)>>>16,l+=(c+=r*o)>>>16,c&=65535,l+=(c+=i*u)>>>16,_+=(l+=n*o)>>>16,l&=65535,_+=(l+=r*u)>>>16,l&=65535,_+=(l+=i*s)>>>16,_+=t*o+n*u+r*s+i*a,f((c&=65535)<<16|(E&=65535),(_&=65535)<<16|(l&=65535),this.unsigned)},O.mul=O.multiply,O.divide=function(e){if(A(e)||(e=S(e)),e.isZero())throw Error("division by zero");var t,n,r;if(h)return this.unsigned||-2147483648!==this.high||-1!==e.low||-1!==e.high?f((this.unsigned?h.div_u:h.div_s)(this.low,this.high,e.low,e.high),h.get_high(),this.unsigned):this;if(this.isZero())return this.unsigned?_:P;if(this.unsigned){if(e.unsigned||(e=e.toUnsigned()),e.gt(this))return _;if(e.gt(this.shru(1)))return I;r=_}else{if(this.eq(C))return e.eq(E)||e.eq(p)?C:e.eq(C)?E:(t=this.shr(1).div(e).shl(1)).eq(P)?e.isNegative()?E:p:(n=this.sub(e.mul(t)),r=t.add(n.div(e)));else if(e.eq(C))return this.unsigned?_:P;if(this.isNegative())return e.isNegative()?this.neg().div(e.neg()):this.neg().div(e).neg();if(e.isNegative())return this.div(e.neg()).neg();r=P}for(n=this;n.gte(e);){t=Math.max(1,Math.floor(n.toNumber()/e.toNumber()));for(var i=Math.ceil(Math.log(t)/Math.LN2),a=i<=48?1:l(2,i-48),s=T(t),u=s.mul(e);u.isNegative()||u.gt(n);)u=(s=T(t-=a,this.unsigned)).mul(e);s.isZero()&&(s=E),r=r.add(s),n=n.sub(u)}return r},O.div=O.divide,O.modulo=function(e){return A(e)||(e=S(e)),h?f((this.unsigned?h.rem_u:h.rem_s)(this.low,this.high,e.low,e.high),h.get_high(),this.unsigned):this.sub(this.div(e).mul(e))},O.mod=O.modulo,O.rem=O.modulo,O.not=function(){return f(~this.low,~this.high,this.unsigned)},O.and=function(e){return A(e)||(e=S(e)),f(this.low&e.low,this.high&e.high,this.unsigned)},O.or=function(e){return A(e)||(e=S(e)),f(this.low|e.low,this.high|e.high,this.unsigned)},O.xor=function(e){return A(e)||(e=S(e)),f(this.low^e.low,this.high^e.high,this.unsigned)},O.shiftLeft=function(e){return A(e)&&(e=e.toInt()),0==(e&=63)?this:e<32?f(this.low<>>32-e,this.unsigned):f(0,this.low<>>e|this.high<<32-e,this.high>>e,this.unsigned):f(this.high>>e-32,0<=this.high?0:-1,this.unsigned)},O.shr=O.shiftRight,O.shiftRightUnsigned=function(e){if(A(e)&&(e=e.toInt()),0===(e&=63))return this;var t=this.high;return e<32?f(this.low>>>e|t<<32-e,t>>>e,this.unsigned):f(32===e?t:t>>>e-32,0,this.unsigned)},O.shru=O.shiftRightUnsigned,O.shr_u=O.shiftRightUnsigned,O.toSigned=function(){return this.unsigned?f(this.low,this.high,!1):this},O.toUnsigned=function(){return this.unsigned?this:f(this.low,this.high,!0)},O.toBytes=function(e){return e?this.toBytesLE():this.toBytesBE()},O.toBytesLE=function(){var e=this.high,t=this.low;return[255&t,t>>>8&255,t>>>16&255,t>>>24,255&e,e>>>8&255,e>>>16&255,e>>>24]},O.toBytesBE=function(){var e=this.high,t=this.low;return[e>>>24,e>>>16&255,e>>>8&255,255&e,t>>>24,t>>>16&255,t>>>8&255,255&t]},r.fromBytes=function(e,t,n){return n?r.fromBytesLE(e,t):r.fromBytesBE(e,t)},r.fromBytesLE=function(e,t){return new r(e[0]|e[1]<<8|e[2]<<16|e[3]<<24,e[4]|e[5]<<8|e[6]<<16|e[7]<<24,t)},r.fromBytesBE=function(e,t){return new r(e[4]<<24|e[5]<<16|e[6]<<8|e[7],e[0]<<24|e[1]<<16|e[2]<<8|e[3],t)}}],jk={},kk.m=ik,kk.c=jk,kk.d=function(e,t,n){kk.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:n})},kk.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return kk.d(t,"a",t),t},kk.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},kk.p="",kk(kk.s=2))}),BSON=unwrapExports(bson_common),bson=BSON.bson,Bson=function(){function e(){_classCallCheck(this,e)}return _createClass(e,null,[{key:"serialize",value:function(e){return bson.serialize(e)}},{key:"deserialize",value:function(e){return bson.deserialize(e)}}]),e}(),SdlPacket=function(){function c(){var e=0>24,_[l++]=(16711680&s)>>16,_[l++]=(65280&s)>>8,_[l++]=255&s,1>24,_[l++]=(16711680&u)>>16,_[l++]=(65280&u)>>8,_[l++]=255&u),null!==o&&0>16&255,a[u++]=r>>8&255,a[u++]=255&r;return 2==i?(r=revLookup[e.charCodeAt(t)]<<2|revLookup[e.charCodeAt(t+1)]>>4,a[u++]=255&r):1==i&&(r=revLookup[e.charCodeAt(t)]<<10|revLookup[e.charCodeAt(t+1)]<<4|revLookup[e.charCodeAt(t+2)]>>2,a[u++]=r>>8&255,a[u++]=255&r),a}function tripletToBase64(e){return lookup[e>>18&63]+lookup[e>>12&63]+lookup[e>>6&63]+lookup[63&e]}function encodeChunk(e,t,n){for(var r,i=[],a=t;a>2],i+=lookup[t<<4&63],i+="=="):2==r&&(t=(e[n-2]<<8)+e[n-1],i+=lookup[t>>10],i+=lookup[t>>4&63],i+=lookup[t<<2&63],i+="="),a.push(i),a.join("")}function read(e,t,n,r,i){var a,s,u=8*i-r-1,o=(1<>1,l=-7,c=n?i-1:0,E=n?-1:1,h=e[t+c];for(c+=E,a=h&(1<<-l)-1,h>>=-l,l+=u;0>=-l,l+=r;0>1,E=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,h=r?0:a-1,A=r?1:-1,T=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(u=isNaN(t)?1:0,s=l):(s=Math.floor(Math.log(t)/Math.LN2),t*(o=Math.pow(2,-s))<1&&(s--,o*=2),2<=(t+=1<=s+c?E/o:E*Math.pow(2,1-c))*o&&(s++,o/=2),l<=s+c?(u=0,s=l):1<=s+c?(u=(t*o-1)*Math.pow(2,i),s+=c):(u=t*Math.pow(2,c-1)*Math.pow(2,i),s=0));8<=i;e[n+h]=255&u,h+=A,u/=256,i-=8);for(s=s<=kMaxLength())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+kMaxLength().toString(16)+" bytes");return 0|e}function internalIsBuffer(e){return!(null==e||!e._isBuffer)}function byteLength(e,t){if(internalIsBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return utf8ToBytes(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return base64ToBytes(e).length;default:if(r)return utf8ToBytes(e).length;t=(""+t).toLowerCase(),r=!0}}function slowToString(e,t,n){var r=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e=e||"utf8";;)switch(e){case"hex":return hexSlice(this,t,n);case"utf8":case"utf-8":return utf8Slice(this,t,n);case"ascii":return asciiSlice(this,t,n);case"latin1":case"binary":return latin1Slice(this,t,n);case"base64":return base64Slice(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return utf16leSlice(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function swap(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function bidirectionalIndexOf(e,t,n,r,i){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):2147483647=e.length){if(i)return-1;n=e.length-1}else if(n<0){if(!i)return-1;n=0}if("string"==typeof t&&(t=Buffer.from(t,r)),internalIsBuffer(t))return 0===t.length?-1:arrayIndexOf(e,t,n,r,i);if("number"==typeof t)return t&=255,Buffer.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):arrayIndexOf(e,[t],n,r,i);throw new TypeError("val must be string, number or Buffer")}function arrayIndexOf(e,t,n,r,i){var a,s=1,u=e.length,o=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;u/=s=2,o/=2,n/=2}function _(e,t){return 1===s?e[t]:e.readUInt16BE(t*s)}if(i){var l=-1;for(a=n;a>>10&1023|55296),l=56320|1023&l),r.push(l),i+=c}return decodeCodePointsArray(r)}Buffer.TYPED_ARRAY_SUPPORT=void 0===global$1.TYPED_ARRAY_SUPPORT||global$1.TYPED_ARRAY_SUPPORT,Buffer.poolSize=8192,Buffer._augment=function(e){return e.__proto__=Buffer.prototype,e},Buffer.from=function(e,t,n){return from(null,e,t,n)},Buffer.TYPED_ARRAY_SUPPORT&&(Buffer.prototype.__proto__=Uint8Array.prototype,Buffer.__proto__=Uint8Array),Buffer.alloc=function(e,t,n){return alloc(null,e,t,n)},Buffer.allocUnsafe=function(e){return allocUnsafe(null,e)},Buffer.allocUnsafeSlow=function(e){return allocUnsafe(null,e)},Buffer.isBuffer=isBuffer,Buffer.compare=function(e,t){if(!internalIsBuffer(e)||!internalIsBuffer(t))throw new TypeError("Arguments must be Buffers");if(e===t)return 0;for(var n=e.length,r=t.length,i=0,a=Math.min(n,r);it&&(e+=" ... ")),""},Buffer.prototype.compare=function(e,t,n,r,i){if(!internalIsBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===i&&(i=this.length),t<0||n>e.length||r<0||i>this.length)throw new RangeError("out of range index");if(i<=r&&n<=t)return 0;if(i<=r)return-1;if(n<=t)return 1;if(this===e)return 0;for(var a=(i>>>=0)-(r>>>=0),s=(n>>>=0)-(t>>>=0),u=Math.min(a,s),o=this.slice(r,i),_=e.slice(t,n),l=0;lthis.length)throw new RangeError("Attempt to write outside buffer bounds");r=r||"utf8";for(var a=!1;;)switch(r){case"hex":return hexWrite(this,e,t,n);case"utf8":case"utf-8":return utf8Write(this,e,t,n);case"ascii":return asciiWrite(this,e,t,n);case"latin1":case"binary":return latin1Write(this,e,t,n);case"base64":return base64Write(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return ucs2Write(this,e,t,n);default:if(a)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),a=!0}},Buffer.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var MAX_ARGUMENTS_LENGTH=4096;function decodeCodePointsArray(e){var t=e.length;if(t<=MAX_ARGUMENTS_LENGTH)return String.fromCharCode.apply(String,e);for(var n="",r=0;re.length)throw new RangeError("Index out of range")}function objectWriteUInt16(e,t,n,r){t<0&&(t=65535+t+1);for(var i=0,a=Math.min(e.length-n,2);i>>8*(r?i:1-i)}function objectWriteUInt32(e,t,n,r){t<0&&(t=4294967295+t+1);for(var i=0,a=Math.min(e.length-n,4);i>>8*(r?i:3-i)&255}function checkIEEE754(e,t,n,r,i,a){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function writeFloat(e,t,n,r,i){return i||checkIEEE754(e,t,n,4),write(e,t,n,r,23,4),n+4}function writeDouble(e,t,n,r,i){return i||checkIEEE754(e,t,n,8),write(e,t,n,r,52,8),n+8}Buffer.prototype.slice=function(e,t){var n,r=this.length;if((e=~~e)<0?(e+=r)<0&&(e=0):r>>8):objectWriteUInt16(this,e,t,!0),t+2},Buffer.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||checkInt(this,e,t,2,65535,0),Buffer.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):objectWriteUInt16(this,e,t,!1),t+2},Buffer.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||checkInt(this,e,t,4,4294967295,0),Buffer.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):objectWriteUInt32(this,e,t,!0),t+4},Buffer.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||checkInt(this,e,t,4,4294967295,0),Buffer.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):objectWriteUInt32(this,e,t,!1),t+4},Buffer.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var i=Math.pow(2,8*n-1);checkInt(this,e,t,n,i-1,-i)}var a=0,s=1,u=0;for(this[t]=255&e;++a>0)-u&255;return t+n},Buffer.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var i=Math.pow(2,8*n-1);checkInt(this,e,t,n,i-1,-i)}var a=n-1,s=1,u=0;for(this[t+a]=255&e;0<=--a&&(s*=256);)e<0&&0===u&&0!==this[t+a+1]&&(u=1),this[t+a]=(e/s>>0)-u&255;return t+n},Buffer.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||checkInt(this,e,t,1,127,-128),Buffer.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},Buffer.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||checkInt(this,e,t,2,32767,-32768),Buffer.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):objectWriteUInt16(this,e,t,!0),t+2},Buffer.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||checkInt(this,e,t,2,32767,-32768),Buffer.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):objectWriteUInt16(this,e,t,!1),t+2},Buffer.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||checkInt(this,e,t,4,2147483647,-2147483648),Buffer.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):objectWriteUInt32(this,e,t,!0),t+4},Buffer.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||checkInt(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),Buffer.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):objectWriteUInt32(this,e,t,!1),t+4},Buffer.prototype.writeFloatLE=function(e,t,n){return writeFloat(this,e,t,!0,n)},Buffer.prototype.writeFloatBE=function(e,t,n){return writeFloat(this,e,t,!1,n)},Buffer.prototype.writeDoubleLE=function(e,t,n){return writeDouble(this,e,t,!0,n)},Buffer.prototype.writeDoubleBE=function(e,t,n){return writeDouble(this,e,t,!1,n)},Buffer.prototype.copy=function(e,t,n,r){if(n=n||0,r||0===r||(r=this.length),t>=e.length&&(t=e.length),t=t||0,0=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t>>=0,n=void 0===n?this.length:n>>>0,"number"==typeof(e=e||0))for(a=t;a>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;a.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;a.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return a}function asciiToBytes(e){for(var t=[],n=0;n>8,i=n%256,a.push(i),a.push(r);return a}function base64ToBytes(e){return toByteArray(base64clean(e))}function blitBuffer(e,t,n,r){for(var i=0;i=t.length||i>=e.length);++i)t[i+n]=e[i];return i}function isnan(e){return e!=e}function isBuffer(e){return null!=e&&(!!e._isBuffer||isFastBuffer(e)||isSlowBuffer(e))}function isFastBuffer(e){return!!e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function isSlowBuffer(e){return"function"==typeof e.readFloatLE&&"function"==typeof e.slice&&isFastBuffer(e.slice(0,0))}var TextEncoder=function(){function e(){_classCallCheck(this,e)}return _createClass(e,null,[{key:"encode",value:function(e){for(var t=e.length,n=-1,r=[],i=0,a=0,s=0;s!==t;){if(i=e.charCodeAt(s),s+=1,55296<=i&&i<=56319){if(s===t){r[n+=1]=239,r[n+=1]=191,r[n+=1]=189;break}if(!(56320<=(a=e.charCodeAt(s))&&a<=57343)){r[n+=1]=239,r[n+=1]=191,r[n+=1]=189;continue}if(s+=1,65535<(i=1024*(i-55296)+a-56320+65536)){r[n+=1]=240|i>>>18,r[n+=1]=128|i>>>12&63,r[n+=1]=128|i>>>6&63,r[n+=1]=128|63&i;continue}}i<=127?r[n+=1]=0|i:(i<=2047?r[n+=1]=192|i>>>6:(r[n+=1]=224|i>>>12,r[n+=1]=128|i>>>6&63),r[n+=1]=128|63&i)}return r.length=n+1,r}}]),e}(),JsonRpcMarshaller=function(){function e(){_classCallCheck(this,e)}return _createClass(e,null,[{key:"marshall",value:function(e){var t=null;try{var n=function e(t){var n=t.getParameters();for(var r in n)n[r]instanceof RpcStruct&&(n[r]=e(n[r]));return n}(e),r=JSON.stringify(n);t=this._encode(r)}catch(e){console.error("Failed to encode messages to JSON.",e)}return t}},{key:"unmarshall",value:function(e){var t=null;try{var n=this._decode(e);t=JSON.parse(n)}catch(e){console.error("Failed to parse JSON",e)}return t}},{key:"_encode",value:function(e){return new Uint8Array(TextEncoder.encode(e))}},{key:"_decode",value:function(e){return Buffer.from(e).toString()}}]),e}(),BinaryFrameHeader=function(){function _(e,t,n,r){_classCallCheck(this,_),this._rpcType=e,this._functionId=t,this._correlationId=n,this._jsonSize=r,this._bulkData=null,this._jsonData=null}return _createClass(_,[{key:"assembleHeaderBytes",value:function(){var e=[],t=this._functionId,n=this._correlationId;this._rpcType;e.push((251658240&t)>>24),e.push((16711680&t)>>16),e.push((65280&t)>>8),e.push(255&t),e.push((4278190080&n)>>24),e.push((16711680&n)>>16),e.push((65280&n)>>8),e.push(255&n);var r=this._jsonSize;return e.push((4278190080&r)>>24),e.push((16711680&r)>>16),e.push((65280&r)>>8),e.push(255&r),e}},{key:"setRpcType",value:function(e){return this._rpcType=e,this}},{key:"getRpcType",value:function(){return this._rpcType}},{key:"setFunctionId",value:function(e){return this._functionId=e,this}},{key:"getFunctionId",value:function(){return this._functionId}},{key:"setCorrelationId",value:function(e){return this._correlationId=e,this}},{key:"getCorrelationId",value:function(){return this._correlationId}},{key:"setJsonSize",value:function(e){return this._jsonSize=e,this}},{key:"getJsonSize",value:function(){return this._jsonSize}},{key:"getJsonData",value:function(){return this._jsonData}},{key:"setJsonData",value:function(e){return this._jsonData=e,this}},{key:"setBulkData",value:function(e){return this._bulkData=e,this}},{key:"getBulkData",value:function(){return this._bulkData}}],[{key:"fromBinaryHeader",value:function(e){var t=e[0]>>4,n=(15&e[0])<<24;n+=(255&e[1])<<16,n+=(255&e[2])<<8,n+=255&e[3];var r=(255&e[4])<<24;r+=(255&e[5])<<16,r+=(255&e[6])<<8,r+=255&e[7];var i=(255&e[8])<<24;i+=(255&e[9])<<16,i+=(255&e[10])<<8;var a=new _(t,n,r,i+=255&e[11]),s=_.HEADER_SIZE,u=_.HEADER_SIZE+i;if(a.setJsonData(e.slice(s,u)),e.length>u){var o=e.slice(u);a.setBulkData(o)}return a}}]),_}();BinaryFrameHeader.HEADER_SIZE=12;var MessageFrameDisassembler=function(){function o(e,t,n,r,i,a,s){if(_classCallCheck(this,o),this._rpcRequest=e,this._sessionId=t,this._messageId=n,this._isEncrypted=a,!r)throw new Error("MTU must be specified.");if(this._mtu=r,!i)throw new Error("Version must be specified.");this._version=i,this._packetCallback=s}return _createClass(o,[{key:"_buildRPCMainBuffer",value:function(){var e=this._rpcRequest.getBulkData(),t=this._rpcRequest.getCorrelationId(),n=this._rpcRequest.getRPCType(),r=this._rpcRequest.getFunctionName(),i=FunctionID.valueForKey(r);if(!i)throw new Error("Failed to find function ".concat(r));var a=JsonRpcMarshaller.marshall(this._rpcRequest),s=a.length,u=new BinaryFrameHeader(n,i,t);u.setJsonData(a),u.setJsonSize(s),u.setBulkData(e);var o=u.getBulkData(),_=0;o&&(_=o.length);var l=new Uint8Array(12+s+_);return l.set(u.assembleHeaderBytes(),0),l.set(a,12),o&&l.set(o,12+s),l}},{key:"doRequest",value:function(){var e=this._version,t=FrameType.SINGLE,n=SdlPacket.SERVICE_TYPE_RPC,r=this._sessionId,i=this._messageId,a=this._isEncrypted,s=this._buildRPCMainBuffer(),u=this._mtu,o=Math.ceil(s.length/u);if(o<=1){var _=this._constructPacket(e,n,0,r,i,t,s,a);this._packetCallback(_)}else{var l=new ArrayBuffer(8),c=new DataView(l);c.setUint32(0,s.length,!1),c.setUint32(4,o,!1);var E=new Uint8Array(l),h=this._constructPacket(e,n,0,r,i,FrameType.FIRST,E,a);this._packetCallback(h),this._buildConsecutiveFrames(e,n,r,i,s,u,a)}}},{key:"_constructPacket",value:function(e,t,n,r,i,a,s,u){var o=s.length;return new SdlPacket(e,u,a,t,n,r,o,i,s,0,o)}},{key:"_buildConsecutiveFrames",value:function(e,t,n,r,i,a,s){for(var u,o=0,_=0;0!==u;){u=_+a>=i.length?0:o%255+1;var l=this._constructPacket(e,t,u,n,r,FrameType.CONSECUTIVE,i.slice(_,_+a),s);this._packetCallback(l),o++,_+=a}}}],[{key:"buildRPC",value:function(e,t,n,r,i,a,s){var u=new o(e,t,n,r,i,a,s);return u.doRequest(),u}}]),o}(),TransportListener=function(){function e(){_classCallCheck(this,e),this._onTransportConnected=null,this._onTransportDisconnected=null,this._onError=null,this._onPacketReceived=null}return _createClass(e,[{key:"setOnTransportConnected",value:function(e){return this._onTransportConnected=e,this}},{key:"setOnTransportDisconnected",value:function(e){return this._onTransportDisconnected=e,this}},{key:"setOnError",value:function(e){return this._onError=e,this}},{key:"setOnPacketReceived",value:function(e){return this._onPacketReceived=e,this}},{key:"onTransportConnected",value:function(){"function"==typeof this._onTransportConnected&&this._onTransportConnected()}},{key:"onTransportDisconnected",value:function(){"function"==typeof this._onTransportDisconnected&&this._onTransportDisconnected()}},{key:"onError",value:function(e){var t=0e.getMajor())return 1;if(this.getMajor()===e.getMajor()){if(this.getMinor()>e.getMinor())return 1;if(this.getMinor()===e.getMinor()){if(this.getPatch()>e.getPatch())return 1;if(this.getPatch()===e.getPatch())return 0}}return-1}}]),r}(),ServiceType=function(){function t(){return _classCallCheck(this,t),_possibleConstructorReturn(this,_getPrototypeOf(t).call(this))}return _inherits(t,Enum),_createClass(t,null,[{key:"valueForKey",value:function(e){return t._valueForKey(e,t._MAP)}},{key:"keyForValue",value:function(e){return t._keyForValue(e,t._MAP)}},{key:"CONTROL",get:function(){return t._MAP.CONTROL}},{key:"RPC",get:function(){return t._MAP.RPC}},{key:"AUDIO",get:function(){return t._MAP.AUDIO}},{key:"VIDEO",get:function(){return t._MAP.VIDEO}},{key:"HYBRID",get:function(){return t._MAP.HYBRID}}]),t}();ServiceType._MAP=Object.freeze({CONTROL:0,RPC:7,AUDIO:10,VIDEO:11,HYBRID:15});var MessageFrameAssembler=function(){function t(e){if(_classCallCheck(this,t),"function"!=typeof e)throw new Error("Callback not of expected type (function) for MessageFrameAssembler");this._callback=e,this._accumulator=[],this._totalConsecutiveFrames=0,this._consecutiveFramesHandledCount=0,this._consecutiveFramesDataLength=0}return _createClass(t,[{key:"handleFrame",value:function(e){var t=e.getFrameType();return t!==FrameType.FIRST&&t!==FrameType.CONSECUTIVE?this._callback(null,e):this._handleMultiFrameMessage(e)}},{key:"_handleFirstDataFrame",value:function(e){var t=e.getPayload();if(t instanceof Uint8Array!=!0||8!==t.length)throw new Error("Error handling first frame. Payload is an invalid length should be length 8.");for(var n in t)if(n<0||255>4,0===this._version?n.ERROR_STATE:(this._encryption=1==(e&n.ENCRYPTION_MASK)>>3,this._frameType=e&n.FRAME_TYPE_MASK,(this._version<1||5FrameType.CONSECUTIVE?n.ERROR_STATE:n.SERVICE_TYPE_STATE);if(t===n.SERVICE_TYPE_STATE)return this._serviceType=255&e,n.CONTROL_FRAME_INFO_STATE;if(t===n.CONTROL_FRAME_INFO_STATE){switch(this._controlFrameInfo=255&e,this._frameType){case FrameType.CONTROL:break;case FrameType.SINGLE:case FrameType.FIRST:if(0!==this._controlFrameInfo)return n.ERROR_STATE;break;case FrameType.CONSECUTIVE:break;default:return n.ERROR_STATE}return n.SESSION_ID_STATE}if(t===n.SESSION_ID_STATE)return this._sessionID=255&e,n.DATA_SIZE_1_STATE;if(t===n.DATA_SIZE_1_STATE)return this._dataLength+=(255&e)<<24,n.DATA_SIZE_2_STATE;if(t===n.DATA_SIZE_2_STATE)return this._dataLength+=(255&e)<<16,n.DATA_SIZE_3_STATE;if(t===n.DATA_SIZE_3_STATE)return this._dataLength+=(255&e)<<8,n.DATA_SIZE_4_STATE;if(t!==n.DATA_SIZE_4_STATE)return t===n.MESSAGE_1_STATE?(this._messageID+=(255&e)<<24,n.MESSAGE_2_STATE):t===n.MESSAGE_2_STATE?(this._messageID+=(255&e)<<16,n.MESSAGE_3_STATE):t===n.MESSAGE_3_STATE?(this._messageID+=(255&e)<<8,n.MESSAGE_4_STATE):t===n.MESSAGE_4_STATE?(this._messageID+=255&e,0===this._dataLength?n.FINISHED_STATE:(this._dumpSize=this._dataLength,this._payload=new Uint8Array(this._dataLength),n.DATA_PUMP_STATE)):t===n.DATA_PUMP_STATE?(this._payload[this._dataLength-this._dumpSize]=e,this._dumpSize-=1,0mediaClock) + * @return {String} + */ + static get CLEAR () { + return UpdateMode._MAP.CLEAR; + } + + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + static valueForKey (key) { + return UpdateMode._valueForKey(key, UpdateMode._MAP); + } + + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + static keyForValue (value) { + return UpdateMode._keyForValue(value, UpdateMode._MAP); + } +} + +UpdateMode._MAP = Object.freeze({ + 'COUNTUP': 'COUNTUP', + 'COUNTDOWN': 'COUNTDOWN', + 'PAUSE': 'PAUSE', + 'RESUME': 'RESUME', + 'CLEAR': 'CLEAR', +}); + +export { UpdateMode }; \ No newline at end of file diff --git a/lib/js/src/rpc/enums/VehicleDataActiveStatus.js b/lib/js/src/rpc/enums/VehicleDataActiveStatus.js new file mode 100644 index 00000000..be9cf47a --- /dev/null +++ b/lib/js/src/rpc/enums/VehicleDataActiveStatus.js @@ -0,0 +1,111 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { Enum } from '../../util/Enum.js'; + +/** + * Reflects the status of given vehicle component. + * @typedef {Enum} VehicleDataActiveStatus + * @property {Object} _MAP + */ +class VehicleDataActiveStatus extends Enum { + /** + * @constructor + */ + constructor () { + super(); + } + + /** + * @return {String} + */ + static get VDAS_INACTIVE_NOT_CONFIRMED () { + return VehicleDataActiveStatus._MAP.VDAS_INACTIVE_NOT_CONFIRMED; + } + + /** + * @return {String} + */ + static get VDAS_INACTIVE_CONFIRMED () { + return VehicleDataActiveStatus._MAP.VDAS_INACTIVE_CONFIRMED; + } + + /** + * @return {String} + */ + static get VDAS_ACTIVE_NOT_CONFIRMED () { + return VehicleDataActiveStatus._MAP.VDAS_ACTIVE_NOT_CONFIRMED; + } + + /** + * @return {String} + */ + static get VDAS_ACTIVE_CONFIRMED () { + return VehicleDataActiveStatus._MAP.VDAS_ACTIVE_CONFIRMED; + } + + /** + * @return {String} + */ + static get VDAS_FAULT () { + return VehicleDataActiveStatus._MAP.VDAS_FAULT; + } + + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + static valueForKey (key) { + return VehicleDataActiveStatus._valueForKey(key, VehicleDataActiveStatus._MAP); + } + + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + static keyForValue (value) { + return VehicleDataActiveStatus._keyForValue(value, VehicleDataActiveStatus._MAP); + } +} + +VehicleDataActiveStatus._MAP = Object.freeze({ + 'VDAS_INACTIVE_NOT_CONFIRMED': 'INACTIVE_NOT_CONFIRMED', + 'VDAS_INACTIVE_CONFIRMED': 'INACTIVE_CONFIRMED', + 'VDAS_ACTIVE_NOT_CONFIRMED': 'ACTIVE_NOT_CONFIRMED', + 'VDAS_ACTIVE_CONFIRMED': 'ACTIVE_CONFIRMED', + 'VDAS_FAULT': 'FAULT', +}); + +export { VehicleDataActiveStatus }; \ No newline at end of file diff --git a/lib/js/src/rpc/enums/VehicleDataEventStatus.js b/lib/js/src/rpc/enums/VehicleDataEventStatus.js new file mode 100644 index 00000000..0cb39425 --- /dev/null +++ b/lib/js/src/rpc/enums/VehicleDataEventStatus.js @@ -0,0 +1,111 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { Enum } from '../../util/Enum.js'; + +/** + * Reflects the status of a vehicle data event; e.g. a seat belt event status. + * @typedef {Enum} VehicleDataEventStatus + * @property {Object} _MAP + */ +class VehicleDataEventStatus extends Enum { + /** + * @constructor + */ + constructor () { + super(); + } + + /** + * @return {String} + */ + static get VDES_NO_EVENT () { + return VehicleDataEventStatus._MAP.VDES_NO_EVENT; + } + + /** + * @return {String} + */ + static get VDES_NO () { + return VehicleDataEventStatus._MAP.VDES_NO; + } + + /** + * @return {String} + */ + static get VDES_YES () { + return VehicleDataEventStatus._MAP.VDES_YES; + } + + /** + * @return {String} + */ + static get VDES_NOT_SUPPORTED () { + return VehicleDataEventStatus._MAP.VDES_NOT_SUPPORTED; + } + + /** + * @return {String} + */ + static get VDES_FAULT () { + return VehicleDataEventStatus._MAP.VDES_FAULT; + } + + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + static valueForKey (key) { + return VehicleDataEventStatus._valueForKey(key, VehicleDataEventStatus._MAP); + } + + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + static keyForValue (value) { + return VehicleDataEventStatus._keyForValue(value, VehicleDataEventStatus._MAP); + } +} + +VehicleDataEventStatus._MAP = Object.freeze({ + 'VDES_NO_EVENT': 'NO_EVENT', + 'VDES_NO': 'NO', + 'VDES_YES': 'YES', + 'VDES_NOT_SUPPORTED': 'NOT_SUPPORTED', + 'VDES_FAULT': 'FAULT', +}); + +export { VehicleDataEventStatus }; \ No newline at end of file diff --git a/lib/js/src/rpc/enums/VehicleDataNotificationStatus.js b/lib/js/src/rpc/enums/VehicleDataNotificationStatus.js new file mode 100644 index 00000000..fa5f1eee --- /dev/null +++ b/lib/js/src/rpc/enums/VehicleDataNotificationStatus.js @@ -0,0 +1,103 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { Enum } from '../../util/Enum.js'; + +/** + * Reflects the status of a vehicle data notification. + * @typedef {Enum} VehicleDataNotificationStatus + * @property {Object} _MAP + */ +class VehicleDataNotificationStatus extends Enum { + /** + * @constructor + */ + constructor () { + super(); + } + + /** + * @return {String} + */ + static get VDNS_NOT_SUPPORTED () { + return VehicleDataNotificationStatus._MAP.VDNS_NOT_SUPPORTED; + } + + /** + * @return {String} + */ + static get VDNS_NORMAL () { + return VehicleDataNotificationStatus._MAP.VDNS_NORMAL; + } + + /** + * @return {String} + */ + static get VDNS_ACTIVE () { + return VehicleDataNotificationStatus._MAP.VDNS_ACTIVE; + } + + /** + * @return {String} + */ + static get VDNS_NOT_USED () { + return VehicleDataNotificationStatus._MAP.VDNS_NOT_USED; + } + + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + static valueForKey (key) { + return VehicleDataNotificationStatus._valueForKey(key, VehicleDataNotificationStatus._MAP); + } + + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + static keyForValue (value) { + return VehicleDataNotificationStatus._keyForValue(value, VehicleDataNotificationStatus._MAP); + } +} + +VehicleDataNotificationStatus._MAP = Object.freeze({ + 'VDNS_NOT_SUPPORTED': 'NOT_SUPPORTED', + 'VDNS_NORMAL': 'NORMAL', + 'VDNS_ACTIVE': 'ACTIVE', + 'VDNS_NOT_USED': 'NOT_USED', +}); + +export { VehicleDataNotificationStatus }; \ No newline at end of file diff --git a/lib/js/src/rpc/enums/VehicleDataResultCode.js b/lib/js/src/rpc/enums/VehicleDataResultCode.js new file mode 100644 index 00000000..3b5e6bb5 --- /dev/null +++ b/lib/js/src/rpc/enums/VehicleDataResultCode.js @@ -0,0 +1,152 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { Enum } from '../../util/Enum.js'; + +/** + * Enumeration that describes possible result codes of a vehicle data entry request. + * @typedef {Enum} VehicleDataResultCode + * @property {Object} _MAP + */ +class VehicleDataResultCode extends Enum { + /** + * @constructor + */ + constructor () { + super(); + } + + /** + * Individual vehicle data item / DTC / DID request or subscription successful + * @return {String} + */ + static get VDRC_SUCCESS () { + return VehicleDataResultCode._MAP.VDRC_SUCCESS; + } + + /** + * DTC / DID request successful, however, not all active DTCs or full contents of DID location available + * @return {String} + */ + static get VDRC_TRUNCATED_DATA () { + return VehicleDataResultCode._MAP.VDRC_TRUNCATED_DATA; + } + + /** + * This vehicle data item is not allowed for this app by the OEM/Manufactorer of the connected module. + * @return {String} + */ + static get VDRC_DISALLOWED () { + return VehicleDataResultCode._MAP.VDRC_DISALLOWED; + } + + /** + * The user has not granted access to this type of vehicle data item at this time. + * @return {String} + */ + static get VDRC_USER_DISALLOWED () { + return VehicleDataResultCode._MAP.VDRC_USER_DISALLOWED; + } + + /** + * The ECU ID referenced is not a valid ID on the bus / system. + * @return {String} + */ + static get VDRC_INVALID_ID () { + return VehicleDataResultCode._MAP.VDRC_INVALID_ID; + } + + /** + * The requested vehicle data item / DTC / DID is not currently available or responding on the bus / system. + * @return {String} + */ + static get VDRC_DATA_NOT_AVAILABLE () { + return VehicleDataResultCode._MAP.VDRC_DATA_NOT_AVAILABLE; + } + + /** + * The vehicle data item is already subscribed. + * @return {String} + */ + static get VDRC_DATA_ALREADY_SUBSCRIBED () { + return VehicleDataResultCode._MAP.VDRC_DATA_ALREADY_SUBSCRIBED; + } + + /** + * The vehicle data item cannot be unsubscribed because it is not currently subscribed. + * @return {String} + */ + static get VDRC_DATA_NOT_SUBSCRIBED () { + return VehicleDataResultCode._MAP.VDRC_DATA_NOT_SUBSCRIBED; + } + + /** + * The request for this item is ignored because it is already in progress. + * @return {String} + */ + static get VDRC_IGNORED () { + return VehicleDataResultCode._MAP.VDRC_IGNORED; + } + + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + static valueForKey (key) { + return VehicleDataResultCode._valueForKey(key, VehicleDataResultCode._MAP); + } + + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + static keyForValue (value) { + return VehicleDataResultCode._keyForValue(value, VehicleDataResultCode._MAP); + } +} + +VehicleDataResultCode._MAP = Object.freeze({ + 'VDRC_SUCCESS': 'SUCCESS', + 'VDRC_TRUNCATED_DATA': 'TRUNCATED_DATA', + 'VDRC_DISALLOWED': 'DISALLOWED', + 'VDRC_USER_DISALLOWED': 'USER_DISALLOWED', + 'VDRC_INVALID_ID': 'INVALID_ID', + 'VDRC_DATA_NOT_AVAILABLE': 'VEHICLE_DATA_NOT_AVAILABLE', + 'VDRC_DATA_ALREADY_SUBSCRIBED': 'DATA_ALREADY_SUBSCRIBED', + 'VDRC_DATA_NOT_SUBSCRIBED': 'DATA_NOT_SUBSCRIBED', + 'VDRC_IGNORED': 'IGNORED', +}); + +export { VehicleDataResultCode }; \ No newline at end of file diff --git a/lib/js/src/rpc/enums/VehicleDataStatus.js b/lib/js/src/rpc/enums/VehicleDataStatus.js new file mode 100644 index 00000000..54733f79 --- /dev/null +++ b/lib/js/src/rpc/enums/VehicleDataStatus.js @@ -0,0 +1,95 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { Enum } from '../../util/Enum.js'; + +/** + * Reflects the status of a binary vehicle data item. + * @typedef {Enum} VehicleDataStatus + * @property {Object} _MAP + */ +class VehicleDataStatus extends Enum { + /** + * @constructor + */ + constructor () { + super(); + } + + /** + * @return {String} + */ + static get VDS_NO_DATA_EXISTS () { + return VehicleDataStatus._MAP.VDS_NO_DATA_EXISTS; + } + + /** + * @return {String} + */ + static get VDS_OFF () { + return VehicleDataStatus._MAP.VDS_OFF; + } + + /** + * @return {String} + */ + static get VDS_ON () { + return VehicleDataStatus._MAP.VDS_ON; + } + + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + static valueForKey (key) { + return VehicleDataStatus._valueForKey(key, VehicleDataStatus._MAP); + } + + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + static keyForValue (value) { + return VehicleDataStatus._keyForValue(value, VehicleDataStatus._MAP); + } +} + +VehicleDataStatus._MAP = Object.freeze({ + 'VDS_NO_DATA_EXISTS': 'NO_DATA_EXISTS', + 'VDS_OFF': 'OFF', + 'VDS_ON': 'ON', +}); + +export { VehicleDataStatus }; \ No newline at end of file diff --git a/lib/js/src/rpc/enums/VehicleDataType.js b/lib/js/src/rpc/enums/VehicleDataType.js new file mode 100644 index 00000000..96c1345c --- /dev/null +++ b/lib/js/src/rpc/enums/VehicleDataType.js @@ -0,0 +1,328 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { Enum } from '../../util/Enum.js'; + +/** + * Defines the data types that can be published and subscribed to. + * @typedef {Enum} VehicleDataType + * @property {Object} _MAP + */ +class VehicleDataType extends Enum { + /** + * @constructor + */ + constructor () { + super(); + } + + /** + * Notifies GPSData may be subscribed + * @return {String} + */ + static get VEHICLEDATA_GPS () { + return VehicleDataType._MAP.VEHICLEDATA_GPS; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_SPEED () { + return VehicleDataType._MAP.VEHICLEDATA_SPEED; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_RPM () { + return VehicleDataType._MAP.VEHICLEDATA_RPM; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_FUELLEVEL () { + return VehicleDataType._MAP.VEHICLEDATA_FUELLEVEL; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_FUELLEVEL_STATE () { + return VehicleDataType._MAP.VEHICLEDATA_FUELLEVEL_STATE; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_FUELCONSUMPTION () { + return VehicleDataType._MAP.VEHICLEDATA_FUELCONSUMPTION; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_EXTERNTEMP () { + return VehicleDataType._MAP.VEHICLEDATA_EXTERNTEMP; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_VIN () { + return VehicleDataType._MAP.VEHICLEDATA_VIN; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_PRNDL () { + return VehicleDataType._MAP.VEHICLEDATA_PRNDL; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_TIREPRESSURE () { + return VehicleDataType._MAP.VEHICLEDATA_TIREPRESSURE; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_ODOMETER () { + return VehicleDataType._MAP.VEHICLEDATA_ODOMETER; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_BELTSTATUS () { + return VehicleDataType._MAP.VEHICLEDATA_BELTSTATUS; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_BODYINFO () { + return VehicleDataType._MAP.VEHICLEDATA_BODYINFO; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_DEVICESTATUS () { + return VehicleDataType._MAP.VEHICLEDATA_DEVICESTATUS; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_ECALLINFO () { + return VehicleDataType._MAP.VEHICLEDATA_ECALLINFO; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_AIRBAGSTATUS () { + return VehicleDataType._MAP.VEHICLEDATA_AIRBAGSTATUS; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_EMERGENCYEVENT () { + return VehicleDataType._MAP.VEHICLEDATA_EMERGENCYEVENT; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_CLUSTERMODESTATUS () { + return VehicleDataType._MAP.VEHICLEDATA_CLUSTERMODESTATUS; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_MYKEY () { + return VehicleDataType._MAP.VEHICLEDATA_MYKEY; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_BRAKING () { + return VehicleDataType._MAP.VEHICLEDATA_BRAKING; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_WIPERSTATUS () { + return VehicleDataType._MAP.VEHICLEDATA_WIPERSTATUS; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_HEADLAMPSTATUS () { + return VehicleDataType._MAP.VEHICLEDATA_HEADLAMPSTATUS; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_BATTVOLTAGE () { + return VehicleDataType._MAP.VEHICLEDATA_BATTVOLTAGE; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_ENGINETORQUE () { + return VehicleDataType._MAP.VEHICLEDATA_ENGINETORQUE; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_ACCPEDAL () { + return VehicleDataType._MAP.VEHICLEDATA_ACCPEDAL; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_STEERINGWHEEL () { + return VehicleDataType._MAP.VEHICLEDATA_STEERINGWHEEL; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_TURNSIGNAL () { + return VehicleDataType._MAP.VEHICLEDATA_TURNSIGNAL; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_FUELRANGE () { + return VehicleDataType._MAP.VEHICLEDATA_FUELRANGE; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_ENGINEOILLIFE () { + return VehicleDataType._MAP.VEHICLEDATA_ENGINEOILLIFE; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_ELECTRONICPARKBRAKESTATUS () { + return VehicleDataType._MAP.VEHICLEDATA_ELECTRONICPARKBRAKESTATUS; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_CLOUDAPPVEHICLEID () { + return VehicleDataType._MAP.VEHICLEDATA_CLOUDAPPVEHICLEID; + } + + /** + * @return {String} + */ + static get VEHICLEDATA_OEM_CUSTOM_DATA () { + return VehicleDataType._MAP.VEHICLEDATA_OEM_CUSTOM_DATA; + } + + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + static valueForKey (key) { + return VehicleDataType._valueForKey(key, VehicleDataType._MAP); + } + + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + static keyForValue (value) { + return VehicleDataType._keyForValue(value, VehicleDataType._MAP); + } +} + +VehicleDataType._MAP = Object.freeze({ + 'VEHICLEDATA_GPS': 'VEHICLEDATA_GPS', + 'VEHICLEDATA_SPEED': 'VEHICLEDATA_SPEED', + 'VEHICLEDATA_RPM': 'VEHICLEDATA_RPM', + 'VEHICLEDATA_FUELLEVEL': 'VEHICLEDATA_FUELLEVEL', + 'VEHICLEDATA_FUELLEVEL_STATE': 'VEHICLEDATA_FUELLEVEL_STATE', + 'VEHICLEDATA_FUELCONSUMPTION': 'VEHICLEDATA_FUELCONSUMPTION', + 'VEHICLEDATA_EXTERNTEMP': 'VEHICLEDATA_EXTERNTEMP', + 'VEHICLEDATA_VIN': 'VEHICLEDATA_VIN', + 'VEHICLEDATA_PRNDL': 'VEHICLEDATA_PRNDL', + 'VEHICLEDATA_TIREPRESSURE': 'VEHICLEDATA_TIREPRESSURE', + 'VEHICLEDATA_ODOMETER': 'VEHICLEDATA_ODOMETER', + 'VEHICLEDATA_BELTSTATUS': 'VEHICLEDATA_BELTSTATUS', + 'VEHICLEDATA_BODYINFO': 'VEHICLEDATA_BODYINFO', + 'VEHICLEDATA_DEVICESTATUS': 'VEHICLEDATA_DEVICESTATUS', + 'VEHICLEDATA_ECALLINFO': 'VEHICLEDATA_ECALLINFO', + 'VEHICLEDATA_AIRBAGSTATUS': 'VEHICLEDATA_AIRBAGSTATUS', + 'VEHICLEDATA_EMERGENCYEVENT': 'VEHICLEDATA_EMERGENCYEVENT', + 'VEHICLEDATA_CLUSTERMODESTATUS': 'VEHICLEDATA_CLUSTERMODESTATUS', + 'VEHICLEDATA_MYKEY': 'VEHICLEDATA_MYKEY', + 'VEHICLEDATA_BRAKING': 'VEHICLEDATA_BRAKING', + 'VEHICLEDATA_WIPERSTATUS': 'VEHICLEDATA_WIPERSTATUS', + 'VEHICLEDATA_HEADLAMPSTATUS': 'VEHICLEDATA_HEADLAMPSTATUS', + 'VEHICLEDATA_BATTVOLTAGE': 'VEHICLEDATA_BATTVOLTAGE', + 'VEHICLEDATA_ENGINETORQUE': 'VEHICLEDATA_ENGINETORQUE', + 'VEHICLEDATA_ACCPEDAL': 'VEHICLEDATA_ACCPEDAL', + 'VEHICLEDATA_STEERINGWHEEL': 'VEHICLEDATA_STEERINGWHEEL', + 'VEHICLEDATA_TURNSIGNAL': 'VEHICLEDATA_TURNSIGNAL', + 'VEHICLEDATA_FUELRANGE': 'VEHICLEDATA_FUELRANGE', + 'VEHICLEDATA_ENGINEOILLIFE': 'VEHICLEDATA_ENGINEOILLIFE', + 'VEHICLEDATA_ELECTRONICPARKBRAKESTATUS': 'VEHICLEDATA_ELECTRONICPARKBRAKESTATUS', + 'VEHICLEDATA_CLOUDAPPVEHICLEID': 'VEHICLEDATA_CLOUDAPPVEHICLEID', + 'VEHICLEDATA_OEM_CUSTOM_DATA': 'VEHICLEDATA_OEM_CUSTOM_DATA', +}); + +export { VehicleDataType }; \ No newline at end of file diff --git a/lib/js/src/rpc/enums/VentilationMode.js b/lib/js/src/rpc/enums/VentilationMode.js new file mode 100644 index 00000000..fa2d72eb --- /dev/null +++ b/lib/js/src/rpc/enums/VentilationMode.js @@ -0,0 +1,102 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { Enum } from '../../util/Enum.js'; + +/** + * @typedef {Enum} VentilationMode + * @property {Object} _MAP + */ +class VentilationMode extends Enum { + /** + * @constructor + */ + constructor () { + super(); + } + + /** + * @return {String} + */ + static get UPPER () { + return VentilationMode._MAP.UPPER; + } + + /** + * @return {String} + */ + static get LOWER () { + return VentilationMode._MAP.LOWER; + } + + /** + * @return {String} + */ + static get BOTH () { + return VentilationMode._MAP.BOTH; + } + + /** + * @return {String} + */ + static get NONE () { + return VentilationMode._MAP.NONE; + } + + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + static valueForKey (key) { + return VentilationMode._valueForKey(key, VentilationMode._MAP); + } + + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + static keyForValue (value) { + return VentilationMode._keyForValue(value, VentilationMode._MAP); + } +} + +VentilationMode._MAP = Object.freeze({ + 'UPPER': 'UPPER', + 'LOWER': 'LOWER', + 'BOTH': 'BOTH', + 'NONE': 'NONE', +}); + +export { VentilationMode }; \ No newline at end of file diff --git a/lib/js/src/rpc/enums/VideoStreamingCodec.js b/lib/js/src/rpc/enums/VideoStreamingCodec.js index 81005805..020099a1 100644 --- a/lib/js/src/rpc/enums/VideoStreamingCodec.js +++ b/lib/js/src/rpc/enums/VideoStreamingCodec.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -33,17 +34,21 @@ import { Enum } from '../../util/Enum.js'; /** + * Enum for each type of video streaming codec. * @typedef {Enum} VideoStreamingCodec * @property {Object} _MAP */ class VideoStreamingCodec extends Enum { /** - * @constructor - */ + * @constructor + */ constructor () { super(); } + /** + * A block-oriented motion-compensation-based video compression standard. As of 2014 it is one of the most + * commonly used formats for the recording, compression, and distribution of video content. * @return {String} */ static get H264 () { @@ -51,6 +56,10 @@ class VideoStreamingCodec extends Enum { } /** + * High Efficiency Video Coding (HEVC), also known as H.265 and MPEG-H Part 2, is a video compression standard, + * one of several potential successors to the widely used AVC (H.264 or MPEG-4 Part 10). In comparison to AVC, + * HEVC offers about double the data compression ratio at the same level of video quality, or substantially + * improved video quality at the same bit rate. It supports resolutions up to 8192x4320, including 8K UHD. * @return {String} */ static get H265 () { @@ -58,6 +67,10 @@ class VideoStreamingCodec extends Enum { } /** + * Theora is derived from the formerly proprietary VP3 codec, released into the public domain by On2 Technologies. + * It is broadly comparable in design and bitrate efficiency to MPEG-4 Part 2, early versions of Windows Media + * Video, and RealVideo while lacking some of the features present in some of these other codecs. It is comparable + * in open standards philosophy to the BBC's Dirac codec. * @return {String} */ static get Theora () { @@ -65,6 +78,9 @@ class VideoStreamingCodec extends Enum { } /** + * VP8 can be multiplexed into the Matroska-based container format WebM along with Vorbis and Opus audio. The + * image format WebP is based on VP8's intra-frame coding. VP8's direct successor, VP9, and the emerging royalty- + * free internet video format AV1 from the Alliance for Open Media (AOMedia) are based on VP8. * @return {String} */ static get VP8 () { @@ -72,6 +88,8 @@ class VideoStreamingCodec extends Enum { } /** + * Similar to VP8, but VP9 is customized for video resolutions beyond high-definition video (UHD) and also enables + * lossless compression. * @return {String} */ static get VP9 () { @@ -79,58 +97,29 @@ class VideoStreamingCodec extends Enum { } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ static valueForKey (key) { return VideoStreamingCodec._valueForKey(key, VideoStreamingCodec._MAP); } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ static keyForValue (value) { return VideoStreamingCodec._keyForValue(value, VideoStreamingCodec._MAP); } } VideoStreamingCodec._MAP = Object.freeze({ - /** - * A block-oriented motion-compensation-based video compression standard. As of 2014 it is one - * of the most commonly used formats for the recording, compression, and distribution of video - * content. - */ 'H264': 'H264', - /** - * High Efficiency Video Coding (HEVC), also known as H.265 and MPEG-H Part 2, is a video - * compression standard, one of several potential successors to the widely used AVC - * (H.264 or MPEG-4 Part 10). In comparison to AVC, HEVC offers about double the data - * compression ratio at the same level of video quality, or substantially improved video quality - * at the same bit rate. It supports resolutions up to 8192x4320, including 8K UHD. - */ 'H265': 'H265', - /** - * Theora is derived from the formerly proprietary VP3 codec, released into the public domain by - * On2 Technologies. It is broadly comparable in design and bitrate efficiency to MPEG-4 Part 2, - * early versions of Windows Media Video, and RealVideo while lacking some of the features - * present in some of these other codecs. It is comparable in open standards philosophy to the - * BBC's Dirac codec. - */ 'Theora': 'Theora', - /** - * VP8 can be multiplexed into the Matroska-based container format WebM along with Vorbis and - * Opus audio. The image format WebP is based on VP8's intra-frame coding. VP8's direct - * successor, VP9, and the emerging royalty-free internet video format AV1 from the Alliance - * for Open Media (AOMedia) are based on VP8. - */ 'VP8': 'VP8', - /** - * Similar to VP8, but VP9 is customized for video resolutions beyond high-definition video - * (UHD) and also enables lossless compression. - */ 'VP9': 'VP9', }); diff --git a/lib/js/src/rpc/enums/VideoStreamingProtocol.js b/lib/js/src/rpc/enums/VideoStreamingProtocol.js index 018e1f5a..92da2d22 100644 --- a/lib/js/src/rpc/enums/VideoStreamingProtocol.js +++ b/lib/js/src/rpc/enums/VideoStreamingProtocol.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -33,17 +34,20 @@ import { Enum } from '../../util/Enum.js'; /** + * Enum for each type of video streaming protocol type. * @typedef {Enum} VideoStreamingProtocol * @property {Object} _MAP */ class VideoStreamingProtocol extends Enum { /** - * @constructor - */ + * @constructor + */ constructor () { super(); } + /** + * Raw stream bytes that contains no timestamp data and is the lowest supported video streaming * @return {String} */ static get RAW () { @@ -51,6 +55,9 @@ class VideoStreamingProtocol extends Enum { } /** + * RTP facilitates the transfer of real-time data. Information provided by this protocol include timestamps (for + * synchronization), sequence numbers (for packet loss and reordering detection) and the payload format which + * indicates the encoded format of the data. * @return {String} */ static get RTP () { @@ -58,6 +65,9 @@ class VideoStreamingProtocol extends Enum { } /** + * The transmission of streaming data itself is not a task of RTSP. Most RTSP servers use the Real-time Transport + * Protocol (RTP) in conjunction with Real-time Control Protocol (RTCP) for media stream delivery. However, some + * vendors implement proprietary transport protocols. * @return {String} */ static get RTSP () { @@ -65,6 +75,9 @@ class VideoStreamingProtocol extends Enum { } /** + * Real-Time Messaging Protocol (RTMP) was initially a proprietary protocol developed by Macromedia for streaming + * audio, video and data over the Internet, between a Flash player and a server. Macromedia is now owned by Adobe, + * which has released an incomplete version of the specification of the protocol for public use. * @return {String} */ static get RTMP () { @@ -72,6 +85,8 @@ class VideoStreamingProtocol extends Enum { } /** + * The WebM container is based on a profile of Matroska. WebM initially supported VP8 video and Vorbis audio + * streams. In 2013 it was updated to accommodate VP9 video and Opus audio. * @return {String} */ static get WEBM () { @@ -79,54 +94,30 @@ class VideoStreamingProtocol extends Enum { } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ static valueForKey (key) { return VideoStreamingProtocol._valueForKey(key, VideoStreamingProtocol._MAP); } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ static keyForValue (value) { return VideoStreamingProtocol._keyForValue(value, VideoStreamingProtocol._MAP); } } VideoStreamingProtocol._MAP = Object.freeze({ - /** - * Raw stream bytes that contains no timestamp data and is the lowest supported video streaming - */ 'RAW': 'RAW', - /** - * RTP facilitates the transfer of real-time data. Information provided by this protocol include - * timestamps (for synchronization), sequence numbers (for packet loss and reordering detection) - * and the payload format which indicates the encoded format of the data. - */ 'RTP': 'RTP', - /** - * The transmission of streaming data itself is not a task of RTSP. Most RTSP servers use the - * Real-time Transport Protocol (RTP) in conjunction with Real-time Control Protocol (RTCP) for - * media stream delivery. However, some vendors implement proprietary transport protocols. - */ 'RTSP': 'RTSP', - /** - * Real-Time Messaging Protocol (RTMP) was initially a proprietary protocol developed by - * Macromedia for streaming audio, video and data over the Internet, between a Flash player and - * a server. Macromedia is now owned by Adobe, which has released an incomplete version of the - * specification of the protocol for public use. - */ 'RTMP': 'RTMP', - /** - * The WebM container is based on a profile of Matroska. WebM initially supported VP8 video and - * Vorbis audio streams. In 2013 it was updated to accommodate VP9 video and Opus audio. - */ 'WEBM': 'WEBM', - }); export { VideoStreamingProtocol }; \ No newline at end of file diff --git a/lib/js/src/rpc/enums/VideoStreamingState.js b/lib/js/src/rpc/enums/VideoStreamingState.js index 73a95092..75ebbcd0 100644 --- a/lib/js/src/rpc/enums/VideoStreamingState.js +++ b/lib/js/src/rpc/enums/VideoStreamingState.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -33,10 +34,14 @@ import { Enum } from '../../util/Enum.js'; /** + * Enumeration that describes possible states of video streaming. * @typedef {Enum} VideoStreamingState * @property {Object} _MAP */ class VideoStreamingState extends Enum { + /** + * @constructor + */ constructor () { super(); } @@ -56,19 +61,19 @@ class VideoStreamingState extends Enum { } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ static valueForKey (key) { return VideoStreamingState._valueForKey(key, VideoStreamingState._MAP); } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ static keyForValue (value) { return VideoStreamingState._keyForValue(value, VideoStreamingState._MAP); } @@ -77,7 +82,6 @@ class VideoStreamingState extends Enum { VideoStreamingState._MAP = Object.freeze({ 'STREAMABLE': 'STREAMABLE', 'NOT_STREAMABLE': 'NOT_STREAMABLE', - }); export { VideoStreamingState }; \ No newline at end of file diff --git a/lib/js/src/rpc/enums/VrCapabilities.js b/lib/js/src/rpc/enums/VrCapabilities.js index 03aeed02..08ead2d6 100644 --- a/lib/js/src/rpc/enums/VrCapabilities.js +++ b/lib/js/src/rpc/enums/VrCapabilities.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -33,10 +34,14 @@ import { Enum } from '../../util/Enum.js'; /** + * Contains information about the VR capabilities. * @typedef {Enum} VrCapabilities * @property {Object} _MAP */ class VrCapabilities extends Enum { + /** + * @constructor + */ constructor () { super(); } @@ -49,19 +54,19 @@ class VrCapabilities extends Enum { } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ static valueForKey (key) { return VrCapabilities._valueForKey(key, VrCapabilities._MAP); } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ static keyForValue (value) { return VrCapabilities._keyForValue(value, VrCapabilities._MAP); } diff --git a/lib/js/src/rpc/enums/WarningLightStatus.js b/lib/js/src/rpc/enums/WarningLightStatus.js new file mode 100644 index 00000000..8ca86d7d --- /dev/null +++ b/lib/js/src/rpc/enums/WarningLightStatus.js @@ -0,0 +1,103 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { Enum } from '../../util/Enum.js'; + +/** + * Reflects the status of a cluster instrument warning light. + * @typedef {Enum} WarningLightStatus + * @property {Object} _MAP + */ +class WarningLightStatus extends Enum { + /** + * @constructor + */ + constructor () { + super(); + } + + /** + * @return {String} + */ + static get WLS_OFF () { + return WarningLightStatus._MAP.WLS_OFF; + } + + /** + * @return {String} + */ + static get WLS_ON () { + return WarningLightStatus._MAP.WLS_ON; + } + + /** + * @return {String} + */ + static get WLS_FLASH () { + return WarningLightStatus._MAP.WLS_FLASH; + } + + /** + * @return {String} + */ + static get WLS_NOT_USED () { + return WarningLightStatus._MAP.WLS_NOT_USED; + } + + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + static valueForKey (key) { + return WarningLightStatus._valueForKey(key, WarningLightStatus._MAP); + } + + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + static keyForValue (value) { + return WarningLightStatus._keyForValue(value, WarningLightStatus._MAP); + } +} + +WarningLightStatus._MAP = Object.freeze({ + 'WLS_OFF': 'OFF', + 'WLS_ON': 'ON', + 'WLS_FLASH': 'FLASH', + 'WLS_NOT_USED': 'NOT_USED', +}); + +export { WarningLightStatus }; \ No newline at end of file diff --git a/lib/js/src/rpc/enums/WayPointType.js b/lib/js/src/rpc/enums/WayPointType.js new file mode 100644 index 00000000..2027f8da --- /dev/null +++ b/lib/js/src/rpc/enums/WayPointType.js @@ -0,0 +1,87 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { Enum } from '../../util/Enum.js'; + +/** + * Describes what kind of waypoint is requested/provided. + * @typedef {Enum} WayPointType + * @property {Object} _MAP + */ +class WayPointType extends Enum { + /** + * @constructor + */ + constructor () { + super(); + } + + /** + * @return {String} + */ + static get ALL () { + return WayPointType._MAP.ALL; + } + + /** + * @return {String} + */ + static get DESTINATION () { + return WayPointType._MAP.DESTINATION; + } + + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + static valueForKey (key) { + return WayPointType._valueForKey(key, WayPointType._MAP); + } + + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + static keyForValue (value) { + return WayPointType._keyForValue(value, WayPointType._MAP); + } +} + +WayPointType._MAP = Object.freeze({ + 'ALL': 'ALL', + 'DESTINATION': 'DESTINATION', +}); + +export { WayPointType }; \ No newline at end of file diff --git a/lib/js/src/rpc/enums/WindowType.js b/lib/js/src/rpc/enums/WindowType.js new file mode 100644 index 00000000..9e3bb930 --- /dev/null +++ b/lib/js/src/rpc/enums/WindowType.js @@ -0,0 +1,89 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { Enum } from '../../util/Enum.js'; + +/** + * @typedef {Enum} WindowType + * @property {Object} _MAP + */ +class WindowType extends Enum { + /** + * @constructor + */ + constructor () { + super(); + } + + /** + * This window type describes the main window on a display. + * @return {String} + */ + static get MAIN () { + return WindowType._MAP.MAIN; + } + + /** + * A widget is a small window that the app can create to provide information and soft buttons for quick app + * control. + * @return {String} + */ + static get WIDGET () { + return WindowType._MAP.WIDGET; + } + + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + static valueForKey (key) { + return WindowType._valueForKey(key, WindowType._MAP); + } + + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + static keyForValue (value) { + return WindowType._keyForValue(value, WindowType._MAP); + } +} + +WindowType._MAP = Object.freeze({ + 'MAIN': 'MAIN', + 'WIDGET': 'WIDGET', +}); + +export { WindowType }; \ No newline at end of file diff --git a/lib/js/src/rpc/enums/WiperStatus.js b/lib/js/src/rpc/enums/WiperStatus.js new file mode 100644 index 00000000..6406ad50 --- /dev/null +++ b/lib/js/src/rpc/enums/WiperStatus.js @@ -0,0 +1,191 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { Enum } from '../../util/Enum.js'; + +/** + * Reflects the status of the wipers. + * @typedef {Enum} WiperStatus + * @property {Object} _MAP + */ +class WiperStatus extends Enum { + /** + * @constructor + */ + constructor () { + super(); + } + + /** + * @return {String} + */ + static get OFF () { + return WiperStatus._MAP.OFF; + } + + /** + * @return {String} + */ + static get AUTO_OFF () { + return WiperStatus._MAP.AUTO_OFF; + } + + /** + * @return {String} + */ + static get OFF_MOVING () { + return WiperStatus._MAP.OFF_MOVING; + } + + /** + * @return {String} + */ + static get MAN_INT_OFF () { + return WiperStatus._MAP.MAN_INT_OFF; + } + + /** + * @return {String} + */ + static get MAN_INT_ON () { + return WiperStatus._MAP.MAN_INT_ON; + } + + /** + * @return {String} + */ + static get MAN_LOW () { + return WiperStatus._MAP.MAN_LOW; + } + + /** + * @return {String} + */ + static get MAN_HIGH () { + return WiperStatus._MAP.MAN_HIGH; + } + + /** + * @return {String} + */ + static get MAN_FLICK () { + return WiperStatus._MAP.MAN_FLICK; + } + + /** + * @return {String} + */ + static get WASH () { + return WiperStatus._MAP.WASH; + } + + /** + * @return {String} + */ + static get AUTO_LOW () { + return WiperStatus._MAP.AUTO_LOW; + } + + /** + * @return {String} + */ + static get AUTO_HIGH () { + return WiperStatus._MAP.AUTO_HIGH; + } + + /** + * @return {String} + */ + static get COURTESYWIPE () { + return WiperStatus._MAP.COURTESYWIPE; + } + + /** + * @return {String} + */ + static get AUTO_ADJUST () { + return WiperStatus._MAP.AUTO_ADJUST; + } + + /** + * @return {String} + */ + static get STALLED () { + return WiperStatus._MAP.STALLED; + } + + /** + * @return {String} + */ + static get NO_DATA_EXISTS () { + return WiperStatus._MAP.NO_DATA_EXISTS; + } + + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + static valueForKey (key) { + return WiperStatus._valueForKey(key, WiperStatus._MAP); + } + + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + static keyForValue (value) { + return WiperStatus._keyForValue(value, WiperStatus._MAP); + } +} + +WiperStatus._MAP = Object.freeze({ + 'OFF': 'OFF', + 'AUTO_OFF': 'AUTO_OFF', + 'OFF_MOVING': 'OFF_MOVING', + 'MAN_INT_OFF': 'MAN_INT_OFF', + 'MAN_INT_ON': 'MAN_INT_ON', + 'MAN_LOW': 'MAN_LOW', + 'MAN_HIGH': 'MAN_HIGH', + 'MAN_FLICK': 'MAN_FLICK', + 'WASH': 'WASH', + 'AUTO_LOW': 'AUTO_LOW', + 'AUTO_HIGH': 'AUTO_HIGH', + 'COURTESYWIPE': 'COURTESYWIPE', + 'AUTO_ADJUST': 'AUTO_ADJUST', + 'STALLED': 'STALLED', + 'NO_DATA_EXISTS': 'NO_DATA_EXISTS', +}); + +export { WiperStatus }; \ No newline at end of file diff --git a/lib/js/src/rpc/enums/messageType.js b/lib/js/src/rpc/enums/messageType.js new file mode 100644 index 00000000..0b71228d --- /dev/null +++ b/lib/js/src/rpc/enums/messageType.js @@ -0,0 +1,95 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { Enum } from '../../util/Enum.js'; + +/** + * Enumeration linking message types with function types in WiPro protocol. Assumes enumeration starts at value 0. + * @typedef {Enum} messageType + * @property {Object} _MAP + */ +class messageType extends Enum { + /** + * @constructor + */ + constructor () { + super(); + } + + /** + * @return {Number} + */ + static get request () { + return messageType._MAP.request; + } + + /** + * @return {Number} + */ + static get response () { + return messageType._MAP.response; + } + + /** + * @return {Number} + */ + static get notification () { + return messageType._MAP.notification; + } + + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + static valueForKey (key) { + return messageType._valueForKey(key, messageType._MAP); + } + + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + static keyForValue (value) { + return messageType._keyForValue(value, messageType._MAP); + } +} + +messageType._MAP = Object.freeze({ + 'request': 0, + 'response': 1, + 'notification': 2, +}); + +export { messageType }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/AddCommand.js b/lib/js/src/rpc/messages/AddCommand.js index 1af5205a..c0a4330f 100644 --- a/lib/js/src/rpc/messages/AddCommand.js +++ b/lib/js/src/rpc/messages/AddCommand.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -31,92 +32,94 @@ */ import { RpcRequest } from '../RpcRequest.js'; -import { Image } from '../structs/Image.js'; -import { MenuParams } from '../structs/MenuParams.js'; import { FunctionID } from '../enums/FunctionID.js'; +import { MenuParams } from '../structs/MenuParams.js'; +import { Image } from '../structs/Image.js'; +/** + * Adds a command to the in application menu. Either menuParams or vrCommands must be provided. + */ class AddCommand extends RpcRequest { /** - * @constructor - */ + * @constructor + */ constructor (store) { super(store); this.setFunctionName(FunctionID.AddCommand); } - /** - * @param {Number} id - * @return {AddCommand} - */ + * @param {Number} id - unique ID of the command to add. + * @return {AddCommand} + */ setCmdID (id) { this.setParameter(AddCommand.KEY_CMD_ID, id); return this; } /** - * @return {Number} - */ + * @return {Number} + */ getCmdID () { return this.getParameter(AddCommand.KEY_CMD_ID); } /** - * @param {MenuParams} menuParams - * @return {AddCommand} - */ - setMenuParams (menuParams) { - this.validateType(MenuParams, menuParams); - - this.setParameter(AddCommand.KEY_MENU_PARAMS, menuParams); + * @param {MenuParams} params - Optional sub value containing menu parameters + * @return {AddCommand} + */ + setMenuParams (params) { + this.validateType(MenuParams, params); + this.setParameter(AddCommand.KEY_MENU_PARAMS, params); return this; } /** - * @return {MenuParams} - */ + * @return {MenuParams} + */ getMenuParams () { return this.getObject(MenuParams, AddCommand.KEY_MENU_PARAMS); } /** - * @param {Array} vrCommands - * @return {AddCommand} - */ - setVrCommands (vrCommands) { - this.setParameter(AddCommand.KEY_VR_COMMANDS, vrCommands); + * @param {String[]} commands - An array of strings to be used as VR synonyms for this command. If this array is + * provided, it may not be empty. + * @return {AddCommand} + */ + setVrCommands (commands) { + this.setParameter(AddCommand.KEY_VR_COMMANDS, commands); return this; } /** - * @return {Array} - */ + * @return {String[]} + */ getVrCommands () { return this.getParameter(AddCommand.KEY_VR_COMMANDS); } /** - * @param {Image} icon - * @return {AddCommand} - */ + * @param {Image} icon - Image struct determining whether static or dynamic icon. If omitted on supported displays, + * no (or the default if applicable) icon shall be displayed. + * @return {AddCommand} + */ setCmdIcon (icon) { this.validateType(Image, icon); - this.setParameter(AddCommand.KEY_CMD_ICON, icon); return this; } /** - * @return {Image} - */ + * @return {Image} + */ getCmdIcon () { return this.getObject(Image, AddCommand.KEY_CMD_ICON); } } -AddCommand.KEY_CMD_ICON = 'cmdIcon'; -AddCommand.KEY_MENU_PARAMS = 'menuParams'; AddCommand.KEY_CMD_ID = 'cmdID'; +AddCommand.KEY_MENU_PARAMS = 'menuParams'; AddCommand.KEY_VR_COMMANDS = 'vrCommands'; +AddCommand.KEY_CMD_ICON = 'cmdIcon'; -export { AddCommand }; +export { AddCommand }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/AddCommandResponse.js b/lib/js/src/rpc/messages/AddCommandResponse.js index a4e655e9..a549e54b 100644 --- a/lib/js/src/rpc/messages/AddCommandResponse.js +++ b/lib/js/src/rpc/messages/AddCommandResponse.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -30,17 +31,18 @@ * POSSIBILITY OF SUCH DAMAGE. */ -import { RpcResponse } from '../RpcResponse.js'; import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; class AddCommandResponse extends RpcResponse { /** - * @constructor - */ + * @constructor + */ constructor (store) { super(store); this.setFunctionName(FunctionID.AddCommand); } } -export { AddCommandResponse }; + +export { AddCommandResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/AddSubMenu.js b/lib/js/src/rpc/messages/AddSubMenu.js new file mode 100644 index 00000000..1b85203f --- /dev/null +++ b/lib/js/src/rpc/messages/AddSubMenu.js @@ -0,0 +1,144 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; +import { MenuLayout } from '../enums/MenuLayout.js'; +import { Image } from '../structs/Image.js'; + +/** + * Adds a sub menu to the in-application menu. + */ +class AddSubMenu extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.AddSubMenu); + } + + /** + * @param {Number} id - unique ID of the sub menu to add. + * @return {AddSubMenu} + */ + setMenuID (id) { + this.setParameter(AddSubMenu.KEY_MENU_ID, id); + return this; + } + + /** + * @return {Number} + */ + getMenuID () { + return this.getParameter(AddSubMenu.KEY_MENU_ID); + } + + /** + * @param {Number} position - Position within the items that are are at top level of the in application menu. 0 will + * insert at the front. 1 will insert at the second position. If position is greater or + * equal than the number of items on top level, the sub menu will be appended to the end. + * Position of any submenu will always be located before the return and exit options If + * this param was omitted the entry will be added at the end. + * @return {AddSubMenu} + */ + setPosition (position) { + this.setParameter(AddSubMenu.KEY_POSITION, position); + return this; + } + + /** + * @return {Number} + */ + getPosition () { + return this.getParameter(AddSubMenu.KEY_POSITION); + } + + /** + * @param {String} name - Text to show in the menu for this sub menu. + * @return {AddSubMenu} + */ + setMenuName (name) { + this.setParameter(AddSubMenu.KEY_MENU_NAME, name); + return this; + } + + /** + * @return {String} + */ + getMenuName () { + return this.getParameter(AddSubMenu.KEY_MENU_NAME); + } + + /** + * @param {Image} icon - The image field for AddSubMenu + * @return {AddSubMenu} + */ + setMenuIcon (icon) { + this.validateType(Image, icon); + this.setParameter(AddSubMenu.KEY_MENU_ICON, icon); + return this; + } + + /** + * @return {Image} + */ + getMenuIcon () { + return this.getObject(Image, AddSubMenu.KEY_MENU_ICON); + } + + /** + * @param {MenuLayout} layout - Sets the layout of the submenu screen. + * @return {AddSubMenu} + */ + setMenuLayout (layout) { + this.validateType(MenuLayout, layout); + this.setParameter(AddSubMenu.KEY_MENU_LAYOUT, layout); + return this; + } + + /** + * @return {MenuLayout} + */ + getMenuLayout () { + return this.getObject(MenuLayout, AddSubMenu.KEY_MENU_LAYOUT); + } +} + +AddSubMenu.KEY_MENU_ID = 'menuID'; +AddSubMenu.KEY_POSITION = 'position'; +AddSubMenu.KEY_MENU_NAME = 'menuName'; +AddSubMenu.KEY_MENU_ICON = 'menuIcon'; +AddSubMenu.KEY_MENU_LAYOUT = 'menuLayout'; + +export { AddSubMenu }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/AddSubMenuResponse.js b/lib/js/src/rpc/messages/AddSubMenuResponse.js new file mode 100644 index 00000000..d47863db --- /dev/null +++ b/lib/js/src/rpc/messages/AddSubMenuResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class AddSubMenuResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.AddSubMenu); + } +} + + +export { AddSubMenuResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/Alert.js b/lib/js/src/rpc/messages/Alert.js new file mode 100644 index 00000000..2e510643 --- /dev/null +++ b/lib/js/src/rpc/messages/Alert.js @@ -0,0 +1,235 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { TTSChunk } from '../structs/TTSChunk.js'; +import { SoftButton } from '../structs/SoftButton.js'; +import { FunctionID } from '../enums/FunctionID.js'; +import { Image } from '../structs/Image.js'; + +/** + * Shows an alert which typically consists of text-to-speech message and text on the display. At least either + * alertText1, alertText2 or TTSChunks need to be provided. + */ +class Alert extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.Alert); + } + + /** + * @param {String} text1 - The first line of the alert text field + * @return {Alert} + */ + setAlertText1 (text1) { + this.setParameter(Alert.KEY_ALERT_TEXT_1, text1); + return this; + } + + /** + * @return {String} + */ + getAlertText1 () { + return this.getParameter(Alert.KEY_ALERT_TEXT_1); + } + + /** + * @param {String} text2 - The second line of the alert text field + * @return {Alert} + */ + setAlertText2 (text2) { + this.setParameter(Alert.KEY_ALERT_TEXT_2, text2); + return this; + } + + /** + * @return {String} + */ + getAlertText2 () { + return this.getParameter(Alert.KEY_ALERT_TEXT_2); + } + + /** + * @param {String} text3 - The optional third line of the alert text field + * @return {Alert} + */ + setAlertText3 (text3) { + this.setParameter(Alert.KEY_ALERT_TEXT_3, text3); + return this; + } + + /** + * @return {String} + */ + getAlertText3 () { + return this.getParameter(Alert.KEY_ALERT_TEXT_3); + } + + /** + * @param {TTSChunk[]} chunks - An array of text chunks of type TTSChunk. See TTSChunk. The array must have at least + * one item. + * @return {Alert} + */ + setTtsChunks (chunks) { + this.validateType(TTSChunk, chunks, true); + this.setParameter(Alert.KEY_TTS_CHUNKS, chunks); + return this; + } + + /** + * @return {TTSChunk[]} + */ + getTtsChunks () { + return this.getObject(TTSChunk, Alert.KEY_TTS_CHUNKS); + } + + /** + * @param {Number} duration - Timeout in milliseconds. Typical timeouts are 3-5 seconds. If omitted, timeout is set + * to 5s. + * @return {Alert} + */ + setDuration (duration) { + this.setParameter(Alert.KEY_DURATION, duration); + return this; + } + + /** + * @return {Number} + */ + getDuration () { + return this.getParameter(Alert.KEY_DURATION); + } + + /** + * @param {Boolean} tone - Defines if tone should be played. Tone is played before TTS. If omitted, no tone is + * played. + * @return {Alert} + */ + setPlayTone (tone) { + this.setParameter(Alert.KEY_PLAY_TONE, tone); + return this; + } + + /** + * @return {Boolean} + */ + getPlayTone () { + return this.getParameter(Alert.KEY_PLAY_TONE); + } + + /** + * @param {Boolean} indicator - If supported on the given platform, the alert GUI will include some sort of + * animation indicating that loading of a feature is progressing. e.g. a spinning wheel + * or hourglass, etc. + * @return {Alert} + */ + setProgressIndicator (indicator) { + this.setParameter(Alert.KEY_PROGRESS_INDICATOR, indicator); + return this; + } + + /** + * @return {Boolean} + */ + getProgressIndicator () { + return this.getParameter(Alert.KEY_PROGRESS_INDICATOR); + } + + /** + * @param {SoftButton[]} buttons - App defined SoftButtons. If omitted on supported displays, the displayed alert + * shall not have any SoftButtons. + * @return {Alert} + */ + setSoftButtons (buttons) { + this.validateType(SoftButton, buttons, true); + this.setParameter(Alert.KEY_SOFT_BUTTONS, buttons); + return this; + } + + /** + * @return {SoftButton[]} + */ + getSoftButtons () { + return this.getObject(SoftButton, Alert.KEY_SOFT_BUTTONS); + } + + /** + * @param {Image} icon - Image struct determining whether static or dynamic icon. If omitted on supported displays, + * no (or the default if applicable) icon should be displayed. + * @return {Alert} + */ + setAlertIcon (icon) { + this.validateType(Image, icon); + this.setParameter(Alert.KEY_ALERT_ICON, icon); + return this; + } + + /** + * @return {Image} + */ + getAlertIcon () { + return this.getObject(Image, Alert.KEY_ALERT_ICON); + } + + /** + * @param {Number} id - An ID for this specific alert to allow cancellation through the `CancelInteraction` RPC. + * @return {Alert} + */ + setCancelID (id) { + this.setParameter(Alert.KEY_CANCEL_ID, id); + return this; + } + + /** + * @return {Number} + */ + getCancelID () { + return this.getParameter(Alert.KEY_CANCEL_ID); + } +} + +Alert.KEY_ALERT_TEXT_1 = 'alertText1'; +Alert.KEY_ALERT_TEXT_2 = 'alertText2'; +Alert.KEY_ALERT_TEXT_3 = 'alertText3'; +Alert.KEY_TTS_CHUNKS = 'ttsChunks'; +Alert.KEY_DURATION = 'duration'; +Alert.KEY_PLAY_TONE = 'playTone'; +Alert.KEY_PROGRESS_INDICATOR = 'progressIndicator'; +Alert.KEY_SOFT_BUTTONS = 'softButtons'; +Alert.KEY_ALERT_ICON = 'alertIcon'; +Alert.KEY_CANCEL_ID = 'cancelID'; + +export { Alert }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/AlertManeuver.js b/lib/js/src/rpc/messages/AlertManeuver.js new file mode 100644 index 00000000..7875fb80 --- /dev/null +++ b/lib/js/src/rpc/messages/AlertManeuver.js @@ -0,0 +1,87 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { TTSChunk } from '../structs/TTSChunk.js'; +import { FunctionID } from '../enums/FunctionID.js'; +import { SoftButton } from '../structs/SoftButton.js'; + +class AlertManeuver extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.AlertManeuver); + } + + /** + * @param {TTSChunk[]} chunks - An array of text chunks of type TTSChunk. See TTSChunk + * @return {AlertManeuver} + */ + setTtsChunks (chunks) { + this.validateType(TTSChunk, chunks, true); + this.setParameter(AlertManeuver.KEY_TTS_CHUNKS, chunks); + return this; + } + + /** + * @return {TTSChunk[]} + */ + getTtsChunks () { + return this.getObject(TTSChunk, AlertManeuver.KEY_TTS_CHUNKS); + } + + /** + * @param {SoftButton[]} buttons - If omitted on supported displays, only the system defined "Close" SoftButton + * shall be displayed. + * @return {AlertManeuver} + */ + setSoftButtons (buttons) { + this.validateType(SoftButton, buttons, true); + this.setParameter(AlertManeuver.KEY_SOFT_BUTTONS, buttons); + return this; + } + + /** + * @return {SoftButton[]} + */ + getSoftButtons () { + return this.getObject(SoftButton, AlertManeuver.KEY_SOFT_BUTTONS); + } +} + +AlertManeuver.KEY_TTS_CHUNKS = 'ttsChunks'; +AlertManeuver.KEY_SOFT_BUTTONS = 'softButtons'; + +export { AlertManeuver }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/AlertManeuverResponse.js b/lib/js/src/rpc/messages/AlertManeuverResponse.js new file mode 100644 index 00000000..b9555952 --- /dev/null +++ b/lib/js/src/rpc/messages/AlertManeuverResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class AlertManeuverResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.AlertManeuver); + } +} + + +export { AlertManeuverResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/AlertResponse.js b/lib/js/src/rpc/messages/AlertResponse.js new file mode 100644 index 00000000..3a432b55 --- /dev/null +++ b/lib/js/src/rpc/messages/AlertResponse.js @@ -0,0 +1,67 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class AlertResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.Alert); + } + + /** + * @param {Number} time - Amount of time (in seconds) that an app must wait before resending an alert. If provided, + * another system event or overlay currently has a higher priority than this alert. An app + * must not send an alert without waiting at least the amount of time dictated. + * @return {AlertResponse} + */ + setTryAgainTime (time) { + this.setParameter(AlertResponse.KEY_TRY_AGAIN_TIME, time); + return this; + } + + /** + * @return {Number} + */ + getTryAgainTime () { + return this.getParameter(AlertResponse.KEY_TRY_AGAIN_TIME); + } +} + +AlertResponse.KEY_TRY_AGAIN_TIME = 'tryAgainTime'; + +export { AlertResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/ButtonPress.js b/lib/js/src/rpc/messages/ButtonPress.js new file mode 100644 index 00000000..60157cdb --- /dev/null +++ b/lib/js/src/rpc/messages/ButtonPress.js @@ -0,0 +1,122 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { ButtonName } from '../enums/ButtonName.js'; +import { FunctionID } from '../enums/FunctionID.js'; +import { ButtonPressMode } from '../enums/ButtonPressMode.js'; +import { ModuleType } from '../enums/ModuleType.js'; +import { RpcRequest } from '../RpcRequest.js'; + +class ButtonPress extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.ButtonPress); + } + + /** + * @param {ModuleType} type - The module where the button should be pressed + * @return {ButtonPress} + */ + setModuleType (type) { + this.validateType(ModuleType, type); + this.setParameter(ButtonPress.KEY_MODULE_TYPE, type); + return this; + } + + /** + * @return {ModuleType} + */ + getModuleType () { + return this.getObject(ModuleType, ButtonPress.KEY_MODULE_TYPE); + } + + /** + * @param {String} id - Id of a module, published by System Capability. + * @return {ButtonPress} + */ + setModuleId (id) { + this.setParameter(ButtonPress.KEY_MODULE_ID, id); + return this; + } + + /** + * @return {String} + */ + getModuleId () { + return this.getParameter(ButtonPress.KEY_MODULE_ID); + } + + /** + * @param {ButtonName} name - The name of supported RC climate or radio button. + * @return {ButtonPress} + */ + setButtonName (name) { + this.validateType(ButtonName, name); + this.setParameter(ButtonPress.KEY_BUTTON_NAME, name); + return this; + } + + /** + * @return {ButtonName} + */ + getButtonName () { + return this.getObject(ButtonName, ButtonPress.KEY_BUTTON_NAME); + } + + /** + * @param {ButtonPressMode} mode - Indicates whether this is a LONG or SHORT button press event. + * @return {ButtonPress} + */ + setButtonPressMode (mode) { + this.validateType(ButtonPressMode, mode); + this.setParameter(ButtonPress.KEY_BUTTON_PRESS_MODE, mode); + return this; + } + + /** + * @return {ButtonPressMode} + */ + getButtonPressMode () { + return this.getObject(ButtonPressMode, ButtonPress.KEY_BUTTON_PRESS_MODE); + } +} + +ButtonPress.KEY_MODULE_TYPE = 'moduleType'; +ButtonPress.KEY_MODULE_ID = 'moduleId'; +ButtonPress.KEY_BUTTON_NAME = 'buttonName'; +ButtonPress.KEY_BUTTON_PRESS_MODE = 'buttonPressMode'; + +export { ButtonPress }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/ButtonPressResponse.js b/lib/js/src/rpc/messages/ButtonPressResponse.js new file mode 100644 index 00000000..8bec65fe --- /dev/null +++ b/lib/js/src/rpc/messages/ButtonPressResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class ButtonPressResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.ButtonPress); + } +} + + +export { ButtonPressResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/CancelInteraction.js b/lib/js/src/rpc/messages/CancelInteraction.js new file mode 100644 index 00000000..8eb9a7f3 --- /dev/null +++ b/lib/js/src/rpc/messages/CancelInteraction.js @@ -0,0 +1,88 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Close an active interaction on the HMI. + */ +class CancelInteraction extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.CancelInteraction); + } + + /** + * @param {Number} id - The ID of the specific interaction you want to dismiss. If not set, the most recent of the + * RPC type set in functionID will be dismissed. + * @return {CancelInteraction} + */ + setCancelID (id) { + this.setParameter(CancelInteraction.KEY_CANCEL_ID, id); + return this; + } + + /** + * @return {Number} + */ + getCancelID () { + return this.getParameter(CancelInteraction.KEY_CANCEL_ID); + } + + /** + * @param {Number} id - The ID of the type of interaction the developer wants to dismiss. Only values 10, + * (PerformInteractionID), 12 (AlertID), 25 (ScrollableMessageID), and 26 (SliderID) are + * permitted. + * @return {CancelInteraction} + */ + setFunctionID (id) { + this.setParameter(CancelInteraction.KEY_FUNCTION_ID, id); + return this; + } + + /** + * @return {Number} + */ + getFunctionID () { + return this.getParameter(CancelInteraction.KEY_FUNCTION_ID); + } +} + +CancelInteraction.KEY_CANCEL_ID = 'cancelID'; +CancelInteraction.KEY_FUNCTION_ID = 'functionID'; + +export { CancelInteraction }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/CancelInteractionResponse.js b/lib/js/src/rpc/messages/CancelInteractionResponse.js new file mode 100644 index 00000000..d78bfb46 --- /dev/null +++ b/lib/js/src/rpc/messages/CancelInteractionResponse.js @@ -0,0 +1,51 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +/** + * If no applicable request can be dismissed, the result will be IGNORED. + */ +class CancelInteractionResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.CancelInteraction); + } +} + + +export { CancelInteractionResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/ChangeRegistration.js b/lib/js/src/rpc/messages/ChangeRegistration.js new file mode 100644 index 00000000..bb688ce9 --- /dev/null +++ b/lib/js/src/rpc/messages/ChangeRegistration.js @@ -0,0 +1,155 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { TTSChunk } from '../structs/TTSChunk.js'; +import { Language } from '../enums/Language.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +class ChangeRegistration extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.ChangeRegistration); + } + + /** + * @param {Language} language - Requested voice engine (VR+TTS) language registration + * @return {ChangeRegistration} + */ + setLanguage (language) { + this.validateType(Language, language); + this.setParameter(ChangeRegistration.KEY_LANGUAGE, language); + return this; + } + + /** + * @return {Language} + */ + getLanguage () { + return this.getObject(Language, ChangeRegistration.KEY_LANGUAGE); + } + + /** + * @param {Language} language - Request display language registration + * @return {ChangeRegistration} + */ + setHmiDisplayLanguage (language) { + this.validateType(Language, language); + this.setParameter(ChangeRegistration.KEY_HMI_DISPLAY_LANGUAGE, language); + return this; + } + + /** + * @return {Language} + */ + getHmiDisplayLanguage () { + return this.getObject(Language, ChangeRegistration.KEY_HMI_DISPLAY_LANGUAGE); + } + + /** + * @param {String} name - Request new app name registration + * @return {ChangeRegistration} + */ + setAppName (name) { + this.setParameter(ChangeRegistration.KEY_APP_NAME, name); + return this; + } + + /** + * @return {String} + */ + getAppName () { + return this.getParameter(ChangeRegistration.KEY_APP_NAME); + } + + /** + * @param {TTSChunk[]} name - Request new ttsName registration + * @return {ChangeRegistration} + */ + setTtsName (name) { + this.validateType(TTSChunk, name, true); + this.setParameter(ChangeRegistration.KEY_TTS_NAME, name); + return this; + } + + /** + * @return {TTSChunk[]} + */ + getTtsName () { + return this.getObject(TTSChunk, ChangeRegistration.KEY_TTS_NAME); + } + + /** + * @param {String} name - Request new app short name registration + * @return {ChangeRegistration} + */ + setNgnMediaScreenAppName (name) { + this.setParameter(ChangeRegistration.KEY_NGN_MEDIA_SCREEN_APP_NAME, name); + return this; + } + + /** + * @return {String} + */ + getNgnMediaScreenAppName () { + return this.getParameter(ChangeRegistration.KEY_NGN_MEDIA_SCREEN_APP_NAME); + } + + /** + * @param {String[]} synonyms - Request new VR synonyms registration + * @return {ChangeRegistration} + */ + setVrSynonyms (synonyms) { + this.setParameter(ChangeRegistration.KEY_VR_SYNONYMS, synonyms); + return this; + } + + /** + * @return {String[]} + */ + getVrSynonyms () { + return this.getParameter(ChangeRegistration.KEY_VR_SYNONYMS); + } +} + +ChangeRegistration.KEY_LANGUAGE = 'language'; +ChangeRegistration.KEY_HMI_DISPLAY_LANGUAGE = 'hmiDisplayLanguage'; +ChangeRegistration.KEY_APP_NAME = 'appName'; +ChangeRegistration.KEY_TTS_NAME = 'ttsName'; +ChangeRegistration.KEY_NGN_MEDIA_SCREEN_APP_NAME = 'ngnMediaScreenAppName'; +ChangeRegistration.KEY_VR_SYNONYMS = 'vrSynonyms'; + +export { ChangeRegistration }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/ChangeRegistrationResponse.js b/lib/js/src/rpc/messages/ChangeRegistrationResponse.js new file mode 100644 index 00000000..3f119b3e --- /dev/null +++ b/lib/js/src/rpc/messages/ChangeRegistrationResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class ChangeRegistrationResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.ChangeRegistration); + } +} + + +export { ChangeRegistrationResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/CloseApplication.js b/lib/js/src/rpc/messages/CloseApplication.js new file mode 100644 index 00000000..8f850979 --- /dev/null +++ b/lib/js/src/rpc/messages/CloseApplication.js @@ -0,0 +1,51 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Request from the application to exit the foreground and enter HMI_NONE. + */ +class CloseApplication extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.CloseApplication); + } +} + + +export { CloseApplication }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/CloseApplicationResponse.js b/lib/js/src/rpc/messages/CloseApplicationResponse.js new file mode 100644 index 00000000..7fbff7c0 --- /dev/null +++ b/lib/js/src/rpc/messages/CloseApplicationResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class CloseApplicationResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.CloseApplication); + } +} + + +export { CloseApplicationResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/CreateInteractionChoiceSet.js b/lib/js/src/rpc/messages/CreateInteractionChoiceSet.js new file mode 100644 index 00000000..e278b6c6 --- /dev/null +++ b/lib/js/src/rpc/messages/CreateInteractionChoiceSet.js @@ -0,0 +1,88 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { Choice } from '../structs/Choice.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * creates interaction choice set to be used later by performInteraction + */ +class CreateInteractionChoiceSet extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.CreateInteractionChoiceSet); + } + + /** + * @param {Number} id - Unique ID used for this interaction choice set. + * @return {CreateInteractionChoiceSet} + */ + setInteractionChoiceSetID (id) { + this.setParameter(CreateInteractionChoiceSet.KEY_INTERACTION_CHOICE_SET_ID, id); + return this; + } + + /** + * @return {Number} + */ + getInteractionChoiceSetID () { + return this.getParameter(CreateInteractionChoiceSet.KEY_INTERACTION_CHOICE_SET_ID); + } + + /** + * @param {Choice[]} set - A choice is an option given to the user, which can be selected either by menu, or through + * voice recognition system. + * @return {CreateInteractionChoiceSet} + */ + setChoiceSet (set) { + this.validateType(Choice, set, true); + this.setParameter(CreateInteractionChoiceSet.KEY_CHOICE_SET, set); + return this; + } + + /** + * @return {Choice[]} + */ + getChoiceSet () { + return this.getObject(Choice, CreateInteractionChoiceSet.KEY_CHOICE_SET); + } +} + +CreateInteractionChoiceSet.KEY_INTERACTION_CHOICE_SET_ID = 'interactionChoiceSetID'; +CreateInteractionChoiceSet.KEY_CHOICE_SET = 'choiceSet'; + +export { CreateInteractionChoiceSet }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/CreateInteractionChoiceSetResponse.js b/lib/js/src/rpc/messages/CreateInteractionChoiceSetResponse.js new file mode 100644 index 00000000..beb01f6a --- /dev/null +++ b/lib/js/src/rpc/messages/CreateInteractionChoiceSetResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class CreateInteractionChoiceSetResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.CreateInteractionChoiceSet); + } +} + + +export { CreateInteractionChoiceSetResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/CreateWindow.js b/lib/js/src/rpc/messages/CreateWindow.js new file mode 100644 index 00000000..92c1c82d --- /dev/null +++ b/lib/js/src/rpc/messages/CreateWindow.js @@ -0,0 +1,155 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { WindowType } from '../enums/WindowType.js'; +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Create a new window on the display with the specified window type. + */ +class CreateWindow extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.CreateWindow); + } + + /** + * @param {Number} id - A unique ID to identify the window. The value of '0' will always be the default main window + * on the main display and should not be used in this context as it will already be created for + * the app. See PredefinedWindows enum. Creating a window with an ID that is already in use + * will be rejected with `INVALID_ID`. + * @return {CreateWindow} + */ + setWindowID (id) { + this.setParameter(CreateWindow.KEY_WINDOW_ID, id); + return this; + } + + /** + * @return {Number} + */ + getWindowID () { + return this.getParameter(CreateWindow.KEY_WINDOW_ID); + } + + /** + * @param {String} name - The window name to be used by the HMI. The name of the pre-created default window will + * match the app name. Multiple apps can share the same window name except for the default + * main window. Creating a window with a name which is already in use by the app will result + * in `DUPLICATE_NAME`. + * @return {CreateWindow} + */ + setWindowName (name) { + this.setParameter(CreateWindow.KEY_WINDOW_NAME, name); + return this; + } + + /** + * @return {String} + */ + getWindowName () { + return this.getParameter(CreateWindow.KEY_WINDOW_NAME); + } + + /** + * @param {WindowType} type - The type of the window to be created. Main window or widget. + * @return {CreateWindow} + */ + setType (type) { + this.validateType(WindowType, type); + this.setParameter(CreateWindow.KEY_TYPE, type); + return this; + } + + /** + * @return {WindowType} + */ + getType () { + return this.getObject(WindowType, CreateWindow.KEY_TYPE); + } + + /** + * @param {String} type - Allows an app to create a widget related to a specific service type. As an example if a + * `MEDIA` app becomes active, this app becomes audible and is allowed to play audio. Actions + * such as skip or play/pause will be directed to this active media app. In case of widgets, + * the system can provide a single "media" widget which will act as a placeholder for the + * active media app. It is only allowed to have one window per service type. This means that + * a media app can only have a single MEDIA widget. Still the app can create widgets omitting + * this parameter. Those widgets would be available as app specific widgets that are + * permanently included in the HMI. This parameter is related to widgets only. The default + * main window, which is pre-created during app registration, will be created based on the + * HMI types specified in the app registration request. + * @return {CreateWindow} + */ + setAssociatedServiceType (type) { + this.setParameter(CreateWindow.KEY_ASSOCIATED_SERVICE_TYPE, type); + return this; + } + + /** + * @return {String} + */ + getAssociatedServiceType () { + return this.getParameter(CreateWindow.KEY_ASSOCIATED_SERVICE_TYPE); + } + + /** + * @param {Number} id - Optional parameter. Specify whether the content sent to an existing window should be + * duplicated to the created window. If there isn't a window with the ID, the request will be + * rejected with `INVALID_DATA`. + * @return {CreateWindow} + */ + setDuplicateUpdatesFromWindowID (id) { + this.setParameter(CreateWindow.KEY_DUPLICATE_UPDATES_FROM_WINDOW_ID, id); + return this; + } + + /** + * @return {Number} + */ + getDuplicateUpdatesFromWindowID () { + return this.getParameter(CreateWindow.KEY_DUPLICATE_UPDATES_FROM_WINDOW_ID); + } +} + +CreateWindow.KEY_WINDOW_ID = 'windowID'; +CreateWindow.KEY_WINDOW_NAME = 'windowName'; +CreateWindow.KEY_TYPE = 'type'; +CreateWindow.KEY_ASSOCIATED_SERVICE_TYPE = 'associatedServiceType'; +CreateWindow.KEY_DUPLICATE_UPDATES_FROM_WINDOW_ID = 'duplicateUpdatesFromWindowID'; + +export { CreateWindow }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/CreateWindowResponse.js b/lib/js/src/rpc/messages/CreateWindowResponse.js new file mode 100644 index 00000000..b7fbb63a --- /dev/null +++ b/lib/js/src/rpc/messages/CreateWindowResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class CreateWindowResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.CreateWindow); + } +} + + +export { CreateWindowResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/DeleteCommand.js b/lib/js/src/rpc/messages/DeleteCommand.js new file mode 100644 index 00000000..7c894bc6 --- /dev/null +++ b/lib/js/src/rpc/messages/DeleteCommand.js @@ -0,0 +1,68 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Deletes all commands from the in-application menu with the specified command id. + */ +class DeleteCommand extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.DeleteCommand); + } + + /** + * @param {Number} id - ID of the command(s) to delete. + * @return {DeleteCommand} + */ + setCmdID (id) { + this.setParameter(DeleteCommand.KEY_CMD_ID, id); + return this; + } + + /** + * @return {Number} + */ + getCmdID () { + return this.getParameter(DeleteCommand.KEY_CMD_ID); + } +} + +DeleteCommand.KEY_CMD_ID = 'cmdID'; + +export { DeleteCommand }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/DeleteCommandResponse.js b/lib/js/src/rpc/messages/DeleteCommandResponse.js new file mode 100644 index 00000000..56acc065 --- /dev/null +++ b/lib/js/src/rpc/messages/DeleteCommandResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class DeleteCommandResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.DeleteCommand); + } +} + + +export { DeleteCommandResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/DeleteFile.js b/lib/js/src/rpc/messages/DeleteFile.js new file mode 100644 index 00000000..3d489d17 --- /dev/null +++ b/lib/js/src/rpc/messages/DeleteFile.js @@ -0,0 +1,69 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Used to delete a file resident on the module in the app's local cache. Not supported on first generation SDL enabled + * vehicles. + */ +class DeleteFile extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.DeleteFile); + } + + /** + * @param {String} name - File reference name. + * @return {DeleteFile} + */ + setSdlFileName (name) { + this.setParameter(DeleteFile.KEY_SDL_FILE_NAME, name); + return this; + } + + /** + * @return {String} + */ + getSdlFileName () { + return this.getParameter(DeleteFile.KEY_SDL_FILE_NAME); + } +} + +DeleteFile.KEY_SDL_FILE_NAME = 'syncFileName'; + +export { DeleteFile }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/DeleteFileResponse.js b/lib/js/src/rpc/messages/DeleteFileResponse.js new file mode 100644 index 00000000..34457726 --- /dev/null +++ b/lib/js/src/rpc/messages/DeleteFileResponse.js @@ -0,0 +1,69 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +/** + * Response is sent, when the file data was deleted (success case). Or when an error occurred. Not supported on First + * generation SDL enabled vehicles. + */ +class DeleteFileResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.DeleteFile); + } + + /** + * @param {Number} available - Provides the total local space available on the module for the registered app. + * @return {DeleteFileResponse} + */ + setSpaceAvailable (available) { + this.setParameter(DeleteFileResponse.KEY_SPACE_AVAILABLE, available); + return this; + } + + /** + * @return {Number} + */ + getSpaceAvailable () { + return this.getParameter(DeleteFileResponse.KEY_SPACE_AVAILABLE); + } +} + +DeleteFileResponse.KEY_SPACE_AVAILABLE = 'spaceAvailable'; + +export { DeleteFileResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/DeleteInteractionChoiceSet.js b/lib/js/src/rpc/messages/DeleteInteractionChoiceSet.js new file mode 100644 index 00000000..85f0a47f --- /dev/null +++ b/lib/js/src/rpc/messages/DeleteInteractionChoiceSet.js @@ -0,0 +1,69 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Deletes interaction choice set that has been created with "CreateInteractionChoiceSet". The interaction may only be + * deleted when not currently in use by a "performInteraction". + */ +class DeleteInteractionChoiceSet extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.DeleteInteractionChoiceSet); + } + + /** + * @param {Number} id - ID of the interaction choice set to delete. + * @return {DeleteInteractionChoiceSet} + */ + setInteractionChoiceSetID (id) { + this.setParameter(DeleteInteractionChoiceSet.KEY_INTERACTION_CHOICE_SET_ID, id); + return this; + } + + /** + * @return {Number} + */ + getInteractionChoiceSetID () { + return this.getParameter(DeleteInteractionChoiceSet.KEY_INTERACTION_CHOICE_SET_ID); + } +} + +DeleteInteractionChoiceSet.KEY_INTERACTION_CHOICE_SET_ID = 'interactionChoiceSetID'; + +export { DeleteInteractionChoiceSet }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/DeleteInteractionChoiceSetResponse.js b/lib/js/src/rpc/messages/DeleteInteractionChoiceSetResponse.js new file mode 100644 index 00000000..2f46dce0 --- /dev/null +++ b/lib/js/src/rpc/messages/DeleteInteractionChoiceSetResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class DeleteInteractionChoiceSetResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.DeleteInteractionChoiceSet); + } +} + + +export { DeleteInteractionChoiceSetResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/DeleteSubMenu.js b/lib/js/src/rpc/messages/DeleteSubMenu.js new file mode 100644 index 00000000..26132c1f --- /dev/null +++ b/lib/js/src/rpc/messages/DeleteSubMenu.js @@ -0,0 +1,68 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Deletes a submenu from the in-application menu. + */ +class DeleteSubMenu extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.DeleteSubMenu); + } + + /** + * @param {Number} id - The "menuID" of the submenu to delete. (See addSubMenu.menuID) + * @return {DeleteSubMenu} + */ + setMenuID (id) { + this.setParameter(DeleteSubMenu.KEY_MENU_ID, id); + return this; + } + + /** + * @return {Number} + */ + getMenuID () { + return this.getParameter(DeleteSubMenu.KEY_MENU_ID); + } +} + +DeleteSubMenu.KEY_MENU_ID = 'menuID'; + +export { DeleteSubMenu }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/DeleteSubMenuResponse.js b/lib/js/src/rpc/messages/DeleteSubMenuResponse.js new file mode 100644 index 00000000..44624c53 --- /dev/null +++ b/lib/js/src/rpc/messages/DeleteSubMenuResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class DeleteSubMenuResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.DeleteSubMenu); + } +} + + +export { DeleteSubMenuResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/DeleteWindow.js b/lib/js/src/rpc/messages/DeleteWindow.js new file mode 100644 index 00000000..c4c99d1f --- /dev/null +++ b/lib/js/src/rpc/messages/DeleteWindow.js @@ -0,0 +1,69 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Deletes previously created window of the SDL application. + */ +class DeleteWindow extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.DeleteWindow); + } + + /** + * @param {Number} id - A unique ID to identify the window. The value of '0' will always be the default main window + * on the main display and cannot be deleted. See PredefinedWindows enum. + * @return {DeleteWindow} + */ + setWindowID (id) { + this.setParameter(DeleteWindow.KEY_WINDOW_ID, id); + return this; + } + + /** + * @return {Number} + */ + getWindowID () { + return this.getParameter(DeleteWindow.KEY_WINDOW_ID); + } +} + +DeleteWindow.KEY_WINDOW_ID = 'windowID'; + +export { DeleteWindow }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/DeleteWindowResponse.js b/lib/js/src/rpc/messages/DeleteWindowResponse.js new file mode 100644 index 00000000..f4f9c409 --- /dev/null +++ b/lib/js/src/rpc/messages/DeleteWindowResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class DeleteWindowResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.DeleteWindow); + } +} + + +export { DeleteWindowResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/DiagnosticMessage.js b/lib/js/src/rpc/messages/DiagnosticMessage.js new file mode 100644 index 00000000..ddddeb28 --- /dev/null +++ b/lib/js/src/rpc/messages/DiagnosticMessage.js @@ -0,0 +1,102 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Non periodic vehicle diagnostic request + */ +class DiagnosticMessage extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.DiagnosticMessage); + } + + /** + * @param {Number} id - Name of target ECU. + * @return {DiagnosticMessage} + */ + setTargetID (id) { + this.setParameter(DiagnosticMessage.KEY_TARGET_ID, id); + return this; + } + + /** + * @return {Number} + */ + getTargetID () { + return this.getParameter(DiagnosticMessage.KEY_TARGET_ID); + } + + /** + * @param {Number} length - Length of message (in bytes). + * @return {DiagnosticMessage} + */ + setMessageLength (length) { + this.setParameter(DiagnosticMessage.KEY_MESSAGE_LENGTH, length); + return this; + } + + /** + * @return {Number} + */ + getMessageLength () { + return this.getParameter(DiagnosticMessage.KEY_MESSAGE_LENGTH); + } + + /** + * @param {Number[]} data - Array of bytes comprising CAN message. + * @return {DiagnosticMessage} + */ + setMessageData (data) { + this.setParameter(DiagnosticMessage.KEY_MESSAGE_DATA, data); + return this; + } + + /** + * @return {Number[]} + */ + getMessageData () { + return this.getParameter(DiagnosticMessage.KEY_MESSAGE_DATA); + } +} + +DiagnosticMessage.KEY_TARGET_ID = 'targetID'; +DiagnosticMessage.KEY_MESSAGE_LENGTH = 'messageLength'; +DiagnosticMessage.KEY_MESSAGE_DATA = 'messageData'; + +export { DiagnosticMessage }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/DiagnosticMessageResponse.js b/lib/js/src/rpc/messages/DiagnosticMessageResponse.js new file mode 100644 index 00000000..32d28058 --- /dev/null +++ b/lib/js/src/rpc/messages/DiagnosticMessageResponse.js @@ -0,0 +1,65 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class DiagnosticMessageResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.DiagnosticMessage); + } + + /** + * @param {Number[]} result - Array of bytes comprising CAN message result. + * @return {DiagnosticMessageResponse} + */ + setMessageDataResult (result) { + this.setParameter(DiagnosticMessageResponse.KEY_MESSAGE_DATA_RESULT, result); + return this; + } + + /** + * @return {Number[]} + */ + getMessageDataResult () { + return this.getParameter(DiagnosticMessageResponse.KEY_MESSAGE_DATA_RESULT); + } +} + +DiagnosticMessageResponse.KEY_MESSAGE_DATA_RESULT = 'messageDataResult'; + +export { DiagnosticMessageResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/DialNumber.js b/lib/js/src/rpc/messages/DialNumber.js new file mode 100644 index 00000000..d4ad65fb --- /dev/null +++ b/lib/js/src/rpc/messages/DialNumber.js @@ -0,0 +1,69 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Dials a phone number and switches to phone application. + */ +class DialNumber extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.DialNumber); + } + + /** + * @param {String} number - Phone number is a string, which can be up to 40 chars. All characters shall be stripped + * from string except digits 0-9 and * # , ; + + * @return {DialNumber} + */ + setNumber (number) { + this.setParameter(DialNumber.KEY_NUMBER, number); + return this; + } + + /** + * @return {String} + */ + getNumber () { + return this.getParameter(DialNumber.KEY_NUMBER); + } +} + +DialNumber.KEY_NUMBER = 'number'; + +export { DialNumber }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/DialNumberResponse.js b/lib/js/src/rpc/messages/DialNumberResponse.js new file mode 100644 index 00000000..9b4eee9d --- /dev/null +++ b/lib/js/src/rpc/messages/DialNumberResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class DialNumberResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.DialNumber); + } +} + + +export { DialNumberResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/EncodedSyncPData.js b/lib/js/src/rpc/messages/EncodedSyncPData.js new file mode 100644 index 00000000..1a920ddd --- /dev/null +++ b/lib/js/src/rpc/messages/EncodedSyncPData.js @@ -0,0 +1,69 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Allows encoded data in the form of SyncP packets to be sent to the SYNC module. Legacy / v1 Protocol implementation; + * use SyncPData instead. *** DEPRECATED *** + */ +class EncodedSyncPData extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.EncodedSyncPData); + } + + /** + * @param {String[]} data - Contains base64 encoded string of SyncP packets. + * @return {EncodedSyncPData} + */ + setData (data) { + this.setParameter(EncodedSyncPData.KEY_DATA, data); + return this; + } + + /** + * @return {String[]} + */ + getData () { + return this.getParameter(EncodedSyncPData.KEY_DATA); + } +} + +EncodedSyncPData.KEY_DATA = 'data'; + +export { EncodedSyncPData }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/EncodedSyncPDataResponse.js b/lib/js/src/rpc/messages/EncodedSyncPDataResponse.js new file mode 100644 index 00000000..083f983a --- /dev/null +++ b/lib/js/src/rpc/messages/EncodedSyncPDataResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class EncodedSyncPDataResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.EncodedSyncPData); + } +} + + +export { EncodedSyncPDataResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/EndAudioPassThru.js b/lib/js/src/rpc/messages/EndAudioPassThru.js new file mode 100644 index 00000000..356b6644 --- /dev/null +++ b/lib/js/src/rpc/messages/EndAudioPassThru.js @@ -0,0 +1,51 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * When this request is invoked, the audio capture stops. + */ +class EndAudioPassThru extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.EndAudioPassThru); + } +} + + +export { EndAudioPassThru }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/EndAudioPassThruResponse.js b/lib/js/src/rpc/messages/EndAudioPassThruResponse.js new file mode 100644 index 00000000..1e072a1c --- /dev/null +++ b/lib/js/src/rpc/messages/EndAudioPassThruResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class EndAudioPassThruResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.EndAudioPassThru); + } +} + + +export { EndAudioPassThruResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/GenericResponseResponse.js b/lib/js/src/rpc/messages/GenericResponseResponse.js new file mode 100644 index 00000000..51773a63 --- /dev/null +++ b/lib/js/src/rpc/messages/GenericResponseResponse.js @@ -0,0 +1,52 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +/** + * Generic Response is sent, when the name of a received msg cannot be retrieved. Only used in case of an error. + * Currently, only resultCode INVALID_DATA is used. + */ +class GenericResponseResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.GenericResponse); + } +} + + +export { GenericResponseResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/GetAppServiceData.js b/lib/js/src/rpc/messages/GetAppServiceData.js new file mode 100644 index 00000000..e61a3a73 --- /dev/null +++ b/lib/js/src/rpc/messages/GetAppServiceData.js @@ -0,0 +1,90 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * This request asks the module for current data related to the specific service. It also includes an option to + * subscribe to that service for future updates + */ +class GetAppServiceData extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.GetAppServiceData); + } + + /** + * @param {String} type - The type of service that is to be offered by this app. See AppServiceType for known enum + * equivalent types. Parameter is a string to allow for new service types to be used by apps + * on older versions of SDL Core. + * @return {GetAppServiceData} + */ + setServiceType (type) { + this.setParameter(GetAppServiceData.KEY_SERVICE_TYPE, type); + return this; + } + + /** + * @return {String} + */ + getServiceType () { + return this.getParameter(GetAppServiceData.KEY_SERVICE_TYPE); + } + + /** + * @param {Boolean} subscribe - If true, the consumer is requesting to subscribe to all future updates from the + * service publisher. If false, the consumer doesn't wish to subscribe and should be + * unsubscribed if it was previously subscribed. + * @return {GetAppServiceData} + */ + setSubscribe (subscribe) { + this.setParameter(GetAppServiceData.KEY_SUBSCRIBE, subscribe); + return this; + } + + /** + * @return {Boolean} + */ + getSubscribe () { + return this.getParameter(GetAppServiceData.KEY_SUBSCRIBE); + } +} + +GetAppServiceData.KEY_SERVICE_TYPE = 'serviceType'; +GetAppServiceData.KEY_SUBSCRIBE = 'subscribe'; + +export { GetAppServiceData }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/GetAppServiceDataResponse.js b/lib/js/src/rpc/messages/GetAppServiceDataResponse.js new file mode 100644 index 00000000..385f3a0f --- /dev/null +++ b/lib/js/src/rpc/messages/GetAppServiceDataResponse.js @@ -0,0 +1,72 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { AppServiceData } from '../structs/AppServiceData.js'; +import { RpcResponse } from '../RpcResponse.js'; + +/** + * This response includes the data that was requested from the specific service + */ +class GetAppServiceDataResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.GetAppServiceData); + } + + /** + * @param {AppServiceData} data - Contains all the current data of the app service. The serviceType will link to + * which of the service data objects are included in this object (e.g. if the service + * type is MEDIA, the mediaServiceData param should be included). + * @return {GetAppServiceDataResponse} + */ + setServiceData (data) { + this.validateType(AppServiceData, data); + this.setParameter(GetAppServiceDataResponse.KEY_SERVICE_DATA, data); + return this; + } + + /** + * @return {AppServiceData} + */ + getServiceData () { + return this.getObject(AppServiceData, GetAppServiceDataResponse.KEY_SERVICE_DATA); + } +} + +GetAppServiceDataResponse.KEY_SERVICE_DATA = 'serviceData'; + +export { GetAppServiceDataResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/GetCloudAppProperties.js b/lib/js/src/rpc/messages/GetCloudAppProperties.js new file mode 100644 index 00000000..02f7f94c --- /dev/null +++ b/lib/js/src/rpc/messages/GetCloudAppProperties.js @@ -0,0 +1,68 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * RPC used to get the current properties of a cloud application + */ +class GetCloudAppProperties extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.GetCloudAppProperties); + } + + /** + * @param {String} id + * @return {GetCloudAppProperties} + */ + setAppID (id) { + this.setParameter(GetCloudAppProperties.KEY_APP_ID, id); + return this; + } + + /** + * @return {String} + */ + getAppID () { + return this.getParameter(GetCloudAppProperties.KEY_APP_ID); + } +} + +GetCloudAppProperties.KEY_APP_ID = 'appID'; + +export { GetCloudAppProperties }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/GetCloudAppPropertiesResponse.js b/lib/js/src/rpc/messages/GetCloudAppPropertiesResponse.js new file mode 100644 index 00000000..65c371a0 --- /dev/null +++ b/lib/js/src/rpc/messages/GetCloudAppPropertiesResponse.js @@ -0,0 +1,70 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { CloudAppProperties } from '../structs/CloudAppProperties.js'; +import { RpcResponse } from '../RpcResponse.js'; + +/** + * The response to GetCloudAppProperties + */ +class GetCloudAppPropertiesResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.GetCloudAppProperties); + } + + /** + * @param {CloudAppProperties} properties - The requested cloud application properties + * @return {GetCloudAppPropertiesResponse} + */ + setProperties (properties) { + this.validateType(CloudAppProperties, properties); + this.setParameter(GetCloudAppPropertiesResponse.KEY_PROPERTIES, properties); + return this; + } + + /** + * @return {CloudAppProperties} + */ + getProperties () { + return this.getObject(CloudAppProperties, GetCloudAppPropertiesResponse.KEY_PROPERTIES); + } +} + +GetCloudAppPropertiesResponse.KEY_PROPERTIES = 'properties'; + +export { GetCloudAppPropertiesResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/GetDTCs.js b/lib/js/src/rpc/messages/GetDTCs.js new file mode 100644 index 00000000..427cb46c --- /dev/null +++ b/lib/js/src/rpc/messages/GetDTCs.js @@ -0,0 +1,85 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Vehicle module diagnostic trouble code request. + */ +class GetDTCs extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.GetDTCs); + } + + /** + * @param {Number} name - Name of ECU. + * @return {GetDTCs} + */ + setEcuName (name) { + this.setParameter(GetDTCs.KEY_ECU_NAME, name); + return this; + } + + /** + * @return {Number} + */ + getEcuName () { + return this.getParameter(GetDTCs.KEY_ECU_NAME); + } + + /** + * @param {Number} mask - DTC Mask Byte to be sent in diagnostic request to module . + * @return {GetDTCs} + */ + setDtcMask (mask) { + this.setParameter(GetDTCs.KEY_DTC_MASK, mask); + return this; + } + + /** + * @return {Number} + */ + getDtcMask () { + return this.getParameter(GetDTCs.KEY_DTC_MASK); + } +} + +GetDTCs.KEY_ECU_NAME = 'ecuName'; +GetDTCs.KEY_DTC_MASK = 'dtcMask'; + +export { GetDTCs }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/GetDTCsResponse.js b/lib/js/src/rpc/messages/GetDTCsResponse.js new file mode 100644 index 00000000..855c4588 --- /dev/null +++ b/lib/js/src/rpc/messages/GetDTCsResponse.js @@ -0,0 +1,84 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class GetDTCsResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.GetDTCs); + } + + /** + * @param {Number} header - 2 byte ECU Header for DTC response (as defined in VHR_Layout_Specification_DTCs.pdf) + * @return {GetDTCsResponse} + */ + setEcuHeader (header) { + this.setParameter(GetDTCsResponse.KEY_ECU_HEADER, header); + return this; + } + + /** + * @return {Number} + */ + getEcuHeader () { + return this.getParameter(GetDTCsResponse.KEY_ECU_HEADER); + } + + /** + * @param {String[]} dtc - Array of all reported DTCs on module (ecuHeader contains information if list is + * truncated). Each DTC is represented by 4 bytes (3 bytes of data and 1 byte status as + * defined in VHR_Layout_Specification_DTCs.pdf). + * @return {GetDTCsResponse} + */ + setDtc (dtc) { + this.setParameter(GetDTCsResponse.KEY_DTC, dtc); + return this; + } + + /** + * @return {String[]} + */ + getDtc () { + return this.getParameter(GetDTCsResponse.KEY_DTC); + } +} + +GetDTCsResponse.KEY_ECU_HEADER = 'ecuHeader'; +GetDTCsResponse.KEY_DTC = 'dtc'; + +export { GetDTCsResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/GetFile.js b/lib/js/src/rpc/messages/GetFile.js new file mode 100644 index 00000000..44c292af --- /dev/null +++ b/lib/js/src/rpc/messages/GetFile.js @@ -0,0 +1,139 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FileType } from '../enums/FileType.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * This request is sent to the module to retrieve a file + */ +class GetFile extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.GetFile); + } + + /** + * @param {String} name - File name that should be retrieved + * @return {GetFile} + */ + setFileName (name) { + this.setParameter(GetFile.KEY_FILE_NAME, name); + return this; + } + + /** + * @return {String} + */ + getFileName () { + return this.getParameter(GetFile.KEY_FILE_NAME); + } + + /** + * @param {String} id - ID of the service that should have uploaded the requested file. + * @return {GetFile} + */ + setAppServiceId (id) { + this.setParameter(GetFile.KEY_APP_SERVICE_ID, id); + return this; + } + + /** + * @return {String} + */ + getAppServiceId () { + return this.getParameter(GetFile.KEY_APP_SERVICE_ID); + } + + /** + * @param {FileType} type - Selected file type. + * @return {GetFile} + */ + setFileType (type) { + this.validateType(FileType, type); + this.setParameter(GetFile.KEY_FILE_TYPE, type); + return this; + } + + /** + * @return {FileType} + */ + getFileType () { + return this.getObject(FileType, GetFile.KEY_FILE_TYPE); + } + + /** + * @param {Number} offset - Optional offset in bytes for resuming partial data chunks + * @return {GetFile} + */ + setOffset (offset) { + this.setParameter(GetFile.KEY_OFFSET, offset); + return this; + } + + /** + * @return {Number} + */ + getOffset () { + return this.getParameter(GetFile.KEY_OFFSET); + } + + /** + * @param {Number} length - Optional length in bytes for resuming partial data chunks If offset is set to 0, then + * length is the total length of the file to be retrieved + * @return {GetFile} + */ + setLength (length) { + this.setParameter(GetFile.KEY_LENGTH, length); + return this; + } + + /** + * @return {Number} + */ + getLength () { + return this.getParameter(GetFile.KEY_LENGTH); + } +} + +GetFile.KEY_FILE_NAME = 'fileName'; +GetFile.KEY_APP_SERVICE_ID = 'appServiceId'; +GetFile.KEY_FILE_TYPE = 'fileType'; +GetFile.KEY_OFFSET = 'offset'; +GetFile.KEY_LENGTH = 'length'; + +export { GetFile }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/GetFileResponse.js b/lib/js/src/rpc/messages/GetFileResponse.js new file mode 100644 index 00000000..5990c58e --- /dev/null +++ b/lib/js/src/rpc/messages/GetFileResponse.js @@ -0,0 +1,122 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; +import { FileType } from '../enums/FileType.js'; + +/** + * This response includes the data that is requested from the specific service + */ +class GetFileResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.GetFile); + } + + /** + * @param {Number} offset - Optional offset in bytes for resuming partial data chunks + * @return {GetFileResponse} + */ + setOffset (offset) { + this.setParameter(GetFileResponse.KEY_OFFSET, offset); + return this; + } + + /** + * @return {Number} + */ + getOffset () { + return this.getParameter(GetFileResponse.KEY_OFFSET); + } + + /** + * @param {Number} length - Optional length in bytes for resuming partial data chunks if offset is set to 0, then + * length is the total length of the file to be downloaded + * @return {GetFileResponse} + */ + setLength (length) { + this.setParameter(GetFileResponse.KEY_LENGTH, length); + return this; + } + + /** + * @return {Number} + */ + getLength () { + return this.getParameter(GetFileResponse.KEY_LENGTH); + } + + /** + * @param {FileType} type - File type that is being sent in response. + * @return {GetFileResponse} + */ + setFileType (type) { + this.validateType(FileType, type); + this.setParameter(GetFileResponse.KEY_FILE_TYPE, type); + return this; + } + + /** + * @return {FileType} + */ + getFileType () { + return this.getObject(FileType, GetFileResponse.KEY_FILE_TYPE); + } + + /** + * @param {Number} crc - Additional CRC32 checksum to protect data integrity up to 512 Mbits + * @return {GetFileResponse} + */ + setCrc (crc) { + this.setParameter(GetFileResponse.KEY_CRC, crc); + return this; + } + + /** + * @return {Number} + */ + getCrc () { + return this.getParameter(GetFileResponse.KEY_CRC); + } +} + +GetFileResponse.KEY_OFFSET = 'offset'; +GetFileResponse.KEY_LENGTH = 'length'; +GetFileResponse.KEY_FILE_TYPE = 'fileType'; +GetFileResponse.KEY_CRC = 'crc'; + +export { GetFileResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/GetInteriorVehicleData.js b/lib/js/src/rpc/messages/GetInteriorVehicleData.js new file mode 100644 index 00000000..6fcaaf85 --- /dev/null +++ b/lib/js/src/rpc/messages/GetInteriorVehicleData.js @@ -0,0 +1,107 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { ModuleType } from '../enums/ModuleType.js'; +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +class GetInteriorVehicleData extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.GetInteriorVehicleData); + } + + /** + * @param {ModuleType} type - The type of a RC module to retrieve module data from the vehicle. In the future, this + * should be the Identification of a module. + * @return {GetInteriorVehicleData} + */ + setModuleType (type) { + this.validateType(ModuleType, type); + this.setParameter(GetInteriorVehicleData.KEY_MODULE_TYPE, type); + return this; + } + + /** + * @return {ModuleType} + */ + getModuleType () { + return this.getObject(ModuleType, GetInteriorVehicleData.KEY_MODULE_TYPE); + } + + /** + * @param {String} id - Id of a module, published by System Capability. + * @return {GetInteriorVehicleData} + */ + setModuleId (id) { + this.setParameter(GetInteriorVehicleData.KEY_MODULE_ID, id); + return this; + } + + /** + * @return {String} + */ + getModuleId () { + return this.getParameter(GetInteriorVehicleData.KEY_MODULE_ID); + } + + /** + * @param {Boolean} subscribe - If subscribe is true, the head unit will register OnInteriorVehicleData + * notifications for the requested module (moduleId and moduleType). If subscribe is + * false, the head unit will unregister OnInteriorVehicleData notifications for the + * requested module (moduleId and moduleType). If subscribe is not included, the + * subscription status of the app for the requested module (moduleId and moduleType) + * will remain unchanged. + * @return {GetInteriorVehicleData} + */ + setSubscribe (subscribe) { + this.setParameter(GetInteriorVehicleData.KEY_SUBSCRIBE, subscribe); + return this; + } + + /** + * @return {Boolean} + */ + getSubscribe () { + return this.getParameter(GetInteriorVehicleData.KEY_SUBSCRIBE); + } +} + +GetInteriorVehicleData.KEY_MODULE_TYPE = 'moduleType'; +GetInteriorVehicleData.KEY_MODULE_ID = 'moduleId'; +GetInteriorVehicleData.KEY_SUBSCRIBE = 'subscribe'; + +export { GetInteriorVehicleData }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/GetInteriorVehicleDataConsent.js b/lib/js/src/rpc/messages/GetInteriorVehicleDataConsent.js new file mode 100644 index 00000000..ba0bc6f3 --- /dev/null +++ b/lib/js/src/rpc/messages/GetInteriorVehicleDataConsent.js @@ -0,0 +1,84 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { ModuleType } from '../enums/ModuleType.js'; +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +class GetInteriorVehicleDataConsent extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.GetInteriorVehicleDataConsent); + } + + /** + * @param {ModuleType} type - The module type that the app requests to control. + * @return {GetInteriorVehicleDataConsent} + */ + setModuleType (type) { + this.validateType(ModuleType, type); + this.setParameter(GetInteriorVehicleDataConsent.KEY_MODULE_TYPE, type); + return this; + } + + /** + * @return {ModuleType} + */ + getModuleType () { + return this.getObject(ModuleType, GetInteriorVehicleDataConsent.KEY_MODULE_TYPE); + } + + /** + * @param {String[]} ids - Ids of a module of same type, published by System Capability. + * @return {GetInteriorVehicleDataConsent} + */ + setModuleIds (ids) { + this.setParameter(GetInteriorVehicleDataConsent.KEY_MODULE_IDS, ids); + return this; + } + + /** + * @return {String[]} + */ + getModuleIds () { + return this.getParameter(GetInteriorVehicleDataConsent.KEY_MODULE_IDS); + } +} + +GetInteriorVehicleDataConsent.KEY_MODULE_TYPE = 'moduleType'; +GetInteriorVehicleDataConsent.KEY_MODULE_IDS = 'moduleIds'; + +export { GetInteriorVehicleDataConsent }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/GetInteriorVehicleDataConsentResponse.js b/lib/js/src/rpc/messages/GetInteriorVehicleDataConsentResponse.js new file mode 100644 index 00000000..2e2f58bf --- /dev/null +++ b/lib/js/src/rpc/messages/GetInteriorVehicleDataConsentResponse.js @@ -0,0 +1,67 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class GetInteriorVehicleDataConsentResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.GetInteriorVehicleDataConsent); + } + + /** + * @param {Boolean[]} allowed - This array has the same size as "moduleIds" in the request and each element + * corresponds to one moduleId If true, SDL grants the permission for the requested + * module If false, SDL denies the permission for the requested module. + * @return {GetInteriorVehicleDataConsentResponse} + */ + setAllowed (allowed) { + this.setParameter(GetInteriorVehicleDataConsentResponse.KEY_ALLOWED, allowed); + return this; + } + + /** + * @return {Boolean[]} + */ + getAllowed () { + return this.getParameter(GetInteriorVehicleDataConsentResponse.KEY_ALLOWED); + } +} + +GetInteriorVehicleDataConsentResponse.KEY_ALLOWED = 'allowed'; + +export { GetInteriorVehicleDataConsentResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/GetInteriorVehicleDataResponse.js b/lib/js/src/rpc/messages/GetInteriorVehicleDataResponse.js new file mode 100644 index 00000000..0390ea09 --- /dev/null +++ b/lib/js/src/rpc/messages/GetInteriorVehicleDataResponse.js @@ -0,0 +1,90 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { ModuleData } from '../structs/ModuleData.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class GetInteriorVehicleDataResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.GetInteriorVehicleData); + } + + /** + * @param {ModuleData} data - The moduleType indicates which type of data should be changed and identifies which + * data object exists in this struct. For example, if the moduleType is CLIMATE then a + * "climateControlData" should exist + * @return {GetInteriorVehicleDataResponse} + */ + setModuleData (data) { + this.validateType(ModuleData, data); + this.setParameter(GetInteriorVehicleDataResponse.KEY_MODULE_DATA, data); + return this; + } + + /** + * @return {ModuleData} + */ + getModuleData () { + return this.getObject(ModuleData, GetInteriorVehicleDataResponse.KEY_MODULE_DATA); + } + + /** + * @param {Boolean} subscribed - It is a conditional-mandatory parameter: must be returned in case "subscribe" + * parameter was present in the related request. if "true" - the "moduleType" from + * request is successfully subscribed and the head unit will send + * onInteriorVehicleData notifications for the moduleType. if "false" - the + * "moduleType" from request is either unsubscribed or failed to subscribe. + * @return {GetInteriorVehicleDataResponse} + */ + setIsSubscribed (subscribed) { + this.setParameter(GetInteriorVehicleDataResponse.KEY_IS_SUBSCRIBED, subscribed); + return this; + } + + /** + * @return {Boolean} + */ + getIsSubscribed () { + return this.getParameter(GetInteriorVehicleDataResponse.KEY_IS_SUBSCRIBED); + } +} + +GetInteriorVehicleDataResponse.KEY_MODULE_DATA = 'moduleData'; +GetInteriorVehicleDataResponse.KEY_IS_SUBSCRIBED = 'isSubscribed'; + +export { GetInteriorVehicleDataResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/GetSystemCapability.js b/lib/js/src/rpc/messages/GetSystemCapability.js new file mode 100644 index 00000000..fa2197d5 --- /dev/null +++ b/lib/js/src/rpc/messages/GetSystemCapability.js @@ -0,0 +1,89 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { SystemCapabilityType } from '../enums/SystemCapabilityType.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Request for expanded information about a supported system/HMI capability + */ +class GetSystemCapability extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.GetSystemCapability); + } + + /** + * @param {SystemCapabilityType} type - The type of system capability to get more information on + * @return {GetSystemCapability} + */ + setSystemCapabilityType (type) { + this.validateType(SystemCapabilityType, type); + this.setParameter(GetSystemCapability.KEY_SYSTEM_CAPABILITY_TYPE, type); + return this; + } + + /** + * @return {SystemCapabilityType} + */ + getSystemCapabilityType () { + return this.getObject(SystemCapabilityType, GetSystemCapability.KEY_SYSTEM_CAPABILITY_TYPE); + } + + /** + * @param {Boolean} subscribe - Flag to subscribe to updates of the supplied service capability type. If true, the + * requester will be subscribed. If false, the requester will not be subscribed and be + * removed as a subscriber if it was previously subscribed. + * @return {GetSystemCapability} + */ + setSubscribe (subscribe) { + this.setParameter(GetSystemCapability.KEY_SUBSCRIBE, subscribe); + return this; + } + + /** + * @return {Boolean} + */ + getSubscribe () { + return this.getParameter(GetSystemCapability.KEY_SUBSCRIBE); + } +} + +GetSystemCapability.KEY_SYSTEM_CAPABILITY_TYPE = 'systemCapabilityType'; +GetSystemCapability.KEY_SUBSCRIBE = 'subscribe'; + +export { GetSystemCapability }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/GetSystemCapabilityResponse.js b/lib/js/src/rpc/messages/GetSystemCapabilityResponse.js new file mode 100644 index 00000000..af0a74a7 --- /dev/null +++ b/lib/js/src/rpc/messages/GetSystemCapabilityResponse.js @@ -0,0 +1,69 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; +import { SystemCapability } from '../structs/SystemCapability.js'; + +class GetSystemCapabilityResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.GetSystemCapability); + } + + /** + * @param {SystemCapability} capability - The systemCapabilityType identifies which data object exists in this + * struct. For example, if the SystemCapability Type is NAVIGATION then a + * "navigationCapability" should exist + * @return {GetSystemCapabilityResponse} + */ + setSystemCapability (capability) { + this.validateType(SystemCapability, capability); + this.setParameter(GetSystemCapabilityResponse.KEY_SYSTEM_CAPABILITY, capability); + return this; + } + + /** + * @return {SystemCapability} + */ + getSystemCapability () { + return this.getObject(SystemCapability, GetSystemCapabilityResponse.KEY_SYSTEM_CAPABILITY); + } +} + +GetSystemCapabilityResponse.KEY_SYSTEM_CAPABILITY = 'systemCapability'; + +export { GetSystemCapabilityResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/GetVehicleData.js b/lib/js/src/rpc/messages/GetVehicleData.js new file mode 100644 index 00000000..132f6c2b --- /dev/null +++ b/lib/js/src/rpc/messages/GetVehicleData.js @@ -0,0 +1,561 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Non periodic vehicle data read request. + */ +class GetVehicleData extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.GetVehicleData); + } + + /** + * @param {Boolean} gps - See GPSData + * @return {GetVehicleData} + */ + setGps (gps) { + this.setParameter(GetVehicleData.KEY_GPS, gps); + return this; + } + + /** + * @return {Boolean} + */ + getGps () { + return this.getParameter(GetVehicleData.KEY_GPS); + } + + /** + * @param {Boolean} speed - The vehicle speed in kilometers per hour + * @return {GetVehicleData} + */ + setSpeed (speed) { + this.setParameter(GetVehicleData.KEY_SPEED, speed); + return this; + } + + /** + * @return {Boolean} + */ + getSpeed () { + return this.getParameter(GetVehicleData.KEY_SPEED); + } + + /** + * @param {Boolean} rpm - The number of revolutions per minute of the engine + * @return {GetVehicleData} + */ + setRpm (rpm) { + this.setParameter(GetVehicleData.KEY_RPM, rpm); + return this; + } + + /** + * @return {Boolean} + */ + getRpm () { + return this.getParameter(GetVehicleData.KEY_RPM); + } + + /** + * @param {Boolean} level - The fuel level in the tank (percentage) + * @return {GetVehicleData} + */ + setFuelLevel (level) { + this.setParameter(GetVehicleData.KEY_FUEL_LEVEL, level); + return this; + } + + /** + * @return {Boolean} + */ + getFuelLevel () { + return this.getParameter(GetVehicleData.KEY_FUEL_LEVEL); + } + + /** + * @param {Boolean} level_state - The fuel level state + * @return {GetVehicleData} + */ + setFuelLevel_State (level_state) { + this.setParameter(GetVehicleData.KEY_FUEL_LEVEL_STATE, level_state); + return this; + } + + /** + * @return {Boolean} + */ + getFuelLevel_State () { + return this.getParameter(GetVehicleData.KEY_FUEL_LEVEL_STATE); + } + + /** + * @param {Boolean} consumption - The instantaneous fuel consumption in microlitres + * @return {GetVehicleData} + */ + setInstantFuelConsumption (consumption) { + this.setParameter(GetVehicleData.KEY_INSTANT_FUEL_CONSUMPTION, consumption); + return this; + } + + /** + * @return {Boolean} + */ + getInstantFuelConsumption () { + return this.getParameter(GetVehicleData.KEY_INSTANT_FUEL_CONSUMPTION); + } + + /** + * @param {Boolean} range - The estimate range in KM the vehicle can travel based on fuel level and consumption + * @return {GetVehicleData} + */ + setFuelRange (range) { + this.setParameter(GetVehicleData.KEY_FUEL_RANGE, range); + return this; + } + + /** + * @return {Boolean} + */ + getFuelRange () { + return this.getParameter(GetVehicleData.KEY_FUEL_RANGE); + } + + /** + * @param {Boolean} temperature - The external temperature in degrees celsius + * @return {GetVehicleData} + */ + setExternalTemperature (temperature) { + this.setParameter(GetVehicleData.KEY_EXTERNAL_TEMPERATURE, temperature); + return this; + } + + /** + * @return {Boolean} + */ + getExternalTemperature () { + return this.getParameter(GetVehicleData.KEY_EXTERNAL_TEMPERATURE); + } + + /** + * @param {Boolean} signal - See TurnSignal + * @return {GetVehicleData} + */ + setTurnSignal (signal) { + this.setParameter(GetVehicleData.KEY_TURN_SIGNAL, signal); + return this; + } + + /** + * @return {Boolean} + */ + getTurnSignal () { + return this.getParameter(GetVehicleData.KEY_TURN_SIGNAL); + } + + /** + * @param {Boolean} vin - Vehicle identification number + * @return {GetVehicleData} + */ + setVin (vin) { + this.setParameter(GetVehicleData.KEY_VIN, vin); + return this; + } + + /** + * @return {Boolean} + */ + getVin () { + return this.getParameter(GetVehicleData.KEY_VIN); + } + + /** + * @param {Boolean} prndl - See PRNDL + * @return {GetVehicleData} + */ + setPrndl (prndl) { + this.setParameter(GetVehicleData.KEY_PRNDL, prndl); + return this; + } + + /** + * @return {Boolean} + */ + getPrndl () { + return this.getParameter(GetVehicleData.KEY_PRNDL); + } + + /** + * @param {Boolean} pressure - See TireStatus + * @return {GetVehicleData} + */ + setTirePressure (pressure) { + this.setParameter(GetVehicleData.KEY_TIRE_PRESSURE, pressure); + return this; + } + + /** + * @return {Boolean} + */ + getTirePressure () { + return this.getParameter(GetVehicleData.KEY_TIRE_PRESSURE); + } + + /** + * @param {Boolean} odometer - Odometer in km + * @return {GetVehicleData} + */ + setOdometer (odometer) { + this.setParameter(GetVehicleData.KEY_ODOMETER, odometer); + return this; + } + + /** + * @return {Boolean} + */ + getOdometer () { + return this.getParameter(GetVehicleData.KEY_ODOMETER); + } + + /** + * @param {Boolean} status - The status of the seat belts + * @return {GetVehicleData} + */ + setBeltStatus (status) { + this.setParameter(GetVehicleData.KEY_BELT_STATUS, status); + return this; + } + + /** + * @return {Boolean} + */ + getBeltStatus () { + return this.getParameter(GetVehicleData.KEY_BELT_STATUS); + } + + /** + * @param {Boolean} information - The body information including ignition status and internal temp + * @return {GetVehicleData} + */ + setBodyInformation (information) { + this.setParameter(GetVehicleData.KEY_BODY_INFORMATION, information); + return this; + } + + /** + * @return {Boolean} + */ + getBodyInformation () { + return this.getParameter(GetVehicleData.KEY_BODY_INFORMATION); + } + + /** + * @param {Boolean} status - The device status including signal and battery strength + * @return {GetVehicleData} + */ + setDeviceStatus (status) { + this.setParameter(GetVehicleData.KEY_DEVICE_STATUS, status); + return this; + } + + /** + * @return {Boolean} + */ + getDeviceStatus () { + return this.getParameter(GetVehicleData.KEY_DEVICE_STATUS); + } + + /** + * @param {Boolean} braking - The status of the brake pedal + * @return {GetVehicleData} + */ + setDriverBraking (braking) { + this.setParameter(GetVehicleData.KEY_DRIVER_BRAKING, braking); + return this; + } + + /** + * @return {Boolean} + */ + getDriverBraking () { + return this.getParameter(GetVehicleData.KEY_DRIVER_BRAKING); + } + + /** + * @param {Boolean} status - The status of the wipers + * @return {GetVehicleData} + */ + setWiperStatus (status) { + this.setParameter(GetVehicleData.KEY_WIPER_STATUS, status); + return this; + } + + /** + * @return {Boolean} + */ + getWiperStatus () { + return this.getParameter(GetVehicleData.KEY_WIPER_STATUS); + } + + /** + * @param {Boolean} status - Status of the head lamps + * @return {GetVehicleData} + */ + setHeadLampStatus (status) { + this.setParameter(GetVehicleData.KEY_HEAD_LAMP_STATUS, status); + return this; + } + + /** + * @return {Boolean} + */ + getHeadLampStatus () { + return this.getParameter(GetVehicleData.KEY_HEAD_LAMP_STATUS); + } + + /** + * @param {Boolean} torque - Torque value for engine (in Nm) on non-diesel variants + * @return {GetVehicleData} + */ + setEngineTorque (torque) { + this.setParameter(GetVehicleData.KEY_ENGINE_TORQUE, torque); + return this; + } + + /** + * @return {Boolean} + */ + getEngineTorque () { + return this.getParameter(GetVehicleData.KEY_ENGINE_TORQUE); + } + + /** + * @param {Boolean} position - Accelerator pedal position (percentage depressed) + * @return {GetVehicleData} + */ + setAccPedalPosition (position) { + this.setParameter(GetVehicleData.KEY_ACC_PEDAL_POSITION, position); + return this; + } + + /** + * @return {Boolean} + */ + getAccPedalPosition () { + return this.getParameter(GetVehicleData.KEY_ACC_PEDAL_POSITION); + } + + /** + * @param {Boolean} angle - Current angle of the steering wheel (in deg) + * @return {GetVehicleData} + */ + setSteeringWheelAngle (angle) { + this.setParameter(GetVehicleData.KEY_STEERING_WHEEL_ANGLE, angle); + return this; + } + + /** + * @return {Boolean} + */ + getSteeringWheelAngle () { + return this.getParameter(GetVehicleData.KEY_STEERING_WHEEL_ANGLE); + } + + /** + * @param {Boolean} life - The estimated percentage of remaining oil life of the engine. + * @return {GetVehicleData} + */ + setEngineOilLife (life) { + this.setParameter(GetVehicleData.KEY_ENGINE_OIL_LIFE, life); + return this; + } + + /** + * @return {Boolean} + */ + getEngineOilLife () { + return this.getParameter(GetVehicleData.KEY_ENGINE_OIL_LIFE); + } + + /** + * @param {Boolean} status - The status of the park brake as provided by Electric Park Brake (EPB) system. + * @return {GetVehicleData} + */ + setElectronicParkBrakeStatus (status) { + this.setParameter(GetVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS, status); + return this; + } + + /** + * @return {Boolean} + */ + getElectronicParkBrakeStatus () { + return this.getParameter(GetVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS); + } + + /** + * @param {Boolean} id - Parameter used by cloud apps to identify a head unit + * @return {GetVehicleData} + */ + setCloudAppVehicleID (id) { + this.setParameter(GetVehicleData.KEY_CLOUD_APP_VEHICLE_ID, id); + return this; + } + + /** + * @return {Boolean} + */ + getCloudAppVehicleID () { + return this.getParameter(GetVehicleData.KEY_CLOUD_APP_VEHICLE_ID); + } + + /** + * @param {Boolean} info - Emergency Call notification and confirmation data + * @return {GetVehicleData} + */ + setECallInfo (info) { + this.setParameter(GetVehicleData.KEY_E_CALL_INFO, info); + return this; + } + + /** + * @return {Boolean} + */ + getECallInfo () { + return this.getParameter(GetVehicleData.KEY_E_CALL_INFO); + } + + /** + * @param {Boolean} status - The status of the air bags + * @return {GetVehicleData} + */ + setAirbagStatus (status) { + this.setParameter(GetVehicleData.KEY_AIRBAG_STATUS, status); + return this; + } + + /** + * @return {Boolean} + */ + getAirbagStatus () { + return this.getParameter(GetVehicleData.KEY_AIRBAG_STATUS); + } + + /** + * @param {Boolean} event - Information related to an emergency event (and if it occurred) + * @return {GetVehicleData} + */ + setEmergencyEvent (event) { + this.setParameter(GetVehicleData.KEY_EMERGENCY_EVENT, event); + return this; + } + + /** + * @return {Boolean} + */ + getEmergencyEvent () { + return this.getParameter(GetVehicleData.KEY_EMERGENCY_EVENT); + } + + /** + * @param {Boolean} status - The status modes of the cluster + * @return {GetVehicleData} + */ + setClusterModeStatus (status) { + this.setParameter(GetVehicleData.KEY_CLUSTER_MODE_STATUS, status); + return this; + } + + /** + * @return {Boolean} + */ + getClusterModeStatus () { + return this.getParameter(GetVehicleData.KEY_CLUSTER_MODE_STATUS); + } + + /** + * @param {Boolean} key - Information related to the MyKey feature + * @return {GetVehicleData} + */ + setMyKey (key) { + this.setParameter(GetVehicleData.KEY_MY_KEY, key); + return this; + } + + /** + * @return {Boolean} + */ + getMyKey () { + return this.getParameter(GetVehicleData.KEY_MY_KEY); + } +} + +GetVehicleData.KEY_GPS = 'gps'; +GetVehicleData.KEY_SPEED = 'speed'; +GetVehicleData.KEY_RPM = 'rpm'; +GetVehicleData.KEY_FUEL_LEVEL = 'fuelLevel'; +GetVehicleData.KEY_FUEL_LEVEL_STATE = 'fuelLevel_State'; +GetVehicleData.KEY_INSTANT_FUEL_CONSUMPTION = 'instantFuelConsumption'; +GetVehicleData.KEY_FUEL_RANGE = 'fuelRange'; +GetVehicleData.KEY_EXTERNAL_TEMPERATURE = 'externalTemperature'; +GetVehicleData.KEY_TURN_SIGNAL = 'turnSignal'; +GetVehicleData.KEY_VIN = 'vin'; +GetVehicleData.KEY_PRNDL = 'prndl'; +GetVehicleData.KEY_TIRE_PRESSURE = 'tirePressure'; +GetVehicleData.KEY_ODOMETER = 'odometer'; +GetVehicleData.KEY_BELT_STATUS = 'beltStatus'; +GetVehicleData.KEY_BODY_INFORMATION = 'bodyInformation'; +GetVehicleData.KEY_DEVICE_STATUS = 'deviceStatus'; +GetVehicleData.KEY_DRIVER_BRAKING = 'driverBraking'; +GetVehicleData.KEY_WIPER_STATUS = 'wiperStatus'; +GetVehicleData.KEY_HEAD_LAMP_STATUS = 'headLampStatus'; +GetVehicleData.KEY_ENGINE_TORQUE = 'engineTorque'; +GetVehicleData.KEY_ACC_PEDAL_POSITION = 'accPedalPosition'; +GetVehicleData.KEY_STEERING_WHEEL_ANGLE = 'steeringWheelAngle'; +GetVehicleData.KEY_ENGINE_OIL_LIFE = 'engineOilLife'; +GetVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS = 'electronicParkBrakeStatus'; +GetVehicleData.KEY_CLOUD_APP_VEHICLE_ID = 'cloudAppVehicleID'; +GetVehicleData.KEY_E_CALL_INFO = 'eCallInfo'; +GetVehicleData.KEY_AIRBAG_STATUS = 'airbagStatus'; +GetVehicleData.KEY_EMERGENCY_EVENT = 'emergencyEvent'; +GetVehicleData.KEY_CLUSTER_MODE_STATUS = 'clusterModeStatus'; +GetVehicleData.KEY_MY_KEY = 'myKey'; + +export { GetVehicleData }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/GetVehicleDataResponse.js b/lib/js/src/rpc/messages/GetVehicleDataResponse.js new file mode 100644 index 00000000..bc9b35a0 --- /dev/null +++ b/lib/js/src/rpc/messages/GetVehicleDataResponse.js @@ -0,0 +1,595 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { AirbagStatus } from '../structs/AirbagStatus.js'; +import { ClusterModeStatus } from '../structs/ClusterModeStatus.js'; +import { VehicleDataEventStatus } from '../enums/VehicleDataEventStatus.js'; +import { EmergencyEvent } from '../structs/EmergencyEvent.js'; +import { TurnSignal } from '../enums/TurnSignal.js'; +import { RpcResponse } from '../RpcResponse.js'; +import { HeadLampStatus } from '../structs/HeadLampStatus.js'; +import { FunctionID } from '../enums/FunctionID.js'; +import { DeviceStatus } from '../structs/DeviceStatus.js'; +import { WiperStatus } from '../enums/WiperStatus.js'; +import { ElectronicParkBrakeStatus } from '../enums/ElectronicParkBrakeStatus.js'; +import { MyKey } from '../structs/MyKey.js'; +import { GPSData } from '../structs/GPSData.js'; +import { PRNDL } from '../enums/PRNDL.js'; +import { FuelRange } from '../structs/FuelRange.js'; +import { ECallInfo } from '../structs/ECallInfo.js'; +import { BeltStatus } from '../structs/BeltStatus.js'; +import { ComponentVolumeStatus } from '../enums/ComponentVolumeStatus.js'; +import { BodyInformation } from '../structs/BodyInformation.js'; +import { TireStatus } from '../structs/TireStatus.js'; + +class GetVehicleDataResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.GetVehicleData); + } + + /** + * @param {GPSData} gps - See GPSData + * @return {GetVehicleDataResponse} + */ + setGps (gps) { + this.validateType(GPSData, gps); + this.setParameter(GetVehicleDataResponse.KEY_GPS, gps); + return this; + } + + /** + * @return {GPSData} + */ + getGps () { + return this.getObject(GPSData, GetVehicleDataResponse.KEY_GPS); + } + + /** + * @param {Number} speed - The vehicle speed in kilometers per hour + * @return {GetVehicleDataResponse} + */ + setSpeed (speed) { + this.setParameter(GetVehicleDataResponse.KEY_SPEED, speed); + return this; + } + + /** + * @return {Number} + */ + getSpeed () { + return this.getParameter(GetVehicleDataResponse.KEY_SPEED); + } + + /** + * @param {Number} rpm - The number of revolutions per minute of the engine + * @return {GetVehicleDataResponse} + */ + setRpm (rpm) { + this.setParameter(GetVehicleDataResponse.KEY_RPM, rpm); + return this; + } + + /** + * @return {Number} + */ + getRpm () { + return this.getParameter(GetVehicleDataResponse.KEY_RPM); + } + + /** + * @param {Number} level - The fuel level in the tank (percentage) + * @return {GetVehicleDataResponse} + */ + setFuelLevel (level) { + this.setParameter(GetVehicleDataResponse.KEY_FUEL_LEVEL, level); + return this; + } + + /** + * @return {Number} + */ + getFuelLevel () { + return this.getParameter(GetVehicleDataResponse.KEY_FUEL_LEVEL); + } + + /** + * @param {ComponentVolumeStatus} level_state - The fuel level state + * @return {GetVehicleDataResponse} + */ + setFuelLevel_State (level_state) { + this.validateType(ComponentVolumeStatus, level_state); + this.setParameter(GetVehicleDataResponse.KEY_FUEL_LEVEL_STATE, level_state); + return this; + } + + /** + * @return {ComponentVolumeStatus} + */ + getFuelLevel_State () { + return this.getObject(ComponentVolumeStatus, GetVehicleDataResponse.KEY_FUEL_LEVEL_STATE); + } + + /** + * @param {Number} consumption - The instantaneous fuel consumption in microlitres + * @return {GetVehicleDataResponse} + */ + setInstantFuelConsumption (consumption) { + this.setParameter(GetVehicleDataResponse.KEY_INSTANT_FUEL_CONSUMPTION, consumption); + return this; + } + + /** + * @return {Number} + */ + getInstantFuelConsumption () { + return this.getParameter(GetVehicleDataResponse.KEY_INSTANT_FUEL_CONSUMPTION); + } + + /** + * @param {FuelRange[]} range - The estimate range in KM the vehicle can travel based on fuel level and consumption + * @return {GetVehicleDataResponse} + */ + setFuelRange (range) { + this.validateType(FuelRange, range, true); + this.setParameter(GetVehicleDataResponse.KEY_FUEL_RANGE, range); + return this; + } + + /** + * @return {FuelRange[]} + */ + getFuelRange () { + return this.getObject(FuelRange, GetVehicleDataResponse.KEY_FUEL_RANGE); + } + + /** + * @param {Number} temperature - The external temperature in degrees celsius + * @return {GetVehicleDataResponse} + */ + setExternalTemperature (temperature) { + this.setParameter(GetVehicleDataResponse.KEY_EXTERNAL_TEMPERATURE, temperature); + return this; + } + + /** + * @return {Number} + */ + getExternalTemperature () { + return this.getParameter(GetVehicleDataResponse.KEY_EXTERNAL_TEMPERATURE); + } + + /** + * @param {TurnSignal} signal - See TurnSignal + * @return {GetVehicleDataResponse} + */ + setTurnSignal (signal) { + this.validateType(TurnSignal, signal); + this.setParameter(GetVehicleDataResponse.KEY_TURN_SIGNAL, signal); + return this; + } + + /** + * @return {TurnSignal} + */ + getTurnSignal () { + return this.getObject(TurnSignal, GetVehicleDataResponse.KEY_TURN_SIGNAL); + } + + /** + * @param {String} vin - Vehicle identification number + * @return {GetVehicleDataResponse} + */ + setVin (vin) { + this.setParameter(GetVehicleDataResponse.KEY_VIN, vin); + return this; + } + + /** + * @return {String} + */ + getVin () { + return this.getParameter(GetVehicleDataResponse.KEY_VIN); + } + + /** + * @param {PRNDL} prndl - See PRNDL + * @return {GetVehicleDataResponse} + */ + setPrndl (prndl) { + this.validateType(PRNDL, prndl); + this.setParameter(GetVehicleDataResponse.KEY_PRNDL, prndl); + return this; + } + + /** + * @return {PRNDL} + */ + getPrndl () { + return this.getObject(PRNDL, GetVehicleDataResponse.KEY_PRNDL); + } + + /** + * @param {TireStatus} pressure - See TireStatus + * @return {GetVehicleDataResponse} + */ + setTirePressure (pressure) { + this.validateType(TireStatus, pressure); + this.setParameter(GetVehicleDataResponse.KEY_TIRE_PRESSURE, pressure); + return this; + } + + /** + * @return {TireStatus} + */ + getTirePressure () { + return this.getObject(TireStatus, GetVehicleDataResponse.KEY_TIRE_PRESSURE); + } + + /** + * @param {Number} odometer - Odometer in km + * @return {GetVehicleDataResponse} + */ + setOdometer (odometer) { + this.setParameter(GetVehicleDataResponse.KEY_ODOMETER, odometer); + return this; + } + + /** + * @return {Number} + */ + getOdometer () { + return this.getParameter(GetVehicleDataResponse.KEY_ODOMETER); + } + + /** + * @param {BeltStatus} status - The status of the seat belts + * @return {GetVehicleDataResponse} + */ + setBeltStatus (status) { + this.validateType(BeltStatus, status); + this.setParameter(GetVehicleDataResponse.KEY_BELT_STATUS, status); + return this; + } + + /** + * @return {BeltStatus} + */ + getBeltStatus () { + return this.getObject(BeltStatus, GetVehicleDataResponse.KEY_BELT_STATUS); + } + + /** + * @param {BodyInformation} information - The body information including power modes + * @return {GetVehicleDataResponse} + */ + setBodyInformation (information) { + this.validateType(BodyInformation, information); + this.setParameter(GetVehicleDataResponse.KEY_BODY_INFORMATION, information); + return this; + } + + /** + * @return {BodyInformation} + */ + getBodyInformation () { + return this.getObject(BodyInformation, GetVehicleDataResponse.KEY_BODY_INFORMATION); + } + + /** + * @param {DeviceStatus} status - The device status including signal and battery strength + * @return {GetVehicleDataResponse} + */ + setDeviceStatus (status) { + this.validateType(DeviceStatus, status); + this.setParameter(GetVehicleDataResponse.KEY_DEVICE_STATUS, status); + return this; + } + + /** + * @return {DeviceStatus} + */ + getDeviceStatus () { + return this.getObject(DeviceStatus, GetVehicleDataResponse.KEY_DEVICE_STATUS); + } + + /** + * @param {VehicleDataEventStatus} braking - The status of the brake pedal + * @return {GetVehicleDataResponse} + */ + setDriverBraking (braking) { + this.validateType(VehicleDataEventStatus, braking); + this.setParameter(GetVehicleDataResponse.KEY_DRIVER_BRAKING, braking); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getDriverBraking () { + return this.getObject(VehicleDataEventStatus, GetVehicleDataResponse.KEY_DRIVER_BRAKING); + } + + /** + * @param {WiperStatus} status - The status of the wipers + * @return {GetVehicleDataResponse} + */ + setWiperStatus (status) { + this.validateType(WiperStatus, status); + this.setParameter(GetVehicleDataResponse.KEY_WIPER_STATUS, status); + return this; + } + + /** + * @return {WiperStatus} + */ + getWiperStatus () { + return this.getObject(WiperStatus, GetVehicleDataResponse.KEY_WIPER_STATUS); + } + + /** + * @param {HeadLampStatus} status - Status of the head lamps + * @return {GetVehicleDataResponse} + */ + setHeadLampStatus (status) { + this.validateType(HeadLampStatus, status); + this.setParameter(GetVehicleDataResponse.KEY_HEAD_LAMP_STATUS, status); + return this; + } + + /** + * @return {HeadLampStatus} + */ + getHeadLampStatus () { + return this.getObject(HeadLampStatus, GetVehicleDataResponse.KEY_HEAD_LAMP_STATUS); + } + + /** + * @param {Number} torque - Torque value for engine (in Nm) on non-diesel variants + * @return {GetVehicleDataResponse} + */ + setEngineTorque (torque) { + this.setParameter(GetVehicleDataResponse.KEY_ENGINE_TORQUE, torque); + return this; + } + + /** + * @return {Number} + */ + getEngineTorque () { + return this.getParameter(GetVehicleDataResponse.KEY_ENGINE_TORQUE); + } + + /** + * @param {Number} position - Accelerator pedal position (percentage depressed) + * @return {GetVehicleDataResponse} + */ + setAccPedalPosition (position) { + this.setParameter(GetVehicleDataResponse.KEY_ACC_PEDAL_POSITION, position); + return this; + } + + /** + * @return {Number} + */ + getAccPedalPosition () { + return this.getParameter(GetVehicleDataResponse.KEY_ACC_PEDAL_POSITION); + } + + /** + * @param {Number} angle - Current angle of the steering wheel (in deg) + * @return {GetVehicleDataResponse} + */ + setSteeringWheelAngle (angle) { + this.setParameter(GetVehicleDataResponse.KEY_STEERING_WHEEL_ANGLE, angle); + return this; + } + + /** + * @return {Number} + */ + getSteeringWheelAngle () { + return this.getParameter(GetVehicleDataResponse.KEY_STEERING_WHEEL_ANGLE); + } + + /** + * @param {Number} life - The estimated percentage of remaining oil life of the engine. + * @return {GetVehicleDataResponse} + */ + setEngineOilLife (life) { + this.setParameter(GetVehicleDataResponse.KEY_ENGINE_OIL_LIFE, life); + return this; + } + + /** + * @return {Number} + */ + getEngineOilLife () { + return this.getParameter(GetVehicleDataResponse.KEY_ENGINE_OIL_LIFE); + } + + /** + * @param {ElectronicParkBrakeStatus} status - The status of the park brake as provided by Electric Park Brake (EPB) + * system. + * @return {GetVehicleDataResponse} + */ + setElectronicParkBrakeStatus (status) { + this.validateType(ElectronicParkBrakeStatus, status); + this.setParameter(GetVehicleDataResponse.KEY_ELECTRONIC_PARK_BRAKE_STATUS, status); + return this; + } + + /** + * @return {ElectronicParkBrakeStatus} + */ + getElectronicParkBrakeStatus () { + return this.getObject(ElectronicParkBrakeStatus, GetVehicleDataResponse.KEY_ELECTRONIC_PARK_BRAKE_STATUS); + } + + /** + * @param {String} id - Parameter used by cloud apps to identify a head unit + * @return {GetVehicleDataResponse} + */ + setCloudAppVehicleID (id) { + this.setParameter(GetVehicleDataResponse.KEY_CLOUD_APP_VEHICLE_ID, id); + return this; + } + + /** + * @return {String} + */ + getCloudAppVehicleID () { + return this.getParameter(GetVehicleDataResponse.KEY_CLOUD_APP_VEHICLE_ID); + } + + /** + * @param {ECallInfo} info - Emergency Call notification and confirmation data + * @return {GetVehicleDataResponse} + */ + setECallInfo (info) { + this.validateType(ECallInfo, info); + this.setParameter(GetVehicleDataResponse.KEY_E_CALL_INFO, info); + return this; + } + + /** + * @return {ECallInfo} + */ + getECallInfo () { + return this.getObject(ECallInfo, GetVehicleDataResponse.KEY_E_CALL_INFO); + } + + /** + * @param {AirbagStatus} status - The status of the air bags + * @return {GetVehicleDataResponse} + */ + setAirbagStatus (status) { + this.validateType(AirbagStatus, status); + this.setParameter(GetVehicleDataResponse.KEY_AIRBAG_STATUS, status); + return this; + } + + /** + * @return {AirbagStatus} + */ + getAirbagStatus () { + return this.getObject(AirbagStatus, GetVehicleDataResponse.KEY_AIRBAG_STATUS); + } + + /** + * @param {EmergencyEvent} event - Information related to an emergency event (and if it occurred) + * @return {GetVehicleDataResponse} + */ + setEmergencyEvent (event) { + this.validateType(EmergencyEvent, event); + this.setParameter(GetVehicleDataResponse.KEY_EMERGENCY_EVENT, event); + return this; + } + + /** + * @return {EmergencyEvent} + */ + getEmergencyEvent () { + return this.getObject(EmergencyEvent, GetVehicleDataResponse.KEY_EMERGENCY_EVENT); + } + + /** + * @param {ClusterModeStatus} status - The status modes of the cluster + * @return {GetVehicleDataResponse} + */ + setClusterModeStatus (status) { + this.validateType(ClusterModeStatus, status); + this.setParameter(GetVehicleDataResponse.KEY_CLUSTER_MODE_STATUS, status); + return this; + } + + /** + * @return {ClusterModeStatus} + */ + getClusterModeStatus () { + return this.getObject(ClusterModeStatus, GetVehicleDataResponse.KEY_CLUSTER_MODE_STATUS); + } + + /** + * @param {MyKey} key - Information related to the MyKey feature + * @return {GetVehicleDataResponse} + */ + setMyKey (key) { + this.validateType(MyKey, key); + this.setParameter(GetVehicleDataResponse.KEY_MY_KEY, key); + return this; + } + + /** + * @return {MyKey} + */ + getMyKey () { + return this.getObject(MyKey, GetVehicleDataResponse.KEY_MY_KEY); + } +} + +GetVehicleDataResponse.KEY_GPS = 'gps'; +GetVehicleDataResponse.KEY_SPEED = 'speed'; +GetVehicleDataResponse.KEY_RPM = 'rpm'; +GetVehicleDataResponse.KEY_FUEL_LEVEL = 'fuelLevel'; +GetVehicleDataResponse.KEY_FUEL_LEVEL_STATE = 'fuelLevel_State'; +GetVehicleDataResponse.KEY_INSTANT_FUEL_CONSUMPTION = 'instantFuelConsumption'; +GetVehicleDataResponse.KEY_FUEL_RANGE = 'fuelRange'; +GetVehicleDataResponse.KEY_EXTERNAL_TEMPERATURE = 'externalTemperature'; +GetVehicleDataResponse.KEY_TURN_SIGNAL = 'turnSignal'; +GetVehicleDataResponse.KEY_VIN = 'vin'; +GetVehicleDataResponse.KEY_PRNDL = 'prndl'; +GetVehicleDataResponse.KEY_TIRE_PRESSURE = 'tirePressure'; +GetVehicleDataResponse.KEY_ODOMETER = 'odometer'; +GetVehicleDataResponse.KEY_BELT_STATUS = 'beltStatus'; +GetVehicleDataResponse.KEY_BODY_INFORMATION = 'bodyInformation'; +GetVehicleDataResponse.KEY_DEVICE_STATUS = 'deviceStatus'; +GetVehicleDataResponse.KEY_DRIVER_BRAKING = 'driverBraking'; +GetVehicleDataResponse.KEY_WIPER_STATUS = 'wiperStatus'; +GetVehicleDataResponse.KEY_HEAD_LAMP_STATUS = 'headLampStatus'; +GetVehicleDataResponse.KEY_ENGINE_TORQUE = 'engineTorque'; +GetVehicleDataResponse.KEY_ACC_PEDAL_POSITION = 'accPedalPosition'; +GetVehicleDataResponse.KEY_STEERING_WHEEL_ANGLE = 'steeringWheelAngle'; +GetVehicleDataResponse.KEY_ENGINE_OIL_LIFE = 'engineOilLife'; +GetVehicleDataResponse.KEY_ELECTRONIC_PARK_BRAKE_STATUS = 'electronicParkBrakeStatus'; +GetVehicleDataResponse.KEY_CLOUD_APP_VEHICLE_ID = 'cloudAppVehicleID'; +GetVehicleDataResponse.KEY_E_CALL_INFO = 'eCallInfo'; +GetVehicleDataResponse.KEY_AIRBAG_STATUS = 'airbagStatus'; +GetVehicleDataResponse.KEY_EMERGENCY_EVENT = 'emergencyEvent'; +GetVehicleDataResponse.KEY_CLUSTER_MODE_STATUS = 'clusterModeStatus'; +GetVehicleDataResponse.KEY_MY_KEY = 'myKey'; + +export { GetVehicleDataResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/GetWayPoints.js b/lib/js/src/rpc/messages/GetWayPoints.js new file mode 100644 index 00000000..1e788796 --- /dev/null +++ b/lib/js/src/rpc/messages/GetWayPoints.js @@ -0,0 +1,71 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { WayPointType } from '../enums/WayPointType.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Request for getting waypoint/destination data. + */ +class GetWayPoints extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.GetWayPoints); + } + + /** + * @param {WayPointType} type - To request for either the destination only or for all waypoints including + * destination + * @return {GetWayPoints} + */ + setWayPointType (type) { + this.validateType(WayPointType, type); + this.setParameter(GetWayPoints.KEY_WAY_POINT_TYPE, type); + return this; + } + + /** + * @return {WayPointType} + */ + getWayPointType () { + return this.getObject(WayPointType, GetWayPoints.KEY_WAY_POINT_TYPE); + } +} + +GetWayPoints.KEY_WAY_POINT_TYPE = 'wayPointType'; + +export { GetWayPoints }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/GetWayPointsResponse.js b/lib/js/src/rpc/messages/GetWayPointsResponse.js new file mode 100644 index 00000000..4125d554 --- /dev/null +++ b/lib/js/src/rpc/messages/GetWayPointsResponse.js @@ -0,0 +1,67 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { LocationDetails } from '../structs/LocationDetails.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class GetWayPointsResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.GetWayPoints); + } + + /** + * @param {LocationDetails[]} points - See LocationDetails + * @return {GetWayPointsResponse} + */ + setWayPoints (points) { + this.validateType(LocationDetails, points, true); + this.setParameter(GetWayPointsResponse.KEY_WAY_POINTS, points); + return this; + } + + /** + * @return {LocationDetails[]} + */ + getWayPoints () { + return this.getObject(LocationDetails, GetWayPointsResponse.KEY_WAY_POINTS); + } +} + +GetWayPointsResponse.KEY_WAY_POINTS = 'wayPoints'; + +export { GetWayPointsResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/ListFiles.js b/lib/js/src/rpc/messages/ListFiles.js new file mode 100644 index 00000000..6c52abf1 --- /dev/null +++ b/lib/js/src/rpc/messages/ListFiles.js @@ -0,0 +1,52 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Requests the current list of resident filenames for the registered app. Not supported on first generation SDL + * enabled vehicles. + */ +class ListFiles extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.ListFiles); + } +} + + +export { ListFiles }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/ListFilesResponse.js b/lib/js/src/rpc/messages/ListFilesResponse.js new file mode 100644 index 00000000..29a1bee9 --- /dev/null +++ b/lib/js/src/rpc/messages/ListFilesResponse.js @@ -0,0 +1,87 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +/** + * Returns the current list of resident filenames for the registered app along with the current space available Not + * supported on First generation SDL enabled vehicles. + */ +class ListFilesResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.ListFiles); + } + + /** + * @param {String[]} filenames - An array of all filenames resident on the module for the given registered app. If + * omitted, then no files currently reside on the system. + * @return {ListFilesResponse} + */ + setFilenames (filenames) { + this.setParameter(ListFilesResponse.KEY_FILENAMES, filenames); + return this; + } + + /** + * @return {String[]} + */ + getFilenames () { + return this.getParameter(ListFilesResponse.KEY_FILENAMES); + } + + /** + * @param {Number} available - Provides the total local space available on the module for the registered app. + * @return {ListFilesResponse} + */ + setSpaceAvailable (available) { + this.setParameter(ListFilesResponse.KEY_SPACE_AVAILABLE, available); + return this; + } + + /** + * @return {Number} + */ + getSpaceAvailable () { + return this.getParameter(ListFilesResponse.KEY_SPACE_AVAILABLE); + } +} + +ListFilesResponse.KEY_FILENAMES = 'filenames'; +ListFilesResponse.KEY_SPACE_AVAILABLE = 'spaceAvailable'; + +export { ListFilesResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/OnAppInterfaceUnregistered.js b/lib/js/src/rpc/messages/OnAppInterfaceUnregistered.js new file mode 100644 index 00000000..54fee94c --- /dev/null +++ b/lib/js/src/rpc/messages/OnAppInterfaceUnregistered.js @@ -0,0 +1,67 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { AppInterfaceUnregisteredReason } from '../enums/AppInterfaceUnregisteredReason.js'; +import { RpcNotification } from '../RpcNotification.js'; + +class OnAppInterfaceUnregistered extends RpcNotification { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.OnAppInterfaceUnregistered); + } + + /** + * @param {AppInterfaceUnregisteredReason} reason - See AppInterfaceUnregisteredReason + * @return {OnAppInterfaceUnregistered} + */ + setReason (reason) { + this.validateType(AppInterfaceUnregisteredReason, reason); + this.setParameter(OnAppInterfaceUnregistered.KEY_REASON, reason); + return this; + } + + /** + * @return {AppInterfaceUnregisteredReason} + */ + getReason () { + return this.getObject(AppInterfaceUnregisteredReason, OnAppInterfaceUnregistered.KEY_REASON); + } +} + +OnAppInterfaceUnregistered.KEY_REASON = 'reason'; + +export { OnAppInterfaceUnregistered }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/OnAppServiceData.js b/lib/js/src/rpc/messages/OnAppServiceData.js new file mode 100644 index 00000000..0274e210 --- /dev/null +++ b/lib/js/src/rpc/messages/OnAppServiceData.js @@ -0,0 +1,72 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { AppServiceData } from '../structs/AppServiceData.js'; +import { RpcNotification } from '../RpcNotification.js'; + +/** + * This notification includes the data that is updated from the specific service + */ +class OnAppServiceData extends RpcNotification { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.OnAppServiceData); + } + + /** + * @param {AppServiceData} data - Contains all the current data of the app service. The serviceType will link to + * which of the service data objects are included in this object (e.g. if the service + * type is MEDIA, the mediaServiceData param should be included). + * @return {OnAppServiceData} + */ + setServiceData (data) { + this.validateType(AppServiceData, data); + this.setParameter(OnAppServiceData.KEY_SERVICE_DATA, data); + return this; + } + + /** + * @return {AppServiceData} + */ + getServiceData () { + return this.getObject(AppServiceData, OnAppServiceData.KEY_SERVICE_DATA); + } +} + +OnAppServiceData.KEY_SERVICE_DATA = 'serviceData'; + +export { OnAppServiceData }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/OnAudioPassThru.js b/lib/js/src/rpc/messages/OnAudioPassThru.js new file mode 100644 index 00000000..b27a5379 --- /dev/null +++ b/lib/js/src/rpc/messages/OnAudioPassThru.js @@ -0,0 +1,51 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcNotification } from '../RpcNotification.js'; + +/** + * Binary data is in binary part of hybrid msg + */ +class OnAudioPassThru extends RpcNotification { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.OnAudioPassThru); + } +} + + +export { OnAudioPassThru }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/OnButtonEvent.js b/lib/js/src/rpc/messages/OnButtonEvent.js new file mode 100644 index 00000000..1f05633b --- /dev/null +++ b/lib/js/src/rpc/messages/OnButtonEvent.js @@ -0,0 +1,107 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { ButtonName } from '../enums/ButtonName.js'; +import { ButtonEventMode } from '../enums/ButtonEventMode.js'; +import { RpcNotification } from '../RpcNotification.js'; + +/** + * Notifies application of UP/DOWN events for buttons to which the application is subscribed. + */ +class OnButtonEvent extends RpcNotification { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.OnButtonEvent); + } + + /** + * @param {ButtonName} name - Defines the hard (physical) and soft (touchscreen) buttons available from the module + * @return {OnButtonEvent} + */ + setButtonName (name) { + this.validateType(ButtonName, name); + this.setParameter(OnButtonEvent.KEY_BUTTON_NAME, name); + return this; + } + + /** + * @return {ButtonName} + */ + getButtonName () { + return this.getObject(ButtonName, OnButtonEvent.KEY_BUTTON_NAME); + } + + /** + * @param {ButtonEventMode} mode - Indicates whether this is an UP or DOWN event. + * @return {OnButtonEvent} + */ + setButtonEventMode (mode) { + this.validateType(ButtonEventMode, mode); + this.setParameter(OnButtonEvent.KEY_BUTTON_EVENT_MODE, mode); + return this; + } + + /** + * @return {ButtonEventMode} + */ + getButtonEventMode () { + return this.getObject(ButtonEventMode, OnButtonEvent.KEY_BUTTON_EVENT_MODE); + } + + /** + * @param {Number} id - If ButtonName is "CUSTOM_BUTTON", this references the integer ID passed by a custom button. + * (e.g. softButton ID) + * @return {OnButtonEvent} + */ + setCustomButtonID (id) { + this.setParameter(OnButtonEvent.KEY_CUSTOM_BUTTON_ID, id); + return this; + } + + /** + * @return {Number} + */ + getCustomButtonID () { + return this.getParameter(OnButtonEvent.KEY_CUSTOM_BUTTON_ID); + } +} + +OnButtonEvent.KEY_BUTTON_NAME = 'buttonName'; +OnButtonEvent.KEY_BUTTON_EVENT_MODE = 'buttonEventMode'; +OnButtonEvent.KEY_CUSTOM_BUTTON_ID = 'customButtonID'; + +export { OnButtonEvent }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/OnButtonPress.js b/lib/js/src/rpc/messages/OnButtonPress.js new file mode 100644 index 00000000..a65d0a3f --- /dev/null +++ b/lib/js/src/rpc/messages/OnButtonPress.js @@ -0,0 +1,107 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { ButtonPressMode } from '../enums/ButtonPressMode.js'; +import { FunctionID } from '../enums/FunctionID.js'; +import { ButtonName } from '../enums/ButtonName.js'; +import { RpcNotification } from '../RpcNotification.js'; + +/** + * Notifies application of LONG/SHORT press events for buttons to which the application is subscribed. + */ +class OnButtonPress extends RpcNotification { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.OnButtonPress); + } + + /** + * @param {ButtonName} name - Defines the hard (physical) and soft (touchscreen) buttons available from the module + * @return {OnButtonPress} + */ + setButtonName (name) { + this.validateType(ButtonName, name); + this.setParameter(OnButtonPress.KEY_BUTTON_NAME, name); + return this; + } + + /** + * @return {ButtonName} + */ + getButtonName () { + return this.getObject(ButtonName, OnButtonPress.KEY_BUTTON_NAME); + } + + /** + * @param {ButtonPressMode} mode - Indicates whether this is a LONG or SHORT button press event. + * @return {OnButtonPress} + */ + setButtonPressMode (mode) { + this.validateType(ButtonPressMode, mode); + this.setParameter(OnButtonPress.KEY_BUTTON_PRESS_MODE, mode); + return this; + } + + /** + * @return {ButtonPressMode} + */ + getButtonPressMode () { + return this.getObject(ButtonPressMode, OnButtonPress.KEY_BUTTON_PRESS_MODE); + } + + /** + * @param {Number} id - If ButtonName is "CUSTOM_BUTTON", this references the integer ID passed by a custom button. + * (e.g. softButton ID) + * @return {OnButtonPress} + */ + setCustomButtonID (id) { + this.setParameter(OnButtonPress.KEY_CUSTOM_BUTTON_ID, id); + return this; + } + + /** + * @return {Number} + */ + getCustomButtonID () { + return this.getParameter(OnButtonPress.KEY_CUSTOM_BUTTON_ID); + } +} + +OnButtonPress.KEY_BUTTON_NAME = 'buttonName'; +OnButtonPress.KEY_BUTTON_PRESS_MODE = 'buttonPressMode'; +OnButtonPress.KEY_CUSTOM_BUTTON_ID = 'customButtonID'; + +export { OnButtonPress }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/OnCommand.js b/lib/js/src/rpc/messages/OnCommand.js new file mode 100644 index 00000000..ac903e95 --- /dev/null +++ b/lib/js/src/rpc/messages/OnCommand.js @@ -0,0 +1,84 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { TriggerSource } from '../enums/TriggerSource.js'; +import { RpcNotification } from '../RpcNotification.js'; + +class OnCommand extends RpcNotification { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.OnCommand); + } + + /** + * @param {Number} id - Command ID, which is related to a specific menu entry + * @return {OnCommand} + */ + setCmdID (id) { + this.setParameter(OnCommand.KEY_CMD_ID, id); + return this; + } + + /** + * @return {Number} + */ + getCmdID () { + return this.getParameter(OnCommand.KEY_CMD_ID); + } + + /** + * @param {TriggerSource} source - See TriggerSource + * @return {OnCommand} + */ + setTriggerSource (source) { + this.validateType(TriggerSource, source); + this.setParameter(OnCommand.KEY_TRIGGER_SOURCE, source); + return this; + } + + /** + * @return {TriggerSource} + */ + getTriggerSource () { + return this.getObject(TriggerSource, OnCommand.KEY_TRIGGER_SOURCE); + } +} + +OnCommand.KEY_CMD_ID = 'cmdID'; +OnCommand.KEY_TRIGGER_SOURCE = 'triggerSource'; + +export { OnCommand }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/OnDriverDistraction.js b/lib/js/src/rpc/messages/OnDriverDistraction.js new file mode 100644 index 00000000..fa5f6c02 --- /dev/null +++ b/lib/js/src/rpc/messages/OnDriverDistraction.js @@ -0,0 +1,109 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { DriverDistractionState } from '../enums/DriverDistractionState.js'; +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcNotification } from '../RpcNotification.js'; + +/** + * Provides driver distraction state to mobile applications + */ +class OnDriverDistraction extends RpcNotification { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.OnDriverDistraction); + } + + /** + * @param {DriverDistractionState} state - Current State of Driver Distraction + * @return {OnDriverDistraction} + */ + setState (state) { + this.validateType(DriverDistractionState, state); + this.setParameter(OnDriverDistraction.KEY_STATE, state); + return this; + } + + /** + * @return {DriverDistractionState} + */ + getState () { + return this.getObject(DriverDistractionState, OnDriverDistraction.KEY_STATE); + } + + /** + * @param {Boolean} enabled - If enabled, the lock screen will be able to be dismissed while connected to SDL, + * allowing users the ability to interact with the app. Dismissals should include a + * warning to the user and ensure that they are not the driver. + * @return {OnDriverDistraction} + */ + setLockScreenDismissalEnabled (enabled) { + this.setParameter(OnDriverDistraction.KEY_LOCK_SCREEN_DISMISSAL_ENABLED, enabled); + return this; + } + + /** + * @return {Boolean} + */ + getLockScreenDismissalEnabled () { + return this.getParameter(OnDriverDistraction.KEY_LOCK_SCREEN_DISMISSAL_ENABLED); + } + + /** + * @param {String} warning - Warning message to be displayed on the lock screen when dismissal is enabled. This + * warning should be used to ensure that the user is not the driver of the vehicle, ex. + * `Swipe down to dismiss, acknowledging that you are not the driver.`. This parameter + * must be present if "lockScreenDismissalEnabled" is set to true. + * @return {OnDriverDistraction} + */ + setLockScreenDismissalWarning (warning) { + this.setParameter(OnDriverDistraction.KEY_LOCK_SCREEN_DISMISSAL_WARNING, warning); + return this; + } + + /** + * @return {String} + */ + getLockScreenDismissalWarning () { + return this.getParameter(OnDriverDistraction.KEY_LOCK_SCREEN_DISMISSAL_WARNING); + } +} + +OnDriverDistraction.KEY_STATE = 'state'; +OnDriverDistraction.KEY_LOCK_SCREEN_DISMISSAL_ENABLED = 'lockScreenDismissalEnabled'; +OnDriverDistraction.KEY_LOCK_SCREEN_DISMISSAL_WARNING = 'lockScreenDismissalWarning'; + +export { OnDriverDistraction }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/OnEncodedSyncPData.js b/lib/js/src/rpc/messages/OnEncodedSyncPData.js new file mode 100644 index 00000000..0a39b17d --- /dev/null +++ b/lib/js/src/rpc/messages/OnEncodedSyncPData.js @@ -0,0 +1,105 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcNotification } from '../RpcNotification.js'; + +/** + * Callback including encoded data of any SyncP packets that SYNC needs to send back to the mobile device. Legacy / v1 + * Protocol implementation; responds to EncodedSyncPData. *** DEPRECATED *** + */ +class OnEncodedSyncPData extends RpcNotification { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.OnEncodedSyncPData); + } + + /** + * @param {String[]} data - Contains base64 encoded string of SyncP packets. + * @return {OnEncodedSyncPData} + */ + setData (data) { + this.setParameter(OnEncodedSyncPData.KEY_DATA, data); + return this; + } + + /** + * @return {String[]} + */ + getData () { + return this.getParameter(OnEncodedSyncPData.KEY_DATA); + } + + /** + * @param {String} url - If blank, the SyncP data shall be forwarded to the app. If not blank, the SyncP data shall + * be forwarded to the provided URL. + * @return {OnEncodedSyncPData} + */ + setURL (url) { + this.setParameter(OnEncodedSyncPData.KEY_URL, url); + return this; + } + + /** + * @return {String} + */ + getURL () { + return this.getParameter(OnEncodedSyncPData.KEY_URL); + } + + /** + * @param {Number} timeout - If blank, the SyncP data shall be forwarded to the app. If not blank, the SyncP data + * shall be forwarded with the provided timeout in seconds. + * @return {OnEncodedSyncPData} + */ + setTimeout (timeout) { + this.setParameter(OnEncodedSyncPData.KEY_TIMEOUT, timeout); + return this; + } + + /** + * @return {Number} + */ + getTimeout () { + return this.getParameter(OnEncodedSyncPData.KEY_TIMEOUT); + } +} + +OnEncodedSyncPData.KEY_DATA = 'data'; +OnEncodedSyncPData.KEY_URL = 'URL'; +OnEncodedSyncPData.KEY_TIMEOUT = 'Timeout'; + +export { OnEncodedSyncPData }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/OnHashChange.js b/lib/js/src/rpc/messages/OnHashChange.js new file mode 100644 index 00000000..e4de2f70 --- /dev/null +++ b/lib/js/src/rpc/messages/OnHashChange.js @@ -0,0 +1,70 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcNotification } from '../RpcNotification.js'; + +/** + * Notification containing an updated hashID which can be used over connection cycles (i.e. loss of connection, + * ignition cycles, etc.). Sent after initial registration and subsequently after any change in the calculated hash of + * all persisted app data. + */ +class OnHashChange extends RpcNotification { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.OnHashChange); + } + + /** + * @param {String} id - Calculated hash ID to be referenced during RegisterAppInterface. + * @return {OnHashChange} + */ + setHashID (id) { + this.setParameter(OnHashChange.KEY_HASH_ID, id); + return this; + } + + /** + * @return {String} + */ + getHashID () { + return this.getParameter(OnHashChange.KEY_HASH_ID); + } +} + +OnHashChange.KEY_HASH_ID = 'hashID'; + +export { OnHashChange }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/OnHmiStatus.js b/lib/js/src/rpc/messages/OnHmiStatus.js index 660de0cd..68404d08 100644 --- a/lib/js/src/rpc/messages/OnHmiStatus.js +++ b/lib/js/src/rpc/messages/OnHmiStatus.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -30,115 +31,114 @@ * POSSIBILITY OF SUCH DAMAGE. */ -import { RpcNotification } from '../RpcNotification.js'; +import { SystemContext } from '../enums/SystemContext.js'; import { FunctionID } from '../enums/FunctionID.js'; -import { HMILevel } from '../enums/HMILevel.js'; +import { RpcNotification } from '../RpcNotification.js'; import { AudioStreamingState } from '../enums/AudioStreamingState.js'; +import { HMILevel } from '../enums/HMILevel.js'; import { VideoStreamingState } from '../enums/VideoStreamingState.js'; -import { SystemContext } from '../enums/SystemContext.js'; -class OnHmiStatus extends RpcNotification { +class OnHMIStatus extends RpcNotification { /** - * @constructor - */ + * @constructor + */ constructor (store) { super(store); this.setFunctionName(FunctionID.OnHMIStatus); } /** - * @param {HMILevel} hmiLevel - * @return {OnHmiStatus} - */ - setHMILevel (hmiLevel) { - this.validateType(HMILevel, hmiLevel); - - this.setParameter(OnHmiStatus.KEY_HMI_LEVEL, hmiLevel); + * @param {HMILevel} level - See HMILevel + * @return {OnHMIStatus} + */ + setHmiLevel (level) { + this.validateType(HMILevel, level); + this.setParameter(OnHMIStatus.KEY_HMI_LEVEL, level); return this; } /** - * @return {HMILevel} - */ - getHMILevel () { - return this.getObject(HMILevel, OnHmiStatus.KEY_HMI_LEVEL); + * @return {HMILevel} + */ + getHmiLevel () { + return this.getObject(HMILevel, OnHMIStatus.KEY_HMI_LEVEL); } /** - * @param {AudioStreamingState} audioStreamingState - * @return {OnHmiStatus} - */ - setAudioStreamingState (audioStreamingState) { - this.validateType(AudioStreamingState, audioStreamingState); - - this.setParameter(OnHmiStatus.KEY_AUDIO_STREAMING_STATE, audioStreamingState); + * @param {AudioStreamingState} state - See AudioStreamingState + * @return {OnHMIStatus} + */ + setAudioStreamingState (state) { + this.validateType(AudioStreamingState, state); + this.setParameter(OnHMIStatus.KEY_AUDIO_STREAMING_STATE, state); return this; } /** - * @return {AudioStreamingState} - */ + * @return {AudioStreamingState} + */ getAudioStreamingState () { - return this.getObject(AudioStreamingState, OnHmiStatus.KEY_AUDIO_STREAMING_STATE); + return this.getObject(AudioStreamingState, OnHMIStatus.KEY_AUDIO_STREAMING_STATE); } /** - * @param {SystemContext} systemContext - * @return {OnHmiStatus} - */ - setSystemContext (systemContext) { - this.validateType(SystemContext, systemContext); - - this.setParameter(OnHmiStatus.KEY_SYSTEM_CONTEXT, systemContext); + * @param {SystemContext} context - See SystemContext + * @return {OnHMIStatus} + */ + setSystemContext (context) { + this.validateType(SystemContext, context); + this.setParameter(OnHMIStatus.KEY_SYSTEM_CONTEXT, context); return this; } /** - * @return {SystemContext} - */ + * @return {SystemContext} + */ getSystemContext () { - return this.getObject(SystemContext, OnHmiStatus.KEY_SYSTEM_CONTEXT); + return this.getObject(SystemContext, OnHMIStatus.KEY_SYSTEM_CONTEXT); } /** - * @param {VideoStreamingState} videoStreamingState - * @return {OnHmiStatus} - */ - setVideoStreamingState (videoStreamingState) { - this.validateType(VideoStreamingState, videoStreamingState); - - this.setParameter(OnHmiStatus.KEY_VIDEO_STREAMING_STATE, videoStreamingState); + * @param {VideoStreamingState} state - See VideoStreamingState. If it is NOT_STREAMABLE, the app must stop + * streaming video to SDL Core(stop service). + * @return {OnHMIStatus} + */ + setVideoStreamingState (state) { + this.validateType(VideoStreamingState, state); + this.setParameter(OnHMIStatus.KEY_VIDEO_STREAMING_STATE, state); return this; } /** - * @return {VideoStreamingState} - */ + * @return {VideoStreamingState} + */ getVideoStreamingState () { - return this.getObject(VideoStreamingState, OnHmiStatus.KEY_VIDEO_STREAMING_STATE); + return this.getObject(VideoStreamingState, OnHMIStatus.KEY_VIDEO_STREAMING_STATE); } /** - * @param {Number} windowID - * @return {Show} - */ - setWindowID (windowID) { - this.setParameter(OnHmiStatus.KEY_WINDOW_ID, windowID); + * @param {Number} id - This is the unique ID assigned to the window that this RPC is intended. If this param is not + * included, it will be assumed that this request is specifically for the main window on the + * main display. See PredefinedWindows enum. + * @return {OnHMIStatus} + */ + setWindowID (id) { + this.setParameter(OnHMIStatus.KEY_WINDOW_ID, id); return this; } /** - * @return {Number} - */ + * @return {Number} + */ getWindowID () { - return this.getParameter(OnHmiStatus.KEY_WINDOW_ID); + return this.getParameter(OnHMIStatus.KEY_WINDOW_ID); } } -OnHmiStatus.KEY_HMI_LEVEL = 'hmiLevel'; -OnHmiStatus.KEY_AUDIO_STREAMING_STATE = 'audioStreamingState'; -OnHmiStatus.KEY_SYSTEM_CONTEXT = 'systemContext'; -OnHmiStatus.KEY_VIDEO_STREAMING_STATE = 'videoStreamingState'; -OnHmiStatus.KEY_WINDOW_ID = 'windowID'; +OnHMIStatus.KEY_HMI_LEVEL = 'hmiLevel'; +OnHMIStatus.KEY_AUDIO_STREAMING_STATE = 'audioStreamingState'; +OnHMIStatus.KEY_SYSTEM_CONTEXT = 'systemContext'; +OnHMIStatus.KEY_VIDEO_STREAMING_STATE = 'videoStreamingState'; +OnHMIStatus.KEY_WINDOW_ID = 'windowID'; -export { OnHmiStatus }; +export { OnHMIStatus }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/OnInteriorVehicleData.js b/lib/js/src/rpc/messages/OnInteriorVehicleData.js new file mode 100644 index 00000000..90967762 --- /dev/null +++ b/lib/js/src/rpc/messages/OnInteriorVehicleData.js @@ -0,0 +1,69 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { ModuleData } from '../structs/ModuleData.js'; +import { RpcNotification } from '../RpcNotification.js'; + +class OnInteriorVehicleData extends RpcNotification { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.OnInteriorVehicleData); + } + + /** + * @param {ModuleData} data - The moduleType indicates which type of data should be changed and identifies which + * data object exists in this struct. For example, if the moduleType is CLIMATE then a + * "climateControlData" should exist + * @return {OnInteriorVehicleData} + */ + setModuleData (data) { + this.validateType(ModuleData, data); + this.setParameter(OnInteriorVehicleData.KEY_MODULE_DATA, data); + return this; + } + + /** + * @return {ModuleData} + */ + getModuleData () { + return this.getObject(ModuleData, OnInteriorVehicleData.KEY_MODULE_DATA); + } +} + +OnInteriorVehicleData.KEY_MODULE_DATA = 'moduleData'; + +export { OnInteriorVehicleData }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/OnKeyboardInput.js b/lib/js/src/rpc/messages/OnKeyboardInput.js new file mode 100644 index 00000000..33c2fe63 --- /dev/null +++ b/lib/js/src/rpc/messages/OnKeyboardInput.js @@ -0,0 +1,90 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { KeyboardEvent } from '../enums/KeyboardEvent.js'; +import { RpcNotification } from '../RpcNotification.js'; + +/** + * On-screen keyboard event. Can be full string or individual keypresses depending on keyboard mode. + */ +class OnKeyboardInput extends RpcNotification { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.OnKeyboardInput); + } + + /** + * @param {KeyboardEvent} event - On-screen keyboard input data. + * @return {OnKeyboardInput} + */ + setEvent (event) { + this.validateType(KeyboardEvent, event); + this.setParameter(OnKeyboardInput.KEY_EVENT, event); + return this; + } + + /** + * @return {KeyboardEvent} + */ + getEvent () { + return this.getObject(KeyboardEvent, OnKeyboardInput.KEY_EVENT); + } + + /** + * @param {String} data - On-screen keyboard input data. For dynamic keypress events, this will be the current + * compounded string of entry text. For entry submission events, this will be the full text + * entry (this will always return regardless of the mode). For entry cancelled and entry + * aborted events, this data param will be omitted. + * @return {OnKeyboardInput} + */ + setData (data) { + this.setParameter(OnKeyboardInput.KEY_DATA, data); + return this; + } + + /** + * @return {String} + */ + getData () { + return this.getParameter(OnKeyboardInput.KEY_DATA); + } +} + +OnKeyboardInput.KEY_EVENT = 'event'; +OnKeyboardInput.KEY_DATA = 'data'; + +export { OnKeyboardInput }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/OnLanguageChange.js b/lib/js/src/rpc/messages/OnLanguageChange.js index b8612cbc..61250abc 100644 --- a/lib/js/src/rpc/messages/OnLanguageChange.js +++ b/lib/js/src/rpc/messages/OnLanguageChange.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -30,52 +31,50 @@ * POSSIBILITY OF SUCH DAMAGE. */ -import { RpcNotification } from '../RpcNotification.js'; -import { Language } from '../enums/Language.js'; import { FunctionID } from '../enums/FunctionID.js'; +import { Language } from '../enums/Language.js'; +import { RpcNotification } from '../RpcNotification.js'; class OnLanguageChange extends RpcNotification { /** - * @constructor - */ + * @constructor + */ constructor (store) { super(store); this.setFunctionName(FunctionID.OnLanguageChange); } /** - * @param {Language} language - * @return {OnLanguageChange} - */ + * @param {Language} language - Current SDL voice engine (VR+TTS) language + * @return {OnLanguageChange} + */ setLanguage (language) { this.validateType(Language, language); - this.setParameter(OnLanguageChange.KEY_LANGUAGE, language); return this; } /** - * @return {Language} - */ + * @return {Language} + */ getLanguage () { return this.getObject(Language, OnLanguageChange.KEY_LANGUAGE); } /** - * @param {Language} language - * @return {OnLanguageChange} - */ - setHMIDisplayLanguage (language) { + * @param {Language} language - Current display language + * @return {OnLanguageChange} + */ + setHmiDisplayLanguage (language) { this.validateType(Language, language); - this.setParameter(OnLanguageChange.KEY_HMI_DISPLAY_LANGUAGE, language); return this; } /** - * @return {Language} - */ - getHMIDisplayLanguage () { + * @return {Language} + */ + getHmiDisplayLanguage () { return this.getObject(Language, OnLanguageChange.KEY_HMI_DISPLAY_LANGUAGE); } } @@ -83,4 +82,4 @@ class OnLanguageChange extends RpcNotification { OnLanguageChange.KEY_LANGUAGE = 'language'; OnLanguageChange.KEY_HMI_DISPLAY_LANGUAGE = 'hmiDisplayLanguage'; -export { OnLanguageChange }; +export { OnLanguageChange }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/OnPermissionsChange.js b/lib/js/src/rpc/messages/OnPermissionsChange.js new file mode 100644 index 00000000..7144aa50 --- /dev/null +++ b/lib/js/src/rpc/messages/OnPermissionsChange.js @@ -0,0 +1,87 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { PermissionItem } from '../structs/PermissionItem.js'; +import { RpcNotification } from '../RpcNotification.js'; + +/** + * Provides update to app of which policy-table-enabled functions are available + */ +class OnPermissionsChange extends RpcNotification { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.OnPermissionsChange); + } + + /** + * @param {PermissionItem[]} item - Change in permissions for a given set of RPCs + * @return {OnPermissionsChange} + */ + setPermissionItem (item) { + this.validateType(PermissionItem, item, true); + this.setParameter(OnPermissionsChange.KEY_PERMISSION_ITEM, item); + return this; + } + + /** + * @return {PermissionItem[]} + */ + getPermissionItem () { + return this.getObject(PermissionItem, OnPermissionsChange.KEY_PERMISSION_ITEM); + } + + /** + * @param {Boolean} encryption + * @return {OnPermissionsChange} + */ + setRequireEncryption (encryption) { + this.setParameter(OnPermissionsChange.KEY_REQUIRE_ENCRYPTION, encryption); + return this; + } + + /** + * @return {Boolean} + */ + getRequireEncryption () { + return this.getParameter(OnPermissionsChange.KEY_REQUIRE_ENCRYPTION); + } +} + +OnPermissionsChange.KEY_PERMISSION_ITEM = 'permissionItem'; +OnPermissionsChange.KEY_REQUIRE_ENCRYPTION = 'requireEncryption'; + +export { OnPermissionsChange }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/OnRCStatus.js b/lib/js/src/rpc/messages/OnRCStatus.js new file mode 100644 index 00000000..93b01ff5 --- /dev/null +++ b/lib/js/src/rpc/messages/OnRCStatus.js @@ -0,0 +1,107 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { ModuleData } from '../structs/ModuleData.js'; +import { RpcNotification } from '../RpcNotification.js'; + +/** + * Issued by SDL to notify the application about remote control status change on SDL + */ +class OnRCStatus extends RpcNotification { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.OnRCStatus); + } + + /** + * @param {Boolean} allowed - If "true" - RC is allowed; if "false" - RC is disallowed. + * @return {OnRCStatus} + */ + setAllowed (allowed) { + this.setParameter(OnRCStatus.KEY_ALLOWED, allowed); + return this; + } + + /** + * @return {Boolean} + */ + getAllowed () { + return this.getParameter(OnRCStatus.KEY_ALLOWED); + } + + /** + * @param {ModuleData[]} modules - Contains a list (zero or more) of module types that are allocated to the + * application. + * @return {OnRCStatus} + */ + setAllocatedModules (modules) { + this.validateType(ModuleData, modules, true); + this.setParameter(OnRCStatus.KEY_ALLOCATED_MODULES, modules); + return this; + } + + /** + * @return {ModuleData[]} + */ + getAllocatedModules () { + return this.getObject(ModuleData, OnRCStatus.KEY_ALLOCATED_MODULES); + } + + /** + * @param {ModuleData[]} modules - Contains a list (zero or more) of module types that are free to access for the + * application. + * @return {OnRCStatus} + */ + setFreeModules (modules) { + this.validateType(ModuleData, modules, true); + this.setParameter(OnRCStatus.KEY_FREE_MODULES, modules); + return this; + } + + /** + * @return {ModuleData[]} + */ + getFreeModules () { + return this.getObject(ModuleData, OnRCStatus.KEY_FREE_MODULES); + } +} + +OnRCStatus.KEY_ALLOWED = 'allowed'; +OnRCStatus.KEY_ALLOCATED_MODULES = 'allocatedModules'; +OnRCStatus.KEY_FREE_MODULES = 'freeModules'; + +export { OnRCStatus }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/OnSystemCapabilityUpdated.js b/lib/js/src/rpc/messages/OnSystemCapabilityUpdated.js new file mode 100644 index 00000000..6b2632d3 --- /dev/null +++ b/lib/js/src/rpc/messages/OnSystemCapabilityUpdated.js @@ -0,0 +1,70 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { SystemCapability } from '../structs/SystemCapability.js'; +import { RpcNotification } from '../RpcNotification.js'; + +/** + * A notification to inform the connected device that a specific system capability has changed. + */ +class OnSystemCapabilityUpdated extends RpcNotification { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.OnSystemCapabilityUpdated); + } + + /** + * @param {SystemCapability} capability - The system capability that has been updated + * @return {OnSystemCapabilityUpdated} + */ + setSystemCapability (capability) { + this.validateType(SystemCapability, capability); + this.setParameter(OnSystemCapabilityUpdated.KEY_SYSTEM_CAPABILITY, capability); + return this; + } + + /** + * @return {SystemCapability} + */ + getSystemCapability () { + return this.getObject(SystemCapability, OnSystemCapabilityUpdated.KEY_SYSTEM_CAPABILITY); + } +} + +OnSystemCapabilityUpdated.KEY_SYSTEM_CAPABILITY = 'systemCapability'; + +export { OnSystemCapabilityUpdated }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/OnSystemRequest.js b/lib/js/src/rpc/messages/OnSystemRequest.js new file mode 100644 index 00000000..aafef9f2 --- /dev/null +++ b/lib/js/src/rpc/messages/OnSystemRequest.js @@ -0,0 +1,178 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RequestType } from '../enums/RequestType.js'; +import { FileType } from '../enums/FileType.js'; +import { RpcNotification } from '../RpcNotification.js'; + +/** + * An asynchronous request from the system for specific data from the device or the cloud or response to a request from + * the device or cloud Binary data can be included in hybrid part of message for some requests (such as Authentication + * request responses) + */ +class OnSystemRequest extends RpcNotification { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.OnSystemRequest); + } + + /** + * @param {RequestType} type - The type of system request. + * @return {OnSystemRequest} + */ + setRequestType (type) { + this.validateType(RequestType, type); + this.setParameter(OnSystemRequest.KEY_REQUEST_TYPE, type); + return this; + } + + /** + * @return {RequestType} + */ + getRequestType () { + return this.getObject(RequestType, OnSystemRequest.KEY_REQUEST_TYPE); + } + + /** + * @param {String} type - This parameter is filled for supporting OEM proprietary data exchanges. + * @return {OnSystemRequest} + */ + setRequestSubType (type) { + this.setParameter(OnSystemRequest.KEY_REQUEST_SUB_TYPE, type); + return this; + } + + /** + * @return {String} + */ + getRequestSubType () { + return this.getParameter(OnSystemRequest.KEY_REQUEST_SUB_TYPE); + } + + /** + * @param {String} url - Optional URL for HTTP requests. If blank, the binary data shall be forwarded to the app. If + * not blank, the binary data shall be forwarded to the url with a provided timeout in + * seconds. + * @return {OnSystemRequest} + */ + setUrl (url) { + this.setParameter(OnSystemRequest.KEY_URL, url); + return this; + } + + /** + * @return {String} + */ + getUrl () { + return this.getParameter(OnSystemRequest.KEY_URL); + } + + /** + * @param {Number} timeout - Optional timeout for HTTP requests Required if a URL is provided + * @return {OnSystemRequest} + */ + setTimeout (timeout) { + this.setParameter(OnSystemRequest.KEY_TIMEOUT, timeout); + return this; + } + + /** + * @return {Number} + */ + getTimeout () { + return this.getParameter(OnSystemRequest.KEY_TIMEOUT); + } + + /** + * @param {FileType} type - Optional file type (meant for HTTP file requests). + * @return {OnSystemRequest} + */ + setFileType (type) { + this.validateType(FileType, type); + this.setParameter(OnSystemRequest.KEY_FILE_TYPE, type); + return this; + } + + /** + * @return {FileType} + */ + getFileType () { + return this.getObject(FileType, OnSystemRequest.KEY_FILE_TYPE); + } + + /** + * @param {Number} offset - Optional offset in bytes for resuming partial data chunks + * @return {OnSystemRequest} + */ + setOffset (offset) { + this.setParameter(OnSystemRequest.KEY_OFFSET, offset); + return this; + } + + /** + * @return {Number} + */ + getOffset () { + return this.getParameter(OnSystemRequest.KEY_OFFSET); + } + + /** + * @param {Number} length - Optional length in bytes for resuming partial data chunks + * @return {OnSystemRequest} + */ + setLength (length) { + this.setParameter(OnSystemRequest.KEY_LENGTH, length); + return this; + } + + /** + * @return {Number} + */ + getLength () { + return this.getParameter(OnSystemRequest.KEY_LENGTH); + } +} + +OnSystemRequest.KEY_REQUEST_TYPE = 'requestType'; +OnSystemRequest.KEY_REQUEST_SUB_TYPE = 'requestSubType'; +OnSystemRequest.KEY_URL = 'url'; +OnSystemRequest.KEY_TIMEOUT = 'timeout'; +OnSystemRequest.KEY_FILE_TYPE = 'fileType'; +OnSystemRequest.KEY_OFFSET = 'offset'; +OnSystemRequest.KEY_LENGTH = 'length'; + +export { OnSystemRequest }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/OnTBTClientState.js b/lib/js/src/rpc/messages/OnTBTClientState.js new file mode 100644 index 00000000..4fc42898 --- /dev/null +++ b/lib/js/src/rpc/messages/OnTBTClientState.js @@ -0,0 +1,70 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { TBTState } from '../enums/TBTState.js'; +import { RpcNotification } from '../RpcNotification.js'; + +/** + * Provides applications with notifications specific to the current TBT client status on the module + */ +class OnTBTClientState extends RpcNotification { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.OnTBTClientState); + } + + /** + * @param {TBTState} state - Current State of TBT client + * @return {OnTBTClientState} + */ + setState (state) { + this.validateType(TBTState, state); + this.setParameter(OnTBTClientState.KEY_STATE, state); + return this; + } + + /** + * @return {TBTState} + */ + getState () { + return this.getObject(TBTState, OnTBTClientState.KEY_STATE); + } +} + +OnTBTClientState.KEY_STATE = 'state'; + +export { OnTBTClientState }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/OnTouchEvent.js b/lib/js/src/rpc/messages/OnTouchEvent.js new file mode 100644 index 00000000..5ed585ef --- /dev/null +++ b/lib/js/src/rpc/messages/OnTouchEvent.js @@ -0,0 +1,89 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { TouchEvent } from '../structs/TouchEvent.js'; +import { TouchType } from '../enums/TouchType.js'; +import { RpcNotification } from '../RpcNotification.js'; + +/** + * Notifies about touch events on the screen's prescribed area + */ +class OnTouchEvent extends RpcNotification { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.OnTouchEvent); + } + + /** + * @param {TouchType} type - The type of touch event. + * @return {OnTouchEvent} + */ + setType (type) { + this.validateType(TouchType, type); + this.setParameter(OnTouchEvent.KEY_TYPE, type); + return this; + } + + /** + * @return {TouchType} + */ + getType () { + return this.getObject(TouchType, OnTouchEvent.KEY_TYPE); + } + + /** + * @param {TouchEvent[]} event - List of all individual touches involved in this event. + * @return {OnTouchEvent} + */ + setEvent (event) { + this.validateType(TouchEvent, event, true); + this.setParameter(OnTouchEvent.KEY_EVENT, event); + return this; + } + + /** + * @return {TouchEvent[]} + */ + getEvent () { + return this.getObject(TouchEvent, OnTouchEvent.KEY_EVENT); + } +} + +OnTouchEvent.KEY_TYPE = 'type'; +OnTouchEvent.KEY_EVENT = 'event'; + +export { OnTouchEvent }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/OnVehicleData.js b/lib/js/src/rpc/messages/OnVehicleData.js new file mode 100644 index 00000000..40b769cc --- /dev/null +++ b/lib/js/src/rpc/messages/OnVehicleData.js @@ -0,0 +1,598 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { AirbagStatus } from '../structs/AirbagStatus.js'; +import { ClusterModeStatus } from '../structs/ClusterModeStatus.js'; +import { VehicleDataEventStatus } from '../enums/VehicleDataEventStatus.js'; +import { EmergencyEvent } from '../structs/EmergencyEvent.js'; +import { TurnSignal } from '../enums/TurnSignal.js'; +import { FunctionID } from '../enums/FunctionID.js'; +import { HeadLampStatus } from '../structs/HeadLampStatus.js'; +import { DeviceStatus } from '../structs/DeviceStatus.js'; +import { WiperStatus } from '../enums/WiperStatus.js'; +import { RpcNotification } from '../RpcNotification.js'; +import { ElectronicParkBrakeStatus } from '../enums/ElectronicParkBrakeStatus.js'; +import { MyKey } from '../structs/MyKey.js'; +import { GPSData } from '../structs/GPSData.js'; +import { PRNDL } from '../enums/PRNDL.js'; +import { FuelRange } from '../structs/FuelRange.js'; +import { ECallInfo } from '../structs/ECallInfo.js'; +import { BeltStatus } from '../structs/BeltStatus.js'; +import { ComponentVolumeStatus } from '../enums/ComponentVolumeStatus.js'; +import { BodyInformation } from '../structs/BodyInformation.js'; +import { TireStatus } from '../structs/TireStatus.js'; + +/** + * Callback for the periodic and non periodic vehicle data read function. + */ +class OnVehicleData extends RpcNotification { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.OnVehicleData); + } + + /** + * @param {GPSData} gps - See GPSData + * @return {OnVehicleData} + */ + setGps (gps) { + this.validateType(GPSData, gps); + this.setParameter(OnVehicleData.KEY_GPS, gps); + return this; + } + + /** + * @return {GPSData} + */ + getGps () { + return this.getObject(GPSData, OnVehicleData.KEY_GPS); + } + + /** + * @param {Number} speed - The vehicle speed in kilometers per hour + * @return {OnVehicleData} + */ + setSpeed (speed) { + this.setParameter(OnVehicleData.KEY_SPEED, speed); + return this; + } + + /** + * @return {Number} + */ + getSpeed () { + return this.getParameter(OnVehicleData.KEY_SPEED); + } + + /** + * @param {Number} rpm - The number of revolutions per minute of the engine + * @return {OnVehicleData} + */ + setRpm (rpm) { + this.setParameter(OnVehicleData.KEY_RPM, rpm); + return this; + } + + /** + * @return {Number} + */ + getRpm () { + return this.getParameter(OnVehicleData.KEY_RPM); + } + + /** + * @param {Number} level - The fuel level in the tank (percentage) + * @return {OnVehicleData} + */ + setFuelLevel (level) { + this.setParameter(OnVehicleData.KEY_FUEL_LEVEL, level); + return this; + } + + /** + * @return {Number} + */ + getFuelLevel () { + return this.getParameter(OnVehicleData.KEY_FUEL_LEVEL); + } + + /** + * @param {ComponentVolumeStatus} level_state - The fuel level state + * @return {OnVehicleData} + */ + setFuelLevel_State (level_state) { + this.validateType(ComponentVolumeStatus, level_state); + this.setParameter(OnVehicleData.KEY_FUEL_LEVEL_STATE, level_state); + return this; + } + + /** + * @return {ComponentVolumeStatus} + */ + getFuelLevel_State () { + return this.getObject(ComponentVolumeStatus, OnVehicleData.KEY_FUEL_LEVEL_STATE); + } + + /** + * @param {Number} consumption - The instantaneous fuel consumption in microlitres + * @return {OnVehicleData} + */ + setInstantFuelConsumption (consumption) { + this.setParameter(OnVehicleData.KEY_INSTANT_FUEL_CONSUMPTION, consumption); + return this; + } + + /** + * @return {Number} + */ + getInstantFuelConsumption () { + return this.getParameter(OnVehicleData.KEY_INSTANT_FUEL_CONSUMPTION); + } + + /** + * @param {FuelRange[]} range - The estimate range in KM the vehicle can travel based on fuel level and consumption + * @return {OnVehicleData} + */ + setFuelRange (range) { + this.validateType(FuelRange, range, true); + this.setParameter(OnVehicleData.KEY_FUEL_RANGE, range); + return this; + } + + /** + * @return {FuelRange[]} + */ + getFuelRange () { + return this.getObject(FuelRange, OnVehicleData.KEY_FUEL_RANGE); + } + + /** + * @param {Number} temperature - The external temperature in degrees celsius + * @return {OnVehicleData} + */ + setExternalTemperature (temperature) { + this.setParameter(OnVehicleData.KEY_EXTERNAL_TEMPERATURE, temperature); + return this; + } + + /** + * @return {Number} + */ + getExternalTemperature () { + return this.getParameter(OnVehicleData.KEY_EXTERNAL_TEMPERATURE); + } + + /** + * @param {TurnSignal} signal - See TurnSignal + * @return {OnVehicleData} + */ + setTurnSignal (signal) { + this.validateType(TurnSignal, signal); + this.setParameter(OnVehicleData.KEY_TURN_SIGNAL, signal); + return this; + } + + /** + * @return {TurnSignal} + */ + getTurnSignal () { + return this.getObject(TurnSignal, OnVehicleData.KEY_TURN_SIGNAL); + } + + /** + * @param {String} vin - Vehicle identification number. + * @return {OnVehicleData} + */ + setVin (vin) { + this.setParameter(OnVehicleData.KEY_VIN, vin); + return this; + } + + /** + * @return {String} + */ + getVin () { + return this.getParameter(OnVehicleData.KEY_VIN); + } + + /** + * @param {PRNDL} prndl - See PRNDL + * @return {OnVehicleData} + */ + setPrndl (prndl) { + this.validateType(PRNDL, prndl); + this.setParameter(OnVehicleData.KEY_PRNDL, prndl); + return this; + } + + /** + * @return {PRNDL} + */ + getPrndl () { + return this.getObject(PRNDL, OnVehicleData.KEY_PRNDL); + } + + /** + * @param {TireStatus} pressure - See TireStatus + * @return {OnVehicleData} + */ + setTirePressure (pressure) { + this.validateType(TireStatus, pressure); + this.setParameter(OnVehicleData.KEY_TIRE_PRESSURE, pressure); + return this; + } + + /** + * @return {TireStatus} + */ + getTirePressure () { + return this.getObject(TireStatus, OnVehicleData.KEY_TIRE_PRESSURE); + } + + /** + * @param {Number} odometer - Odometer in km + * @return {OnVehicleData} + */ + setOdometer (odometer) { + this.setParameter(OnVehicleData.KEY_ODOMETER, odometer); + return this; + } + + /** + * @return {Number} + */ + getOdometer () { + return this.getParameter(OnVehicleData.KEY_ODOMETER); + } + + /** + * @param {BeltStatus} status - The status of the seat belts + * @return {OnVehicleData} + */ + setBeltStatus (status) { + this.validateType(BeltStatus, status); + this.setParameter(OnVehicleData.KEY_BELT_STATUS, status); + return this; + } + + /** + * @return {BeltStatus} + */ + getBeltStatus () { + return this.getObject(BeltStatus, OnVehicleData.KEY_BELT_STATUS); + } + + /** + * @param {BodyInformation} information - The body information including power modes + * @return {OnVehicleData} + */ + setBodyInformation (information) { + this.validateType(BodyInformation, information); + this.setParameter(OnVehicleData.KEY_BODY_INFORMATION, information); + return this; + } + + /** + * @return {BodyInformation} + */ + getBodyInformation () { + return this.getObject(BodyInformation, OnVehicleData.KEY_BODY_INFORMATION); + } + + /** + * @param {DeviceStatus} status - The device status including signal and battery strength + * @return {OnVehicleData} + */ + setDeviceStatus (status) { + this.validateType(DeviceStatus, status); + this.setParameter(OnVehicleData.KEY_DEVICE_STATUS, status); + return this; + } + + /** + * @return {DeviceStatus} + */ + getDeviceStatus () { + return this.getObject(DeviceStatus, OnVehicleData.KEY_DEVICE_STATUS); + } + + /** + * @param {VehicleDataEventStatus} braking - The status of the brake pedal + * @return {OnVehicleData} + */ + setDriverBraking (braking) { + this.validateType(VehicleDataEventStatus, braking); + this.setParameter(OnVehicleData.KEY_DRIVER_BRAKING, braking); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getDriverBraking () { + return this.getObject(VehicleDataEventStatus, OnVehicleData.KEY_DRIVER_BRAKING); + } + + /** + * @param {WiperStatus} status - The status of the wipers + * @return {OnVehicleData} + */ + setWiperStatus (status) { + this.validateType(WiperStatus, status); + this.setParameter(OnVehicleData.KEY_WIPER_STATUS, status); + return this; + } + + /** + * @return {WiperStatus} + */ + getWiperStatus () { + return this.getObject(WiperStatus, OnVehicleData.KEY_WIPER_STATUS); + } + + /** + * @param {HeadLampStatus} status - Status of the head lamps + * @return {OnVehicleData} + */ + setHeadLampStatus (status) { + this.validateType(HeadLampStatus, status); + this.setParameter(OnVehicleData.KEY_HEAD_LAMP_STATUS, status); + return this; + } + + /** + * @return {HeadLampStatus} + */ + getHeadLampStatus () { + return this.getObject(HeadLampStatus, OnVehicleData.KEY_HEAD_LAMP_STATUS); + } + + /** + * @param {Number} torque - Torque value for engine (in Nm) on non-diesel variants + * @return {OnVehicleData} + */ + setEngineTorque (torque) { + this.setParameter(OnVehicleData.KEY_ENGINE_TORQUE, torque); + return this; + } + + /** + * @return {Number} + */ + getEngineTorque () { + return this.getParameter(OnVehicleData.KEY_ENGINE_TORQUE); + } + + /** + * @param {Number} position - Accelerator pedal position (percentage depressed) + * @return {OnVehicleData} + */ + setAccPedalPosition (position) { + this.setParameter(OnVehicleData.KEY_ACC_PEDAL_POSITION, position); + return this; + } + + /** + * @return {Number} + */ + getAccPedalPosition () { + return this.getParameter(OnVehicleData.KEY_ACC_PEDAL_POSITION); + } + + /** + * @param {Number} angle - Current angle of the steering wheel (in deg) + * @return {OnVehicleData} + */ + setSteeringWheelAngle (angle) { + this.setParameter(OnVehicleData.KEY_STEERING_WHEEL_ANGLE, angle); + return this; + } + + /** + * @return {Number} + */ + getSteeringWheelAngle () { + return this.getParameter(OnVehicleData.KEY_STEERING_WHEEL_ANGLE); + } + + /** + * @param {Number} life - The estimated percentage of remaining oil life of the engine. + * @return {OnVehicleData} + */ + setEngineOilLife (life) { + this.setParameter(OnVehicleData.KEY_ENGINE_OIL_LIFE, life); + return this; + } + + /** + * @return {Number} + */ + getEngineOilLife () { + return this.getParameter(OnVehicleData.KEY_ENGINE_OIL_LIFE); + } + + /** + * @param {ElectronicParkBrakeStatus} status - The status of the park brake as provided by Electric Park Brake (EPB) + * system. + * @return {OnVehicleData} + */ + setElectronicParkBrakeStatus (status) { + this.validateType(ElectronicParkBrakeStatus, status); + this.setParameter(OnVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS, status); + return this; + } + + /** + * @return {ElectronicParkBrakeStatus} + */ + getElectronicParkBrakeStatus () { + return this.getObject(ElectronicParkBrakeStatus, OnVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS); + } + + /** + * @param {String} id - Parameter used by cloud apps to identify a head unit + * @return {OnVehicleData} + */ + setCloudAppVehicleID (id) { + this.setParameter(OnVehicleData.KEY_CLOUD_APP_VEHICLE_ID, id); + return this; + } + + /** + * @return {String} + */ + getCloudAppVehicleID () { + return this.getParameter(OnVehicleData.KEY_CLOUD_APP_VEHICLE_ID); + } + + /** + * @param {ECallInfo} info - Emergency Call notification and confirmation data + * @return {OnVehicleData} + */ + setECallInfo (info) { + this.validateType(ECallInfo, info); + this.setParameter(OnVehicleData.KEY_E_CALL_INFO, info); + return this; + } + + /** + * @return {ECallInfo} + */ + getECallInfo () { + return this.getObject(ECallInfo, OnVehicleData.KEY_E_CALL_INFO); + } + + /** + * @param {AirbagStatus} status - The status of the air bags + * @return {OnVehicleData} + */ + setAirbagStatus (status) { + this.validateType(AirbagStatus, status); + this.setParameter(OnVehicleData.KEY_AIRBAG_STATUS, status); + return this; + } + + /** + * @return {AirbagStatus} + */ + getAirbagStatus () { + return this.getObject(AirbagStatus, OnVehicleData.KEY_AIRBAG_STATUS); + } + + /** + * @param {EmergencyEvent} event - Information related to an emergency event (and if it occurred) + * @return {OnVehicleData} + */ + setEmergencyEvent (event) { + this.validateType(EmergencyEvent, event); + this.setParameter(OnVehicleData.KEY_EMERGENCY_EVENT, event); + return this; + } + + /** + * @return {EmergencyEvent} + */ + getEmergencyEvent () { + return this.getObject(EmergencyEvent, OnVehicleData.KEY_EMERGENCY_EVENT); + } + + /** + * @param {ClusterModeStatus} status - The status modes of the cluster + * @return {OnVehicleData} + */ + setClusterModeStatus (status) { + this.validateType(ClusterModeStatus, status); + this.setParameter(OnVehicleData.KEY_CLUSTER_MODE_STATUS, status); + return this; + } + + /** + * @return {ClusterModeStatus} + */ + getClusterModeStatus () { + return this.getObject(ClusterModeStatus, OnVehicleData.KEY_CLUSTER_MODE_STATUS); + } + + /** + * @param {MyKey} key - Information related to the MyKey feature + * @return {OnVehicleData} + */ + setMyKey (key) { + this.validateType(MyKey, key); + this.setParameter(OnVehicleData.KEY_MY_KEY, key); + return this; + } + + /** + * @return {MyKey} + */ + getMyKey () { + return this.getObject(MyKey, OnVehicleData.KEY_MY_KEY); + } +} + +OnVehicleData.KEY_GPS = 'gps'; +OnVehicleData.KEY_SPEED = 'speed'; +OnVehicleData.KEY_RPM = 'rpm'; +OnVehicleData.KEY_FUEL_LEVEL = 'fuelLevel'; +OnVehicleData.KEY_FUEL_LEVEL_STATE = 'fuelLevel_State'; +OnVehicleData.KEY_INSTANT_FUEL_CONSUMPTION = 'instantFuelConsumption'; +OnVehicleData.KEY_FUEL_RANGE = 'fuelRange'; +OnVehicleData.KEY_EXTERNAL_TEMPERATURE = 'externalTemperature'; +OnVehicleData.KEY_TURN_SIGNAL = 'turnSignal'; +OnVehicleData.KEY_VIN = 'vin'; +OnVehicleData.KEY_PRNDL = 'prndl'; +OnVehicleData.KEY_TIRE_PRESSURE = 'tirePressure'; +OnVehicleData.KEY_ODOMETER = 'odometer'; +OnVehicleData.KEY_BELT_STATUS = 'beltStatus'; +OnVehicleData.KEY_BODY_INFORMATION = 'bodyInformation'; +OnVehicleData.KEY_DEVICE_STATUS = 'deviceStatus'; +OnVehicleData.KEY_DRIVER_BRAKING = 'driverBraking'; +OnVehicleData.KEY_WIPER_STATUS = 'wiperStatus'; +OnVehicleData.KEY_HEAD_LAMP_STATUS = 'headLampStatus'; +OnVehicleData.KEY_ENGINE_TORQUE = 'engineTorque'; +OnVehicleData.KEY_ACC_PEDAL_POSITION = 'accPedalPosition'; +OnVehicleData.KEY_STEERING_WHEEL_ANGLE = 'steeringWheelAngle'; +OnVehicleData.KEY_ENGINE_OIL_LIFE = 'engineOilLife'; +OnVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS = 'electronicParkBrakeStatus'; +OnVehicleData.KEY_CLOUD_APP_VEHICLE_ID = 'cloudAppVehicleID'; +OnVehicleData.KEY_E_CALL_INFO = 'eCallInfo'; +OnVehicleData.KEY_AIRBAG_STATUS = 'airbagStatus'; +OnVehicleData.KEY_EMERGENCY_EVENT = 'emergencyEvent'; +OnVehicleData.KEY_CLUSTER_MODE_STATUS = 'clusterModeStatus'; +OnVehicleData.KEY_MY_KEY = 'myKey'; + +export { OnVehicleData }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/OnWayPointChange.js b/lib/js/src/rpc/messages/OnWayPointChange.js new file mode 100644 index 00000000..68bc467c --- /dev/null +++ b/lib/js/src/rpc/messages/OnWayPointChange.js @@ -0,0 +1,70 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { LocationDetails } from '../structs/LocationDetails.js'; +import { RpcNotification } from '../RpcNotification.js'; + +/** + * Notification which provides the entire LocationDetails when there is a change to any waypoints or destination. + */ +class OnWayPointChange extends RpcNotification { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.OnWayPointChange); + } + + /** + * @param {LocationDetails[]} points - See LocationDetails + * @return {OnWayPointChange} + */ + setWayPoints (points) { + this.validateType(LocationDetails, points, true); + this.setParameter(OnWayPointChange.KEY_WAY_POINTS, points); + return this; + } + + /** + * @return {LocationDetails[]} + */ + getWayPoints () { + return this.getObject(LocationDetails, OnWayPointChange.KEY_WAY_POINTS); + } +} + +OnWayPointChange.KEY_WAY_POINTS = 'wayPoints'; + +export { OnWayPointChange }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/PerformAppServiceInteraction.js b/lib/js/src/rpc/messages/PerformAppServiceInteraction.js new file mode 100644 index 00000000..1eb6e73b --- /dev/null +++ b/lib/js/src/rpc/messages/PerformAppServiceInteraction.js @@ -0,0 +1,119 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +class PerformAppServiceInteraction extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.PerformAppServiceInteraction); + } + + /** + * @param {String} uri - Fully qualified URI based on a predetermined scheme provided by the app service. SDL makes + * no guarantee that this URI is correct. + * @return {PerformAppServiceInteraction} + */ + setServiceUri (uri) { + this.setParameter(PerformAppServiceInteraction.KEY_SERVICE_URI, uri); + return this; + } + + /** + * @return {String} + */ + getServiceUri () { + return this.getParameter(PerformAppServiceInteraction.KEY_SERVICE_URI); + } + + /** + * @param {String} id - The service ID that the app consumer wishes to send this URI. + * @return {PerformAppServiceInteraction} + */ + setServiceID (id) { + this.setParameter(PerformAppServiceInteraction.KEY_SERVICE_ID, id); + return this; + } + + /** + * @return {String} + */ + getServiceID () { + return this.getParameter(PerformAppServiceInteraction.KEY_SERVICE_ID); + } + + /** + * @param {String} app - This string is the appID of the app requesting the app service provider take the specific + * action. + * @return {PerformAppServiceInteraction} + */ + setOriginApp (app) { + this.setParameter(PerformAppServiceInteraction.KEY_ORIGIN_APP, app); + return this; + } + + /** + * @return {String} + */ + getOriginApp () { + return this.getParameter(PerformAppServiceInteraction.KEY_ORIGIN_APP); + } + + /** + * @param {Boolean} active - This flag signals the requesting consumer would like this service to become the active + * primary service of the destination's type. + * @return {PerformAppServiceInteraction} + */ + setRequestServiceActive (active) { + this.setParameter(PerformAppServiceInteraction.KEY_REQUEST_SERVICE_ACTIVE, active); + return this; + } + + /** + * @return {Boolean} + */ + getRequestServiceActive () { + return this.getParameter(PerformAppServiceInteraction.KEY_REQUEST_SERVICE_ACTIVE); + } +} + +PerformAppServiceInteraction.KEY_SERVICE_URI = 'serviceUri'; +PerformAppServiceInteraction.KEY_SERVICE_ID = 'serviceID'; +PerformAppServiceInteraction.KEY_ORIGIN_APP = 'originApp'; +PerformAppServiceInteraction.KEY_REQUEST_SERVICE_ACTIVE = 'requestServiceActive'; + +export { PerformAppServiceInteraction }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/PerformAppServiceInteractionResponse.js b/lib/js/src/rpc/messages/PerformAppServiceInteractionResponse.js new file mode 100644 index 00000000..3a1e8696 --- /dev/null +++ b/lib/js/src/rpc/messages/PerformAppServiceInteractionResponse.js @@ -0,0 +1,65 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class PerformAppServiceInteractionResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.PerformAppServiceInteraction); + } + + /** + * @param {String} result - The service can provide specific result strings to the consumer through this param. + * @return {PerformAppServiceInteractionResponse} + */ + setServiceSpecificResult (result) { + this.setParameter(PerformAppServiceInteractionResponse.KEY_SERVICE_SPECIFIC_RESULT, result); + return this; + } + + /** + * @return {String} + */ + getServiceSpecificResult () { + return this.getParameter(PerformAppServiceInteractionResponse.KEY_SERVICE_SPECIFIC_RESULT); + } +} + +PerformAppServiceInteractionResponse.KEY_SERVICE_SPECIFIC_RESULT = 'serviceSpecificResult'; + +export { PerformAppServiceInteractionResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/PerformAudioPassThru.js b/lib/js/src/rpc/messages/PerformAudioPassThru.js new file mode 100644 index 00000000..43cea934 --- /dev/null +++ b/lib/js/src/rpc/messages/PerformAudioPassThru.js @@ -0,0 +1,198 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { TTSChunk } from '../structs/TTSChunk.js'; +import { AudioType } from '../enums/AudioType.js'; +import { BitsPerSample } from '../enums/BitsPerSample.js'; +import { RpcRequest } from '../RpcRequest.js'; +import { SamplingRate } from '../enums/SamplingRate.js'; + +/** + * Starts audio pass thru session + */ +class PerformAudioPassThru extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.PerformAudioPassThru); + } + + /** + * @param {TTSChunk[]} prompt - The module will speak this prompt before opening the audio pass thru session. An + * array of text chunks of type TTSChunk. See TTSChunk. The array must have at least + * one item. If omitted, then no initial prompt is spoken. + * @return {PerformAudioPassThru} + */ + setInitialPrompt (prompt) { + this.validateType(TTSChunk, prompt, true); + this.setParameter(PerformAudioPassThru.KEY_INITIAL_PROMPT, prompt); + return this; + } + + /** + * @return {TTSChunk[]} + */ + getInitialPrompt () { + return this.getObject(TTSChunk, PerformAudioPassThru.KEY_INITIAL_PROMPT); + } + + /** + * @param {String} text1 - First line of text displayed during audio capture. + * @return {PerformAudioPassThru} + */ + setAudioPassThruDisplayText1 (text1) { + this.setParameter(PerformAudioPassThru.KEY_AUDIO_PASS_THRU_DISPLAY_TEXT_1, text1); + return this; + } + + /** + * @return {String} + */ + getAudioPassThruDisplayText1 () { + return this.getParameter(PerformAudioPassThru.KEY_AUDIO_PASS_THRU_DISPLAY_TEXT_1); + } + + /** + * @param {String} text2 - Second line of text displayed during audio capture. + * @return {PerformAudioPassThru} + */ + setAudioPassThruDisplayText2 (text2) { + this.setParameter(PerformAudioPassThru.KEY_AUDIO_PASS_THRU_DISPLAY_TEXT_2, text2); + return this; + } + + /** + * @return {String} + */ + getAudioPassThruDisplayText2 () { + return this.getParameter(PerformAudioPassThru.KEY_AUDIO_PASS_THRU_DISPLAY_TEXT_2); + } + + /** + * @param {SamplingRate} rate - This value shall be allowed at 8 kHz or 16 or 22 or 44 kHz. + * @return {PerformAudioPassThru} + */ + setSamplingRate (rate) { + this.validateType(SamplingRate, rate); + this.setParameter(PerformAudioPassThru.KEY_SAMPLING_RATE, rate); + return this; + } + + /** + * @return {SamplingRate} + */ + getSamplingRate () { + return this.getObject(SamplingRate, PerformAudioPassThru.KEY_SAMPLING_RATE); + } + + /** + * @param {Number} duration - The maximum duration of audio recording in milliseconds. + * @return {PerformAudioPassThru} + */ + setMaxDuration (duration) { + this.setParameter(PerformAudioPassThru.KEY_MAX_DURATION, duration); + return this; + } + + /** + * @return {Number} + */ + getMaxDuration () { + return this.getParameter(PerformAudioPassThru.KEY_MAX_DURATION); + } + + /** + * @param {BitsPerSample} sample - Specifies the quality the audio is recorded. Currently 8 bit or 16 bit. + * @return {PerformAudioPassThru} + */ + setBitsPerSample (sample) { + this.validateType(BitsPerSample, sample); + this.setParameter(PerformAudioPassThru.KEY_BITS_PER_SAMPLE, sample); + return this; + } + + /** + * @return {BitsPerSample} + */ + getBitsPerSample () { + return this.getObject(BitsPerSample, PerformAudioPassThru.KEY_BITS_PER_SAMPLE); + } + + /** + * @param {AudioType} type - Specifies the type of audio data being requested. + * @return {PerformAudioPassThru} + */ + setAudioType (type) { + this.validateType(AudioType, type); + this.setParameter(PerformAudioPassThru.KEY_AUDIO_TYPE, type); + return this; + } + + /** + * @return {AudioType} + */ + getAudioType () { + return this.getObject(AudioType, PerformAudioPassThru.KEY_AUDIO_TYPE); + } + + /** + * @param {Boolean} audio - Defines if the current audio source should be muted during the APT session. If not, the + * audio source will play without interruption. If omitted, the value is set to true. + * @return {PerformAudioPassThru} + */ + setMuteAudio (audio) { + this.setParameter(PerformAudioPassThru.KEY_MUTE_AUDIO, audio); + return this; + } + + /** + * @return {Boolean} + */ + getMuteAudio () { + return this.getParameter(PerformAudioPassThru.KEY_MUTE_AUDIO); + } +} + +PerformAudioPassThru.KEY_INITIAL_PROMPT = 'initialPrompt'; +PerformAudioPassThru.KEY_AUDIO_PASS_THRU_DISPLAY_TEXT_1 = 'audioPassThruDisplayText1'; +PerformAudioPassThru.KEY_AUDIO_PASS_THRU_DISPLAY_TEXT_2 = 'audioPassThruDisplayText2'; +PerformAudioPassThru.KEY_SAMPLING_RATE = 'samplingRate'; +PerformAudioPassThru.KEY_MAX_DURATION = 'maxDuration'; +PerformAudioPassThru.KEY_BITS_PER_SAMPLE = 'bitsPerSample'; +PerformAudioPassThru.KEY_AUDIO_TYPE = 'audioType'; +PerformAudioPassThru.KEY_MUTE_AUDIO = 'muteAudio'; + +export { PerformAudioPassThru }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/PerformAudioPassThruResponse.js b/lib/js/src/rpc/messages/PerformAudioPassThruResponse.js new file mode 100644 index 00000000..fa9f2c83 --- /dev/null +++ b/lib/js/src/rpc/messages/PerformAudioPassThruResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class PerformAudioPassThruResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.PerformAudioPassThru); + } +} + + +export { PerformAudioPassThruResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/PerformInteraction.js b/lib/js/src/rpc/messages/PerformInteraction.js new file mode 100644 index 00000000..87bf954e --- /dev/null +++ b/lib/js/src/rpc/messages/PerformInteraction.js @@ -0,0 +1,241 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { VrHelpItem } from '../structs/VrHelpItem.js'; +import { LayoutMode } from '../enums/LayoutMode.js'; +import { FunctionID } from '../enums/FunctionID.js'; +import { TTSChunk } from '../structs/TTSChunk.js'; +import { RpcRequest } from '../RpcRequest.js'; +import { InteractionMode } from '../enums/InteractionMode.js'; + +/** + * Triggers an interaction (e.g. "Permit GPS?" - Yes, no, Always Allow). + */ +class PerformInteraction extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.PerformInteraction); + } + + /** + * @param {String} text - Text to be displayed first. + * @return {PerformInteraction} + */ + setInitialText (text) { + this.setParameter(PerformInteraction.KEY_INITIAL_TEXT, text); + return this; + } + + /** + * @return {String} + */ + getInitialText () { + return this.getParameter(PerformInteraction.KEY_INITIAL_TEXT); + } + + /** + * @param {TTSChunk[]} prompt - This is the initial prompt spoken to the user at the start of an interaction. An + * array of text chunks of type TTSChunk. See TTSChunk. The array must have at least + * one item. + * @return {PerformInteraction} + */ + setInitialPrompt (prompt) { + this.validateType(TTSChunk, prompt, true); + this.setParameter(PerformInteraction.KEY_INITIAL_PROMPT, prompt); + return this; + } + + /** + * @return {TTSChunk[]} + */ + getInitialPrompt () { + return this.getObject(TTSChunk, PerformInteraction.KEY_INITIAL_PROMPT); + } + + /** + * @param {InteractionMode} mode - See InteractionMode. + * @return {PerformInteraction} + */ + setInteractionMode (mode) { + this.validateType(InteractionMode, mode); + this.setParameter(PerformInteraction.KEY_INTERACTION_MODE, mode); + return this; + } + + /** + * @return {InteractionMode} + */ + getInteractionMode () { + return this.getObject(InteractionMode, PerformInteraction.KEY_INTERACTION_MODE); + } + + /** + * @param {Number[]} list - List of interaction choice set IDs to use with an interaction. + * @return {PerformInteraction} + */ + setInteractionChoiceSetIDList (list) { + this.setParameter(PerformInteraction.KEY_INTERACTION_CHOICE_SET_IDLIST, list); + return this; + } + + /** + * @return {Number[]} + */ + getInteractionChoiceSetIDList () { + return this.getParameter(PerformInteraction.KEY_INTERACTION_CHOICE_SET_IDLIST); + } + + /** + * @param {TTSChunk[]} prompt - Help text. This is the spoken string when a user speaks "help" when the interaction + * is occurring. An array of text chunks of type TTSChunk. See TTSChunk. The array must + * have at least one item. + * @return {PerformInteraction} + */ + setHelpPrompt (prompt) { + this.validateType(TTSChunk, prompt, true); + this.setParameter(PerformInteraction.KEY_HELP_PROMPT, prompt); + return this; + } + + /** + * @return {TTSChunk[]} + */ + getHelpPrompt () { + return this.getObject(TTSChunk, PerformInteraction.KEY_HELP_PROMPT); + } + + /** + * @param {TTSChunk[]} prompt - Timeout text. This text is spoken when a VR interaction times out. An array of text + * chunks of type TTSChunk. See TTSChunk. The array must have at least one item. + * @return {PerformInteraction} + */ + setTimeoutPrompt (prompt) { + this.validateType(TTSChunk, prompt, true); + this.setParameter(PerformInteraction.KEY_TIMEOUT_PROMPT, prompt); + return this; + } + + /** + * @return {TTSChunk[]} + */ + getTimeoutPrompt () { + return this.getObject(TTSChunk, PerformInteraction.KEY_TIMEOUT_PROMPT); + } + + /** + * @param {Number} timeout - Timeout in milliseconds. If omitted a standard value of 10000 milliseconds is used. + * Applies only to the menu portion of the interaction. The VR timeout will be handled by + * the platform. + * @return {PerformInteraction} + */ + setTimeout (timeout) { + this.setParameter(PerformInteraction.KEY_TIMEOUT, timeout); + return this; + } + + /** + * @return {Number} + */ + getTimeout () { + return this.getParameter(PerformInteraction.KEY_TIMEOUT); + } + + /** + * @param {VrHelpItem[]} help - Ability to send suggested VR Help Items to display on-screen during Perform + * Interaction. If omitted on supported displays, the default generated list of + * suggested choices shall be displayed. + * @return {PerformInteraction} + */ + setVrHelp (help) { + this.validateType(VrHelpItem, help, true); + this.setParameter(PerformInteraction.KEY_VR_HELP, help); + return this; + } + + /** + * @return {VrHelpItem[]} + */ + getVrHelp () { + return this.getObject(VrHelpItem, PerformInteraction.KEY_VR_HELP); + } + + /** + * @param {LayoutMode} layout - See LayoutMode. + * @return {PerformInteraction} + */ + setInteractionLayout (layout) { + this.validateType(LayoutMode, layout); + this.setParameter(PerformInteraction.KEY_INTERACTION_LAYOUT, layout); + return this; + } + + /** + * @return {LayoutMode} + */ + getInteractionLayout () { + return this.getObject(LayoutMode, PerformInteraction.KEY_INTERACTION_LAYOUT); + } + + /** + * @param {Number} id - An ID for this specific PerformInteraction to allow cancellation through the + * `CancelInteraction` RPC. + * @return {PerformInteraction} + */ + setCancelID (id) { + this.setParameter(PerformInteraction.KEY_CANCEL_ID, id); + return this; + } + + /** + * @return {Number} + */ + getCancelID () { + return this.getParameter(PerformInteraction.KEY_CANCEL_ID); + } +} + +PerformInteraction.KEY_INITIAL_TEXT = 'initialText'; +PerformInteraction.KEY_INITIAL_PROMPT = 'initialPrompt'; +PerformInteraction.KEY_INTERACTION_MODE = 'interactionMode'; +PerformInteraction.KEY_INTERACTION_CHOICE_SET_IDLIST = 'interactionChoiceSetIDList'; +PerformInteraction.KEY_HELP_PROMPT = 'helpPrompt'; +PerformInteraction.KEY_TIMEOUT_PROMPT = 'timeoutPrompt'; +PerformInteraction.KEY_TIMEOUT = 'timeout'; +PerformInteraction.KEY_VR_HELP = 'vrHelp'; +PerformInteraction.KEY_INTERACTION_LAYOUT = 'interactionLayout'; +PerformInteraction.KEY_CANCEL_ID = 'cancelID'; + +export { PerformInteraction }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/PerformInteractionResponse.js b/lib/js/src/rpc/messages/PerformInteractionResponse.js new file mode 100644 index 00000000..d0655bb6 --- /dev/null +++ b/lib/js/src/rpc/messages/PerformInteractionResponse.js @@ -0,0 +1,103 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { TriggerSource } from '../enums/TriggerSource.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class PerformInteractionResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.PerformInteraction); + } + + /** + * @param {Number} id - ID of the choice that was selected in response to PerformInteraction. Only is valid if + * general result is "success:true". + * @return {PerformInteractionResponse} + */ + setChoiceID (id) { + this.setParameter(PerformInteractionResponse.KEY_CHOICE_ID, id); + return this; + } + + /** + * @return {Number} + */ + getChoiceID () { + return this.getParameter(PerformInteractionResponse.KEY_CHOICE_ID); + } + + /** + * @param {String} entry - Manually entered text selection, e.g. through keyboard Can be returned in lieu of + * choiceID, depending on trigger source + * @return {PerformInteractionResponse} + */ + setManualTextEntry (entry) { + this.setParameter(PerformInteractionResponse.KEY_MANUAL_TEXT_ENTRY, entry); + return this; + } + + /** + * @return {String} + */ + getManualTextEntry () { + return this.getParameter(PerformInteractionResponse.KEY_MANUAL_TEXT_ENTRY); + } + + /** + * @param {TriggerSource} source - See TriggerSource Only is valid if resultCode is SUCCESS. + * @return {PerformInteractionResponse} + */ + setTriggerSource (source) { + this.validateType(TriggerSource, source); + this.setParameter(PerformInteractionResponse.KEY_TRIGGER_SOURCE, source); + return this; + } + + /** + * @return {TriggerSource} + */ + getTriggerSource () { + return this.getObject(TriggerSource, PerformInteractionResponse.KEY_TRIGGER_SOURCE); + } +} + +PerformInteractionResponse.KEY_CHOICE_ID = 'choiceID'; +PerformInteractionResponse.KEY_MANUAL_TEXT_ENTRY = 'manualTextEntry'; +PerformInteractionResponse.KEY_TRIGGER_SOURCE = 'triggerSource'; + +export { PerformInteractionResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/PublishAppService.js b/lib/js/src/rpc/messages/PublishAppService.js new file mode 100644 index 00000000..005396b0 --- /dev/null +++ b/lib/js/src/rpc/messages/PublishAppService.js @@ -0,0 +1,72 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { AppServiceManifest } from '../structs/AppServiceManifest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Registers a service offered by this app on the module. Subsequent calls with the same service type will update the + * manifest for that service. + */ +class PublishAppService extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.PublishAppService); + } + + /** + * @param {AppServiceManifest} manifest - The manifest of the service that wishes to be published. If already + * published, the updated manifest for this service. + * @return {PublishAppService} + */ + setAppServiceManifest (manifest) { + this.validateType(AppServiceManifest, manifest); + this.setParameter(PublishAppService.KEY_APP_SERVICE_MANIFEST, manifest); + return this; + } + + /** + * @return {AppServiceManifest} + */ + getAppServiceManifest () { + return this.getObject(AppServiceManifest, PublishAppService.KEY_APP_SERVICE_MANIFEST); + } +} + +PublishAppService.KEY_APP_SERVICE_MANIFEST = 'appServiceManifest'; + +export { PublishAppService }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/PublishAppServiceResponse.js b/lib/js/src/rpc/messages/PublishAppServiceResponse.js new file mode 100644 index 00000000..149b244a --- /dev/null +++ b/lib/js/src/rpc/messages/PublishAppServiceResponse.js @@ -0,0 +1,72 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; +import { AppServiceRecord } from '../structs/AppServiceRecord.js'; + +/** + * Response to the request to register a service offered by this app on the module + */ +class PublishAppServiceResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.PublishAppService); + } + + /** + * @param {AppServiceRecord} record - If the request was successful, this object will be the current status of the + * service record for the published service. This will include the Core supplied + * service ID. + * @return {PublishAppServiceResponse} + */ + setAppServiceRecord (record) { + this.validateType(AppServiceRecord, record); + this.setParameter(PublishAppServiceResponse.KEY_APP_SERVICE_RECORD, record); + return this; + } + + /** + * @return {AppServiceRecord} + */ + getAppServiceRecord () { + return this.getObject(AppServiceRecord, PublishAppServiceResponse.KEY_APP_SERVICE_RECORD); + } +} + +PublishAppServiceResponse.KEY_APP_SERVICE_RECORD = 'appServiceRecord'; + +export { PublishAppServiceResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/PutFile.js b/lib/js/src/rpc/messages/PutFile.js index 3346995f..af234f0c 100644 --- a/lib/js/src/rpc/messages/PutFile.js +++ b/lib/js/src/rpc/messages/PutFile.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -34,10 +35,14 @@ import { RpcRequest } from '../RpcRequest.js'; import { FileType } from '../enums/FileType.js'; import { FunctionID } from '../enums/FunctionID.js'; +/** + * Used to push a binary data onto the module from a mobile device, such as icons and album art Not supported on first + * generation of SDL enabled modules. Binary data is in binary part of hybrid msg. + */ class PutFile extends RpcRequest { /** - * @constructor - */ + * @constructor + */ constructor (store) { super(store); this.setFunctionName(FunctionID.PutFile); @@ -46,133 +51,140 @@ class PutFile extends RpcRequest { // ------ Not part of the RPC spec itself ----- /** - * @param {Uint8Array} fileData - * @return {PutFile} - */ + * @param {Uint8Array} fileData + * @return {PutFile} + */ setFileData (fileData) { this.setBulkData(fileData); return this; } /** - * @return {Uint8Array} - */ + * @return {Uint8Array} + */ getFileData () { return this.getBulkData(); } // ----------------- END ----------------------- - /** - * @param {String} fileName - * @return {PutFile} - */ - setFileName (fileName) { - this.setParameter(PutFile.KEY_FILE_NAME, fileName); + * @param {String} name - File reference name. + * @return {PutFile} + */ + setFileName (name) { + this.setParameter(PutFile.KEY_FILE_NAME, name); return this; } /** - * @return {String} - */ + * @return {String} + */ getFileName () { return this.getParameter(PutFile.KEY_FILE_NAME); } /** - * @param {FileType} fileType - * @return {PutFile} - */ - setFileType (fileType) { - this.validateType(FileType, fileType); - this.setParameter(PutFile.KEY_FILE_TYPE, fileType); + * @param {FileType} type - Selected file type. + * @return {PutFile} + */ + setFileType (type) { + this.validateType(FileType, type); + this.setParameter(PutFile.KEY_FILE_TYPE, type); return this; } /** - * @return {FileType} - */ + * @return {FileType} + */ getFileType () { - return this.getObject(FileType, PutFile.KEY_MENU_PARAMS); + return this.getObject(FileType, PutFile.KEY_FILE_TYPE); } /** - * @param {Boolean} persistentFile - * @return {PutFile} - */ - setPersistentFile (persistentFile) { - this.setParameter(PutFile.KEY_PERSISTENT_FILE, persistentFile); + * @param {Boolean} file - Indicates if the file is meant to persist between sessions / ignition cycles. If set to + * TRUE, then the system will aim to persist this file through session / cycles. While files + * with this designation will have priority over others, they are subject to deletion by the + * system at any time. In the event of automatic deletion by the system, the app will + * receive a rejection and have to resend the file. If omitted, the value will be set to + * false. + * @return {PutFile} + */ + setPersistentFile (file) { + this.setParameter(PutFile.KEY_PERSISTENT_FILE, file); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getPersistentFile () { return this.getParameter(PutFile.KEY_PERSISTENT_FILE); } /** - * @param {Boolean} systemFile - * @return {PutFile} - */ - setSystemFile (systemFile) { - this.setParameter(PutFile.KEY_SYSTEM_FILE, systemFile); + * @param {Boolean} file - Indicates if the file is meant to be passed thru core to elsewhere on the system. If set + * to TRUE, then the system will instead pass the data thru as it arrives to a predetermined + * area outside of core. If omitted, the value will be set to false. + * @return {PutFile} + */ + setSystemFile (file) { + this.setParameter(PutFile.KEY_SYSTEM_FILE, file); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getSystemFile () { return this.getParameter(PutFile.KEY_SYSTEM_FILE); } /** - * @param {Number} offset - * @return {PutFile} - */ + * @param {Number} offset - Optional offset in bytes for resuming partial data chunks + * @return {PutFile} + */ setOffset (offset) { this.setParameter(PutFile.KEY_OFFSET, offset); return this; } /** - * @return {Number} - */ + * @return {Number} + */ getOffset () { return this.getParameter(PutFile.KEY_OFFSET); } /** - * @param {Number} length - * @return {PutFile} - */ + * @param {Number} length - Optional length in bytes for resuming partial data chunks If offset is set to 0, then + * length is the total length of the file to be downloaded + * @return {PutFile} + */ setLength (length) { this.setParameter(PutFile.KEY_LENGTH, length); return this; } /** - * @return {Number} - */ + * @return {Number} + */ getLength () { return this.getParameter(PutFile.KEY_LENGTH); } /** - * @param {Number} crc - * @return {PutFile} - */ - setCRC (crc) { + * @param {Number} crc - Additional CRC32 checksum to protect data integrity up to 512 Mbits + * @return {PutFile} + */ + setCrc (crc) { this.setParameter(PutFile.KEY_CRC, crc); return this; } /** - * @return {Number} - */ - getCRC () { + * @return {Number} + */ + getCrc () { return this.getParameter(PutFile.KEY_CRC); } } @@ -185,4 +197,4 @@ PutFile.KEY_OFFSET = 'offset'; PutFile.KEY_LENGTH = 'length'; PutFile.KEY_CRC = 'crc'; -export { PutFile }; +export { PutFile }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/PutFileResponse.js b/lib/js/src/rpc/messages/PutFileResponse.js index 25709690..18dd7cc7 100644 --- a/lib/js/src/rpc/messages/PutFileResponse.js +++ b/lib/js/src/rpc/messages/PutFileResponse.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -30,31 +31,35 @@ * POSSIBILITY OF SUCH DAMAGE. */ -import { RpcResponse } from '../RpcResponse.js'; import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; +/** + * Response is sent, when the file data was copied (success case). Or when an error occurred. Not supported on first + * generation SDL enabled vehicles. + */ class PutFileResponse extends RpcResponse { /** - * @constructor - */ + * @constructor + */ constructor (store) { super(store); this.setFunctionName(FunctionID.PutFile); } - /** - * @param {Number} spaceAvailable - * @return {PutFileResponse} - */ - setSpaceAvailable (spaceAvailable) { - this.setParameter(PutFileResponse.KEY_SPACE_AVAILABLE, spaceAvailable); + * @param {Number} available - Provides the total local space available in SDL Core for the registered app. If the + * transfer has systemFile enabled, then the value will be set to 0 automatically. + * @return {PutFileResponse} + */ + setSpaceAvailable (available) { + this.setParameter(PutFileResponse.KEY_SPACE_AVAILABLE, available); return this; } /** - * @return {Number} - */ + * @return {Number} + */ getSpaceAvailable () { return this.getParameter(PutFileResponse.KEY_SPACE_AVAILABLE); } @@ -62,4 +67,4 @@ class PutFileResponse extends RpcResponse { PutFileResponse.KEY_SPACE_AVAILABLE = 'spaceAvailable'; -export { PutFileResponse }; +export { PutFileResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/ReadDID.js b/lib/js/src/rpc/messages/ReadDID.js new file mode 100644 index 00000000..4a99669f --- /dev/null +++ b/lib/js/src/rpc/messages/ReadDID.js @@ -0,0 +1,85 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Non periodic vehicle data read request + */ +class ReadDID extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.ReadDID); + } + + /** + * @param {Number} name - Name of ECU. + * @return {ReadDID} + */ + setEcuName (name) { + this.setParameter(ReadDID.KEY_ECU_NAME, name); + return this; + } + + /** + * @return {Number} + */ + getEcuName () { + return this.getParameter(ReadDID.KEY_ECU_NAME); + } + + /** + * @param {Number[]} location - Get raw data from vehicle data DID location(s) + * @return {ReadDID} + */ + setDidLocation (location) { + this.setParameter(ReadDID.KEY_DID_LOCATION, location); + return this; + } + + /** + * @return {Number[]} + */ + getDidLocation () { + return this.getParameter(ReadDID.KEY_DID_LOCATION); + } +} + +ReadDID.KEY_ECU_NAME = 'ecuName'; +ReadDID.KEY_DID_LOCATION = 'didLocation'; + +export { ReadDID }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/ReadDIDResponse.js b/lib/js/src/rpc/messages/ReadDIDResponse.js new file mode 100644 index 00000000..b23b91a7 --- /dev/null +++ b/lib/js/src/rpc/messages/ReadDIDResponse.js @@ -0,0 +1,67 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { DIDResult } from '../structs/DIDResult.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class ReadDIDResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.ReadDID); + } + + /** + * @param {DIDResult[]} result - Array of requested DID results (with data if available). + * @return {ReadDIDResponse} + */ + setDidResult (result) { + this.validateType(DIDResult, result, true); + this.setParameter(ReadDIDResponse.KEY_DID_RESULT, result); + return this; + } + + /** + * @return {DIDResult[]} + */ + getDidResult () { + return this.getObject(DIDResult, ReadDIDResponse.KEY_DID_RESULT); + } +} + +ReadDIDResponse.KEY_DID_RESULT = 'didResult'; + +export { ReadDIDResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/RegisterAppInterface.js b/lib/js/src/rpc/messages/RegisterAppInterface.js index 94b19446..1072a4d2 100644 --- a/lib/js/src/rpc/messages/RegisterAppInterface.js +++ b/lib/js/src/rpc/messages/RegisterAppInterface.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -30,336 +31,352 @@ * POSSIBILITY OF SUCH DAMAGE. */ -import { RpcRequest } from '../RpcRequest.js'; -import { SdlMsgVersion } from '../structs/SdlMsgVersion.js'; -import { TTSChunk } from '../structs/TTSChunk.js'; -import { DeviceInfo } from '../structs/DeviceInfo.js'; import { AppInfo } from '../structs/AppInfo.js'; import { TemplateColorScheme } from '../structs/TemplateColorScheme.js'; - -import { Language } from '../enums/Language.js'; -import { AppHMIType } from '../enums/AppHMIType.js'; import { FunctionID } from '../enums/FunctionID.js'; +import { TTSChunk } from '../structs/TTSChunk.js'; +import { SdlMsgVersion } from '../structs/SdlMsgVersion.js'; +import { AppHMIType } from '../enums/AppHMIType.js'; +import { Language } from '../enums/Language.js'; +import { RpcRequest } from '../RpcRequest.js'; +import { DeviceInfo } from '../structs/DeviceInfo.js'; +/** + * Establishes an interface with a mobile application. Before registerAppInterface no other commands will be + * accepted/executed. + */ class RegisterAppInterface extends RpcRequest { + /** + * @constructor + */ constructor (store) { super(store); this.setFunctionName(FunctionID.RegisterAppInterface); } /** - * @param {SdlMsgVersion} The max RPC Spec version supported by this library - * @return {RegisterAppInterface} - */ - setSdlMsgVersion (sdlMsgVersion) { - this.validateType(SdlMsgVersion, sdlMsgVersion); + * @param {String} fullAppId + * @return {RegisterAppInterface} + */ + setFullAppId (fullAppId) { + this.validateType(String, fullAppId); + + if (fullAppId !== null) { + fullAppId = fullAppId.toLowerCase(); + this.setParameter(RegisterAppInterface.KEY_FULL_APP_ID, fullAppId); + let appID; + if (fullAppId.length <= RegisterAppInterface.APP_ID_MAX_LENGTH) { + appID = fullAppId; + } else { + appID = fullAppId.replace('-', '').substring(0, RegisterAppInterface.APP_ID_MAX_LENGTH); + } + this._setAppId(appID); + } else { + this.setParameter(RegisterAppInterface.KEY_FULL_APP_ID, null); + } - this.setParameter(RegisterAppInterface.KEY_SDL_MSG_VERSION, sdlMsgVersion); return this; } /** - * @return {SdlMsgVersion} - */ - getSdlMsgVersion () { - return this.getObject(SdlMsgVersion, RegisterAppInterface.KEY_SDL_MSG_VERSION); + * @return {String} the app id + */ + getFullAppId () { + return this.getParameter(RegisterAppInterface.KEY_FULL_APP_ID); } + /** + * @param {String} appId - This method should not be accessed directly by developers. Only set the full ID and this + * param will be set. + * @return {RegisterAppInterface} + */ + _setAppId (appId) { + this.validateType(String, appId); + + this.setParameter(RegisterAppInterface.KEY_APP_ID, appId); + return this; + } /** - * @param {String} appName the name of the app that is registering - * @return {RegisterAppInterface} - */ - setAppName (appName) { - this.validateType(String, appName); + * @return {String} the app id + */ + getAppId () { + return this.getParameter(RegisterAppInterface.KEY_APP_ID); + } - this.setParameter(RegisterAppInterface.KEY_APP_NAME, appName); + /** + * @param {SdlMsgVersion} version - See SyncMsgVersion + * @return {RegisterAppInterface} + */ + setSdlMsgVersion (version) { + this.validateType(SdlMsgVersion, version); + this.setParameter(RegisterAppInterface.KEY_SDL_MSG_VERSION, version); return this; } /** - * @return {String} the app name - */ + * @return {SdlMsgVersion} + */ + getSdlMsgVersion () { + return this.getObject(SdlMsgVersion, RegisterAppInterface.KEY_SDL_MSG_VERSION); + } + + /** + * @param {String} name - The mobile application name, e.g. "My SDL App". Needs to be unique over all applications + * from the same device. May not be empty. May not start with a new line character. May not + * interfere with any name or synonym of previously registered applications from the same + * device and any predefined blacklist of words (global commands) Additional applications + * with the same name from the same device will be rejected. Only characters from char set + * @return {RegisterAppInterface} + */ + setAppName (name) { + this.setParameter(RegisterAppInterface.KEY_APP_NAME, name); + return this; + } + + /** + * @return {String} + */ getAppName () { return this.getParameter(RegisterAppInterface.KEY_APP_NAME); } /** - * @param {Array} ttsNames TTS string for VR recognition of the mobile application name, e.g. "My S D L App". - * Meant to overcome any failing on speech engine in properly pronouncing / understanding - * app name. Needs to be unique over all applications from the same device. May not be - * empty. May not start with a new line character. Only characters from char set - * @return {RegisterAppInterface} - */ - setTtsName (ttsNames) { - this.setParameter(RegisterAppInterface.KEY_TTS_NAME, ttsNames); + * @param {TTSChunk[]} name - TTS string for VR recognition of the mobile application name, e.g. "My S D L App". + * Meant to overcome any failing on speech engine in properly pronouncing / understanding + * app name. Needs to be unique over all applications from the same device. May not be + * empty. May not start with a new line character. Only characters from char set + * @return {RegisterAppInterface} + */ + setTtsName (name) { + this.validateType(TTSChunk, name, true); + this.setParameter(RegisterAppInterface.KEY_TTS_NAME, name); return this; } /** - * @return {Array} - */ + * @return {TTSChunk[]} + */ getTtsName () { return this.getObject(TTSChunk, RegisterAppInterface.KEY_TTS_NAME); } /** - * @param {String} ngnppName Provides an abbreviated version of the app name (if needed), that will be displayed - * on the NGN media screen. If not provided, the appName is used instead (and - * will be truncated if too long)Only characters from char set. - * @return {RegisterAppInterface} - */ - setNgnMediaScreenAppName (ngnppName) { - this.validateType(String, ngnppName); - - this.setParameter(RegisterAppInterface.KEY_NGN_MEDIA_SCREEN_APP_NAME, ngnppName); + * @param {String} name - Provides an abbreviated version of the app name (if needed), that will be displayed on the + * NGN media screen. If not provided, the appName is used instead (and will be truncated if + * too long) Only characters from char set + * @return {RegisterAppInterface} + */ + setNgnMediaScreenAppName (name) { + this.setParameter(RegisterAppInterface.KEY_NGN_MEDIA_SCREEN_APP_NAME, name); return this; } /** - * @return {String} an abbreviated version of the app name - */ + * @return {String} + */ getNgnMediaScreenAppName () { return this.getParameter(RegisterAppInterface.KEY_NGN_MEDIA_SCREEN_APP_NAME); } /** - * @param {Array} vrSynonyms Defines an additional voice recognition command. May not - * interfere with any app name of previously registered applications - * from the same device and any predefined blacklist of words (global - * commands)Only characters from char set - * @return {RegisterAppInterface} - */ - setVrSynonyms (vrSynonyms) { - this.setParameter(RegisterAppInterface.KEY_VR_SYNONYMS, vrSynonyms); + * @param {String[]} synonyms - Defines an additional voice recognition command. May not interfere with any app name + * of previously registered applications from the same device and any predefined + * blacklist of words (global commands) Only characters from char set + * @return {RegisterAppInterface} + */ + setVrSynonyms (synonyms) { + this.setParameter(RegisterAppInterface.KEY_VR_SYNONYMS, synonyms); return this; } /** - * @return {Array} - */ + * @return {String[]} + */ getVrSynonyms () { return this.getParameter(RegisterAppInterface.KEY_VR_SYNONYMS); } /** - * @param {Boolean} isMediaApplication Indicates if the application is a media or a non-media application. - * Only media applications will be able to stream audio to the module - * that is audible outside of the BT media source. - * @return {RegisterAppInterface} - */ - setIsMediaApplication (isMediaApplication) { - this.setParameter(RegisterAppInterface.KEY_IS_MEDIA_APPLICATION, isMediaApplication); + * @param {Boolean} application - Indicates if the application is a media or a non-media application. Only media + * applications will be able to stream audio to the module that is audible outside of + * the BT media source. + * @return {RegisterAppInterface} + */ + setIsMediaApplication (application) { + this.setParameter(RegisterAppInterface.KEY_IS_MEDIA_APPLICATION, application); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getIsMediaApplication () { return this.getParameter(RegisterAppInterface.KEY_IS_MEDIA_APPLICATION); } /** - * @param {Language} languageDesired - * @return {RegisterAppInterface} - */ - setLanguageDesired (languageDesired) { - this.validateType(Language, languageDesired); - - this.setParameter(RegisterAppInterface.KEY_LANGUAGE_DESIRED, languageDesired); + * @param {Language} desired - See Language Current app's expected VR+TTS language If there is a mismatch with the + * module, the app will be able to change this registration with changeRegistration + * prior to app being brought into focus. + * @return {RegisterAppInterface} + */ + setLanguageDesired (desired) { + this.validateType(Language, desired); + this.setParameter(RegisterAppInterface.KEY_LANGUAGE_DESIRED, desired); return this; } /** - * @return {Language} - */ + * @return {Language} + */ getLanguageDesired () { return this.getObject(Language, RegisterAppInterface.KEY_LANGUAGE_DESIRED); } - /** - * @param {Language} hmiDisplayLanguageDesired - * @return {RegisterAppInterface} - */ - setHmiDisplayLanguageDesired (hmiDisplayLanguageDesired) { - this.validateType(Language, hmiDisplayLanguageDesired); - - this.setParameter(RegisterAppInterface.KEY_HMI_DISPLAY_LANGUAGE_DESIRED, hmiDisplayLanguageDesired); + * @param {Language} desired - See Language Current app's expected display language If there is a mismatch with the + * module, the app will be able to change this registration with changeRegistration + * prior to app being brought into focus. + * @return {RegisterAppInterface} + */ + setHmiDisplayLanguageDesired (desired) { + this.validateType(Language, desired); + this.setParameter(RegisterAppInterface.KEY_HMI_DISPLAY_LANGUAGE_DESIRED, desired); return this; } /** - * @return {Language} - */ + * @return {Language} + */ getHmiDisplayLanguageDesired () { return this.getObject(Language, RegisterAppInterface.KEY_HMI_DISPLAY_LANGUAGE_DESIRED); } - /** - * @param {Array} appHMIType - * @return {RegisterAppInterface} - */ - setAppHmiType (appHMIType) { - // TODO make validate type accept arrays - // this.validateType(AppHMIType, appHMIType); - - this.setParameter(RegisterAppInterface.KEY_APP_HMI_TYPE, appHMIType); + * @param {AppHMIType[]} type - See AppHMIType List of all applicable app HMI types stating which HMI + * classifications to be given to the app. + * @return {RegisterAppInterface} + */ + setAppHMIType (type) { + this.validateType(AppHMIType, type, true); + this.setParameter(RegisterAppInterface.KEY_APP_HMI_TYPE, type); return this; } /** - * @return {Array} - */ - getAppHmiType () { + * @return {AppHMIType[]} + */ + getAppHMIType () { return this.getObject(AppHMIType, RegisterAppInterface.KEY_APP_HMI_TYPE); } /** - * @param {String} hashID the hash ID - * @return {RegisterAppInterface} - */ - setHashID (hashID) { - this.validateType(String, hashID); - - this.setParameter(RegisterAppInterface.KEY_HASH_ID, hashID); + * @param {String} id - ID used to uniquely identify current state of all app data that can persist through + * connection cycles (e.g. ignition cycles). This registered data (commands, submenus, choice + * sets, etc.) can be reestablished without needing to explicitly reregister each piece. If + * omitted, then the previous state of an app's commands, etc. will not be restored. When + * sending hashID, all RegisterAppInterface parameters should still be provided (e.g. ttsName, + * etc.). + * @return {RegisterAppInterface} + */ + setHashID (id) { + this.setParameter(RegisterAppInterface.KEY_HASH_ID, id); return this; } /** - * @return {String} the hash ID - */ + * @return {String} + */ getHashID () { return this.getParameter(RegisterAppInterface.KEY_HASH_ID); } /** - * @param {DeviceInfo} deviceInfo + * @param {DeviceInfo} info - See DeviceInfo. * @return {RegisterAppInterface} */ - setDeviceInfo (deviceInfo) { - this.validateType(DeviceInfo, deviceInfo); - - this.setParameter(RegisterAppInterface.KEY_DEVICE_INFO, deviceInfo); + setDeviceInfo (info) { + this.validateType(DeviceInfo, info); + this.setParameter(RegisterAppInterface.KEY_DEVICE_INFO, info); return this; } /** - * @return {DeviceInfo} - */ + * @return {DeviceInfo} + */ getDeviceInfo () { return this.getObject(DeviceInfo, RegisterAppInterface.KEY_DEVICE_INFO); } - /** - * @param {String} appName This method should not be accessed directly by developers. Only set the full ID and this param will be set. - * @return {RegisterAppInterface} - */ - _setAppId (appId) { - this.validateType(String, appId); - - this.setParameter(RegisterAppInterface.KEY_APP_ID, appId); - return this; - } - - /** - * @return {String} the app id - */ - getAppId () { - return this.getParameter(RegisterAppInterface.KEY_APP_ID); - } - - /** - * @param {String} fullAppId - * @return {RegisterAppInterface} - */ - setFullAppId (fullAppId) { - this.validateType(String, fullAppId); - - if (fullAppId !== null) { - fullAppId = fullAppId.toLowerCase(); - this.setParameter(RegisterAppInterface.KEY_FULL_APP_ID, fullAppId); - let appId; - if (fullAppId.length <= RegisterAppInterface.APP_ID_MAX_LENGTH) { - appId = fullAppId; - } else { - appId = fullAppId.replace('-', '').substring(0, RegisterAppInterface.APP_ID_MAX_LENGTH); - } - this._setAppId(appId); - } else { - this.setParameter(RegisterAppInterface.KEY_FULL_APP_ID, null); - } - + * @param {String} id - ID used to validate app with policy table entries + * @return {RegisterAppInterface} + */ + setFullAppID (id) { + this.setParameter(RegisterAppInterface.KEY_FULL_APP_ID, id); return this; } /** - * @return {String} the app id - */ - getFullAppId () { + * @return {String} + */ + getFullAppID () { return this.getParameter(RegisterAppInterface.KEY_FULL_APP_ID); } - /** - * @param {AppInfo} appInfo + * @param {AppInfo} info - See AppInfo. * @return {RegisterAppInterface} */ - setAppInfo (appInfo) { - this.validateType(AppInfo, appInfo); - - this.setParameter(RegisterAppInterface.KEY_APP_INFO, appInfo); + setAppInfo (info) { + this.validateType(AppInfo, info); + this.setParameter(RegisterAppInterface.KEY_APP_INFO, info); return this; } /** - * @return {AppInfo} - */ + * @return {AppInfo} + */ getAppInfo () { return this.getObject(AppInfo, RegisterAppInterface.KEY_APP_INFO); } /** - * @param {TemplateColorScheme} dayColorScheme + * @param {TemplateColorScheme} scheme - A color scheme for all display layout templates. * @return {RegisterAppInterface} */ - setDayColorScheme (dayColorScheme) { - this.validateType(TemplateColorScheme, dayColorScheme); - - this.setParameter(RegisterAppInterface.KEY_DAY_COLOR_SCHEME, dayColorScheme); + setDayColorScheme (scheme) { + this.validateType(TemplateColorScheme, scheme); + this.setParameter(RegisterAppInterface.KEY_DAY_COLOR_SCHEME, scheme); return this; } /** - * @return {TemplateColorScheme} - */ + * @return {TemplateColorScheme} + */ getDayColorScheme () { return this.getObject(TemplateColorScheme, RegisterAppInterface.KEY_DAY_COLOR_SCHEME); } /** - * @param {TemplateColorScheme} nightColorScheme + * @param {TemplateColorScheme} scheme - A color scheme for all display layout templates. * @return {RegisterAppInterface} */ - setNightColorScheme (nightColorScheme) { - this.validateType(TemplateColorScheme, nightColorScheme); - - this.setParameter(RegisterAppInterface.KEY_NIGHT_COLOR_SCHEME, nightColorScheme); + setNightColorScheme (scheme) { + this.validateType(TemplateColorScheme, scheme); + this.setParameter(RegisterAppInterface.KEY_NIGHT_COLOR_SCHEME, scheme); return this; } /** - * @return {TemplateColorScheme} - */ + * @return {TemplateColorScheme} + */ getNightColorScheme () { return this.getObject(TemplateColorScheme, RegisterAppInterface.KEY_NIGHT_COLOR_SCHEME); } } -RegisterAppInterface.KEY_SYNC_MSG_VERSION = 'syncMsgVersion'; RegisterAppInterface.KEY_SDL_MSG_VERSION = 'syncMsgVersion'; RegisterAppInterface.KEY_APP_NAME = 'appName'; RegisterAppInterface.KEY_TTS_NAME = 'ttsName'; @@ -378,4 +395,4 @@ RegisterAppInterface.KEY_DAY_COLOR_SCHEME = 'dayColorScheme'; RegisterAppInterface.KEY_NIGHT_COLOR_SCHEME = 'nightColorScheme'; RegisterAppInterface.APP_ID_MAX_LENGTH = 10; -export { RegisterAppInterface }; +export { RegisterAppInterface }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/RegisterAppInterfaceResponse.js b/lib/js/src/rpc/messages/RegisterAppInterfaceResponse.js index af742b39..3530ada6 100644 --- a/lib/js/src/rpc/messages/RegisterAppInterfaceResponse.js +++ b/lib/js/src/rpc/messages/RegisterAppInterfaceResponse.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -30,367 +31,358 @@ * POSSIBILITY OF SUCH DAMAGE. */ +import { SoftButtonCapabilities } from '../structs/SoftButtonCapabilities.js'; import { RpcResponse } from '../RpcResponse.js'; +import { FunctionID } from '../enums/FunctionID.js'; import { SdlMsgVersion } from '../structs/SdlMsgVersion.js'; -import { DisplayCapabilities } from '../structs/DisplayCapabilities.js'; -import { ButtonCapabilities } from '../structs/ButtonCapabilities.js'; -import { SoftButtonCapabilities } from '../structs/SoftButtonCapabilities.js'; +import { PrerecordedSpeech } from '../enums/PrerecordedSpeech.js'; +import { SpeechCapabilities } from '../enums/SpeechCapabilities.js'; import { PresetBankCapabilities } from '../structs/PresetBankCapabilities.js'; import { VehicleType } from '../structs/VehicleType.js'; -import { Language } from '../enums/Language.js'; import { HmiZoneCapabilities } from '../enums/HmiZoneCapabilities.js'; -import { SpeechCapabilities } from '../enums/SpeechCapabilities.js'; -import { PrerecordedSpeech } from '../enums/PrerecordedSpeech.js'; -import { FunctionID } from '../enums/FunctionID.js'; +import { DisplayCapabilities } from '../structs/DisplayCapabilities.js'; +import { Language } from '../enums/Language.js'; import { AudioPassThruCapabilities } from '../structs/AudioPassThruCapabilities.js'; import { VrCapabilities } from '../enums/VrCapabilities.js'; +import { ButtonCapabilities } from '../structs/ButtonCapabilities.js'; import { HMICapabilities } from '../structs/HMICapabilities.js'; +/** + * The response to registerAppInterface + */ class RegisterAppInterfaceResponse extends RpcResponse { + /** + * @constructor + */ constructor (store) { super(store); this.setFunctionName(FunctionID.RegisterAppInterface); } /** - * @param {SdlMsgVersion} The max RPC Spec version supported by this library - * @return {RegisterAppInterfaceResponse} - */ - setSdlMsgVersion (sdlMsgVersion) { - this.validateType(SdlMsgVersion, sdlMsgVersion); - - this.setParameter(RegisterAppInterfaceResponse.KEY_SDL_MSG_VERSION, sdlMsgVersion); + * @param {SdlMsgVersion} version - See SyncMsgVersion + * @return {RegisterAppInterfaceResponse} + */ + setSdlMsgVersion (version) { + this.validateType(SdlMsgVersion, version); + this.setParameter(RegisterAppInterfaceResponse.KEY_SDL_MSG_VERSION, version); return this; } /** - * @return {SdlMsgVersion} - */ + * @return {SdlMsgVersion} + */ getSdlMsgVersion () { return this.getObject(SdlMsgVersion, RegisterAppInterfaceResponse.KEY_SDL_MSG_VERSION); } /** - * @param {Language} language - * @return {RegisterAppInterfaceResponse} - */ + * @param {Language} language - The currently active VR+TTS language on the module. See "Language" for options. + * @return {RegisterAppInterfaceResponse} + */ setLanguage (language) { this.validateType(Language, language); - this.setParameter(RegisterAppInterfaceResponse.KEY_LANGUAGE, language); return this; } /** - * @return {Language} - */ + * @return {Language} + */ getLanguage () { return this.getObject(Language, RegisterAppInterfaceResponse.KEY_LANGUAGE); } - /** - * @param {Language} hmiDisplayLanguage - * @return {RegisterAppInterfaceResponse} - */ - setHmiDisplayLanguage (hmiDisplayLanguage) { - this.validateType(Language, hmiDisplayLanguage); - - this.setParameter(RegisterAppInterfaceResponse.KEY_HMI_DISPLAY_LANGUAGE, hmiDisplayLanguage); + * @param {Language} language - The currently active display language on the module. See "Language" for options. + * @return {RegisterAppInterfaceResponse} + */ + setHmiDisplayLanguage (language) { + this.validateType(Language, language); + this.setParameter(RegisterAppInterfaceResponse.KEY_HMI_DISPLAY_LANGUAGE, language); return this; } /** - * @return {Language} - */ + * @return {Language} + */ getHmiDisplayLanguage () { return this.getObject(Language, RegisterAppInterfaceResponse.KEY_HMI_DISPLAY_LANGUAGE); } /** - * @param {DisplayCapabilities} displayCapabilities - * @return {RegisterAppInterfaceResponse} - */ - setDisplayCapabilities (displayCapabilities) { - this.validateType(DisplayCapabilities, displayCapabilities); - - this.setParameter(RegisterAppInterfaceResponse.KEY_DISPLAY_CAPABILITIES, displayCapabilities); + * @param {DisplayCapabilities} capabilities - See DisplayCapabilities. This parameter is deprecated and replaced by + * SystemCapability using DISPLAYS. + * @return {RegisterAppInterfaceResponse} + */ + setDisplayCapabilities (capabilities) { + this.validateType(DisplayCapabilities, capabilities); + this.setParameter(RegisterAppInterfaceResponse.KEY_DISPLAY_CAPABILITIES, capabilities); return this; } /** - * @return {DisplayCapabilities} - */ + * @return {DisplayCapabilities} + */ getDisplayCapabilities () { return this.getObject(DisplayCapabilities, RegisterAppInterfaceResponse.KEY_DISPLAY_CAPABILITIES); } - /** - * @param {Array} buttonCapabilities - * @return {RegisterAppInterfaceResponse} - */ - setButtonCapabilities (buttonCapabilities) { - // TODO make this work with arrays - // this.validateType(Language, buttonCapabilities); - - this.setParameter(RegisterAppInterfaceResponse.KEY_BUTTON_CAPABILITIES, buttonCapabilities); + * @param {ButtonCapabilities[]} capabilities - See ButtonCapabilities. This parameter is deprecated and replaced by + * SystemCapability using DISPLAYS. + * @return {RegisterAppInterfaceResponse} + */ + setButtonCapabilities (capabilities) { + this.validateType(ButtonCapabilities, capabilities, true); + this.setParameter(RegisterAppInterfaceResponse.KEY_BUTTON_CAPABILITIES, capabilities); return this; } /** - * @return {Array} - */ + * @return {ButtonCapabilities[]} + */ getButtonCapabilities () { return this.getObject(ButtonCapabilities, RegisterAppInterfaceResponse.KEY_BUTTON_CAPABILITIES); } /** - * @param {Array} softButtonCapabilities - * @return {RegisterAppInterfaceResponse} - */ - setSoftButtonCapabilities (softButtonCapabilities) { - // TODO make this work with arrays - // this.validateType(SoftButtonCapabilities, softButtonCapabilities); - - this.setParameter(RegisterAppInterfaceResponse.KEY_SOFT_BUTTON_CAPABILITIES, softButtonCapabilities); + * @param {SoftButtonCapabilities[]} capabilities - If returned, the platform supports on-screen SoftButtons; see + * SoftButtonCapabilities. This parameter is deprecated and + * replaced by SystemCapability using DISPLAYS. + * @return {RegisterAppInterfaceResponse} + */ + setSoftButtonCapabilities (capabilities) { + this.validateType(SoftButtonCapabilities, capabilities, true); + this.setParameter(RegisterAppInterfaceResponse.KEY_SOFT_BUTTON_CAPABILITIES, capabilities); return this; } /** - * @return {Array} - */ + * @return {SoftButtonCapabilities[]} + */ getSoftButtonCapabilities () { return this.getObject(SoftButtonCapabilities, RegisterAppInterfaceResponse.KEY_SOFT_BUTTON_CAPABILITIES); } /** - * @param {PresetBankCapabilities} presetBankCapabilities - * @return {RegisterAppInterfaceResponse} - */ - setPresetBankCapabilities (presetBankCapabilities) { - this.validateType(PresetBankCapabilities, presetBankCapabilities); - - this.setParameter(RegisterAppInterfaceResponse.KEY_PRESET_BANK_CAPABILITIES, presetBankCapabilities); + * @param {PresetBankCapabilities} capabilities - If returned, the platform supports custom on-screen Presets; see + * PresetBankCapabilities. This parameter is deprecated and replaced + * by SystemCapability using DISPLAYS. + * @return {RegisterAppInterfaceResponse} + */ + setPresetBankCapabilities (capabilities) { + this.validateType(PresetBankCapabilities, capabilities); + this.setParameter(RegisterAppInterfaceResponse.KEY_PRESET_BANK_CAPABILITIES, capabilities); return this; } /** - * @return {PresetBankCapabilities} - */ + * @return {PresetBankCapabilities} + */ getPresetBankCapabilities () { return this.getObject(PresetBankCapabilities, RegisterAppInterfaceResponse.KEY_PRESET_BANK_CAPABILITIES); } /** - * @param {Array} hmiZoneCapabilities - * @return {RegisterAppInterfaceResponse} - */ - setHmiZoneCapabilities (hmiZoneCapabilities) { - // TODO make this work for arrays - // this.validateType(HmiZoneCapabilities, hmiZoneCapabilities); - - this.setParameter(RegisterAppInterfaceResponse.KEY_HMI_ZONE_CAPABILITIES, hmiZoneCapabilities); + * @param {HmiZoneCapabilities[]} capabilities - See HmiZoneCapabilities + * @return {RegisterAppInterfaceResponse} + */ + setHmiZoneCapabilities (capabilities) { + this.validateType(HmiZoneCapabilities, capabilities, true); + this.setParameter(RegisterAppInterfaceResponse.KEY_HMI_ZONE_CAPABILITIES, capabilities); return this; } /** - * @return {Array} - */ + * @return {HmiZoneCapabilities[]} + */ getHmiZoneCapabilities () { return this.getObject(HmiZoneCapabilities, RegisterAppInterfaceResponse.KEY_HMI_ZONE_CAPABILITIES); } /** - * @param {Array} speechCapabilities - * @return {RegisterAppInterfaceResponse} - */ - setSpeechCapabilities (speechCapabilities) { - // TODO make this work for arrays - // this.validateType(SpeechCapabilities, speechCapabilities); - - this.setParameter(RegisterAppInterfaceResponse.KEY_SPEECH_CAPABILITIES, speechCapabilities); + * @param {SpeechCapabilities[]} capabilities - See SpeechCapabilities + * @return {RegisterAppInterfaceResponse} + */ + setSpeechCapabilities (capabilities) { + this.validateType(SpeechCapabilities, capabilities, true); + this.setParameter(RegisterAppInterfaceResponse.KEY_SPEECH_CAPABILITIES, capabilities); return this; } /** - * @return {Array} - */ + * @return {SpeechCapabilities[]} + */ getSpeechCapabilities () { return this.getObject(SpeechCapabilities, RegisterAppInterfaceResponse.KEY_SPEECH_CAPABILITIES); } /** - * @param {Array} speechCapabilities - * @return {RegisterAppInterfaceResponse} - */ - setPrerecordedSpeech (speechCapabilities) { - // TODO make this work for arrays - // this.validateType(PrerecordedSpeech, speechCapabilities); - - this.setParameter(RegisterAppInterfaceResponse.KEY_PRERECORDED_SPEECH, speechCapabilities); + * @param {PrerecordedSpeech[]} speech - See PrerecordedSpeech + * @return {RegisterAppInterfaceResponse} + */ + setPrerecordedSpeech (speech) { + this.validateType(PrerecordedSpeech, speech, true); + this.setParameter(RegisterAppInterfaceResponse.KEY_PRERECORDED_SPEECH, speech); return this; } /** - * @return {Array} - */ + * @return {PrerecordedSpeech[]} + */ getPrerecordedSpeech () { return this.getObject(PrerecordedSpeech, RegisterAppInterfaceResponse.KEY_PRERECORDED_SPEECH); } /** - * @param {Array} vrCapabilities - * @return {RegisterAppInterfaceResponse} - */ - setVrCapabilities (vrCapabilities) { - // TODO make this work for arrays - // this.validateType(VrCapabilities, vrCapabilities); - - this.setParameter(RegisterAppInterfaceResponse.KEY_VR_CAPABILITIES, vrCapabilities); + * @param {VrCapabilities[]} capabilities - See VrCapabilities + * @return {RegisterAppInterfaceResponse} + */ + setVrCapabilities (capabilities) { + this.validateType(VrCapabilities, capabilities, true); + this.setParameter(RegisterAppInterfaceResponse.KEY_VR_CAPABILITIES, capabilities); return this; } /** - * @return {Array} - */ + * @return {VrCapabilities[]} + */ getVrCapabilities () { return this.getObject(VrCapabilities, RegisterAppInterfaceResponse.KEY_VR_CAPABILITIES); } /** - * @param {Array} audioPassThruCapabilities - * @return {RegisterAppInterfaceResponse} - */ - setAudioPassThruCapabilities (audioPassThruCapabilities) { - // TODO make this work for arrays - // this.validateType(AudioPassThruCapabilities, audioPassThruCapabilities); - - this.setParameter(RegisterAppInterfaceResponse.KEY_AUDIO_PASS_THRU_CAPABILITIES, audioPassThruCapabilities); + * @param {AudioPassThruCapabilities[]} capabilities - See AudioPassThruCapability + * @return {RegisterAppInterfaceResponse} + */ + setAudioPassThruCapabilities (capabilities) { + this.validateType(AudioPassThruCapabilities, capabilities, true); + this.setParameter(RegisterAppInterfaceResponse.KEY_AUDIO_PASS_THRU_CAPABILITIES, capabilities); return this; } /** - * @return {Array} - */ + * @return {AudioPassThruCapabilities[]} + */ getAudioPassThruCapabilities () { return this.getObject(AudioPassThruCapabilities, RegisterAppInterfaceResponse.KEY_AUDIO_PASS_THRU_CAPABILITIES); } /** - * @param {AudioPassThruCapabilities} pcmStreamCapabilities - * @return {RegisterAppInterfaceResponse} - */ - setPcmStreamCapabilities (pcmStreamCapabilities) { - this.validateType(AudioPassThruCapabilities, pcmStreamCapabilities); - - this.setParameter(RegisterAppInterfaceResponse.KEY_PCM_STREAM_CAPABILITIES, pcmStreamCapabilities); + * @param {AudioPassThruCapabilities} capabilities - See AudioPassThruCapability + * @return {RegisterAppInterfaceResponse} + */ + setPcmStreamCapabilities (capabilities) { + this.validateType(AudioPassThruCapabilities, capabilities); + this.setParameter(RegisterAppInterfaceResponse.KEY_PCM_STREAM_CAPABILITIES, capabilities); return this; } /** - * @return {AudioPassThruCapabilities} - */ + * @return {AudioPassThruCapabilities} + */ getPcmStreamCapabilities () { return this.getObject(AudioPassThruCapabilities, RegisterAppInterfaceResponse.KEY_PCM_STREAM_CAPABILITIES); } /** - * @param {VehicleType} vehicleType - * @return {RegisterAppInterfaceResponse} - */ - setVehicleType (vehicleType) { - this.validateType(VehicleType, vehicleType); - - this.setParameter(RegisterAppInterfaceResponse.KEY_VEHICLE_TYPE, vehicleType); + * @param {VehicleType} type - Specifies the vehicle's type. See VehicleType. + * @return {RegisterAppInterfaceResponse} + */ + setVehicleType (type) { + this.validateType(VehicleType, type); + this.setParameter(RegisterAppInterfaceResponse.KEY_VEHICLE_TYPE, type); return this; } /** - * @return {VehicleType} - */ + * @return {VehicleType} + */ getVehicleType () { return this.getObject(VehicleType, RegisterAppInterfaceResponse.KEY_VEHICLE_TYPE); } /** - * @param {Number} supportedDiagModes - * @return {RegisterAppInterfaceResponse} - */ - setSupportedDiagModes (supportedDiagModes) { - this.setParameter(RegisterAppInterfaceResponse.KEY_SUPPORTED_DIAG_MODE, supportedDiagModes); + * @param {Number[]} modes - Specifies the white-list of supported diagnostic modes (0x00-0xFF) capable for + * DiagnosticMessage requests. If a mode outside this list is requested, it will be + * rejected. + * @return {RegisterAppInterfaceResponse} + */ + setSupportedDiagModes (modes) { + this.setParameter(RegisterAppInterfaceResponse.KEY_SUPPORTED_DIAG_MODES, modes); return this; } /** - * @return {Number} - */ + * @return {Number[]} + */ getSupportedDiagModes () { - return this.getParameter(RegisterAppInterfaceResponse.KEY_SUPPORTED_DIAG_MODE); + return this.getParameter(RegisterAppInterfaceResponse.KEY_SUPPORTED_DIAG_MODES); } /** - * @param {HMICapabilities} hmiCapabilities - * @return {RegisterAppInterfaceResponse} - */ - setHMICapabilities (hmiCapabilities) { - this.validateType(HMICapabilities, hmiCapabilities); - - this.setParameter(RegisterAppInterfaceResponse.KEY_HMI_CAPABILITIES, hmiCapabilities); + * @param {HMICapabilities} capabilities - Specifies the HMI's capabilities. See HMICapabilities. + * @return {RegisterAppInterfaceResponse} + */ + setHmiCapabilities (capabilities) { + this.validateType(HMICapabilities, capabilities); + this.setParameter(RegisterAppInterfaceResponse.KEY_HMI_CAPABILITIES, capabilities); return this; } /** - * @return {HMICapabilities} - */ - getHMICapabilities () { + * @return {HMICapabilities} + */ + getHmiCapabilities () { return this.getObject(HMICapabilities, RegisterAppInterfaceResponse.KEY_HMI_CAPABILITIES); } /** - * @param {String} sdlVersion - * @return {RegisterAppInterfaceResponse} - */ - setSdlVersion (sdlVersion) { - this.setParameter(RegisterAppInterfaceResponse.KEY_SDL_VERSION, sdlVersion); + * @param {String} version - The SmartDeviceLink version. + * @return {RegisterAppInterfaceResponse} + */ + setSdlVersion (version) { + this.setParameter(RegisterAppInterfaceResponse.KEY_SDL_VERSION, version); return this; } /** - * @return {String} - */ + * @return {String} + */ getSdlVersion () { return this.getParameter(RegisterAppInterfaceResponse.KEY_SDL_VERSION); } /** - * @param {String} systemSoftwareVersion - * @return {RegisterAppInterfaceResponse} - */ - setSystemSoftwareVersion (systemSoftwareVersion) { - this.setParameter(RegisterAppInterfaceResponse.KEY_SYSTEM_SOFTWARE_VERSION, systemSoftwareVersion); + * @param {String} version - The software version of the system that implements the SmartDeviceLink core. + * @return {RegisterAppInterfaceResponse} + */ + setSystemSoftwareVersion (version) { + this.setParameter(RegisterAppInterfaceResponse.KEY_SYSTEM_SOFTWARE_VERSION, version); return this; } /** - * @return {String} - */ + * @return {String} + */ getSystemSoftwareVersion () { return this.getParameter(RegisterAppInterfaceResponse.KEY_SYSTEM_SOFTWARE_VERSION); } /** - * @param {Boolean} iconResumed - * @return {RegisterAppInterfaceResponse} - */ - setIconResumed (iconResumed) { - this.setParameter(RegisterAppInterfaceResponse.KEY_ICON_RESUMED, iconResumed); + * @param {Boolean} resumed - Existence of apps icon at system. If true, apps icon was resumed at system. If false, + * apps icon is not resumed at system + * @return {RegisterAppInterfaceResponse} + */ + setIconResumed (resumed) { + this.setParameter(RegisterAppInterfaceResponse.KEY_ICON_RESUMED, resumed); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getIconResumed () { return this.getParameter(RegisterAppInterfaceResponse.KEY_ICON_RESUMED); } @@ -410,10 +402,10 @@ RegisterAppInterfaceResponse.KEY_VR_CAPABILITIES = 'vrCapabilities'; RegisterAppInterfaceResponse.KEY_AUDIO_PASS_THRU_CAPABILITIES = 'audioPassThruCapabilities'; RegisterAppInterfaceResponse.KEY_PCM_STREAM_CAPABILITIES = 'pcmStreamCapabilities'; RegisterAppInterfaceResponse.KEY_VEHICLE_TYPE = 'vehicleType'; -RegisterAppInterfaceResponse.KEY_SUPPORTED_DIAG_MODE = 'supportedDiagModes'; +RegisterAppInterfaceResponse.KEY_SUPPORTED_DIAG_MODES = 'supportedDiagModes'; RegisterAppInterfaceResponse.KEY_HMI_CAPABILITIES = 'hmiCapabilities'; RegisterAppInterfaceResponse.KEY_SDL_VERSION = 'sdlVersion'; RegisterAppInterfaceResponse.KEY_SYSTEM_SOFTWARE_VERSION = 'systemSoftwareVersion'; RegisterAppInterfaceResponse.KEY_ICON_RESUMED = 'iconResumed'; -export { RegisterAppInterfaceResponse }; +export { RegisterAppInterfaceResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/ReleaseInteriorVehicleDataModule.js b/lib/js/src/rpc/messages/ReleaseInteriorVehicleDataModule.js new file mode 100644 index 00000000..98daee7c --- /dev/null +++ b/lib/js/src/rpc/messages/ReleaseInteriorVehicleDataModule.js @@ -0,0 +1,84 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { ModuleType } from '../enums/ModuleType.js'; +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +class ReleaseInteriorVehicleDataModule extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.ReleaseInteriorVehicleDataModule); + } + + /** + * @param {ModuleType} type + * @return {ReleaseInteriorVehicleDataModule} + */ + setModuleType (type) { + this.validateType(ModuleType, type); + this.setParameter(ReleaseInteriorVehicleDataModule.KEY_MODULE_TYPE, type); + return this; + } + + /** + * @return {ModuleType} + */ + getModuleType () { + return this.getObject(ModuleType, ReleaseInteriorVehicleDataModule.KEY_MODULE_TYPE); + } + + /** + * @param {String} id - Id of a module, published by System Capability. + * @return {ReleaseInteriorVehicleDataModule} + */ + setModuleId (id) { + this.setParameter(ReleaseInteriorVehicleDataModule.KEY_MODULE_ID, id); + return this; + } + + /** + * @return {String} + */ + getModuleId () { + return this.getParameter(ReleaseInteriorVehicleDataModule.KEY_MODULE_ID); + } +} + +ReleaseInteriorVehicleDataModule.KEY_MODULE_TYPE = 'moduleType'; +ReleaseInteriorVehicleDataModule.KEY_MODULE_ID = 'moduleId'; + +export { ReleaseInteriorVehicleDataModule }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/ReleaseInteriorVehicleDataModuleResponse.js b/lib/js/src/rpc/messages/ReleaseInteriorVehicleDataModuleResponse.js new file mode 100644 index 00000000..b01a77b6 --- /dev/null +++ b/lib/js/src/rpc/messages/ReleaseInteriorVehicleDataModuleResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class ReleaseInteriorVehicleDataModuleResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.ReleaseInteriorVehicleDataModule); + } +} + + +export { ReleaseInteriorVehicleDataModuleResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/ResetGlobalProperties.js b/lib/js/src/rpc/messages/ResetGlobalProperties.js new file mode 100644 index 00000000..4e38a2e8 --- /dev/null +++ b/lib/js/src/rpc/messages/ResetGlobalProperties.js @@ -0,0 +1,72 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { GlobalProperty } from '../enums/GlobalProperty.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Allows resetting global properties. + */ +class ResetGlobalProperties extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.ResetGlobalProperties); + } + + /** + * @param {GlobalProperty[]} properties - Contains the names of all global properties (like timeoutPrompt) that + * should be unset. Resetting means, that they have the same value as at + * start up (default) + * @return {ResetGlobalProperties} + */ + setProperties (properties) { + this.validateType(GlobalProperty, properties, true); + this.setParameter(ResetGlobalProperties.KEY_PROPERTIES, properties); + return this; + } + + /** + * @return {GlobalProperty[]} + */ + getProperties () { + return this.getObject(GlobalProperty, ResetGlobalProperties.KEY_PROPERTIES); + } +} + +ResetGlobalProperties.KEY_PROPERTIES = 'properties'; + +export { ResetGlobalProperties }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/ResetGlobalPropertiesResponse.js b/lib/js/src/rpc/messages/ResetGlobalPropertiesResponse.js new file mode 100644 index 00000000..969b1abb --- /dev/null +++ b/lib/js/src/rpc/messages/ResetGlobalPropertiesResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class ResetGlobalPropertiesResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.ResetGlobalProperties); + } +} + + +export { ResetGlobalPropertiesResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/ScrollableMessage.js b/lib/js/src/rpc/messages/ScrollableMessage.js new file mode 100644 index 00000000..185306bf --- /dev/null +++ b/lib/js/src/rpc/messages/ScrollableMessage.js @@ -0,0 +1,125 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; +import { SoftButton } from '../structs/SoftButton.js'; + +/** + * Creates a full screen overlay containing a large block of formatted text that can be scrolled with up to 8 + * SoftButtons defined + */ +class ScrollableMessage extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.ScrollableMessage); + } + + /** + * @param {String} body - Body of text that can include newlines and tabs. + * @return {ScrollableMessage} + */ + setScrollableMessageBody (body) { + this.setParameter(ScrollableMessage.KEY_SCROLLABLE_MESSAGE_BODY, body); + return this; + } + + /** + * @return {String} + */ + getScrollableMessageBody () { + return this.getParameter(ScrollableMessage.KEY_SCROLLABLE_MESSAGE_BODY); + } + + /** + * @param {Number} timeout - App defined timeout. Indicates how long of a timeout from the last action (i.e. + * scrolling message resets timeout). + * @return {ScrollableMessage} + */ + setTimeout (timeout) { + this.setParameter(ScrollableMessage.KEY_TIMEOUT, timeout); + return this; + } + + /** + * @return {Number} + */ + getTimeout () { + return this.getParameter(ScrollableMessage.KEY_TIMEOUT); + } + + /** + * @param {SoftButton[]} buttons - App defined SoftButtons. If omitted on supported displays, only the system + * defined "Close" SoftButton will be displayed. + * @return {ScrollableMessage} + */ + setSoftButtons (buttons) { + this.validateType(SoftButton, buttons, true); + this.setParameter(ScrollableMessage.KEY_SOFT_BUTTONS, buttons); + return this; + } + + /** + * @return {SoftButton[]} + */ + getSoftButtons () { + return this.getObject(SoftButton, ScrollableMessage.KEY_SOFT_BUTTONS); + } + + /** + * @param {Number} id - An ID for this specific ScrollableMessage to allow cancellation through the + * `CancelInteraction` RPC. + * @return {ScrollableMessage} + */ + setCancelID (id) { + this.setParameter(ScrollableMessage.KEY_CANCEL_ID, id); + return this; + } + + /** + * @return {Number} + */ + getCancelID () { + return this.getParameter(ScrollableMessage.KEY_CANCEL_ID); + } +} + +ScrollableMessage.KEY_SCROLLABLE_MESSAGE_BODY = 'scrollableMessageBody'; +ScrollableMessage.KEY_TIMEOUT = 'timeout'; +ScrollableMessage.KEY_SOFT_BUTTONS = 'softButtons'; +ScrollableMessage.KEY_CANCEL_ID = 'cancelID'; + +export { ScrollableMessage }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/ScrollableMessageResponse.js b/lib/js/src/rpc/messages/ScrollableMessageResponse.js new file mode 100644 index 00000000..375f76b8 --- /dev/null +++ b/lib/js/src/rpc/messages/ScrollableMessageResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class ScrollableMessageResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.ScrollableMessage); + } +} + + +export { ScrollableMessageResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SendHapticData.js b/lib/js/src/rpc/messages/SendHapticData.js new file mode 100644 index 00000000..f045bfc1 --- /dev/null +++ b/lib/js/src/rpc/messages/SendHapticData.js @@ -0,0 +1,75 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; +import { HapticRect } from '../structs/HapticRect.js'; + +/** + * Send the spatial data gathered from SDLCarWindow or VirtualDisplayEncoder to the HMI. This data will be utilized by + * the HMI to determine how and when haptic events should occur + */ +class SendHapticData extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SendHapticData); + } + + /** + * @param {HapticRect[]} data - Array of spatial data structures that represent the locations of all user controls + * present on the HMI. This data should be updated if/when the application presents a + * new screen. When a request is sent, if successful, it will replace all spatial data + * previously sent through RPC. If an empty array is sent, the existing spatial data + * will be cleared + * @return {SendHapticData} + */ + setHapticRectData (data) { + this.validateType(HapticRect, data, true); + this.setParameter(SendHapticData.KEY_HAPTIC_RECT_DATA, data); + return this; + } + + /** + * @return {HapticRect[]} + */ + getHapticRectData () { + return this.getObject(HapticRect, SendHapticData.KEY_HAPTIC_RECT_DATA); + } +} + +SendHapticData.KEY_HAPTIC_RECT_DATA = 'hapticRectData'; + +export { SendHapticData }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SendHapticDataResponse.js b/lib/js/src/rpc/messages/SendHapticDataResponse.js new file mode 100644 index 00000000..39c979c7 --- /dev/null +++ b/lib/js/src/rpc/messages/SendHapticDataResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class SendHapticDataResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SendHapticData); + } +} + + +export { SendHapticDataResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SendLocation.js b/lib/js/src/rpc/messages/SendLocation.js new file mode 100644 index 00000000..f949f9cb --- /dev/null +++ b/lib/js/src/rpc/messages/SendLocation.js @@ -0,0 +1,226 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { DeliveryMode } from '../enums/DeliveryMode.js'; +import { DateTime } from '../structs/DateTime.js'; +import { RpcRequest } from '../RpcRequest.js'; +import { OASISAddress } from '../structs/OASISAddress.js'; +import { Image } from '../structs/Image.js'; + +class SendLocation extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SendLocation); + } + + /** + * @param {Number} degrees + * @return {SendLocation} + */ + setLongitudeDegrees (degrees) { + this.setParameter(SendLocation.KEY_LONGITUDE_DEGREES, degrees); + return this; + } + + /** + * @return {Number} + */ + getLongitudeDegrees () { + return this.getParameter(SendLocation.KEY_LONGITUDE_DEGREES); + } + + /** + * @param {Number} degrees + * @return {SendLocation} + */ + setLatitudeDegrees (degrees) { + this.setParameter(SendLocation.KEY_LATITUDE_DEGREES, degrees); + return this; + } + + /** + * @return {Number} + */ + getLatitudeDegrees () { + return this.getParameter(SendLocation.KEY_LATITUDE_DEGREES); + } + + /** + * @param {String} name - Name / title of intended location + * @return {SendLocation} + */ + setLocationName (name) { + this.setParameter(SendLocation.KEY_LOCATION_NAME, name); + return this; + } + + /** + * @return {String} + */ + getLocationName () { + return this.getParameter(SendLocation.KEY_LOCATION_NAME); + } + + /** + * @param {String} description - Description intended location / establishment (if applicable) + * @return {SendLocation} + */ + setLocationDescription (description) { + this.setParameter(SendLocation.KEY_LOCATION_DESCRIPTION, description); + return this; + } + + /** + * @return {String} + */ + getLocationDescription () { + return this.getParameter(SendLocation.KEY_LOCATION_DESCRIPTION); + } + + /** + * @param {String[]} lines - Location address (if applicable) + * @return {SendLocation} + */ + setAddressLines (lines) { + this.setParameter(SendLocation.KEY_ADDRESS_LINES, lines); + return this; + } + + /** + * @return {String[]} + */ + getAddressLines () { + return this.getParameter(SendLocation.KEY_ADDRESS_LINES); + } + + /** + * @param {String} number - Phone number of intended location / establishment (if applicable) + * @return {SendLocation} + */ + setPhoneNumber (number) { + this.setParameter(SendLocation.KEY_PHONE_NUMBER, number); + return this; + } + + /** + * @return {String} + */ + getPhoneNumber () { + return this.getParameter(SendLocation.KEY_PHONE_NUMBER); + } + + /** + * @param {Image} image - Image / icon of intended location (if applicable and supported) + * @return {SendLocation} + */ + setLocationImage (image) { + this.validateType(Image, image); + this.setParameter(SendLocation.KEY_LOCATION_IMAGE, image); + return this; + } + + /** + * @return {Image} + */ + getLocationImage () { + return this.getObject(Image, SendLocation.KEY_LOCATION_IMAGE); + } + + /** + * @param {DateTime} stamp - timestamp in ISO 8601 format + * @return {SendLocation} + */ + setTimeStamp (stamp) { + this.validateType(DateTime, stamp); + this.setParameter(SendLocation.KEY_TIME_STAMP, stamp); + return this; + } + + /** + * @return {DateTime} + */ + getTimeStamp () { + return this.getObject(DateTime, SendLocation.KEY_TIME_STAMP); + } + + /** + * @param {OASISAddress} address - Address to be used for setting destination + * @return {SendLocation} + */ + setAddress (address) { + this.validateType(OASISAddress, address); + this.setParameter(SendLocation.KEY_ADDRESS, address); + return this; + } + + /** + * @return {OASISAddress} + */ + getAddress () { + return this.getObject(OASISAddress, SendLocation.KEY_ADDRESS); + } + + /** + * @param {DeliveryMode} mode - Defines the mode of prompt for user + * @return {SendLocation} + */ + setDeliveryMode (mode) { + this.validateType(DeliveryMode, mode); + this.setParameter(SendLocation.KEY_DELIVERY_MODE, mode); + return this; + } + + /** + * @return {DeliveryMode} + */ + getDeliveryMode () { + return this.getObject(DeliveryMode, SendLocation.KEY_DELIVERY_MODE); + } +} + +SendLocation.KEY_LONGITUDE_DEGREES = 'longitudeDegrees'; +SendLocation.KEY_LATITUDE_DEGREES = 'latitudeDegrees'; +SendLocation.KEY_LOCATION_NAME = 'locationName'; +SendLocation.KEY_LOCATION_DESCRIPTION = 'locationDescription'; +SendLocation.KEY_ADDRESS_LINES = 'addressLines'; +SendLocation.KEY_PHONE_NUMBER = 'phoneNumber'; +SendLocation.KEY_LOCATION_IMAGE = 'locationImage'; +SendLocation.KEY_TIME_STAMP = 'timeStamp'; +SendLocation.KEY_ADDRESS = 'address'; +SendLocation.KEY_DELIVERY_MODE = 'deliveryMode'; + +export { SendLocation }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SendLocationResponse.js b/lib/js/src/rpc/messages/SendLocationResponse.js new file mode 100644 index 00000000..17895eb8 --- /dev/null +++ b/lib/js/src/rpc/messages/SendLocationResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class SendLocationResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SendLocation); + } +} + + +export { SendLocationResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SetAppIcon.js b/lib/js/src/rpc/messages/SetAppIcon.js index 0d9b13ce..fc73ae6c 100644 --- a/lib/js/src/rpc/messages/SetAppIcon.js +++ b/lib/js/src/rpc/messages/SetAppIcon.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -33,27 +34,31 @@ import { RpcRequest } from '../RpcRequest.js'; import { FunctionID } from '../enums/FunctionID.js'; +/** + * Used to set existing local file on the module as the app's icon Not supported on first generation SDL enabled + * vehicles. + */ class SetAppIcon extends RpcRequest { /** - * @constructor - */ + * @constructor + */ constructor (store) { super(store); this.setFunctionName(FunctionID.SetAppIcon); } /** - * @param {String} fileName - * @return {SetAppIcon} - */ - setFileName (fileName) { - this.setParameter(SetAppIcon.KEY_FILE_NAME, fileName); + * @param {String} name - File reference name. + * @return {SetAppIcon} + */ + setFileName (name) { + this.setParameter(SetAppIcon.KEY_FILE_NAME, name); return this; } /** - * @return {String} - */ + * @return {String} + */ getFileName () { return this.getParameter(SetAppIcon.KEY_FILE_NAME); } @@ -61,5 +66,4 @@ class SetAppIcon extends RpcRequest { SetAppIcon.KEY_FILE_NAME = 'syncFileName'; - -export { SetAppIcon }; +export { SetAppIcon }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SetAppIconResponse.js b/lib/js/src/rpc/messages/SetAppIconResponse.js index 5051fc83..b1f2ffae 100644 --- a/lib/js/src/rpc/messages/SetAppIconResponse.js +++ b/lib/js/src/rpc/messages/SetAppIconResponse.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -30,17 +31,22 @@ * POSSIBILITY OF SUCH DAMAGE. */ -import { RpcResponse } from '../RpcResponse.js'; import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; +/** + * Response is sent, when the file data was copied (success case). Or when an error occurred. Not supported on First + * generation SDL enabled vehicles. + */ class SetAppIconResponse extends RpcResponse { /** - * @constructor - */ + * @constructor + */ constructor (store) { super(store); this.setFunctionName(FunctionID.SetAppIcon); } } -export { SetAppIconResponse }; + +export { SetAppIconResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SetCloudAppProperties.js b/lib/js/src/rpc/messages/SetCloudAppProperties.js new file mode 100644 index 00000000..cae17605 --- /dev/null +++ b/lib/js/src/rpc/messages/SetCloudAppProperties.js @@ -0,0 +1,70 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { CloudAppProperties } from '../structs/CloudAppProperties.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * RPC used to enable/disable a cloud application and set its cloud-related policy properties + */ +class SetCloudAppProperties extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SetCloudAppProperties); + } + + /** + * @param {CloudAppProperties} properties - The new cloud application properties + * @return {SetCloudAppProperties} + */ + setProperties (properties) { + this.validateType(CloudAppProperties, properties); + this.setParameter(SetCloudAppProperties.KEY_PROPERTIES, properties); + return this; + } + + /** + * @return {CloudAppProperties} + */ + getProperties () { + return this.getObject(CloudAppProperties, SetCloudAppProperties.KEY_PROPERTIES); + } +} + +SetCloudAppProperties.KEY_PROPERTIES = 'properties'; + +export { SetCloudAppProperties }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SetCloudAppPropertiesResponse.js b/lib/js/src/rpc/messages/SetCloudAppPropertiesResponse.js new file mode 100644 index 00000000..4325e97c --- /dev/null +++ b/lib/js/src/rpc/messages/SetCloudAppPropertiesResponse.js @@ -0,0 +1,51 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +/** + * The response to SetCloudAppProperties + */ +class SetCloudAppPropertiesResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SetCloudAppProperties); + } +} + + +export { SetCloudAppPropertiesResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SetDisplayLayout.js b/lib/js/src/rpc/messages/SetDisplayLayout.js new file mode 100644 index 00000000..47a89e17 --- /dev/null +++ b/lib/js/src/rpc/messages/SetDisplayLayout.js @@ -0,0 +1,114 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { TemplateColorScheme } from '../structs/TemplateColorScheme.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * This RPC is deprecated. Use Show RPC to change layout. + * @deprecated + */ +class SetDisplayLayout extends RpcRequest { + /** + * @deprecated + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SetDisplayLayout); + } + + /** + * @deprecated + * @param {String} layout - Predefined or dynamically created screen layout. Currently only predefined screen + * layouts are defined. + * @return {SetDisplayLayout} + */ + setDisplayLayout (layout) { + this.setParameter(SetDisplayLayout.KEY_DISPLAY_LAYOUT, layout); + return this; + } + + /** + * @deprecated + * @return {String} + */ + getDisplayLayout () { + return this.getParameter(SetDisplayLayout.KEY_DISPLAY_LAYOUT); + } + + /** + * @deprecated + * @param {TemplateColorScheme} scheme - A color scheme for all display layout templates. + * @return {SetDisplayLayout} + */ + setDayColorScheme (scheme) { + this.validateType(TemplateColorScheme, scheme); + this.setParameter(SetDisplayLayout.KEY_DAY_COLOR_SCHEME, scheme); + return this; + } + + /** + * @deprecated + * @return {TemplateColorScheme} + */ + getDayColorScheme () { + return this.getObject(TemplateColorScheme, SetDisplayLayout.KEY_DAY_COLOR_SCHEME); + } + + /** + * @deprecated + * @param {TemplateColorScheme} scheme - A color scheme for all display layout templates. + * @return {SetDisplayLayout} + */ + setNightColorScheme (scheme) { + this.validateType(TemplateColorScheme, scheme); + this.setParameter(SetDisplayLayout.KEY_NIGHT_COLOR_SCHEME, scheme); + return this; + } + + /** + * @deprecated + * @return {TemplateColorScheme} + */ + getNightColorScheme () { + return this.getObject(TemplateColorScheme, SetDisplayLayout.KEY_NIGHT_COLOR_SCHEME); + } +} + +SetDisplayLayout.KEY_DISPLAY_LAYOUT = 'displayLayout'; +SetDisplayLayout.KEY_DAY_COLOR_SCHEME = 'dayColorScheme'; +SetDisplayLayout.KEY_NIGHT_COLOR_SCHEME = 'nightColorScheme'; + +export { SetDisplayLayout }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SetDisplayLayoutResponse.js b/lib/js/src/rpc/messages/SetDisplayLayoutResponse.js new file mode 100644 index 00000000..77851fad --- /dev/null +++ b/lib/js/src/rpc/messages/SetDisplayLayoutResponse.js @@ -0,0 +1,139 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcResponse } from '../RpcResponse.js'; +import { SoftButtonCapabilities } from '../structs/SoftButtonCapabilities.js'; +import { PresetBankCapabilities } from '../structs/PresetBankCapabilities.js'; +import { DisplayCapabilities } from '../structs/DisplayCapabilities.js'; +import { FunctionID } from '../enums/FunctionID.js'; +import { ButtonCapabilities } from '../structs/ButtonCapabilities.js'; + +/** + * This RPC is deprecated. Use Show RPC to change layout. + * @deprecated + */ +class SetDisplayLayoutResponse extends RpcResponse { + /** + * @deprecated + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SetDisplayLayout); + } + + /** + * @deprecated + * @param {DisplayCapabilities} capabilities - See DisplayCapabilities + * @return {SetDisplayLayoutResponse} + */ + setDisplayCapabilities (capabilities) { + this.validateType(DisplayCapabilities, capabilities); + this.setParameter(SetDisplayLayoutResponse.KEY_DISPLAY_CAPABILITIES, capabilities); + return this; + } + + /** + * @deprecated + * @return {DisplayCapabilities} + */ + getDisplayCapabilities () { + return this.getObject(DisplayCapabilities, SetDisplayLayoutResponse.KEY_DISPLAY_CAPABILITIES); + } + + /** + * @deprecated + * @param {ButtonCapabilities[]} capabilities - See ButtonCapabilities + * @return {SetDisplayLayoutResponse} + */ + setButtonCapabilities (capabilities) { + this.validateType(ButtonCapabilities, capabilities, true); + this.setParameter(SetDisplayLayoutResponse.KEY_BUTTON_CAPABILITIES, capabilities); + return this; + } + + /** + * @deprecated + * @return {ButtonCapabilities[]} + */ + getButtonCapabilities () { + return this.getObject(ButtonCapabilities, SetDisplayLayoutResponse.KEY_BUTTON_CAPABILITIES); + } + + /** + * @deprecated + * @param {SoftButtonCapabilities[]} capabilities - If returned, the platform supports on-screen SoftButtons; see + * SoftButtonCapabilities. + * @return {SetDisplayLayoutResponse} + */ + setSoftButtonCapabilities (capabilities) { + this.validateType(SoftButtonCapabilities, capabilities, true); + this.setParameter(SetDisplayLayoutResponse.KEY_SOFT_BUTTON_CAPABILITIES, capabilities); + return this; + } + + /** + * @deprecated + * @return {SoftButtonCapabilities[]} + */ + getSoftButtonCapabilities () { + return this.getObject(SoftButtonCapabilities, SetDisplayLayoutResponse.KEY_SOFT_BUTTON_CAPABILITIES); + } + + /** + * @deprecated + * @param {PresetBankCapabilities} capabilities - If returned, the platform supports custom on-screen Presets; see + * PresetBankCapabilities. + * @return {SetDisplayLayoutResponse} + */ + setPresetBankCapabilities (capabilities) { + this.validateType(PresetBankCapabilities, capabilities); + this.setParameter(SetDisplayLayoutResponse.KEY_PRESET_BANK_CAPABILITIES, capabilities); + return this; + } + + /** + * @deprecated + * @return {PresetBankCapabilities} + */ + getPresetBankCapabilities () { + return this.getObject(PresetBankCapabilities, SetDisplayLayoutResponse.KEY_PRESET_BANK_CAPABILITIES); + } +} + +SetDisplayLayoutResponse.KEY_DISPLAY_CAPABILITIES = 'displayCapabilities'; +SetDisplayLayoutResponse.KEY_BUTTON_CAPABILITIES = 'buttonCapabilities'; +SetDisplayLayoutResponse.KEY_SOFT_BUTTON_CAPABILITIES = 'softButtonCapabilities'; +SetDisplayLayoutResponse.KEY_PRESET_BANK_CAPABILITIES = 'presetBankCapabilities'; + +export { SetDisplayLayoutResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SetGlobalProperties.js b/lib/js/src/rpc/messages/SetGlobalProperties.js new file mode 100644 index 00000000..e1f13a28 --- /dev/null +++ b/lib/js/src/rpc/messages/SetGlobalProperties.js @@ -0,0 +1,226 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { VrHelpItem } from '../structs/VrHelpItem.js'; +import { FunctionID } from '../enums/FunctionID.js'; +import { SeatLocation } from '../structs/SeatLocation.js'; +import { TTSChunk } from '../structs/TTSChunk.js'; +import { MenuLayout } from '../enums/MenuLayout.js'; +import { KeyboardProperties } from '../structs/KeyboardProperties.js'; +import { RpcRequest } from '../RpcRequest.js'; +import { Image } from '../structs/Image.js'; + +/** + * Allows setting global properties. + */ +class SetGlobalProperties extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SetGlobalProperties); + } + + /** + * @param {SeatLocation} location - Location of the user's seat. Default is driver's seat location if it is not set + * yet. + * @return {SetGlobalProperties} + */ + setUserLocation (location) { + this.validateType(SeatLocation, location); + this.setParameter(SetGlobalProperties.KEY_USER_LOCATION, location); + return this; + } + + /** + * @return {SeatLocation} + */ + getUserLocation () { + return this.getObject(SeatLocation, SetGlobalProperties.KEY_USER_LOCATION); + } + + /** + * @param {TTSChunk[]} prompt - The help prompt. An array of text chunks of type TTSChunk. See TTSChunk. The array + * must have at least one item. + * @return {SetGlobalProperties} + */ + setHelpPrompt (prompt) { + this.validateType(TTSChunk, prompt, true); + this.setParameter(SetGlobalProperties.KEY_HELP_PROMPT, prompt); + return this; + } + + /** + * @return {TTSChunk[]} + */ + getHelpPrompt () { + return this.getObject(TTSChunk, SetGlobalProperties.KEY_HELP_PROMPT); + } + + /** + * @param {TTSChunk[]} prompt - Help text for a wait timeout. An array of text chunks of type TTSChunk. See + * TTSChunk. The array must have at least one item. + * @return {SetGlobalProperties} + */ + setTimeoutPrompt (prompt) { + this.validateType(TTSChunk, prompt, true); + this.setParameter(SetGlobalProperties.KEY_TIMEOUT_PROMPT, prompt); + return this; + } + + /** + * @return {TTSChunk[]} + */ + getTimeoutPrompt () { + return this.getObject(TTSChunk, SetGlobalProperties.KEY_TIMEOUT_PROMPT); + } + + /** + * @param {String} title - VR Help Title text. If omitted on supported displays, the default module help title shall + * be used. If omitted and one or more vrHelp items are provided, the request will be + * rejected. + * @return {SetGlobalProperties} + */ + setVrHelpTitle (title) { + this.setParameter(SetGlobalProperties.KEY_VR_HELP_TITLE, title); + return this; + } + + /** + * @return {String} + */ + getVrHelpTitle () { + return this.getParameter(SetGlobalProperties.KEY_VR_HELP_TITLE); + } + + /** + * @param {VrHelpItem[]} help - VR Help Items. If omitted on supported displays, the default SmartDeviceLink VR help + * / What Can I Say? screen shall be used. If the list of VR Help Items contains + * nonsequential positions (e.g. [1,2,4]), the RPC shall be rejected. If omitted and a + * vrHelpTitle is provided, the request will be rejected. + * @return {SetGlobalProperties} + */ + setVrHelp (help) { + this.validateType(VrHelpItem, help, true); + this.setParameter(SetGlobalProperties.KEY_VR_HELP, help); + return this; + } + + /** + * @return {VrHelpItem[]} + */ + getVrHelp () { + return this.getObject(VrHelpItem, SetGlobalProperties.KEY_VR_HELP); + } + + /** + * @param {String} title - Optional text to label an app menu button (for certain touchscreen platforms). + * @return {SetGlobalProperties} + */ + setMenuTitle (title) { + this.setParameter(SetGlobalProperties.KEY_MENU_TITLE, title); + return this; + } + + /** + * @return {String} + */ + getMenuTitle () { + return this.getParameter(SetGlobalProperties.KEY_MENU_TITLE); + } + + /** + * @param {Image} icon - Optional icon to draw on an app menu button (for certain touchscreen platforms). + * @return {SetGlobalProperties} + */ + setMenuIcon (icon) { + this.validateType(Image, icon); + this.setParameter(SetGlobalProperties.KEY_MENU_ICON, icon); + return this; + } + + /** + * @return {Image} + */ + getMenuIcon () { + return this.getObject(Image, SetGlobalProperties.KEY_MENU_ICON); + } + + /** + * @param {KeyboardProperties} properties - On-screen keyboard configuration (if available). + * @return {SetGlobalProperties} + */ + setKeyboardProperties (properties) { + this.validateType(KeyboardProperties, properties); + this.setParameter(SetGlobalProperties.KEY_KEYBOARD_PROPERTIES, properties); + return this; + } + + /** + * @return {KeyboardProperties} + */ + getKeyboardProperties () { + return this.getObject(KeyboardProperties, SetGlobalProperties.KEY_KEYBOARD_PROPERTIES); + } + + /** + * @param {MenuLayout} layout - Sets the layout of the main menu screen. If this is sent while a menu is already on- + * screen, the head unit will change the display to the new layout type. + * @return {SetGlobalProperties} + */ + setMenuLayout (layout) { + this.validateType(MenuLayout, layout); + this.setParameter(SetGlobalProperties.KEY_MENU_LAYOUT, layout); + return this; + } + + /** + * @return {MenuLayout} + */ + getMenuLayout () { + return this.getObject(MenuLayout, SetGlobalProperties.KEY_MENU_LAYOUT); + } +} + +SetGlobalProperties.KEY_USER_LOCATION = 'userLocation'; +SetGlobalProperties.KEY_HELP_PROMPT = 'helpPrompt'; +SetGlobalProperties.KEY_TIMEOUT_PROMPT = 'timeoutPrompt'; +SetGlobalProperties.KEY_VR_HELP_TITLE = 'vrHelpTitle'; +SetGlobalProperties.KEY_VR_HELP = 'vrHelp'; +SetGlobalProperties.KEY_MENU_TITLE = 'menuTitle'; +SetGlobalProperties.KEY_MENU_ICON = 'menuIcon'; +SetGlobalProperties.KEY_KEYBOARD_PROPERTIES = 'keyboardProperties'; +SetGlobalProperties.KEY_MENU_LAYOUT = 'menuLayout'; + +export { SetGlobalProperties }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SetGlobalPropertiesResponse.js b/lib/js/src/rpc/messages/SetGlobalPropertiesResponse.js new file mode 100644 index 00000000..866addb5 --- /dev/null +++ b/lib/js/src/rpc/messages/SetGlobalPropertiesResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class SetGlobalPropertiesResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SetGlobalProperties); + } +} + + +export { SetGlobalPropertiesResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SetInteriorVehicleData.js b/lib/js/src/rpc/messages/SetInteriorVehicleData.js new file mode 100644 index 00000000..9a9ccb14 --- /dev/null +++ b/lib/js/src/rpc/messages/SetInteriorVehicleData.js @@ -0,0 +1,67 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { ModuleData } from '../structs/ModuleData.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +class SetInteriorVehicleData extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SetInteriorVehicleData); + } + + /** + * @param {ModuleData} data - The module data to set for the requested RC module. + * @return {SetInteriorVehicleData} + */ + setModuleData (data) { + this.validateType(ModuleData, data); + this.setParameter(SetInteriorVehicleData.KEY_MODULE_DATA, data); + return this; + } + + /** + * @return {ModuleData} + */ + getModuleData () { + return this.getObject(ModuleData, SetInteriorVehicleData.KEY_MODULE_DATA); + } +} + +SetInteriorVehicleData.KEY_MODULE_DATA = 'moduleData'; + +export { SetInteriorVehicleData }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SetInteriorVehicleDataResponse.js b/lib/js/src/rpc/messages/SetInteriorVehicleDataResponse.js new file mode 100644 index 00000000..617534cb --- /dev/null +++ b/lib/js/src/rpc/messages/SetInteriorVehicleDataResponse.js @@ -0,0 +1,72 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { ModuleData } from '../structs/ModuleData.js'; +import { RpcResponse } from '../RpcResponse.js'; + +/** + * Used to set the values of one remote control module + */ +class SetInteriorVehicleDataResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SetInteriorVehicleData); + } + + /** + * @param {ModuleData} data - The moduleType indicates which type of data should be changed and identifies which + * data object exists in this struct. For example, if the moduleType is CLIMATE then a + * "climateControlData" should exist + * @return {SetInteriorVehicleDataResponse} + */ + setModuleData (data) { + this.validateType(ModuleData, data); + this.setParameter(SetInteriorVehicleDataResponse.KEY_MODULE_DATA, data); + return this; + } + + /** + * @return {ModuleData} + */ + getModuleData () { + return this.getObject(ModuleData, SetInteriorVehicleDataResponse.KEY_MODULE_DATA); + } +} + +SetInteriorVehicleDataResponse.KEY_MODULE_DATA = 'moduleData'; + +export { SetInteriorVehicleDataResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SetMediaClockTimer.js b/lib/js/src/rpc/messages/SetMediaClockTimer.js new file mode 100644 index 00000000..6b5993a7 --- /dev/null +++ b/lib/js/src/rpc/messages/SetMediaClockTimer.js @@ -0,0 +1,135 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { StartTime } from '../structs/StartTime.js'; +import { UpdateMode } from '../enums/UpdateMode.js'; +import { FunctionID } from '../enums/FunctionID.js'; +import { AudioStreamingIndicator } from '../enums/AudioStreamingIndicator.js'; +import { RpcRequest } from '../RpcRequest.js'; + +/** + * Sets the initial media clock value and automatic update method. + */ +class SetMediaClockTimer extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SetMediaClockTimer); + } + + /** + * @param {StartTime} time - See StartTime. startTime must be provided for "COUNTUP" and "COUNTDOWN". startTime will + * be ignored for "RESUME", and "CLEAR" startTime can be sent for "PAUSE", in which case + * it will update the paused startTime + * @return {SetMediaClockTimer} + */ + setStartTime (time) { + this.validateType(StartTime, time); + this.setParameter(SetMediaClockTimer.KEY_START_TIME, time); + return this; + } + + /** + * @return {StartTime} + */ + getStartTime () { + return this.getObject(StartTime, SetMediaClockTimer.KEY_START_TIME); + } + + /** + * @param {StartTime} time - See StartTime. endTime can be provided for "COUNTUP" and "COUNTDOWN"; to be used to + * calculate any visual progress bar (if not provided, this feature is ignored) If endTime + * is greater then startTime for COUNTDOWN or less than startTime for COUNTUP, then the + * request will return an INVALID_DATA. endTime will be ignored for "RESUME", and "CLEAR" + * endTime can be sent for "PAUSE", in which case it will update the paused endTime + * @return {SetMediaClockTimer} + */ + setEndTime (time) { + this.validateType(StartTime, time); + this.setParameter(SetMediaClockTimer.KEY_END_TIME, time); + return this; + } + + /** + * @return {StartTime} + */ + getEndTime () { + return this.getObject(StartTime, SetMediaClockTimer.KEY_END_TIME); + } + + /** + * @param {UpdateMode} mode - Enumeration to control the media clock. In case of pause, resume, or clear, the start + * time value is ignored and shall be left out. For resume, the time continues with the + * same value as it was when paused. + * @return {SetMediaClockTimer} + */ + setUpdateMode (mode) { + this.validateType(UpdateMode, mode); + this.setParameter(SetMediaClockTimer.KEY_UPDATE_MODE, mode); + return this; + } + + /** + * @return {UpdateMode} + */ + getUpdateMode () { + return this.getObject(UpdateMode, SetMediaClockTimer.KEY_UPDATE_MODE); + } + + /** + * @param {AudioStreamingIndicator} indicator - Enumeration for the indicator icon on a play/pause button. see + * AudioStreamingIndicator. + * @return {SetMediaClockTimer} + */ + setAudioStreamingIndicator (indicator) { + this.validateType(AudioStreamingIndicator, indicator); + this.setParameter(SetMediaClockTimer.KEY_AUDIO_STREAMING_INDICATOR, indicator); + return this; + } + + /** + * @return {AudioStreamingIndicator} + */ + getAudioStreamingIndicator () { + return this.getObject(AudioStreamingIndicator, SetMediaClockTimer.KEY_AUDIO_STREAMING_INDICATOR); + } +} + +SetMediaClockTimer.KEY_START_TIME = 'startTime'; +SetMediaClockTimer.KEY_END_TIME = 'endTime'; +SetMediaClockTimer.KEY_UPDATE_MODE = 'updateMode'; +SetMediaClockTimer.KEY_AUDIO_STREAMING_INDICATOR = 'audioStreamingIndicator'; + +export { SetMediaClockTimer }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SetMediaClockTimerResponse.js b/lib/js/src/rpc/messages/SetMediaClockTimerResponse.js new file mode 100644 index 00000000..5b633cfa --- /dev/null +++ b/lib/js/src/rpc/messages/SetMediaClockTimerResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class SetMediaClockTimerResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SetMediaClockTimer); + } +} + + +export { SetMediaClockTimerResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/Show.js b/lib/js/src/rpc/messages/Show.js index 91c6e662..b6133f00 100644 --- a/lib/js/src/rpc/messages/Show.js +++ b/lib/js/src/rpc/messages/Show.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -30,274 +31,311 @@ * POSSIBILITY OF SUCH DAMAGE. */ -import { RpcRequest } from '../RpcRequest.js'; +import { TextAlignment } from '../enums/TextAlignment.js'; +import { FunctionID } from '../enums/FunctionID.js'; import { SoftButton } from '../structs/SoftButton.js'; -import { Image } from '../structs/Image.js'; +import { TemplateConfiguration } from '../structs/TemplateConfiguration.js'; import { MetadataTags } from '../structs/MetadataTags.js'; +import { RpcRequest } from '../RpcRequest.js'; +import { Image } from '../structs/Image.js'; -import { FunctionID } from '../enums/FunctionID.js'; -import { TextAlignment } from '../enums/TextAlignment.js'; - +/** + * Updates the persistent display. Supported fields depend on display capabilities. + */ class Show extends RpcRequest { /** - * @constructor - */ + * @constructor + */ constructor (store) { super(store); this.setFunctionName(FunctionID.Show); } - /** - * @param {String} mainField1 - * @return {Show} - */ - setMainField1 (mainField1) { - this.setParameter(Show.KEY_MAIN_FIELD_1, mainField1); + * @param {String} field1 - The text that should be displayed in a single or upper display line. If this text is not + * set, the text of mainField1 stays unchanged. If this text is empty "", the field will be + * cleared. + * @return {Show} + */ + setMainField1 (field1) { + this.setParameter(Show.KEY_MAIN_FIELD_1, field1); return this; } /** - * @return {String} - */ + * @return {String} + */ getMainField1 () { return this.getParameter(Show.KEY_MAIN_FIELD_1); } /** - * @param {String} mainField2 - * @return {Show} - */ - setMainField2 (mainField2) { - this.setParameter(Show.KEY_MAIN_FIELD_2, mainField2); + * @param {String} field2 - The text that should be displayed on the second display line. If this text is not set, + * the text of mainField2 stays unchanged. If this text is empty "", the field will be + * cleared. + * @return {Show} + */ + setMainField2 (field2) { + this.setParameter(Show.KEY_MAIN_FIELD_2, field2); return this; } /** - * @return {String} - */ + * @return {String} + */ getMainField2 () { return this.getParameter(Show.KEY_MAIN_FIELD_2); } /** - * @param {String} mainField3 - * @return {Show} - */ - setMainField3 (mainField3) { - this.setParameter(Show.KEY_MAIN_FIELD_3, mainField3); + * @param {String} field3 - The text that should be displayed on the second "page" first display line. If this text + * is not set, the text of mainField3 stays unchanged. If this text is empty "", the field + * will be cleared. + * @return {Show} + */ + setMainField3 (field3) { + this.setParameter(Show.KEY_MAIN_FIELD_3, field3); return this; } /** - * @return {String} - */ + * @return {String} + */ getMainField3 () { return this.getParameter(Show.KEY_MAIN_FIELD_3); } /** - * @param {String} mainField4 - * @return {Show} - */ - setMainField4 (mainField4) { - this.setParameter(Show.KEY_MAIN_FIELD_4, mainField4); + * @param {String} field4 - The text that should be displayed on the second "page" second display line. If this text + * is not set, the text of mainField4 stays unchanged. If this text is empty "", the field + * will be cleared. + * @return {Show} + */ + setMainField4 (field4) { + this.setParameter(Show.KEY_MAIN_FIELD_4, field4); return this; } /** - * @return {String} - */ + * @return {String} + */ getMainField4 () { return this.getParameter(Show.KEY_MAIN_FIELD_4); } /** - * @param {TextAlignment} menuParams - * @return {Show} - */ + * @param {TextAlignment} alignment - Specifies how mainField1 and mainField2 texts should be aligned on display. If + * omitted, texts will be centered. + * @return {Show} + */ setAlignment (alignment) { this.validateType(TextAlignment, alignment); - this.setParameter(Show.KEY_ALIGNMENT, alignment); return this; } /** - * @return {TextAlignment} - */ + * @return {TextAlignment} + */ getAlignment () { return this.getObject(TextAlignment, Show.KEY_ALIGNMENT); } /** - * @param {String} statusBar - * @return {Show} - */ - setStatusBar (statusBar) { - this.setParameter(Show.KEY_STATUS_BAR, statusBar); + * @param {String} bar - Requires investigation regarding the nav display capabilities. Potentially lower + * lowerStatusBar, upperStatusBar, titleBar, etc. + * @return {Show} + */ + setStatusBar (bar) { + this.setParameter(Show.KEY_STATUS_BAR, bar); return this; } /** - * @return {String} - */ + * @return {String} + */ getStatusBar () { return this.getParameter(Show.KEY_STATUS_BAR); } /** - * @param {String} mediaClock - * @return {Show} - */ - setMediaClock (mediaClock) { - this.setParameter(Show.KEY_MEDIA_CLOCK, mediaClock); + * @param {String} clock - Text value for MediaClock field. Has to be properly formatted by Mobile App according to + * the module's capabilities. If this text is set, any automatic media clock updates + * previously set with SetMediaClockTimer will be stopped. + * @return {Show} + */ + setMediaClock (clock) { + this.setParameter(Show.KEY_MEDIA_CLOCK, clock); return this; } /** - * @return {String} - */ + * @return {String} + */ getMediaClock () { return this.getParameter(Show.KEY_MEDIA_CLOCK); } /** - * @param {String} mediaTrack - * @return {Show} - */ - setMediaTrack (mediaTrack) { - this.setParameter(Show.KEY_MEDIA_TRACK, mediaTrack); + * @param {String} track - The text that should be displayed in the track field. If this text is not set, the text + * of mediaTrack stays unchanged. If this text is empty "", the field will be cleared. + * @return {Show} + */ + setMediaTrack (track) { + this.setParameter(Show.KEY_MEDIA_TRACK, track); return this; } /** - * @return {String} - */ + * @return {String} + */ getMediaTrack () { return this.getParameter(Show.KEY_MEDIA_TRACK); } /** - * @param {Image} graphic - * @return {Show} - */ + * @param {Image} graphic - Image struct determining whether static or dynamic image to display in app. If omitted + * on supported displays, the displayed graphic shall not change. + * @return {Show} + */ setGraphic (graphic) { this.validateType(Image, graphic); - this.setParameter(Show.KEY_GRAPHIC, graphic); return this; } /** - * @return {Image} - */ + * @return {Image} + */ getGraphic () { return this.getObject(Image, Show.KEY_GRAPHIC); } /** - * @param {Image} secondaryGraphic - * @return {Show} - */ - setSecondaryGraphic (secondaryGraphic) { - this.validateType(Image, secondaryGraphic); - - this.setParameter(Show.KEY_SECONDARY_GRAPHIC, secondaryGraphic); + * @param {Image} graphic - Image struct determining whether static or dynamic secondary image to display in app. If + * omitted on supported displays, the displayed secondary graphic shall not change. + * @return {Show} + */ + setSecondaryGraphic (graphic) { + this.validateType(Image, graphic); + this.setParameter(Show.KEY_SECONDARY_GRAPHIC, graphic); return this; } /** - * @return {Image} - */ + * @return {Image} + */ getSecondaryGraphic () { return this.getObject(Image, Show.KEY_SECONDARY_GRAPHIC); } /** - * @param {Array} softButtons - * @return {Show} - */ - setSoftButtons (softButtons) { - // TODO make this work for arrays - // this.validateType(SoftButton, softButtons); - - this.setParameter(Show.KEY_SOFT_BUTTONS, softButtons); + * @param {SoftButton[]} buttons - App defined SoftButtons. If omitted on supported displays, the currently + * displayed SoftButton values will not change. + * @return {Show} + */ + setSoftButtons (buttons) { + this.validateType(SoftButton, buttons, true); + this.setParameter(Show.KEY_SOFT_BUTTONS, buttons); return this; } /** - * @return {Array} - */ + * @return {SoftButton[]} + */ getSoftButtons () { return this.getObject(SoftButton, Show.KEY_SOFT_BUTTONS); } /** - * @param {Array} customPresets - * @return {Show} - */ - setCustomPresets (customPresets) { - this.setParameter(Show.KEY_CUSTOM_PRESETS, customPresets); + * @param {String[]} presets - App labeled on-screen presets (i.e. on-screen media presets or dynamic search + * suggestions). If omitted on supported displays, the presets will be shown as not + * defined. + * @return {Show} + */ + setCustomPresets (presets) { + this.setParameter(Show.KEY_CUSTOM_PRESETS, presets); return this; } /** - * @return {Array} - */ + * @return {String[]} + */ getCustomPresets () { return this.getParameter(Show.KEY_CUSTOM_PRESETS); } /** - * @param {MetadataTags} metadataTags - * @return {Show} - */ - setMetadataTags (metadataTags) { - this.validateType(MetadataTags, metadataTags); - - this.setParameter(Show.KEY_METADATA_TAGS, metadataTags); + * @param {MetadataTags} tags - App defined metadata information. See MetadataStruct. Uses mainField1, mainField2, + * mainField3, mainField4. If omitted on supported displays, the currently set metadata + * tags will not change. If any text field contains no tags or the none tag, the + * metadata tag for that textfield should be removed. + * @return {Show} + */ + setMetadataTags (tags) { + this.validateType(MetadataTags, tags); + this.setParameter(Show.KEY_METADATA_TAGS, tags); return this; } /** - * @return {MetadataTags} - */ + * @return {MetadataTags} + */ getMetadataTags () { return this.getObject(MetadataTags, Show.KEY_METADATA_TAGS); } /** - * @param {String} templateTitle - * @return {Show} - */ - setTemplateTitle (templateTitle) { - this.setParameter(Show.KEY_TEMPLATE_TITLE, templateTitle); + * @param {String} title - The title of the new template that will be displayed. How this will be displayed is + * dependent on the OEM design and implementation of the template. + * @return {Show} + */ + setTemplateTitle (title) { + this.setParameter(Show.KEY_TEMPLATE_TITLE, title); return this; } /** - * @return {String} - */ + * @return {String} + */ getTemplateTitle () { return this.getParameter(Show.KEY_TEMPLATE_TITLE); } /** - * @param {Number} windowID - * @return {Show} - */ - setWindowID (windowID) { - this.setParameter(Show.KEY_WINDOW_ID, windowID); + * @param {Number} id - This is the unique ID assigned to the window that this RPC is intended. If this param is not + * included, it will be assumed that this request is specifically for the main window on the + * main display. See PredefinedWindows enum. + * @return {Show} + */ + setWindowID (id) { + this.setParameter(Show.KEY_WINDOW_ID, id); return this; } /** - * @return {Number} - */ + * @return {Number} + */ getWindowID () { return this.getParameter(Show.KEY_WINDOW_ID); } + + /** + * @param {TemplateConfiguration} configuration - Used to set an alternate template layout to a window. + * @return {Show} + */ + setTemplateConfiguration (configuration) { + this.validateType(TemplateConfiguration, configuration); + this.setParameter(Show.KEY_TEMPLATE_CONFIGURATION, configuration); + return this; + } + + /** + * @return {TemplateConfiguration} + */ + getTemplateConfiguration () { + return this.getObject(TemplateConfiguration, Show.KEY_TEMPLATE_CONFIGURATION); + } } Show.KEY_MAIN_FIELD_1 = 'mainField1'; @@ -315,5 +353,6 @@ Show.KEY_CUSTOM_PRESETS = 'customPresets'; Show.KEY_METADATA_TAGS = 'metadataTags'; Show.KEY_TEMPLATE_TITLE = 'templateTitle'; Show.KEY_WINDOW_ID = 'windowID'; +Show.KEY_TEMPLATE_CONFIGURATION = 'templateConfiguration'; -export { Show }; +export { Show }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/ShowAppMenu.js b/lib/js/src/rpc/messages/ShowAppMenu.js new file mode 100644 index 00000000..76915927 --- /dev/null +++ b/lib/js/src/rpc/messages/ShowAppMenu.js @@ -0,0 +1,69 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Shows the built in menu view + */ +class ShowAppMenu extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.ShowAppMenu); + } + + /** + * @param {Number} id - If omitted the HMI opens the app's menu. If set to a sub-menu ID the HMI opens the + * corresponding sub-menu previously added using `AddSubMenu`. + * @return {ShowAppMenu} + */ + setMenuID (id) { + this.setParameter(ShowAppMenu.KEY_MENU_ID, id); + return this; + } + + /** + * @return {Number} + */ + getMenuID () { + return this.getParameter(ShowAppMenu.KEY_MENU_ID); + } +} + +ShowAppMenu.KEY_MENU_ID = 'menuID'; + +export { ShowAppMenu }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/ShowAppMenuResponse.js b/lib/js/src/rpc/messages/ShowAppMenuResponse.js new file mode 100644 index 00000000..af63f17f --- /dev/null +++ b/lib/js/src/rpc/messages/ShowAppMenuResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class ShowAppMenuResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.ShowAppMenu); + } +} + + +export { ShowAppMenuResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/ShowConstantTBT.js b/lib/js/src/rpc/messages/ShowConstantTBT.js new file mode 100644 index 00000000..0b2ceb37 --- /dev/null +++ b/lib/js/src/rpc/messages/ShowConstantTBT.js @@ -0,0 +1,246 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { SoftButton } from '../structs/SoftButton.js'; +import { FunctionID } from '../enums/FunctionID.js'; +import { Image } from '../structs/Image.js'; + +class ShowConstantTBT extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.ShowConstantTBT); + } + + /** + * @param {String} text1 + * @return {ShowConstantTBT} + */ + setNavigationText1 (text1) { + this.setParameter(ShowConstantTBT.KEY_NAVIGATION_TEXT_1, text1); + return this; + } + + /** + * @return {String} + */ + getNavigationText1 () { + return this.getParameter(ShowConstantTBT.KEY_NAVIGATION_TEXT_1); + } + + /** + * @param {String} text2 + * @return {ShowConstantTBT} + */ + setNavigationText2 (text2) { + this.setParameter(ShowConstantTBT.KEY_NAVIGATION_TEXT_2, text2); + return this; + } + + /** + * @return {String} + */ + getNavigationText2 () { + return this.getParameter(ShowConstantTBT.KEY_NAVIGATION_TEXT_2); + } + + /** + * @param {String} eta + * @return {ShowConstantTBT} + */ + setEta (eta) { + this.setParameter(ShowConstantTBT.KEY_ETA, eta); + return this; + } + + /** + * @return {String} + */ + getEta () { + return this.getParameter(ShowConstantTBT.KEY_ETA); + } + + /** + * @param {String} destination + * @return {ShowConstantTBT} + */ + setTimeToDestination (destination) { + this.setParameter(ShowConstantTBT.KEY_TIME_TO_DESTINATION, destination); + return this; + } + + /** + * @return {String} + */ + getTimeToDestination () { + return this.getParameter(ShowConstantTBT.KEY_TIME_TO_DESTINATION); + } + + /** + * @param {String} distance + * @return {ShowConstantTBT} + */ + setTotalDistance (distance) { + this.setParameter(ShowConstantTBT.KEY_TOTAL_DISTANCE, distance); + return this; + } + + /** + * @return {String} + */ + getTotalDistance () { + return this.getParameter(ShowConstantTBT.KEY_TOTAL_DISTANCE); + } + + /** + * @param {Image} icon + * @return {ShowConstantTBT} + */ + setTurnIcon (icon) { + this.validateType(Image, icon); + this.setParameter(ShowConstantTBT.KEY_TURN_ICON, icon); + return this; + } + + /** + * @return {Image} + */ + getTurnIcon () { + return this.getObject(Image, ShowConstantTBT.KEY_TURN_ICON); + } + + /** + * @param {Image} icon + * @return {ShowConstantTBT} + */ + setNextTurnIcon (icon) { + this.validateType(Image, icon); + this.setParameter(ShowConstantTBT.KEY_NEXT_TURN_ICON, icon); + return this; + } + + /** + * @return {Image} + */ + getNextTurnIcon () { + return this.getObject(Image, ShowConstantTBT.KEY_NEXT_TURN_ICON); + } + + /** + * @param {Number} maneuver - Fraction of distance till next maneuver (starting from when AlertManeuver is + * triggered). Used to calculate progress bar. + * @return {ShowConstantTBT} + */ + setDistanceToManeuver (maneuver) { + this.setParameter(ShowConstantTBT.KEY_DISTANCE_TO_MANEUVER, maneuver); + return this; + } + + /** + * @return {Number} + */ + getDistanceToManeuver () { + return this.getParameter(ShowConstantTBT.KEY_DISTANCE_TO_MANEUVER); + } + + /** + * @param {Number} scale - Distance till next maneuver (starting from) from previous maneuver. Used to calculate + * progress bar. + * @return {ShowConstantTBT} + */ + setDistanceToManeuverScale (scale) { + this.setParameter(ShowConstantTBT.KEY_DISTANCE_TO_MANEUVER_SCALE, scale); + return this; + } + + /** + * @return {Number} + */ + getDistanceToManeuverScale () { + return this.getParameter(ShowConstantTBT.KEY_DISTANCE_TO_MANEUVER_SCALE); + } + + /** + * @param {Boolean} complete - If and when a maneuver has completed while an AlertManeuver is active, the app must + * send this value set to TRUE in order to clear the AlertManeuver overlay. If omitted + * the value will be assumed as FALSE. + * @return {ShowConstantTBT} + */ + setManeuverComplete (complete) { + this.setParameter(ShowConstantTBT.KEY_MANEUVER_COMPLETE, complete); + return this; + } + + /** + * @return {Boolean} + */ + getManeuverComplete () { + return this.getParameter(ShowConstantTBT.KEY_MANEUVER_COMPLETE); + } + + /** + * @param {SoftButton[]} buttons - Three dynamic SoftButtons available (first SoftButton is fixed to "Turns"). If + * omitted on supported displays, the currently displayed SoftButton values will not + * change. + * @return {ShowConstantTBT} + */ + setSoftButtons (buttons) { + this.validateType(SoftButton, buttons, true); + this.setParameter(ShowConstantTBT.KEY_SOFT_BUTTONS, buttons); + return this; + } + + /** + * @return {SoftButton[]} + */ + getSoftButtons () { + return this.getObject(SoftButton, ShowConstantTBT.KEY_SOFT_BUTTONS); + } +} + +ShowConstantTBT.KEY_NAVIGATION_TEXT_1 = 'navigationText1'; +ShowConstantTBT.KEY_NAVIGATION_TEXT_2 = 'navigationText2'; +ShowConstantTBT.KEY_ETA = 'eta'; +ShowConstantTBT.KEY_TIME_TO_DESTINATION = 'timeToDestination'; +ShowConstantTBT.KEY_TOTAL_DISTANCE = 'totalDistance'; +ShowConstantTBT.KEY_TURN_ICON = 'turnIcon'; +ShowConstantTBT.KEY_NEXT_TURN_ICON = 'nextTurnIcon'; +ShowConstantTBT.KEY_DISTANCE_TO_MANEUVER = 'distanceToManeuver'; +ShowConstantTBT.KEY_DISTANCE_TO_MANEUVER_SCALE = 'distanceToManeuverScale'; +ShowConstantTBT.KEY_MANEUVER_COMPLETE = 'maneuverComplete'; +ShowConstantTBT.KEY_SOFT_BUTTONS = 'softButtons'; + +export { ShowConstantTBT }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/ShowConstantTBTResponse.js b/lib/js/src/rpc/messages/ShowConstantTBTResponse.js new file mode 100644 index 00000000..fd46cc22 --- /dev/null +++ b/lib/js/src/rpc/messages/ShowConstantTBTResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class ShowConstantTBTResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.ShowConstantTBT); + } +} + + +export { ShowConstantTBTResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/ShowResponse.js b/lib/js/src/rpc/messages/ShowResponse.js index 0b636fc8..2a62a053 100644 --- a/lib/js/src/rpc/messages/ShowResponse.js +++ b/lib/js/src/rpc/messages/ShowResponse.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -30,17 +31,18 @@ * POSSIBILITY OF SUCH DAMAGE. */ -import { RpcResponse } from '../RpcResponse.js'; import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; class ShowResponse extends RpcResponse { /** - * @constructor - */ + * @constructor + */ constructor (store) { super(store); this.setFunctionName(FunctionID.Show); } } -export { ShowResponse }; + +export { ShowResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/Slider.js b/lib/js/src/rpc/messages/Slider.js new file mode 100644 index 00000000..54a28e65 --- /dev/null +++ b/lib/js/src/rpc/messages/Slider.js @@ -0,0 +1,158 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Creates a full screen or pop-up overlay (depending on platform) with a single user controlled slider. + */ +class Slider extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.Slider); + } + + /** + * @param {Number} ticks - Number of selectable items on a horizontal axis + * @return {Slider} + */ + setNumTicks (ticks) { + this.setParameter(Slider.KEY_NUM_TICKS, ticks); + return this; + } + + /** + * @return {Number} + */ + getNumTicks () { + return this.getParameter(Slider.KEY_NUM_TICKS); + } + + /** + * @param {Number} position - Initial position of slider control (cannot exceed numTicks) + * @return {Slider} + */ + setPosition (position) { + this.setParameter(Slider.KEY_POSITION, position); + return this; + } + + /** + * @return {Number} + */ + getPosition () { + return this.getParameter(Slider.KEY_POSITION); + } + + /** + * @param {String} header - Text header to display + * @return {Slider} + */ + setSliderHeader (header) { + this.setParameter(Slider.KEY_SLIDER_HEADER, header); + return this; + } + + /** + * @return {String} + */ + getSliderHeader () { + return this.getParameter(Slider.KEY_SLIDER_HEADER); + } + + /** + * @param {String[]} footer - Text footer to display (meant to display min/max threshold descriptors). For a static + * text footer, only one footer string shall be provided in the array. For a dynamic text + * footer, the number of footer text string in the array must match the numTicks value. + * For a dynamic text footer, text array string should correlate with potential slider + * position index. If omitted on supported displays, no footer text shall be displayed. + * @return {Slider} + */ + setSliderFooter (footer) { + this.setParameter(Slider.KEY_SLIDER_FOOTER, footer); + return this; + } + + /** + * @return {String[]} + */ + getSliderFooter () { + return this.getParameter(Slider.KEY_SLIDER_FOOTER); + } + + /** + * @param {Number} timeout - App defined timeout. Indicates how long of a timeout from the last action (i.e. sliding + * control resets timeout). If omitted, the value is set to 10000. + * @return {Slider} + */ + setTimeout (timeout) { + this.setParameter(Slider.KEY_TIMEOUT, timeout); + return this; + } + + /** + * @return {Number} + */ + getTimeout () { + return this.getParameter(Slider.KEY_TIMEOUT); + } + + /** + * @param {Number} id - An ID for this specific Slider to allow cancellation through the `CancelInteraction` RPC. + * @return {Slider} + */ + setCancelID (id) { + this.setParameter(Slider.KEY_CANCEL_ID, id); + return this; + } + + /** + * @return {Number} + */ + getCancelID () { + return this.getParameter(Slider.KEY_CANCEL_ID); + } +} + +Slider.KEY_NUM_TICKS = 'numTicks'; +Slider.KEY_POSITION = 'position'; +Slider.KEY_SLIDER_HEADER = 'sliderHeader'; +Slider.KEY_SLIDER_FOOTER = 'sliderFooter'; +Slider.KEY_TIMEOUT = 'timeout'; +Slider.KEY_CANCEL_ID = 'cancelID'; + +export { Slider }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SliderResponse.js b/lib/js/src/rpc/messages/SliderResponse.js new file mode 100644 index 00000000..b0848bb4 --- /dev/null +++ b/lib/js/src/rpc/messages/SliderResponse.js @@ -0,0 +1,66 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class SliderResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.Slider); + } + + /** + * @param {Number} position - Current slider value returned when saved or canceled (aborted) This value is only + * returned for resultCodes "SAVED" or "ABORTED" + * @return {SliderResponse} + */ + setSliderPosition (position) { + this.setParameter(SliderResponse.KEY_SLIDER_POSITION, position); + return this; + } + + /** + * @return {Number} + */ + getSliderPosition () { + return this.getParameter(SliderResponse.KEY_SLIDER_POSITION); + } +} + +SliderResponse.KEY_SLIDER_POSITION = 'sliderPosition'; + +export { SliderResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/Speak.js b/lib/js/src/rpc/messages/Speak.js new file mode 100644 index 00000000..8ede0a3f --- /dev/null +++ b/lib/js/src/rpc/messages/Speak.js @@ -0,0 +1,71 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { TTSChunk } from '../structs/TTSChunk.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Speaks a text. + */ +class Speak extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.Speak); + } + + /** + * @param {TTSChunk[]} chunks - An array of text chunks of type TTSChunk. See TTSChunk. The array must have at least + * one item. + * @return {Speak} + */ + setTtsChunks (chunks) { + this.validateType(TTSChunk, chunks, true); + this.setParameter(Speak.KEY_TTS_CHUNKS, chunks); + return this; + } + + /** + * @return {TTSChunk[]} + */ + getTtsChunks () { + return this.getObject(TTSChunk, Speak.KEY_TTS_CHUNKS); + } +} + +Speak.KEY_TTS_CHUNKS = 'ttsChunks'; + +export { Speak }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SpeakResponse.js b/lib/js/src/rpc/messages/SpeakResponse.js new file mode 100644 index 00000000..a25587e7 --- /dev/null +++ b/lib/js/src/rpc/messages/SpeakResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class SpeakResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.Speak); + } +} + + +export { SpeakResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SubscribeButton.js b/lib/js/src/rpc/messages/SubscribeButton.js new file mode 100644 index 00000000..2028ce2b --- /dev/null +++ b/lib/js/src/rpc/messages/SubscribeButton.js @@ -0,0 +1,71 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { ButtonName } from '../enums/ButtonName.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Subscribes to built-in HMI buttons. The application will be notified by the OnButtonEvent and OnButtonPress. To + * unsubscribe the notifications, use unsubscribeButton. + */ +class SubscribeButton extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SubscribeButton); + } + + /** + * @param {ButtonName} name - Name of the button to subscribe. + * @return {SubscribeButton} + */ + setButtonName (name) { + this.validateType(ButtonName, name); + this.setParameter(SubscribeButton.KEY_BUTTON_NAME, name); + return this; + } + + /** + * @return {ButtonName} + */ + getButtonName () { + return this.getObject(ButtonName, SubscribeButton.KEY_BUTTON_NAME); + } +} + +SubscribeButton.KEY_BUTTON_NAME = 'buttonName'; + +export { SubscribeButton }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SubscribeButtonResponse.js b/lib/js/src/rpc/messages/SubscribeButtonResponse.js new file mode 100644 index 00000000..517f779b --- /dev/null +++ b/lib/js/src/rpc/messages/SubscribeButtonResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class SubscribeButtonResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SubscribeButton); + } +} + + +export { SubscribeButtonResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SubscribeVehicleData.js b/lib/js/src/rpc/messages/SubscribeVehicleData.js new file mode 100644 index 00000000..37134212 --- /dev/null +++ b/lib/js/src/rpc/messages/SubscribeVehicleData.js @@ -0,0 +1,546 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Subscribes for specific published data items. The data will be only sent if it has changed. The application will be + * notified by the onVehicleData notification whenever new data is available. To unsubscribe the notifications, use + * unsubscribe with the same subscriptionType. + */ +class SubscribeVehicleData extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SubscribeVehicleData); + } + + /** + * @param {Boolean} gps - See GPSData + * @return {SubscribeVehicleData} + */ + setGps (gps) { + this.setParameter(SubscribeVehicleData.KEY_GPS, gps); + return this; + } + + /** + * @return {Boolean} + */ + getGps () { + return this.getParameter(SubscribeVehicleData.KEY_GPS); + } + + /** + * @param {Boolean} speed - The vehicle speed in kilometers per hour + * @return {SubscribeVehicleData} + */ + setSpeed (speed) { + this.setParameter(SubscribeVehicleData.KEY_SPEED, speed); + return this; + } + + /** + * @return {Boolean} + */ + getSpeed () { + return this.getParameter(SubscribeVehicleData.KEY_SPEED); + } + + /** + * @param {Boolean} rpm - The number of revolutions per minute of the engine + * @return {SubscribeVehicleData} + */ + setRpm (rpm) { + this.setParameter(SubscribeVehicleData.KEY_RPM, rpm); + return this; + } + + /** + * @return {Boolean} + */ + getRpm () { + return this.getParameter(SubscribeVehicleData.KEY_RPM); + } + + /** + * @param {Boolean} level - The fuel level in the tank (percentage) + * @return {SubscribeVehicleData} + */ + setFuelLevel (level) { + this.setParameter(SubscribeVehicleData.KEY_FUEL_LEVEL, level); + return this; + } + + /** + * @return {Boolean} + */ + getFuelLevel () { + return this.getParameter(SubscribeVehicleData.KEY_FUEL_LEVEL); + } + + /** + * @param {Boolean} level_state - The fuel level state + * @return {SubscribeVehicleData} + */ + setFuelLevel_State (level_state) { + this.setParameter(SubscribeVehicleData.KEY_FUEL_LEVEL_STATE, level_state); + return this; + } + + /** + * @return {Boolean} + */ + getFuelLevel_State () { + return this.getParameter(SubscribeVehicleData.KEY_FUEL_LEVEL_STATE); + } + + /** + * @param {Boolean} consumption - The instantaneous fuel consumption in microlitres + * @return {SubscribeVehicleData} + */ + setInstantFuelConsumption (consumption) { + this.setParameter(SubscribeVehicleData.KEY_INSTANT_FUEL_CONSUMPTION, consumption); + return this; + } + + /** + * @return {Boolean} + */ + getInstantFuelConsumption () { + return this.getParameter(SubscribeVehicleData.KEY_INSTANT_FUEL_CONSUMPTION); + } + + /** + * @param {Boolean} range - The estimate range in KM the vehicle can travel based on fuel level and consumption + * @return {SubscribeVehicleData} + */ + setFuelRange (range) { + this.setParameter(SubscribeVehicleData.KEY_FUEL_RANGE, range); + return this; + } + + /** + * @return {Boolean} + */ + getFuelRange () { + return this.getParameter(SubscribeVehicleData.KEY_FUEL_RANGE); + } + + /** + * @param {Boolean} temperature - The external temperature in degrees celsius + * @return {SubscribeVehicleData} + */ + setExternalTemperature (temperature) { + this.setParameter(SubscribeVehicleData.KEY_EXTERNAL_TEMPERATURE, temperature); + return this; + } + + /** + * @return {Boolean} + */ + getExternalTemperature () { + return this.getParameter(SubscribeVehicleData.KEY_EXTERNAL_TEMPERATURE); + } + + /** + * @param {Boolean} signal - See TurnSignal + * @return {SubscribeVehicleData} + */ + setTurnSignal (signal) { + this.setParameter(SubscribeVehicleData.KEY_TURN_SIGNAL, signal); + return this; + } + + /** + * @return {Boolean} + */ + getTurnSignal () { + return this.getParameter(SubscribeVehicleData.KEY_TURN_SIGNAL); + } + + /** + * @param {Boolean} prndl - See PRNDL + * @return {SubscribeVehicleData} + */ + setPrndl (prndl) { + this.setParameter(SubscribeVehicleData.KEY_PRNDL, prndl); + return this; + } + + /** + * @return {Boolean} + */ + getPrndl () { + return this.getParameter(SubscribeVehicleData.KEY_PRNDL); + } + + /** + * @param {Boolean} pressure - See TireStatus + * @return {SubscribeVehicleData} + */ + setTirePressure (pressure) { + this.setParameter(SubscribeVehicleData.KEY_TIRE_PRESSURE, pressure); + return this; + } + + /** + * @return {Boolean} + */ + getTirePressure () { + return this.getParameter(SubscribeVehicleData.KEY_TIRE_PRESSURE); + } + + /** + * @param {Boolean} odometer - Odometer in km + * @return {SubscribeVehicleData} + */ + setOdometer (odometer) { + this.setParameter(SubscribeVehicleData.KEY_ODOMETER, odometer); + return this; + } + + /** + * @return {Boolean} + */ + getOdometer () { + return this.getParameter(SubscribeVehicleData.KEY_ODOMETER); + } + + /** + * @param {Boolean} status - The status of the seat belts + * @return {SubscribeVehicleData} + */ + setBeltStatus (status) { + this.setParameter(SubscribeVehicleData.KEY_BELT_STATUS, status); + return this; + } + + /** + * @return {Boolean} + */ + getBeltStatus () { + return this.getParameter(SubscribeVehicleData.KEY_BELT_STATUS); + } + + /** + * @param {Boolean} information - The body information including power modes + * @return {SubscribeVehicleData} + */ + setBodyInformation (information) { + this.setParameter(SubscribeVehicleData.KEY_BODY_INFORMATION, information); + return this; + } + + /** + * @return {Boolean} + */ + getBodyInformation () { + return this.getParameter(SubscribeVehicleData.KEY_BODY_INFORMATION); + } + + /** + * @param {Boolean} status - The device status including signal and battery strength + * @return {SubscribeVehicleData} + */ + setDeviceStatus (status) { + this.setParameter(SubscribeVehicleData.KEY_DEVICE_STATUS, status); + return this; + } + + /** + * @return {Boolean} + */ + getDeviceStatus () { + return this.getParameter(SubscribeVehicleData.KEY_DEVICE_STATUS); + } + + /** + * @param {Boolean} braking - The status of the brake pedal + * @return {SubscribeVehicleData} + */ + setDriverBraking (braking) { + this.setParameter(SubscribeVehicleData.KEY_DRIVER_BRAKING, braking); + return this; + } + + /** + * @return {Boolean} + */ + getDriverBraking () { + return this.getParameter(SubscribeVehicleData.KEY_DRIVER_BRAKING); + } + + /** + * @param {Boolean} status - The status of the wipers + * @return {SubscribeVehicleData} + */ + setWiperStatus (status) { + this.setParameter(SubscribeVehicleData.KEY_WIPER_STATUS, status); + return this; + } + + /** + * @return {Boolean} + */ + getWiperStatus () { + return this.getParameter(SubscribeVehicleData.KEY_WIPER_STATUS); + } + + /** + * @param {Boolean} status - Status of the head lamps + * @return {SubscribeVehicleData} + */ + setHeadLampStatus (status) { + this.setParameter(SubscribeVehicleData.KEY_HEAD_LAMP_STATUS, status); + return this; + } + + /** + * @return {Boolean} + */ + getHeadLampStatus () { + return this.getParameter(SubscribeVehicleData.KEY_HEAD_LAMP_STATUS); + } + + /** + * @param {Boolean} torque - Torque value for engine (in Nm) on non-diesel variants + * @return {SubscribeVehicleData} + */ + setEngineTorque (torque) { + this.setParameter(SubscribeVehicleData.KEY_ENGINE_TORQUE, torque); + return this; + } + + /** + * @return {Boolean} + */ + getEngineTorque () { + return this.getParameter(SubscribeVehicleData.KEY_ENGINE_TORQUE); + } + + /** + * @param {Boolean} position - Accelerator pedal position (percentage depressed) + * @return {SubscribeVehicleData} + */ + setAccPedalPosition (position) { + this.setParameter(SubscribeVehicleData.KEY_ACC_PEDAL_POSITION, position); + return this; + } + + /** + * @return {Boolean} + */ + getAccPedalPosition () { + return this.getParameter(SubscribeVehicleData.KEY_ACC_PEDAL_POSITION); + } + + /** + * @param {Boolean} angle - Current angle of the steering wheel (in deg) + * @return {SubscribeVehicleData} + */ + setSteeringWheelAngle (angle) { + this.setParameter(SubscribeVehicleData.KEY_STEERING_WHEEL_ANGLE, angle); + return this; + } + + /** + * @return {Boolean} + */ + getSteeringWheelAngle () { + return this.getParameter(SubscribeVehicleData.KEY_STEERING_WHEEL_ANGLE); + } + + /** + * @param {Boolean} life - The estimated percentage of remaining oil life of the engine. + * @return {SubscribeVehicleData} + */ + setEngineOilLife (life) { + this.setParameter(SubscribeVehicleData.KEY_ENGINE_OIL_LIFE, life); + return this; + } + + /** + * @return {Boolean} + */ + getEngineOilLife () { + return this.getParameter(SubscribeVehicleData.KEY_ENGINE_OIL_LIFE); + } + + /** + * @param {Boolean} status - The status of the park brake as provided by Electric Park Brake (EPB) system. + * @return {SubscribeVehicleData} + */ + setElectronicParkBrakeStatus (status) { + this.setParameter(SubscribeVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS, status); + return this; + } + + /** + * @return {Boolean} + */ + getElectronicParkBrakeStatus () { + return this.getParameter(SubscribeVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS); + } + + /** + * @param {Boolean} id - Parameter used by cloud apps to identify a head unit + * @return {SubscribeVehicleData} + */ + setCloudAppVehicleID (id) { + this.setParameter(SubscribeVehicleData.KEY_CLOUD_APP_VEHICLE_ID, id); + return this; + } + + /** + * @return {Boolean} + */ + getCloudAppVehicleID () { + return this.getParameter(SubscribeVehicleData.KEY_CLOUD_APP_VEHICLE_ID); + } + + /** + * @param {Boolean} info - Emergency Call notification and confirmation data + * @return {SubscribeVehicleData} + */ + setECallInfo (info) { + this.setParameter(SubscribeVehicleData.KEY_E_CALL_INFO, info); + return this; + } + + /** + * @return {Boolean} + */ + getECallInfo () { + return this.getParameter(SubscribeVehicleData.KEY_E_CALL_INFO); + } + + /** + * @param {Boolean} status - The status of the air bags + * @return {SubscribeVehicleData} + */ + setAirbagStatus (status) { + this.setParameter(SubscribeVehicleData.KEY_AIRBAG_STATUS, status); + return this; + } + + /** + * @return {Boolean} + */ + getAirbagStatus () { + return this.getParameter(SubscribeVehicleData.KEY_AIRBAG_STATUS); + } + + /** + * @param {Boolean} event - Information related to an emergency event (and if it occurred) + * @return {SubscribeVehicleData} + */ + setEmergencyEvent (event) { + this.setParameter(SubscribeVehicleData.KEY_EMERGENCY_EVENT, event); + return this; + } + + /** + * @return {Boolean} + */ + getEmergencyEvent () { + return this.getParameter(SubscribeVehicleData.KEY_EMERGENCY_EVENT); + } + + /** + * @param {Boolean} status - The status modes of the cluster + * @return {SubscribeVehicleData} + */ + setClusterModeStatus (status) { + this.setParameter(SubscribeVehicleData.KEY_CLUSTER_MODE_STATUS, status); + return this; + } + + /** + * @return {Boolean} + */ + getClusterModeStatus () { + return this.getParameter(SubscribeVehicleData.KEY_CLUSTER_MODE_STATUS); + } + + /** + * @param {Boolean} key - Information related to the MyKey feature + * @return {SubscribeVehicleData} + */ + setMyKey (key) { + this.setParameter(SubscribeVehicleData.KEY_MY_KEY, key); + return this; + } + + /** + * @return {Boolean} + */ + getMyKey () { + return this.getParameter(SubscribeVehicleData.KEY_MY_KEY); + } +} + +SubscribeVehicleData.KEY_GPS = 'gps'; +SubscribeVehicleData.KEY_SPEED = 'speed'; +SubscribeVehicleData.KEY_RPM = 'rpm'; +SubscribeVehicleData.KEY_FUEL_LEVEL = 'fuelLevel'; +SubscribeVehicleData.KEY_FUEL_LEVEL_STATE = 'fuelLevel_State'; +SubscribeVehicleData.KEY_INSTANT_FUEL_CONSUMPTION = 'instantFuelConsumption'; +SubscribeVehicleData.KEY_FUEL_RANGE = 'fuelRange'; +SubscribeVehicleData.KEY_EXTERNAL_TEMPERATURE = 'externalTemperature'; +SubscribeVehicleData.KEY_TURN_SIGNAL = 'turnSignal'; +SubscribeVehicleData.KEY_PRNDL = 'prndl'; +SubscribeVehicleData.KEY_TIRE_PRESSURE = 'tirePressure'; +SubscribeVehicleData.KEY_ODOMETER = 'odometer'; +SubscribeVehicleData.KEY_BELT_STATUS = 'beltStatus'; +SubscribeVehicleData.KEY_BODY_INFORMATION = 'bodyInformation'; +SubscribeVehicleData.KEY_DEVICE_STATUS = 'deviceStatus'; +SubscribeVehicleData.KEY_DRIVER_BRAKING = 'driverBraking'; +SubscribeVehicleData.KEY_WIPER_STATUS = 'wiperStatus'; +SubscribeVehicleData.KEY_HEAD_LAMP_STATUS = 'headLampStatus'; +SubscribeVehicleData.KEY_ENGINE_TORQUE = 'engineTorque'; +SubscribeVehicleData.KEY_ACC_PEDAL_POSITION = 'accPedalPosition'; +SubscribeVehicleData.KEY_STEERING_WHEEL_ANGLE = 'steeringWheelAngle'; +SubscribeVehicleData.KEY_ENGINE_OIL_LIFE = 'engineOilLife'; +SubscribeVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS = 'electronicParkBrakeStatus'; +SubscribeVehicleData.KEY_CLOUD_APP_VEHICLE_ID = 'cloudAppVehicleID'; +SubscribeVehicleData.KEY_E_CALL_INFO = 'eCallInfo'; +SubscribeVehicleData.KEY_AIRBAG_STATUS = 'airbagStatus'; +SubscribeVehicleData.KEY_EMERGENCY_EVENT = 'emergencyEvent'; +SubscribeVehicleData.KEY_CLUSTER_MODE_STATUS = 'clusterModeStatus'; +SubscribeVehicleData.KEY_MY_KEY = 'myKey'; + +export { SubscribeVehicleData }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SubscribeVehicleDataResponse.js b/lib/js/src/rpc/messages/SubscribeVehicleDataResponse.js new file mode 100644 index 00000000..9189ccee --- /dev/null +++ b/lib/js/src/rpc/messages/SubscribeVehicleDataResponse.js @@ -0,0 +1,572 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; +import { VehicleDataResult } from '../structs/VehicleDataResult.js'; + +class SubscribeVehicleDataResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SubscribeVehicleData); + } + + /** + * @param {VehicleDataResult} gps - See GPSData + * @return {SubscribeVehicleDataResponse} + */ + setGps (gps) { + this.validateType(VehicleDataResult, gps); + this.setParameter(SubscribeVehicleDataResponse.KEY_GPS, gps); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getGps () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_GPS); + } + + /** + * @param {VehicleDataResult} speed - The vehicle speed in kilometers per hour + * @return {SubscribeVehicleDataResponse} + */ + setSpeed (speed) { + this.validateType(VehicleDataResult, speed); + this.setParameter(SubscribeVehicleDataResponse.KEY_SPEED, speed); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getSpeed () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_SPEED); + } + + /** + * @param {VehicleDataResult} rpm - The number of revolutions per minute of the engine + * @return {SubscribeVehicleDataResponse} + */ + setRpm (rpm) { + this.validateType(VehicleDataResult, rpm); + this.setParameter(SubscribeVehicleDataResponse.KEY_RPM, rpm); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getRpm () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_RPM); + } + + /** + * @param {VehicleDataResult} level - The fuel level in the tank (percentage) + * @return {SubscribeVehicleDataResponse} + */ + setFuelLevel (level) { + this.validateType(VehicleDataResult, level); + this.setParameter(SubscribeVehicleDataResponse.KEY_FUEL_LEVEL, level); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getFuelLevel () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_FUEL_LEVEL); + } + + /** + * @param {VehicleDataResult} level_state - The fuel level state + * @return {SubscribeVehicleDataResponse} + */ + setFuelLevel_State (level_state) { + this.validateType(VehicleDataResult, level_state); + this.setParameter(SubscribeVehicleDataResponse.KEY_FUEL_LEVEL_STATE, level_state); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getFuelLevel_State () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_FUEL_LEVEL_STATE); + } + + /** + * @param {VehicleDataResult} consumption - The instantaneous fuel consumption in microlitres + * @return {SubscribeVehicleDataResponse} + */ + setInstantFuelConsumption (consumption) { + this.validateType(VehicleDataResult, consumption); + this.setParameter(SubscribeVehicleDataResponse.KEY_INSTANT_FUEL_CONSUMPTION, consumption); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getInstantFuelConsumption () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_INSTANT_FUEL_CONSUMPTION); + } + + /** + * @param {VehicleDataResult} range - The estimate range in KM the vehicle can travel based on fuel level and + * consumption + * @return {SubscribeVehicleDataResponse} + */ + setFuelRange (range) { + this.validateType(VehicleDataResult, range); + this.setParameter(SubscribeVehicleDataResponse.KEY_FUEL_RANGE, range); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getFuelRange () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_FUEL_RANGE); + } + + /** + * @param {VehicleDataResult} temperature - The external temperature in degrees celsius. + * @return {SubscribeVehicleDataResponse} + */ + setExternalTemperature (temperature) { + this.validateType(VehicleDataResult, temperature); + this.setParameter(SubscribeVehicleDataResponse.KEY_EXTERNAL_TEMPERATURE, temperature); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getExternalTemperature () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_EXTERNAL_TEMPERATURE); + } + + /** + * @param {VehicleDataResult} signal - See TurnSignal + * @return {SubscribeVehicleDataResponse} + */ + setTurnSignal (signal) { + this.validateType(VehicleDataResult, signal); + this.setParameter(SubscribeVehicleDataResponse.KEY_TURN_SIGNAL, signal); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getTurnSignal () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_TURN_SIGNAL); + } + + /** + * @param {VehicleDataResult} prndl - See PRNDL + * @return {SubscribeVehicleDataResponse} + */ + setPrndl (prndl) { + this.validateType(VehicleDataResult, prndl); + this.setParameter(SubscribeVehicleDataResponse.KEY_PRNDL, prndl); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getPrndl () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_PRNDL); + } + + /** + * @param {VehicleDataResult} pressure - See TireStatus + * @return {SubscribeVehicleDataResponse} + */ + setTirePressure (pressure) { + this.validateType(VehicleDataResult, pressure); + this.setParameter(SubscribeVehicleDataResponse.KEY_TIRE_PRESSURE, pressure); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getTirePressure () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_TIRE_PRESSURE); + } + + /** + * @param {VehicleDataResult} odometer - Odometer in km + * @return {SubscribeVehicleDataResponse} + */ + setOdometer (odometer) { + this.validateType(VehicleDataResult, odometer); + this.setParameter(SubscribeVehicleDataResponse.KEY_ODOMETER, odometer); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getOdometer () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_ODOMETER); + } + + /** + * @param {VehicleDataResult} status - The status of the seat belts + * @return {SubscribeVehicleDataResponse} + */ + setBeltStatus (status) { + this.validateType(VehicleDataResult, status); + this.setParameter(SubscribeVehicleDataResponse.KEY_BELT_STATUS, status); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getBeltStatus () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_BELT_STATUS); + } + + /** + * @param {VehicleDataResult} information - The body information including power modes + * @return {SubscribeVehicleDataResponse} + */ + setBodyInformation (information) { + this.validateType(VehicleDataResult, information); + this.setParameter(SubscribeVehicleDataResponse.KEY_BODY_INFORMATION, information); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getBodyInformation () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_BODY_INFORMATION); + } + + /** + * @param {VehicleDataResult} status - The device status including signal and battery strength + * @return {SubscribeVehicleDataResponse} + */ + setDeviceStatus (status) { + this.validateType(VehicleDataResult, status); + this.setParameter(SubscribeVehicleDataResponse.KEY_DEVICE_STATUS, status); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getDeviceStatus () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_DEVICE_STATUS); + } + + /** + * @param {VehicleDataResult} braking - The status of the brake pedal + * @return {SubscribeVehicleDataResponse} + */ + setDriverBraking (braking) { + this.validateType(VehicleDataResult, braking); + this.setParameter(SubscribeVehicleDataResponse.KEY_DRIVER_BRAKING, braking); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getDriverBraking () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_DRIVER_BRAKING); + } + + /** + * @param {VehicleDataResult} status - The status of the wipers + * @return {SubscribeVehicleDataResponse} + */ + setWiperStatus (status) { + this.validateType(VehicleDataResult, status); + this.setParameter(SubscribeVehicleDataResponse.KEY_WIPER_STATUS, status); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getWiperStatus () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_WIPER_STATUS); + } + + /** + * @param {VehicleDataResult} status - Status of the head lamps + * @return {SubscribeVehicleDataResponse} + */ + setHeadLampStatus (status) { + this.validateType(VehicleDataResult, status); + this.setParameter(SubscribeVehicleDataResponse.KEY_HEAD_LAMP_STATUS, status); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getHeadLampStatus () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_HEAD_LAMP_STATUS); + } + + /** + * @param {VehicleDataResult} torque - Torque value for engine (in Nm) on non-diesel variants + * @return {SubscribeVehicleDataResponse} + */ + setEngineTorque (torque) { + this.validateType(VehicleDataResult, torque); + this.setParameter(SubscribeVehicleDataResponse.KEY_ENGINE_TORQUE, torque); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getEngineTorque () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_ENGINE_TORQUE); + } + + /** + * @param {VehicleDataResult} position - Accelerator pedal position (percentage depressed) + * @return {SubscribeVehicleDataResponse} + */ + setAccPedalPosition (position) { + this.validateType(VehicleDataResult, position); + this.setParameter(SubscribeVehicleDataResponse.KEY_ACC_PEDAL_POSITION, position); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getAccPedalPosition () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_ACC_PEDAL_POSITION); + } + + /** + * @param {VehicleDataResult} angle - Current angle of the steering wheel (in deg) + * @return {SubscribeVehicleDataResponse} + */ + setSteeringWheelAngle (angle) { + this.validateType(VehicleDataResult, angle); + this.setParameter(SubscribeVehicleDataResponse.KEY_STEERING_WHEEL_ANGLE, angle); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getSteeringWheelAngle () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_STEERING_WHEEL_ANGLE); + } + + /** + * @param {VehicleDataResult} life - The estimated percentage of remaining oil life of the engine. + * @return {SubscribeVehicleDataResponse} + */ + setEngineOilLife (life) { + this.validateType(VehicleDataResult, life); + this.setParameter(SubscribeVehicleDataResponse.KEY_ENGINE_OIL_LIFE, life); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getEngineOilLife () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_ENGINE_OIL_LIFE); + } + + /** + * @param {VehicleDataResult} status - The status of the park brake as provided by Electric Park Brake (EPB) system. + * @return {SubscribeVehicleDataResponse} + */ + setElectronicParkBrakeStatus (status) { + this.validateType(VehicleDataResult, status); + this.setParameter(SubscribeVehicleDataResponse.KEY_ELECTRONIC_PARK_BRAKE_STATUS, status); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getElectronicParkBrakeStatus () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_ELECTRONIC_PARK_BRAKE_STATUS); + } + + /** + * @param {VehicleDataResult} id - Parameter used by cloud apps to identify a head unit + * @return {SubscribeVehicleDataResponse} + */ + setCloudAppVehicleID (id) { + this.validateType(VehicleDataResult, id); + this.setParameter(SubscribeVehicleDataResponse.KEY_CLOUD_APP_VEHICLE_ID, id); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getCloudAppVehicleID () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_CLOUD_APP_VEHICLE_ID); + } + + /** + * @param {VehicleDataResult} info - Emergency Call notification and confirmation data + * @return {SubscribeVehicleDataResponse} + */ + setECallInfo (info) { + this.validateType(VehicleDataResult, info); + this.setParameter(SubscribeVehicleDataResponse.KEY_E_CALL_INFO, info); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getECallInfo () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_E_CALL_INFO); + } + + /** + * @param {VehicleDataResult} status - The status of the air bags + * @return {SubscribeVehicleDataResponse} + */ + setAirbagStatus (status) { + this.validateType(VehicleDataResult, status); + this.setParameter(SubscribeVehicleDataResponse.KEY_AIRBAG_STATUS, status); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getAirbagStatus () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_AIRBAG_STATUS); + } + + /** + * @param {VehicleDataResult} event - Information related to an emergency event (and if it occurred) + * @return {SubscribeVehicleDataResponse} + */ + setEmergencyEvent (event) { + this.validateType(VehicleDataResult, event); + this.setParameter(SubscribeVehicleDataResponse.KEY_EMERGENCY_EVENT, event); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getEmergencyEvent () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_EMERGENCY_EVENT); + } + + /** + * @param {VehicleDataResult} modes - The status modes of the cluster + * @return {SubscribeVehicleDataResponse} + */ + setClusterModes (modes) { + this.validateType(VehicleDataResult, modes); + this.setParameter(SubscribeVehicleDataResponse.KEY_CLUSTER_MODES, modes); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getClusterModes () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_CLUSTER_MODES); + } + + /** + * @param {VehicleDataResult} key - Information related to the MyKey feature + * @return {SubscribeVehicleDataResponse} + */ + setMyKey (key) { + this.validateType(VehicleDataResult, key); + this.setParameter(SubscribeVehicleDataResponse.KEY_MY_KEY, key); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getMyKey () { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_MY_KEY); + } +} + +SubscribeVehicleDataResponse.KEY_GPS = 'gps'; +SubscribeVehicleDataResponse.KEY_SPEED = 'speed'; +SubscribeVehicleDataResponse.KEY_RPM = 'rpm'; +SubscribeVehicleDataResponse.KEY_FUEL_LEVEL = 'fuelLevel'; +SubscribeVehicleDataResponse.KEY_FUEL_LEVEL_STATE = 'fuelLevel_State'; +SubscribeVehicleDataResponse.KEY_INSTANT_FUEL_CONSUMPTION = 'instantFuelConsumption'; +SubscribeVehicleDataResponse.KEY_FUEL_RANGE = 'fuelRange'; +SubscribeVehicleDataResponse.KEY_EXTERNAL_TEMPERATURE = 'externalTemperature'; +SubscribeVehicleDataResponse.KEY_TURN_SIGNAL = 'turnSignal'; +SubscribeVehicleDataResponse.KEY_PRNDL = 'prndl'; +SubscribeVehicleDataResponse.KEY_TIRE_PRESSURE = 'tirePressure'; +SubscribeVehicleDataResponse.KEY_ODOMETER = 'odometer'; +SubscribeVehicleDataResponse.KEY_BELT_STATUS = 'beltStatus'; +SubscribeVehicleDataResponse.KEY_BODY_INFORMATION = 'bodyInformation'; +SubscribeVehicleDataResponse.KEY_DEVICE_STATUS = 'deviceStatus'; +SubscribeVehicleDataResponse.KEY_DRIVER_BRAKING = 'driverBraking'; +SubscribeVehicleDataResponse.KEY_WIPER_STATUS = 'wiperStatus'; +SubscribeVehicleDataResponse.KEY_HEAD_LAMP_STATUS = 'headLampStatus'; +SubscribeVehicleDataResponse.KEY_ENGINE_TORQUE = 'engineTorque'; +SubscribeVehicleDataResponse.KEY_ACC_PEDAL_POSITION = 'accPedalPosition'; +SubscribeVehicleDataResponse.KEY_STEERING_WHEEL_ANGLE = 'steeringWheelAngle'; +SubscribeVehicleDataResponse.KEY_ENGINE_OIL_LIFE = 'engineOilLife'; +SubscribeVehicleDataResponse.KEY_ELECTRONIC_PARK_BRAKE_STATUS = 'electronicParkBrakeStatus'; +SubscribeVehicleDataResponse.KEY_CLOUD_APP_VEHICLE_ID = 'cloudAppVehicleID'; +SubscribeVehicleDataResponse.KEY_E_CALL_INFO = 'eCallInfo'; +SubscribeVehicleDataResponse.KEY_AIRBAG_STATUS = 'airbagStatus'; +SubscribeVehicleDataResponse.KEY_EMERGENCY_EVENT = 'emergencyEvent'; +SubscribeVehicleDataResponse.KEY_CLUSTER_MODES = 'clusterModes'; +SubscribeVehicleDataResponse.KEY_MY_KEY = 'myKey'; + +export { SubscribeVehicleDataResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SubscribeWayPoints.js b/lib/js/src/rpc/messages/SubscribeWayPoints.js new file mode 100644 index 00000000..309be2c3 --- /dev/null +++ b/lib/js/src/rpc/messages/SubscribeWayPoints.js @@ -0,0 +1,51 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * To subscribe in getting changes for Waypoints/destinations + */ +class SubscribeWayPoints extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SubscribeWayPoints); + } +} + + +export { SubscribeWayPoints }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SubscribeWayPointsResponse.js b/lib/js/src/rpc/messages/SubscribeWayPointsResponse.js new file mode 100644 index 00000000..d2100e99 --- /dev/null +++ b/lib/js/src/rpc/messages/SubscribeWayPointsResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class SubscribeWayPointsResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SubscribeWayPoints); + } +} + + +export { SubscribeWayPointsResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SystemRequest.js b/lib/js/src/rpc/messages/SystemRequest.js new file mode 100644 index 00000000..094eff86 --- /dev/null +++ b/lib/js/src/rpc/messages/SystemRequest.js @@ -0,0 +1,107 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { RequestType } from '../enums/RequestType.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * An asynchronous request from the device; binary data can be included in hybrid part of message for some requests + * (such as HTTP, Proprietary, or Authentication requests) + */ +class SystemRequest extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SystemRequest); + } + + /** + * @param {RequestType} type - The type of system request. Note that Proprietary requests should forward the binary + * data to the known proprietary module on the system. + * @return {SystemRequest} + */ + setRequestType (type) { + this.validateType(RequestType, type); + this.setParameter(SystemRequest.KEY_REQUEST_TYPE, type); + return this; + } + + /** + * @return {RequestType} + */ + getRequestType () { + return this.getObject(RequestType, SystemRequest.KEY_REQUEST_TYPE); + } + + /** + * @param {String} type - This parameter is filled for supporting OEM proprietary data exchanges. + * @return {SystemRequest} + */ + setRequestSubType (type) { + this.setParameter(SystemRequest.KEY_REQUEST_SUB_TYPE, type); + return this; + } + + /** + * @return {String} + */ + getRequestSubType () { + return this.getParameter(SystemRequest.KEY_REQUEST_SUB_TYPE); + } + + /** + * @param {String} name - Filename of HTTP data to store in predefined system staging area. Mandatory if requestType + * is HTTP. PROPRIETARY requestType should ignore this parameter. + * @return {SystemRequest} + */ + setFileName (name) { + this.setParameter(SystemRequest.KEY_FILE_NAME, name); + return this; + } + + /** + * @return {String} + */ + getFileName () { + return this.getParameter(SystemRequest.KEY_FILE_NAME); + } +} + +SystemRequest.KEY_REQUEST_TYPE = 'requestType'; +SystemRequest.KEY_REQUEST_SUB_TYPE = 'requestSubType'; +SystemRequest.KEY_FILE_NAME = 'fileName'; + +export { SystemRequest }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/SystemRequestResponse.js b/lib/js/src/rpc/messages/SystemRequestResponse.js new file mode 100644 index 00000000..2bb1c832 --- /dev/null +++ b/lib/js/src/rpc/messages/SystemRequestResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class SystemRequestResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.SystemRequest); + } +} + + +export { SystemRequestResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/UnpublishAppService.js b/lib/js/src/rpc/messages/UnpublishAppService.js new file mode 100644 index 00000000..0fcb69b1 --- /dev/null +++ b/lib/js/src/rpc/messages/UnpublishAppService.js @@ -0,0 +1,68 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Unpublish an existing service published by this application. + */ +class UnpublishAppService extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.UnpublishAppService); + } + + /** + * @param {String} id - The ID of the service to be unpublished. + * @return {UnpublishAppService} + */ + setServiceID (id) { + this.setParameter(UnpublishAppService.KEY_SERVICE_ID, id); + return this; + } + + /** + * @return {String} + */ + getServiceID () { + return this.getParameter(UnpublishAppService.KEY_SERVICE_ID); + } +} + +UnpublishAppService.KEY_SERVICE_ID = 'serviceID'; + +export { UnpublishAppService }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/UnpublishAppServiceResponse.js b/lib/js/src/rpc/messages/UnpublishAppServiceResponse.js new file mode 100644 index 00000000..6ab57439 --- /dev/null +++ b/lib/js/src/rpc/messages/UnpublishAppServiceResponse.js @@ -0,0 +1,51 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +/** + * The response to UnpublishAppService + */ +class UnpublishAppServiceResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.UnpublishAppService); + } +} + + +export { UnpublishAppServiceResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/UnregisterAppInterface.js b/lib/js/src/rpc/messages/UnregisterAppInterface.js index 0116a608..c754d6cb 100644 --- a/lib/js/src/rpc/messages/UnregisterAppInterface.js +++ b/lib/js/src/rpc/messages/UnregisterAppInterface.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -33,10 +34,15 @@ import { RpcRequest } from '../RpcRequest.js'; import { FunctionID } from '../enums/FunctionID.js'; +/** + * Closes an interface from a mobile application. After unregisterAppInterface, no commands other than + * registerAppInterface will be accepted/executed. Will fail, if no registerAppInterface was completed successfully + * before. + */ class UnregisterAppInterface extends RpcRequest { /** - * @constructor - */ + * @constructor + */ constructor (store) { super(store); this.setFunctionName(FunctionID.UnregisterAppInterface); @@ -44,4 +50,4 @@ class UnregisterAppInterface extends RpcRequest { } -export { UnregisterAppInterface }; +export { UnregisterAppInterface }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/UnregisterAppInterfaceResponse.js b/lib/js/src/rpc/messages/UnregisterAppInterfaceResponse.js index cb785934..983550ab 100644 --- a/lib/js/src/rpc/messages/UnregisterAppInterfaceResponse.js +++ b/lib/js/src/rpc/messages/UnregisterAppInterfaceResponse.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -30,17 +31,18 @@ * POSSIBILITY OF SUCH DAMAGE. */ -import { RpcResponse } from '../RpcResponse.js'; import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; class UnregisterAppInterfaceResponse extends RpcResponse { /** - * @constructor - */ + * @constructor + */ constructor (store) { super(store); this.setFunctionName(FunctionID.UnregisterAppInterface); } } -export { UnregisterAppInterfaceResponse }; + +export { UnregisterAppInterfaceResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/UnsubscribeButton.js b/lib/js/src/rpc/messages/UnsubscribeButton.js new file mode 100644 index 00000000..d4dd7af9 --- /dev/null +++ b/lib/js/src/rpc/messages/UnsubscribeButton.js @@ -0,0 +1,70 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { ButtonName } from '../enums/ButtonName.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Unsubscribes from built-in HMI buttons. + */ +class UnsubscribeButton extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.UnsubscribeButton); + } + + /** + * @param {ButtonName} name - Name of the button to unsubscribe. + * @return {UnsubscribeButton} + */ + setButtonName (name) { + this.validateType(ButtonName, name); + this.setParameter(UnsubscribeButton.KEY_BUTTON_NAME, name); + return this; + } + + /** + * @return {ButtonName} + */ + getButtonName () { + return this.getObject(ButtonName, UnsubscribeButton.KEY_BUTTON_NAME); + } +} + +UnsubscribeButton.KEY_BUTTON_NAME = 'buttonName'; + +export { UnsubscribeButton }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/UnsubscribeButtonResponse.js b/lib/js/src/rpc/messages/UnsubscribeButtonResponse.js new file mode 100644 index 00000000..386b785c --- /dev/null +++ b/lib/js/src/rpc/messages/UnsubscribeButtonResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class UnsubscribeButtonResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.UnsubscribeButton); + } +} + + +export { UnsubscribeButtonResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/UnsubscribeVehicleData.js b/lib/js/src/rpc/messages/UnsubscribeVehicleData.js new file mode 100644 index 00000000..2bf5f92d --- /dev/null +++ b/lib/js/src/rpc/messages/UnsubscribeVehicleData.js @@ -0,0 +1,544 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * This function is used to unsubscribe the notifications from the subscribeVehicleData function. + */ +class UnsubscribeVehicleData extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.UnsubscribeVehicleData); + } + + /** + * @param {Boolean} gps - See GPSData + * @return {UnsubscribeVehicleData} + */ + setGps (gps) { + this.setParameter(UnsubscribeVehicleData.KEY_GPS, gps); + return this; + } + + /** + * @return {Boolean} + */ + getGps () { + return this.getParameter(UnsubscribeVehicleData.KEY_GPS); + } + + /** + * @param {Boolean} speed - The vehicle speed in kilometers per hour + * @return {UnsubscribeVehicleData} + */ + setSpeed (speed) { + this.setParameter(UnsubscribeVehicleData.KEY_SPEED, speed); + return this; + } + + /** + * @return {Boolean} + */ + getSpeed () { + return this.getParameter(UnsubscribeVehicleData.KEY_SPEED); + } + + /** + * @param {Boolean} rpm - The number of revolutions per minute of the engine + * @return {UnsubscribeVehicleData} + */ + setRpm (rpm) { + this.setParameter(UnsubscribeVehicleData.KEY_RPM, rpm); + return this; + } + + /** + * @return {Boolean} + */ + getRpm () { + return this.getParameter(UnsubscribeVehicleData.KEY_RPM); + } + + /** + * @param {Boolean} level - The fuel level in the tank (percentage) + * @return {UnsubscribeVehicleData} + */ + setFuelLevel (level) { + this.setParameter(UnsubscribeVehicleData.KEY_FUEL_LEVEL, level); + return this; + } + + /** + * @return {Boolean} + */ + getFuelLevel () { + return this.getParameter(UnsubscribeVehicleData.KEY_FUEL_LEVEL); + } + + /** + * @param {Boolean} level_state - The fuel level state + * @return {UnsubscribeVehicleData} + */ + setFuelLevel_State (level_state) { + this.setParameter(UnsubscribeVehicleData.KEY_FUEL_LEVEL_STATE, level_state); + return this; + } + + /** + * @return {Boolean} + */ + getFuelLevel_State () { + return this.getParameter(UnsubscribeVehicleData.KEY_FUEL_LEVEL_STATE); + } + + /** + * @param {Boolean} consumption - The instantaneous fuel consumption in microlitres + * @return {UnsubscribeVehicleData} + */ + setInstantFuelConsumption (consumption) { + this.setParameter(UnsubscribeVehicleData.KEY_INSTANT_FUEL_CONSUMPTION, consumption); + return this; + } + + /** + * @return {Boolean} + */ + getInstantFuelConsumption () { + return this.getParameter(UnsubscribeVehicleData.KEY_INSTANT_FUEL_CONSUMPTION); + } + + /** + * @param {Boolean} range - The estimate range in KM the vehicle can travel based on fuel level and consumption + * @return {UnsubscribeVehicleData} + */ + setFuelRange (range) { + this.setParameter(UnsubscribeVehicleData.KEY_FUEL_RANGE, range); + return this; + } + + /** + * @return {Boolean} + */ + getFuelRange () { + return this.getParameter(UnsubscribeVehicleData.KEY_FUEL_RANGE); + } + + /** + * @param {Boolean} temperature - The external temperature in degrees celsius. + * @return {UnsubscribeVehicleData} + */ + setExternalTemperature (temperature) { + this.setParameter(UnsubscribeVehicleData.KEY_EXTERNAL_TEMPERATURE, temperature); + return this; + } + + /** + * @return {Boolean} + */ + getExternalTemperature () { + return this.getParameter(UnsubscribeVehicleData.KEY_EXTERNAL_TEMPERATURE); + } + + /** + * @param {Boolean} signal - See TurnSignal + * @return {UnsubscribeVehicleData} + */ + setTurnSignal (signal) { + this.setParameter(UnsubscribeVehicleData.KEY_TURN_SIGNAL, signal); + return this; + } + + /** + * @return {Boolean} + */ + getTurnSignal () { + return this.getParameter(UnsubscribeVehicleData.KEY_TURN_SIGNAL); + } + + /** + * @param {Boolean} prndl - See PRNDL + * @return {UnsubscribeVehicleData} + */ + setPrndl (prndl) { + this.setParameter(UnsubscribeVehicleData.KEY_PRNDL, prndl); + return this; + } + + /** + * @return {Boolean} + */ + getPrndl () { + return this.getParameter(UnsubscribeVehicleData.KEY_PRNDL); + } + + /** + * @param {Boolean} pressure - See TireStatus + * @return {UnsubscribeVehicleData} + */ + setTirePressure (pressure) { + this.setParameter(UnsubscribeVehicleData.KEY_TIRE_PRESSURE, pressure); + return this; + } + + /** + * @return {Boolean} + */ + getTirePressure () { + return this.getParameter(UnsubscribeVehicleData.KEY_TIRE_PRESSURE); + } + + /** + * @param {Boolean} odometer - Odometer in km + * @return {UnsubscribeVehicleData} + */ + setOdometer (odometer) { + this.setParameter(UnsubscribeVehicleData.KEY_ODOMETER, odometer); + return this; + } + + /** + * @return {Boolean} + */ + getOdometer () { + return this.getParameter(UnsubscribeVehicleData.KEY_ODOMETER); + } + + /** + * @param {Boolean} status - The status of the seat belts + * @return {UnsubscribeVehicleData} + */ + setBeltStatus (status) { + this.setParameter(UnsubscribeVehicleData.KEY_BELT_STATUS, status); + return this; + } + + /** + * @return {Boolean} + */ + getBeltStatus () { + return this.getParameter(UnsubscribeVehicleData.KEY_BELT_STATUS); + } + + /** + * @param {Boolean} information - The body information including power modes + * @return {UnsubscribeVehicleData} + */ + setBodyInformation (information) { + this.setParameter(UnsubscribeVehicleData.KEY_BODY_INFORMATION, information); + return this; + } + + /** + * @return {Boolean} + */ + getBodyInformation () { + return this.getParameter(UnsubscribeVehicleData.KEY_BODY_INFORMATION); + } + + /** + * @param {Boolean} status - The device status including signal and battery strength + * @return {UnsubscribeVehicleData} + */ + setDeviceStatus (status) { + this.setParameter(UnsubscribeVehicleData.KEY_DEVICE_STATUS, status); + return this; + } + + /** + * @return {Boolean} + */ + getDeviceStatus () { + return this.getParameter(UnsubscribeVehicleData.KEY_DEVICE_STATUS); + } + + /** + * @param {Boolean} braking - The status of the brake pedal + * @return {UnsubscribeVehicleData} + */ + setDriverBraking (braking) { + this.setParameter(UnsubscribeVehicleData.KEY_DRIVER_BRAKING, braking); + return this; + } + + /** + * @return {Boolean} + */ + getDriverBraking () { + return this.getParameter(UnsubscribeVehicleData.KEY_DRIVER_BRAKING); + } + + /** + * @param {Boolean} status - The status of the wipers + * @return {UnsubscribeVehicleData} + */ + setWiperStatus (status) { + this.setParameter(UnsubscribeVehicleData.KEY_WIPER_STATUS, status); + return this; + } + + /** + * @return {Boolean} + */ + getWiperStatus () { + return this.getParameter(UnsubscribeVehicleData.KEY_WIPER_STATUS); + } + + /** + * @param {Boolean} status - Status of the head lamps + * @return {UnsubscribeVehicleData} + */ + setHeadLampStatus (status) { + this.setParameter(UnsubscribeVehicleData.KEY_HEAD_LAMP_STATUS, status); + return this; + } + + /** + * @return {Boolean} + */ + getHeadLampStatus () { + return this.getParameter(UnsubscribeVehicleData.KEY_HEAD_LAMP_STATUS); + } + + /** + * @param {Boolean} torque - Torque value for engine (in Nm) on non-diesel variants + * @return {UnsubscribeVehicleData} + */ + setEngineTorque (torque) { + this.setParameter(UnsubscribeVehicleData.KEY_ENGINE_TORQUE, torque); + return this; + } + + /** + * @return {Boolean} + */ + getEngineTorque () { + return this.getParameter(UnsubscribeVehicleData.KEY_ENGINE_TORQUE); + } + + /** + * @param {Boolean} position - Accelerator pedal position (percentage depressed) + * @return {UnsubscribeVehicleData} + */ + setAccPedalPosition (position) { + this.setParameter(UnsubscribeVehicleData.KEY_ACC_PEDAL_POSITION, position); + return this; + } + + /** + * @return {Boolean} + */ + getAccPedalPosition () { + return this.getParameter(UnsubscribeVehicleData.KEY_ACC_PEDAL_POSITION); + } + + /** + * @param {Boolean} angle - Current angle of the steering wheel (in deg) + * @return {UnsubscribeVehicleData} + */ + setSteeringWheelAngle (angle) { + this.setParameter(UnsubscribeVehicleData.KEY_STEERING_WHEEL_ANGLE, angle); + return this; + } + + /** + * @return {Boolean} + */ + getSteeringWheelAngle () { + return this.getParameter(UnsubscribeVehicleData.KEY_STEERING_WHEEL_ANGLE); + } + + /** + * @param {Boolean} life - The estimated percentage of remaining oil life of the engine. + * @return {UnsubscribeVehicleData} + */ + setEngineOilLife (life) { + this.setParameter(UnsubscribeVehicleData.KEY_ENGINE_OIL_LIFE, life); + return this; + } + + /** + * @return {Boolean} + */ + getEngineOilLife () { + return this.getParameter(UnsubscribeVehicleData.KEY_ENGINE_OIL_LIFE); + } + + /** + * @param {Boolean} status - The status of the park brake as provided by Electric Park Brake (EPB) system. + * @return {UnsubscribeVehicleData} + */ + setElectronicParkBrakeStatus (status) { + this.setParameter(UnsubscribeVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS, status); + return this; + } + + /** + * @return {Boolean} + */ + getElectronicParkBrakeStatus () { + return this.getParameter(UnsubscribeVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS); + } + + /** + * @param {Boolean} id - Parameter used by cloud apps to identify a head unit + * @return {UnsubscribeVehicleData} + */ + setCloudAppVehicleID (id) { + this.setParameter(UnsubscribeVehicleData.KEY_CLOUD_APP_VEHICLE_ID, id); + return this; + } + + /** + * @return {Boolean} + */ + getCloudAppVehicleID () { + return this.getParameter(UnsubscribeVehicleData.KEY_CLOUD_APP_VEHICLE_ID); + } + + /** + * @param {Boolean} info - Emergency Call notification and confirmation data + * @return {UnsubscribeVehicleData} + */ + setECallInfo (info) { + this.setParameter(UnsubscribeVehicleData.KEY_E_CALL_INFO, info); + return this; + } + + /** + * @return {Boolean} + */ + getECallInfo () { + return this.getParameter(UnsubscribeVehicleData.KEY_E_CALL_INFO); + } + + /** + * @param {Boolean} status - The status of the air bags + * @return {UnsubscribeVehicleData} + */ + setAirbagStatus (status) { + this.setParameter(UnsubscribeVehicleData.KEY_AIRBAG_STATUS, status); + return this; + } + + /** + * @return {Boolean} + */ + getAirbagStatus () { + return this.getParameter(UnsubscribeVehicleData.KEY_AIRBAG_STATUS); + } + + /** + * @param {Boolean} event - Information related to an emergency event (and if it occurred) + * @return {UnsubscribeVehicleData} + */ + setEmergencyEvent (event) { + this.setParameter(UnsubscribeVehicleData.KEY_EMERGENCY_EVENT, event); + return this; + } + + /** + * @return {Boolean} + */ + getEmergencyEvent () { + return this.getParameter(UnsubscribeVehicleData.KEY_EMERGENCY_EVENT); + } + + /** + * @param {Boolean} status - The status modes of the cluster + * @return {UnsubscribeVehicleData} + */ + setClusterModeStatus (status) { + this.setParameter(UnsubscribeVehicleData.KEY_CLUSTER_MODE_STATUS, status); + return this; + } + + /** + * @return {Boolean} + */ + getClusterModeStatus () { + return this.getParameter(UnsubscribeVehicleData.KEY_CLUSTER_MODE_STATUS); + } + + /** + * @param {Boolean} key - Information related to the MyKey feature + * @return {UnsubscribeVehicleData} + */ + setMyKey (key) { + this.setParameter(UnsubscribeVehicleData.KEY_MY_KEY, key); + return this; + } + + /** + * @return {Boolean} + */ + getMyKey () { + return this.getParameter(UnsubscribeVehicleData.KEY_MY_KEY); + } +} + +UnsubscribeVehicleData.KEY_GPS = 'gps'; +UnsubscribeVehicleData.KEY_SPEED = 'speed'; +UnsubscribeVehicleData.KEY_RPM = 'rpm'; +UnsubscribeVehicleData.KEY_FUEL_LEVEL = 'fuelLevel'; +UnsubscribeVehicleData.KEY_FUEL_LEVEL_STATE = 'fuelLevel_State'; +UnsubscribeVehicleData.KEY_INSTANT_FUEL_CONSUMPTION = 'instantFuelConsumption'; +UnsubscribeVehicleData.KEY_FUEL_RANGE = 'fuelRange'; +UnsubscribeVehicleData.KEY_EXTERNAL_TEMPERATURE = 'externalTemperature'; +UnsubscribeVehicleData.KEY_TURN_SIGNAL = 'turnSignal'; +UnsubscribeVehicleData.KEY_PRNDL = 'prndl'; +UnsubscribeVehicleData.KEY_TIRE_PRESSURE = 'tirePressure'; +UnsubscribeVehicleData.KEY_ODOMETER = 'odometer'; +UnsubscribeVehicleData.KEY_BELT_STATUS = 'beltStatus'; +UnsubscribeVehicleData.KEY_BODY_INFORMATION = 'bodyInformation'; +UnsubscribeVehicleData.KEY_DEVICE_STATUS = 'deviceStatus'; +UnsubscribeVehicleData.KEY_DRIVER_BRAKING = 'driverBraking'; +UnsubscribeVehicleData.KEY_WIPER_STATUS = 'wiperStatus'; +UnsubscribeVehicleData.KEY_HEAD_LAMP_STATUS = 'headLampStatus'; +UnsubscribeVehicleData.KEY_ENGINE_TORQUE = 'engineTorque'; +UnsubscribeVehicleData.KEY_ACC_PEDAL_POSITION = 'accPedalPosition'; +UnsubscribeVehicleData.KEY_STEERING_WHEEL_ANGLE = 'steeringWheelAngle'; +UnsubscribeVehicleData.KEY_ENGINE_OIL_LIFE = 'engineOilLife'; +UnsubscribeVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS = 'electronicParkBrakeStatus'; +UnsubscribeVehicleData.KEY_CLOUD_APP_VEHICLE_ID = 'cloudAppVehicleID'; +UnsubscribeVehicleData.KEY_E_CALL_INFO = 'eCallInfo'; +UnsubscribeVehicleData.KEY_AIRBAG_STATUS = 'airbagStatus'; +UnsubscribeVehicleData.KEY_EMERGENCY_EVENT = 'emergencyEvent'; +UnsubscribeVehicleData.KEY_CLUSTER_MODE_STATUS = 'clusterModeStatus'; +UnsubscribeVehicleData.KEY_MY_KEY = 'myKey'; + +export { UnsubscribeVehicleData }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/UnsubscribeVehicleDataResponse.js b/lib/js/src/rpc/messages/UnsubscribeVehicleDataResponse.js new file mode 100644 index 00000000..f538f055 --- /dev/null +++ b/lib/js/src/rpc/messages/UnsubscribeVehicleDataResponse.js @@ -0,0 +1,572 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; +import { VehicleDataResult } from '../structs/VehicleDataResult.js'; + +class UnsubscribeVehicleDataResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.UnsubscribeVehicleData); + } + + /** + * @param {VehicleDataResult} gps - See GPSData + * @return {UnsubscribeVehicleDataResponse} + */ + setGps (gps) { + this.validateType(VehicleDataResult, gps); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_GPS, gps); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getGps () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_GPS); + } + + /** + * @param {VehicleDataResult} speed - The vehicle speed in kilometers per hour + * @return {UnsubscribeVehicleDataResponse} + */ + setSpeed (speed) { + this.validateType(VehicleDataResult, speed); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_SPEED, speed); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getSpeed () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_SPEED); + } + + /** + * @param {VehicleDataResult} rpm - The number of revolutions per minute of the engine + * @return {UnsubscribeVehicleDataResponse} + */ + setRpm (rpm) { + this.validateType(VehicleDataResult, rpm); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_RPM, rpm); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getRpm () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_RPM); + } + + /** + * @param {VehicleDataResult} level - The fuel level in the tank (percentage) + * @return {UnsubscribeVehicleDataResponse} + */ + setFuelLevel (level) { + this.validateType(VehicleDataResult, level); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_FUEL_LEVEL, level); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getFuelLevel () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_FUEL_LEVEL); + } + + /** + * @param {VehicleDataResult} level_state - The fuel level state + * @return {UnsubscribeVehicleDataResponse} + */ + setFuelLevel_State (level_state) { + this.validateType(VehicleDataResult, level_state); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_FUEL_LEVEL_STATE, level_state); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getFuelLevel_State () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_FUEL_LEVEL_STATE); + } + + /** + * @param {VehicleDataResult} consumption - The instantaneous fuel consumption in microlitres + * @return {UnsubscribeVehicleDataResponse} + */ + setInstantFuelConsumption (consumption) { + this.validateType(VehicleDataResult, consumption); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_INSTANT_FUEL_CONSUMPTION, consumption); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getInstantFuelConsumption () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_INSTANT_FUEL_CONSUMPTION); + } + + /** + * @param {VehicleDataResult} range - The estimate range in KM the vehicle can travel based on fuel level and + * consumption + * @return {UnsubscribeVehicleDataResponse} + */ + setFuelRange (range) { + this.validateType(VehicleDataResult, range); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_FUEL_RANGE, range); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getFuelRange () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_FUEL_RANGE); + } + + /** + * @param {VehicleDataResult} temperature - The external temperature in degrees celsius + * @return {UnsubscribeVehicleDataResponse} + */ + setExternalTemperature (temperature) { + this.validateType(VehicleDataResult, temperature); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_EXTERNAL_TEMPERATURE, temperature); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getExternalTemperature () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_EXTERNAL_TEMPERATURE); + } + + /** + * @param {VehicleDataResult} signal - See TurnSignal + * @return {UnsubscribeVehicleDataResponse} + */ + setTurnSignal (signal) { + this.validateType(VehicleDataResult, signal); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_TURN_SIGNAL, signal); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getTurnSignal () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_TURN_SIGNAL); + } + + /** + * @param {VehicleDataResult} prndl - See PRNDL + * @return {UnsubscribeVehicleDataResponse} + */ + setPrndl (prndl) { + this.validateType(VehicleDataResult, prndl); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_PRNDL, prndl); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getPrndl () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_PRNDL); + } + + /** + * @param {VehicleDataResult} pressure - See TireStatus + * @return {UnsubscribeVehicleDataResponse} + */ + setTirePressure (pressure) { + this.validateType(VehicleDataResult, pressure); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_TIRE_PRESSURE, pressure); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getTirePressure () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_TIRE_PRESSURE); + } + + /** + * @param {VehicleDataResult} odometer - Odometer in km + * @return {UnsubscribeVehicleDataResponse} + */ + setOdometer (odometer) { + this.validateType(VehicleDataResult, odometer); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_ODOMETER, odometer); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getOdometer () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_ODOMETER); + } + + /** + * @param {VehicleDataResult} status - The status of the seat belts + * @return {UnsubscribeVehicleDataResponse} + */ + setBeltStatus (status) { + this.validateType(VehicleDataResult, status); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_BELT_STATUS, status); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getBeltStatus () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_BELT_STATUS); + } + + /** + * @param {VehicleDataResult} information - The body information including power modes + * @return {UnsubscribeVehicleDataResponse} + */ + setBodyInformation (information) { + this.validateType(VehicleDataResult, information); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_BODY_INFORMATION, information); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getBodyInformation () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_BODY_INFORMATION); + } + + /** + * @param {VehicleDataResult} status - The device status including signal and battery strength + * @return {UnsubscribeVehicleDataResponse} + */ + setDeviceStatus (status) { + this.validateType(VehicleDataResult, status); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_DEVICE_STATUS, status); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getDeviceStatus () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_DEVICE_STATUS); + } + + /** + * @param {VehicleDataResult} braking - The status of the brake pedal + * @return {UnsubscribeVehicleDataResponse} + */ + setDriverBraking (braking) { + this.validateType(VehicleDataResult, braking); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_DRIVER_BRAKING, braking); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getDriverBraking () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_DRIVER_BRAKING); + } + + /** + * @param {VehicleDataResult} status - The status of the wipers + * @return {UnsubscribeVehicleDataResponse} + */ + setWiperStatus (status) { + this.validateType(VehicleDataResult, status); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_WIPER_STATUS, status); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getWiperStatus () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_WIPER_STATUS); + } + + /** + * @param {VehicleDataResult} status - Status of the head lamps + * @return {UnsubscribeVehicleDataResponse} + */ + setHeadLampStatus (status) { + this.validateType(VehicleDataResult, status); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_HEAD_LAMP_STATUS, status); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getHeadLampStatus () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_HEAD_LAMP_STATUS); + } + + /** + * @param {VehicleDataResult} torque - Torque value for engine (in Nm) on non-diesel variants + * @return {UnsubscribeVehicleDataResponse} + */ + setEngineTorque (torque) { + this.validateType(VehicleDataResult, torque); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_ENGINE_TORQUE, torque); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getEngineTorque () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_ENGINE_TORQUE); + } + + /** + * @param {VehicleDataResult} position - Accelerator pedal position (percentage depressed) + * @return {UnsubscribeVehicleDataResponse} + */ + setAccPedalPosition (position) { + this.validateType(VehicleDataResult, position); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_ACC_PEDAL_POSITION, position); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getAccPedalPosition () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_ACC_PEDAL_POSITION); + } + + /** + * @param {VehicleDataResult} angle - Current angle of the steering wheel (in deg) + * @return {UnsubscribeVehicleDataResponse} + */ + setSteeringWheelAngle (angle) { + this.validateType(VehicleDataResult, angle); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_STEERING_WHEEL_ANGLE, angle); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getSteeringWheelAngle () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_STEERING_WHEEL_ANGLE); + } + + /** + * @param {VehicleDataResult} life - The estimated percentage of remaining oil life of the engine. + * @return {UnsubscribeVehicleDataResponse} + */ + setEngineOilLife (life) { + this.validateType(VehicleDataResult, life); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_ENGINE_OIL_LIFE, life); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getEngineOilLife () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_ENGINE_OIL_LIFE); + } + + /** + * @param {VehicleDataResult} status - The status of the park brake as provided by Electric Park Brake (EPB) system. + * @return {UnsubscribeVehicleDataResponse} + */ + setElectronicParkBrakeStatus (status) { + this.validateType(VehicleDataResult, status); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_ELECTRONIC_PARK_BRAKE_STATUS, status); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getElectronicParkBrakeStatus () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_ELECTRONIC_PARK_BRAKE_STATUS); + } + + /** + * @param {VehicleDataResult} id - Parameter used by cloud apps to identify a head unit + * @return {UnsubscribeVehicleDataResponse} + */ + setCloudAppVehicleID (id) { + this.validateType(VehicleDataResult, id); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_CLOUD_APP_VEHICLE_ID, id); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getCloudAppVehicleID () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_CLOUD_APP_VEHICLE_ID); + } + + /** + * @param {VehicleDataResult} info - Emergency Call notification and confirmation data + * @return {UnsubscribeVehicleDataResponse} + */ + setECallInfo (info) { + this.validateType(VehicleDataResult, info); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_E_CALL_INFO, info); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getECallInfo () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_E_CALL_INFO); + } + + /** + * @param {VehicleDataResult} status - The status of the air bags + * @return {UnsubscribeVehicleDataResponse} + */ + setAirbagStatus (status) { + this.validateType(VehicleDataResult, status); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_AIRBAG_STATUS, status); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getAirbagStatus () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_AIRBAG_STATUS); + } + + /** + * @param {VehicleDataResult} event - Information related to an emergency event (and if it occurred) + * @return {UnsubscribeVehicleDataResponse} + */ + setEmergencyEvent (event) { + this.validateType(VehicleDataResult, event); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_EMERGENCY_EVENT, event); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getEmergencyEvent () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_EMERGENCY_EVENT); + } + + /** + * @param {VehicleDataResult} modes - The status modes of the cluster + * @return {UnsubscribeVehicleDataResponse} + */ + setClusterModes (modes) { + this.validateType(VehicleDataResult, modes); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_CLUSTER_MODES, modes); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getClusterModes () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_CLUSTER_MODES); + } + + /** + * @param {VehicleDataResult} key - Information related to the MyKey feature + * @return {UnsubscribeVehicleDataResponse} + */ + setMyKey (key) { + this.validateType(VehicleDataResult, key); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_MY_KEY, key); + return this; + } + + /** + * @return {VehicleDataResult} + */ + getMyKey () { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_MY_KEY); + } +} + +UnsubscribeVehicleDataResponse.KEY_GPS = 'gps'; +UnsubscribeVehicleDataResponse.KEY_SPEED = 'speed'; +UnsubscribeVehicleDataResponse.KEY_RPM = 'rpm'; +UnsubscribeVehicleDataResponse.KEY_FUEL_LEVEL = 'fuelLevel'; +UnsubscribeVehicleDataResponse.KEY_FUEL_LEVEL_STATE = 'fuelLevel_State'; +UnsubscribeVehicleDataResponse.KEY_INSTANT_FUEL_CONSUMPTION = 'instantFuelConsumption'; +UnsubscribeVehicleDataResponse.KEY_FUEL_RANGE = 'fuelRange'; +UnsubscribeVehicleDataResponse.KEY_EXTERNAL_TEMPERATURE = 'externalTemperature'; +UnsubscribeVehicleDataResponse.KEY_TURN_SIGNAL = 'turnSignal'; +UnsubscribeVehicleDataResponse.KEY_PRNDL = 'prndl'; +UnsubscribeVehicleDataResponse.KEY_TIRE_PRESSURE = 'tirePressure'; +UnsubscribeVehicleDataResponse.KEY_ODOMETER = 'odometer'; +UnsubscribeVehicleDataResponse.KEY_BELT_STATUS = 'beltStatus'; +UnsubscribeVehicleDataResponse.KEY_BODY_INFORMATION = 'bodyInformation'; +UnsubscribeVehicleDataResponse.KEY_DEVICE_STATUS = 'deviceStatus'; +UnsubscribeVehicleDataResponse.KEY_DRIVER_BRAKING = 'driverBraking'; +UnsubscribeVehicleDataResponse.KEY_WIPER_STATUS = 'wiperStatus'; +UnsubscribeVehicleDataResponse.KEY_HEAD_LAMP_STATUS = 'headLampStatus'; +UnsubscribeVehicleDataResponse.KEY_ENGINE_TORQUE = 'engineTorque'; +UnsubscribeVehicleDataResponse.KEY_ACC_PEDAL_POSITION = 'accPedalPosition'; +UnsubscribeVehicleDataResponse.KEY_STEERING_WHEEL_ANGLE = 'steeringWheelAngle'; +UnsubscribeVehicleDataResponse.KEY_ENGINE_OIL_LIFE = 'engineOilLife'; +UnsubscribeVehicleDataResponse.KEY_ELECTRONIC_PARK_BRAKE_STATUS = 'electronicParkBrakeStatus'; +UnsubscribeVehicleDataResponse.KEY_CLOUD_APP_VEHICLE_ID = 'cloudAppVehicleID'; +UnsubscribeVehicleDataResponse.KEY_E_CALL_INFO = 'eCallInfo'; +UnsubscribeVehicleDataResponse.KEY_AIRBAG_STATUS = 'airbagStatus'; +UnsubscribeVehicleDataResponse.KEY_EMERGENCY_EVENT = 'emergencyEvent'; +UnsubscribeVehicleDataResponse.KEY_CLUSTER_MODES = 'clusterModes'; +UnsubscribeVehicleDataResponse.KEY_MY_KEY = 'myKey'; + +export { UnsubscribeVehicleDataResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/UnsubscribeWayPoints.js b/lib/js/src/rpc/messages/UnsubscribeWayPoints.js new file mode 100644 index 00000000..919049c5 --- /dev/null +++ b/lib/js/src/rpc/messages/UnsubscribeWayPoints.js @@ -0,0 +1,51 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; + +/** + * Request to unsubscribe from WayPoints and Destination + */ +class UnsubscribeWayPoints extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.UnsubscribeWayPoints); + } +} + + +export { UnsubscribeWayPoints }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/UnsubscribeWayPointsResponse.js b/lib/js/src/rpc/messages/UnsubscribeWayPointsResponse.js new file mode 100644 index 00000000..72d0611a --- /dev/null +++ b/lib/js/src/rpc/messages/UnsubscribeWayPointsResponse.js @@ -0,0 +1,67 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { LocationDetails } from '../structs/LocationDetails.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class UnsubscribeWayPointsResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.UnsubscribeWayPoints); + } + + /** + * @param {LocationDetails[]} points - See LocationDetails + * @return {UnsubscribeWayPointsResponse} + */ + setWayPoints (points) { + this.validateType(LocationDetails, points, true); + this.setParameter(UnsubscribeWayPointsResponse.KEY_WAY_POINTS, points); + return this; + } + + /** + * @return {LocationDetails[]} + */ + getWayPoints () { + return this.getObject(LocationDetails, UnsubscribeWayPointsResponse.KEY_WAY_POINTS); + } +} + +UnsubscribeWayPointsResponse.KEY_WAY_POINTS = 'wayPoints'; + +export { UnsubscribeWayPointsResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/UpdateTurnList.js b/lib/js/src/rpc/messages/UpdateTurnList.js new file mode 100644 index 00000000..87daf9cc --- /dev/null +++ b/lib/js/src/rpc/messages/UpdateTurnList.js @@ -0,0 +1,86 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { Turn } from '../structs/Turn.js'; +import { RpcRequest } from '../RpcRequest.js'; +import { FunctionID } from '../enums/FunctionID.js'; +import { SoftButton } from '../structs/SoftButton.js'; + +class UpdateTurnList extends RpcRequest { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.UpdateTurnList); + } + + /** + * @param {Turn[]} list + * @return {UpdateTurnList} + */ + setTurnList (list) { + this.validateType(Turn, list, true); + this.setParameter(UpdateTurnList.KEY_TURN_LIST, list); + return this; + } + + /** + * @return {Turn[]} + */ + getTurnList () { + return this.getObject(Turn, UpdateTurnList.KEY_TURN_LIST); + } + + /** + * @param {SoftButton[]} buttons - If omitted on supported displays, app-defined SoftButton will be left blank. + * @return {UpdateTurnList} + */ + setSoftButtons (buttons) { + this.validateType(SoftButton, buttons, true); + this.setParameter(UpdateTurnList.KEY_SOFT_BUTTONS, buttons); + return this; + } + + /** + * @return {SoftButton[]} + */ + getSoftButtons () { + return this.getObject(SoftButton, UpdateTurnList.KEY_SOFT_BUTTONS); + } +} + +UpdateTurnList.KEY_TURN_LIST = 'turnList'; +UpdateTurnList.KEY_SOFT_BUTTONS = 'softButtons'; + +export { UpdateTurnList }; \ No newline at end of file diff --git a/lib/js/src/rpc/messages/UpdateTurnListResponse.js b/lib/js/src/rpc/messages/UpdateTurnListResponse.js new file mode 100644 index 00000000..788902a6 --- /dev/null +++ b/lib/js/src/rpc/messages/UpdateTurnListResponse.js @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { FunctionID } from '../enums/FunctionID.js'; +import { RpcResponse } from '../RpcResponse.js'; + +class UpdateTurnListResponse extends RpcResponse { + /** + * @constructor + */ + constructor (store) { + super(store); + this.setFunctionName(FunctionID.UpdateTurnList); + } +} + + +export { UpdateTurnListResponse }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/AirbagStatus.js b/lib/js/src/rpc/structs/AirbagStatus.js new file mode 100644 index 00000000..8f463b91 --- /dev/null +++ b/lib/js/src/rpc/structs/AirbagStatus.js @@ -0,0 +1,197 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { VehicleDataEventStatus } from '../enums/VehicleDataEventStatus.js'; + +class AirbagStatus extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsDrvBag_D_Ltchd". See VehicleDataEventStatus. + * @return {AirbagStatus} + */ + setDriverAirbagDeployed (deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(AirbagStatus.KEY_DRIVER_AIRBAG_DEPLOYED, deployed); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getDriverAirbagDeployed () { + return this.getObject(VehicleDataEventStatus, AirbagStatus.KEY_DRIVER_AIRBAG_DEPLOYED); + } + + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsDrvSideBag_D_Ltchd". See + * VehicleDataEventStatus. + * @return {AirbagStatus} + */ + setDriverSideAirbagDeployed (deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(AirbagStatus.KEY_DRIVER_SIDE_AIRBAG_DEPLOYED, deployed); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getDriverSideAirbagDeployed () { + return this.getObject(VehicleDataEventStatus, AirbagStatus.KEY_DRIVER_SIDE_AIRBAG_DEPLOYED); + } + + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsDrvCrtnBag_D_Ltchd". See + * VehicleDataEventStatus. + * @return {AirbagStatus} + */ + setDriverCurtainAirbagDeployed (deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(AirbagStatus.KEY_DRIVER_CURTAIN_AIRBAG_DEPLOYED, deployed); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getDriverCurtainAirbagDeployed () { + return this.getObject(VehicleDataEventStatus, AirbagStatus.KEY_DRIVER_CURTAIN_AIRBAG_DEPLOYED); + } + + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsPasBag_D_Ltchd". See VehicleDataEventStatus. + * @return {AirbagStatus} + */ + setPassengerAirbagDeployed (deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(AirbagStatus.KEY_PASSENGER_AIRBAG_DEPLOYED, deployed); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getPassengerAirbagDeployed () { + return this.getObject(VehicleDataEventStatus, AirbagStatus.KEY_PASSENGER_AIRBAG_DEPLOYED); + } + + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsPasCrtnBag_D_Ltchd". See + * VehicleDataEventStatus. + * @return {AirbagStatus} + */ + setPassengerCurtainAirbagDeployed (deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(AirbagStatus.KEY_PASSENGER_CURTAIN_AIRBAG_DEPLOYED, deployed); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getPassengerCurtainAirbagDeployed () { + return this.getObject(VehicleDataEventStatus, AirbagStatus.KEY_PASSENGER_CURTAIN_AIRBAG_DEPLOYED); + } + + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsKneeDrvBag_D_Ltchd". See + * VehicleDataEventStatus. + * @return {AirbagStatus} + */ + setDriverKneeAirbagDeployed (deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(AirbagStatus.KEY_DRIVER_KNEE_AIRBAG_DEPLOYED, deployed); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getDriverKneeAirbagDeployed () { + return this.getObject(VehicleDataEventStatus, AirbagStatus.KEY_DRIVER_KNEE_AIRBAG_DEPLOYED); + } + + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsPasSideBag_D_Ltchd". See + * VehicleDataEventStatus. + * @return {AirbagStatus} + */ + setPassengerSideAirbagDeployed (deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(AirbagStatus.KEY_PASSENGER_SIDE_AIRBAG_DEPLOYED, deployed); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getPassengerSideAirbagDeployed () { + return this.getObject(VehicleDataEventStatus, AirbagStatus.KEY_PASSENGER_SIDE_AIRBAG_DEPLOYED); + } + + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsKneePasBag_D_Ltchd". See + * VehicleDataEventStatus. + * @return {AirbagStatus} + */ + setPassengerKneeAirbagDeployed (deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(AirbagStatus.KEY_PASSENGER_KNEE_AIRBAG_DEPLOYED, deployed); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getPassengerKneeAirbagDeployed () { + return this.getObject(VehicleDataEventStatus, AirbagStatus.KEY_PASSENGER_KNEE_AIRBAG_DEPLOYED); + } +} + +AirbagStatus.KEY_DRIVER_AIRBAG_DEPLOYED = 'driverAirbagDeployed'; +AirbagStatus.KEY_DRIVER_SIDE_AIRBAG_DEPLOYED = 'driverSideAirbagDeployed'; +AirbagStatus.KEY_DRIVER_CURTAIN_AIRBAG_DEPLOYED = 'driverCurtainAirbagDeployed'; +AirbagStatus.KEY_PASSENGER_AIRBAG_DEPLOYED = 'passengerAirbagDeployed'; +AirbagStatus.KEY_PASSENGER_CURTAIN_AIRBAG_DEPLOYED = 'passengerCurtainAirbagDeployed'; +AirbagStatus.KEY_DRIVER_KNEE_AIRBAG_DEPLOYED = 'driverKneeAirbagDeployed'; +AirbagStatus.KEY_PASSENGER_SIDE_AIRBAG_DEPLOYED = 'passengerSideAirbagDeployed'; +AirbagStatus.KEY_PASSENGER_KNEE_AIRBAG_DEPLOYED = 'passengerKneeAirbagDeployed'; + +export { AirbagStatus }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/AppInfo.js b/lib/js/src/rpc/structs/AppInfo.js index c8745f29..6a3e25c3 100644 --- a/lib/js/src/rpc/structs/AppInfo.js +++ b/lib/js/src/rpc/structs/AppInfo.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -32,73 +33,80 @@ import { RpcStruct } from '../RpcStruct.js'; +/** + * Contains detailed information about the registered application. + */ class AppInfo extends RpcStruct { + /** + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {String} appDisplayName - * @return {AppInfo} - */ - setAppDisplayName (appDisplayName) { - this.setParameter(AppInfo.KEY_APP_DISPLAY_NAME, appDisplayName); + * @param {String} name - The name displayed for the mobile application on the mobile device (can differ from the + * app name set in the initial RAI request). + * @return {AppInfo} + */ + setAppDisplayName (name) { + this.setParameter(AppInfo.KEY_APP_DISPLAY_NAME, name); return this; } /** - * @return {String} - */ + * @return {String} + */ getAppDisplayName () { return this.getParameter(AppInfo.KEY_APP_DISPLAY_NAME); } - /** - * @param {String} appBundleID - * @return {AppInfo} - */ - setAppBundleID (appBundleID) { - this.setParameter(AppInfo.KEY_APP_BUNDLE_ID, appBundleID); + * @param {String} id - The AppBundleID of an iOS application or package name of the Android application. This + * supports App Launch strategies for each platform. + * @return {AppInfo} + */ + setAppBundleID (id) { + this.setParameter(AppInfo.KEY_APP_BUNDLE_ID, id); return this; } /** - * @return {String} - */ + * @return {String} + */ getAppBundleID () { return this.getParameter(AppInfo.KEY_APP_BUNDLE_ID); } - /** - * @param {String} appVersion - * @return {AppInfo} - */ - setAppVersion (appVersion) { - this.setParameter(AppInfo.KEY_APP_VERSION, appVersion); + * @param {String} version - Represents the build version number of this particular mobile app. + * @return {AppInfo} + */ + setAppVersion (version) { + this.setParameter(AppInfo.KEY_APP_VERSION, version); return this; } /** - * @return {String} - */ + * @return {String} + */ getAppVersion () { return this.getParameter(AppInfo.KEY_APP_VERSION); } /** - * @param {String} appIcon string of the app icon file name - * @return {AppInfo} - */ - setAppIcon (appIcon) { - this.setParameter(AppInfo.KEY_APP_ICON, appIcon); + * @param {String} icon - A file reference to the icon utilized by this app (simplifies the process of setting an + * app icon during app registration). + * @return {AppInfo} + */ + setAppIcon (icon) { + this.setParameter(AppInfo.KEY_APP_ICON, icon); return this; } /** - * @return {String} - */ + * @return {String} + */ getAppIcon () { return this.getParameter(AppInfo.KEY_APP_ICON); } @@ -109,4 +117,4 @@ AppInfo.KEY_APP_BUNDLE_ID = 'appBundleID'; AppInfo.KEY_APP_VERSION = 'appVersion'; AppInfo.KEY_APP_ICON = 'appIcon'; -export { AppInfo }; +export { AppInfo }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/AppServiceCapability.js b/lib/js/src/rpc/structs/AppServiceCapability.js new file mode 100644 index 00000000..4201a6dd --- /dev/null +++ b/lib/js/src/rpc/structs/AppServiceCapability.js @@ -0,0 +1,85 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { ServiceUpdateReason } from '../enums/ServiceUpdateReason.js'; +import { AppServiceRecord } from './AppServiceRecord.js'; + +class AppServiceCapability extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {ServiceUpdateReason} reason - Only included in OnSystemCapabilityUpdated. Update reason for service + * record. + * @return {AppServiceCapability} + */ + setUpdateReason (reason) { + this.validateType(ServiceUpdateReason, reason); + this.setParameter(AppServiceCapability.KEY_UPDATE_REASON, reason); + return this; + } + + /** + * @return {ServiceUpdateReason} + */ + getUpdateReason () { + return this.getObject(ServiceUpdateReason, AppServiceCapability.KEY_UPDATE_REASON); + } + + /** + * @param {AppServiceRecord} record - Service record for a specific app service provider + * @return {AppServiceCapability} + */ + setUpdatedAppServiceRecord (record) { + this.validateType(AppServiceRecord, record); + this.setParameter(AppServiceCapability.KEY_UPDATED_APP_SERVICE_RECORD, record); + return this; + } + + /** + * @return {AppServiceRecord} + */ + getUpdatedAppServiceRecord () { + return this.getObject(AppServiceRecord, AppServiceCapability.KEY_UPDATED_APP_SERVICE_RECORD); + } +} + +AppServiceCapability.KEY_UPDATE_REASON = 'updateReason'; +AppServiceCapability.KEY_UPDATED_APP_SERVICE_RECORD = 'updatedAppServiceRecord'; + +export { AppServiceCapability }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/AppServiceData.js b/lib/js/src/rpc/structs/AppServiceData.js new file mode 100644 index 00000000..3b9e9501 --- /dev/null +++ b/lib/js/src/rpc/structs/AppServiceData.js @@ -0,0 +1,143 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { NavigationServiceData } from './NavigationServiceData.js'; +import { MediaServiceData } from './MediaServiceData.js'; +import { WeatherServiceData } from './WeatherServiceData.js'; + +/** + * Contains all the current data of the app service. The serviceType will link to which of the service data objects are + * included in this object (e.g. if the service type is MEDIA, the mediaServiceData param should be included). + */ +class AppServiceData extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {String} type - The type of service that is to be offered by this app. See AppServiceType for known enum + * equivalent types. Parameter is a string to allow for new service types to be used by apps + * on older versions of SDL Core. + * @return {AppServiceData} + */ + setServiceType (type) { + this.setParameter(AppServiceData.KEY_SERVICE_TYPE, type); + return this; + } + + /** + * @return {String} + */ + getServiceType () { + return this.getParameter(AppServiceData.KEY_SERVICE_TYPE); + } + + /** + * @param {String} id + * @return {AppServiceData} + */ + setServiceID (id) { + this.setParameter(AppServiceData.KEY_SERVICE_ID, id); + return this; + } + + /** + * @return {String} + */ + getServiceID () { + return this.getParameter(AppServiceData.KEY_SERVICE_ID); + } + + /** + * @param {MediaServiceData} data - This data is related to what a media service should provide + * @return {AppServiceData} + */ + setMediaServiceData (data) { + this.validateType(MediaServiceData, data); + this.setParameter(AppServiceData.KEY_MEDIA_SERVICE_DATA, data); + return this; + } + + /** + * @return {MediaServiceData} + */ + getMediaServiceData () { + return this.getObject(MediaServiceData, AppServiceData.KEY_MEDIA_SERVICE_DATA); + } + + /** + * @param {WeatherServiceData} data - This data is related to what a weather service would provide + * @return {AppServiceData} + */ + setWeatherServiceData (data) { + this.validateType(WeatherServiceData, data); + this.setParameter(AppServiceData.KEY_WEATHER_SERVICE_DATA, data); + return this; + } + + /** + * @return {WeatherServiceData} + */ + getWeatherServiceData () { + return this.getObject(WeatherServiceData, AppServiceData.KEY_WEATHER_SERVICE_DATA); + } + + /** + * @param {NavigationServiceData} data - This data is related to what a navigation service would provide. + * @return {AppServiceData} + */ + setNavigationServiceData (data) { + this.validateType(NavigationServiceData, data); + this.setParameter(AppServiceData.KEY_NAVIGATION_SERVICE_DATA, data); + return this; + } + + /** + * @return {NavigationServiceData} + */ + getNavigationServiceData () { + return this.getObject(NavigationServiceData, AppServiceData.KEY_NAVIGATION_SERVICE_DATA); + } +} + +AppServiceData.KEY_SERVICE_TYPE = 'serviceType'; +AppServiceData.KEY_SERVICE_ID = 'serviceID'; +AppServiceData.KEY_MEDIA_SERVICE_DATA = 'mediaServiceData'; +AppServiceData.KEY_WEATHER_SERVICE_DATA = 'weatherServiceData'; +AppServiceData.KEY_NAVIGATION_SERVICE_DATA = 'navigationServiceData'; + +export { AppServiceData }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/AppServiceManifest.js b/lib/js/src/rpc/structs/AppServiceManifest.js new file mode 100644 index 00000000..a89403f9 --- /dev/null +++ b/lib/js/src/rpc/structs/AppServiceManifest.js @@ -0,0 +1,220 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { NavigationServiceManifest } from './NavigationServiceManifest.js'; +import { Image } from './Image.js'; +import { SdlMsgVersion } from './SdlMsgVersion.js'; +import { WeatherServiceManifest } from './WeatherServiceManifest.js'; +import { RpcStruct } from '../RpcStruct.js'; +import { MediaServiceManifest } from './MediaServiceManifest.js'; + +/** + * This manifest contains all the information necessary for the service to be published, activated, and consumers able + * to interact with it + */ +class AppServiceManifest extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {String} name - Unique name of this service + * @return {AppServiceManifest} + */ + setServiceName (name) { + this.setParameter(AppServiceManifest.KEY_SERVICE_NAME, name); + return this; + } + + /** + * @return {String} + */ + getServiceName () { + return this.getParameter(AppServiceManifest.KEY_SERVICE_NAME); + } + + /** + * @param {String} type - The type of service that is to be offered by this app. See AppServiceType for known enum + * equivalent types. Parameter is a string to allow for new service types to be used by apps + * on older versions of SDL Core. + * @return {AppServiceManifest} + */ + setServiceType (type) { + this.setParameter(AppServiceManifest.KEY_SERVICE_TYPE, type); + return this; + } + + /** + * @return {String} + */ + getServiceType () { + return this.getParameter(AppServiceManifest.KEY_SERVICE_TYPE); + } + + /** + * @param {Image} icon - The icon to be associated with this service. Most likely the same as the appIcon. + * @return {AppServiceManifest} + */ + setServiceIcon (icon) { + this.validateType(Image, icon); + this.setParameter(AppServiceManifest.KEY_SERVICE_ICON, icon); + return this; + } + + /** + * @return {Image} + */ + getServiceIcon () { + return this.getObject(Image, AppServiceManifest.KEY_SERVICE_ICON); + } + + /** + * @param {Boolean} consumers - If true, app service consumers beyond the IVI system will be able to access this + * service. If false, only the IVI system will be able consume the service. If not + * provided, it is assumed to be false. + * @return {AppServiceManifest} + */ + setAllowAppConsumers (consumers) { + this.setParameter(AppServiceManifest.KEY_ALLOW_APP_CONSUMERS, consumers); + return this; + } + + /** + * @return {Boolean} + */ + getAllowAppConsumers () { + return this.getParameter(AppServiceManifest.KEY_ALLOW_APP_CONSUMERS); + } + + /** + * @param {SdlMsgVersion} version - This is the max RPC Spec version the app service understands. This is important + * during the RPC passthrough functionality. If not included, it is assumed the max + * version of the module is acceptable. + * @return {AppServiceManifest} + */ + setRpcSpecVersion (version) { + this.validateType(SdlMsgVersion, version); + this.setParameter(AppServiceManifest.KEY_RPC_SPEC_VERSION, version); + return this; + } + + /** + * @return {SdlMsgVersion} + */ + getRpcSpecVersion () { + return this.getObject(SdlMsgVersion, AppServiceManifest.KEY_RPC_SPEC_VERSION); + } + + /** + * @param {Number[]} cs - This field contains the Function IDs for the RPCs that this service intends to handle + * correctly. This means the service will provide meaningful responses. + * @return {AppServiceManifest} + */ + setHandledRPCs (cs) { + this.setParameter(AppServiceManifest.KEY_HANDLED_RPCS, cs); + return this; + } + + /** + * @return {Number[]} + */ + getHandledRPCs () { + return this.getParameter(AppServiceManifest.KEY_HANDLED_RPCS); + } + + /** + * @param {MediaServiceManifest} manifest + * @return {AppServiceManifest} + */ + setMediaServiceManifest (manifest) { + this.validateType(MediaServiceManifest, manifest); + this.setParameter(AppServiceManifest.KEY_MEDIA_SERVICE_MANIFEST, manifest); + return this; + } + + /** + * @return {MediaServiceManifest} + */ + getMediaServiceManifest () { + return this.getObject(MediaServiceManifest, AppServiceManifest.KEY_MEDIA_SERVICE_MANIFEST); + } + + /** + * @param {WeatherServiceManifest} manifest + * @return {AppServiceManifest} + */ + setWeatherServiceManifest (manifest) { + this.validateType(WeatherServiceManifest, manifest); + this.setParameter(AppServiceManifest.KEY_WEATHER_SERVICE_MANIFEST, manifest); + return this; + } + + /** + * @return {WeatherServiceManifest} + */ + getWeatherServiceManifest () { + return this.getObject(WeatherServiceManifest, AppServiceManifest.KEY_WEATHER_SERVICE_MANIFEST); + } + + /** + * @param {NavigationServiceManifest} manifest + * @return {AppServiceManifest} + */ + setNavigationServiceManifest (manifest) { + this.validateType(NavigationServiceManifest, manifest); + this.setParameter(AppServiceManifest.KEY_NAVIGATION_SERVICE_MANIFEST, manifest); + return this; + } + + /** + * @return {NavigationServiceManifest} + */ + getNavigationServiceManifest () { + return this.getObject(NavigationServiceManifest, AppServiceManifest.KEY_NAVIGATION_SERVICE_MANIFEST); + } +} + +AppServiceManifest.KEY_SERVICE_NAME = 'serviceName'; +AppServiceManifest.KEY_SERVICE_TYPE = 'serviceType'; +AppServiceManifest.KEY_SERVICE_ICON = 'serviceIcon'; +AppServiceManifest.KEY_ALLOW_APP_CONSUMERS = 'allowAppConsumers'; +AppServiceManifest.KEY_RPC_SPEC_VERSION = 'rpcSpecVersion'; +AppServiceManifest.KEY_HANDLED_RPCS = 'handledRPCs'; +AppServiceManifest.KEY_MEDIA_SERVICE_MANIFEST = 'mediaServiceManifest'; +AppServiceManifest.KEY_WEATHER_SERVICE_MANIFEST = 'weatherServiceManifest'; +AppServiceManifest.KEY_NAVIGATION_SERVICE_MANIFEST = 'navigationServiceManifest'; + +export { AppServiceManifest }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/AppServiceRecord.js b/lib/js/src/rpc/structs/AppServiceRecord.js new file mode 100644 index 00000000..c5a6b9a5 --- /dev/null +++ b/lib/js/src/rpc/structs/AppServiceRecord.js @@ -0,0 +1,125 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { AppServiceManifest } from './AppServiceManifest.js'; + +/** + * This is the record of an app service publisher that the module has. It should contain the most up to date + * information including the service's active state + */ +class AppServiceRecord extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {String} id - A unique ID tied to this specific service record. The ID is supplied by the module that + * services publish themselves. + * @return {AppServiceRecord} + */ + setServiceID (id) { + this.setParameter(AppServiceRecord.KEY_SERVICE_ID, id); + return this; + } + + /** + * @return {String} + */ + getServiceID () { + return this.getParameter(AppServiceRecord.KEY_SERVICE_ID); + } + + /** + * @param {AppServiceManifest} manifest - Manifest for the service that this record is for. + * @return {AppServiceRecord} + */ + setServiceManifest (manifest) { + this.validateType(AppServiceManifest, manifest); + this.setParameter(AppServiceRecord.KEY_SERVICE_MANIFEST, manifest); + return this; + } + + /** + * @return {AppServiceManifest} + */ + getServiceManifest () { + return this.getObject(AppServiceManifest, AppServiceRecord.KEY_SERVICE_MANIFEST); + } + + /** + * @param {Boolean} published - If true, the service is published and available. If false, the service has likely + * just been unpublished, and should be considered unavailable. + * @return {AppServiceRecord} + */ + setServicePublished (published) { + this.setParameter(AppServiceRecord.KEY_SERVICE_PUBLISHED, published); + return this; + } + + /** + * @return {Boolean} + */ + getServicePublished () { + return this.getParameter(AppServiceRecord.KEY_SERVICE_PUBLISHED); + } + + /** + * @param {Boolean} active - If true, the service is the active primary service of the supplied service type. It + * will receive all potential RPCs that are passed through to that service type. If false, + * it is not the primary service of the supplied type. See servicePublished for its + * availability. + * @return {AppServiceRecord} + */ + setServiceActive (active) { + this.setParameter(AppServiceRecord.KEY_SERVICE_ACTIVE, active); + return this; + } + + /** + * @return {Boolean} + */ + getServiceActive () { + return this.getParameter(AppServiceRecord.KEY_SERVICE_ACTIVE); + } +} + +AppServiceRecord.KEY_SERVICE_ID = 'serviceID'; +AppServiceRecord.KEY_SERVICE_MANIFEST = 'serviceManifest'; +AppServiceRecord.KEY_SERVICE_PUBLISHED = 'servicePublished'; +AppServiceRecord.KEY_SERVICE_ACTIVE = 'serviceActive'; + +export { AppServiceRecord }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/AppServicesCapabilities.js b/lib/js/src/rpc/structs/AppServicesCapabilities.js new file mode 100644 index 00000000..74153e50 --- /dev/null +++ b/lib/js/src/rpc/structs/AppServicesCapabilities.js @@ -0,0 +1,70 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { AppServiceCapability } from './AppServiceCapability.js'; + +/** + * Capabilities of app services including what service types are supported and the current state of services. + */ +class AppServicesCapabilities extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {AppServiceCapability[]} services - An array of currently available services. If this is an update to the + * capability the affected services will include an update reason in that + * item + * @return {AppServicesCapabilities} + */ + setAppServices (services) { + this.validateType(AppServiceCapability, services, true); + this.setParameter(AppServicesCapabilities.KEY_APP_SERVICES, services); + return this; + } + + /** + * @return {AppServiceCapability[]} + */ + getAppServices () { + return this.getObject(AppServiceCapability, AppServicesCapabilities.KEY_APP_SERVICES); + } +} + +AppServicesCapabilities.KEY_APP_SERVICES = 'appServices'; + +export { AppServicesCapabilities }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/AudioControlCapabilities.js b/lib/js/src/rpc/structs/AudioControlCapabilities.js new file mode 100644 index 00000000..ff71a361 --- /dev/null +++ b/lib/js/src/rpc/structs/AudioControlCapabilities.js @@ -0,0 +1,169 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { ModuleInfo } from './ModuleInfo.js'; + +class AudioControlCapabilities extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {String} name - The short friendly name of the light control module. It should not be used to identify a + * module by mobile application. + * @return {AudioControlCapabilities} + */ + setModuleName (name) { + this.setParameter(AudioControlCapabilities.KEY_MODULE_NAME, name); + return this; + } + + /** + * @return {String} + */ + getModuleName () { + return this.getParameter(AudioControlCapabilities.KEY_MODULE_NAME); + } + + /** + * @param {ModuleInfo} info - Information about a RC module, including its id. + * @return {AudioControlCapabilities} + */ + setModuleInfo (info) { + this.validateType(ModuleInfo, info); + this.setParameter(AudioControlCapabilities.KEY_MODULE_INFO, info); + return this; + } + + /** + * @return {ModuleInfo} + */ + getModuleInfo () { + return this.getObject(ModuleInfo, AudioControlCapabilities.KEY_MODULE_INFO); + } + + /** + * @param {Boolean} available - Availability of the control of audio source. + * @return {AudioControlCapabilities} + */ + setSourceAvailable (available) { + this.setParameter(AudioControlCapabilities.KEY_SOURCE_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getSourceAvailable () { + return this.getParameter(AudioControlCapabilities.KEY_SOURCE_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the keepContext parameter. + * @return {AudioControlCapabilities} + */ + setKeepContextAvailable (available) { + this.setParameter(AudioControlCapabilities.KEY_KEEP_CONTEXT_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getKeepContextAvailable () { + return this.getParameter(AudioControlCapabilities.KEY_KEEP_CONTEXT_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the control of audio volume. + * @return {AudioControlCapabilities} + */ + setVolumeAvailable (available) { + this.setParameter(AudioControlCapabilities.KEY_VOLUME_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getVolumeAvailable () { + return this.getParameter(AudioControlCapabilities.KEY_VOLUME_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the control of Equalizer Settings. + * @return {AudioControlCapabilities} + */ + setEqualizerAvailable (available) { + this.setParameter(AudioControlCapabilities.KEY_EQUALIZER_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getEqualizerAvailable () { + return this.getParameter(AudioControlCapabilities.KEY_EQUALIZER_AVAILABLE); + } + + /** + * @param {Number} id - Must be included if equalizerAvailable=true, and assume all IDs starting from 1 to this + * value are valid + * @return {AudioControlCapabilities} + */ + setEqualizerMaxChannelId (id) { + this.setParameter(AudioControlCapabilities.KEY_EQUALIZER_MAX_CHANNEL_ID, id); + return this; + } + + /** + * @return {Number} + */ + getEqualizerMaxChannelId () { + return this.getParameter(AudioControlCapabilities.KEY_EQUALIZER_MAX_CHANNEL_ID); + } +} + +AudioControlCapabilities.KEY_MODULE_NAME = 'moduleName'; +AudioControlCapabilities.KEY_MODULE_INFO = 'moduleInfo'; +AudioControlCapabilities.KEY_SOURCE_AVAILABLE = 'sourceAvailable'; +AudioControlCapabilities.KEY_KEEP_CONTEXT_AVAILABLE = 'keepContextAvailable'; +AudioControlCapabilities.KEY_VOLUME_AVAILABLE = 'volumeAvailable'; +AudioControlCapabilities.KEY_EQUALIZER_AVAILABLE = 'equalizerAvailable'; +AudioControlCapabilities.KEY_EQUALIZER_MAX_CHANNEL_ID = 'equalizerMaxChannelId'; + +export { AudioControlCapabilities }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/AudioControlData.js b/lib/js/src/rpc/structs/AudioControlData.js new file mode 100644 index 00000000..9fd6bf00 --- /dev/null +++ b/lib/js/src/rpc/structs/AudioControlData.js @@ -0,0 +1,127 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { PrimaryAudioSource } from '../enums/PrimaryAudioSource.js'; +import { EqualizerSettings } from './EqualizerSettings.js'; + +class AudioControlData extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {PrimaryAudioSource} source - In a getter response or a notification, it is the current primary audio + * source of the system. In a setter request, it is the target audio source + * that the system shall switch to. If the value is MOBILE_APP, the system + * shall switch to the mobile media app that issues the setter RPC. + * @return {AudioControlData} + */ + setSource (source) { + this.validateType(PrimaryAudioSource, source); + this.setParameter(AudioControlData.KEY_SOURCE, source); + return this; + } + + /** + * @return {PrimaryAudioSource} + */ + getSource () { + return this.getObject(PrimaryAudioSource, AudioControlData.KEY_SOURCE); + } + + /** + * @param {Boolean} context - This parameter shall not be present in any getter responses or notifications. This + * parameter is optional in a setter request. The default value is false if it is not + * included. If it is false, the system not only changes the audio source but also brings + * the default application or system UI associated with the audio source to foreground. + * If it is true, the system only changes the audio source, but keeps the current + * application in foreground. + * @return {AudioControlData} + */ + setKeepContext (context) { + this.setParameter(AudioControlData.KEY_KEEP_CONTEXT, context); + return this; + } + + /** + * @return {Boolean} + */ + getKeepContext () { + return this.getParameter(AudioControlData.KEY_KEEP_CONTEXT); + } + + /** + * @param {Number} volume - Reflects the volume of audio, from 0%-100%. + * @return {AudioControlData} + */ + setVolume (volume) { + this.setParameter(AudioControlData.KEY_VOLUME, volume); + return this; + } + + /** + * @return {Number} + */ + getVolume () { + return this.getParameter(AudioControlData.KEY_VOLUME); + } + + /** + * @param {EqualizerSettings[]} settings - Defines the list of supported channels (band) and their current/desired + * settings on HMI + * @return {AudioControlData} + */ + setEqualizerSettings (settings) { + this.validateType(EqualizerSettings, settings, true); + this.setParameter(AudioControlData.KEY_EQUALIZER_SETTINGS, settings); + return this; + } + + /** + * @return {EqualizerSettings[]} + */ + getEqualizerSettings () { + return this.getObject(EqualizerSettings, AudioControlData.KEY_EQUALIZER_SETTINGS); + } +} + +AudioControlData.KEY_SOURCE = 'source'; +AudioControlData.KEY_KEEP_CONTEXT = 'keepContext'; +AudioControlData.KEY_VOLUME = 'volume'; +AudioControlData.KEY_EQUALIZER_SETTINGS = 'equalizerSettings'; + +export { AudioControlData }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/AudioPassThruCapabilities.js b/lib/js/src/rpc/structs/AudioPassThruCapabilities.js index f5ec65f6..8ea9c8b4 100644 --- a/lib/js/src/rpc/structs/AudioPassThruCapabilities.js +++ b/lib/js/src/rpc/structs/AudioPassThruCapabilities.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -35,61 +36,65 @@ import { SamplingRate } from '../enums/SamplingRate.js'; import { BitsPerSample } from '../enums/BitsPerSample.js'; import { AudioType } from '../enums/AudioType.js'; +/** + * Describes different audio type configurations for PerformAudioPassThru. e.g. {8kHz,8-bit,PCM} The audio is recorded + * in monaural. + */ class AudioPassThruCapabilities extends RpcStruct { + /** + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {SamplingRate} samplingRate - * @return {AudioPassThruCapabilities} - */ - setSamplingRate (samplingRate) { - this.validateType(SamplingRate, samplingRate); - - this.setParameter(AudioPassThruCapabilities.KEY_SAMPLING_RATE, samplingRate); + * @param {SamplingRate} rate - Describes different sampling options for PerformAudioPassThru. + * @return {AudioPassThruCapabilities} + */ + setSamplingRate (rate) { + this.validateType(SamplingRate, rate); + this.setParameter(AudioPassThruCapabilities.KEY_SAMPLING_RATE, rate); return this; } /** - * @return {SamplingRate} - */ + * @return {SamplingRate} + */ getSamplingRate () { return this.getObject(SamplingRate, AudioPassThruCapabilities.KEY_SAMPLING_RATE); } /** - * @param {BitsPerSample} bitsPerSample - * @return {AudioPassThruCapabilities} - */ - setBitsPerSample (bitsPerSample) { - this.validateType(BitsPerSample, bitsPerSample); - - this.setParameter(AudioPassThruCapabilities.KEY_BITS_PER_SAMPLE, bitsPerSample); + * @param {BitsPerSample} sample - Describes different quality options for PerformAudioPassThru. + * @return {AudioPassThruCapabilities} + */ + setBitsPerSample (sample) { + this.validateType(BitsPerSample, sample); + this.setParameter(AudioPassThruCapabilities.KEY_BITS_PER_SAMPLE, sample); return this; } /** - * @return {BitsPerSample} - */ + * @return {BitsPerSample} + */ getBitsPerSample () { return this.getObject(BitsPerSample, AudioPassThruCapabilities.KEY_BITS_PER_SAMPLE); } /** - * @param {AudioType} bitsPerSample - * @return {AudioPassThruCapabilities} - */ - setAudioType (audioType) { - this.validateType(AudioType, audioType); - - this.setParameter(AudioPassThruCapabilities.KEY_AUDIO_TYPE, audioType); + * @param {AudioType} type - Describes different audio type options for PerformAudioPassThru. + * @return {AudioPassThruCapabilities} + */ + setAudioType (type) { + this.validateType(AudioType, type); + this.setParameter(AudioPassThruCapabilities.KEY_AUDIO_TYPE, type); return this; } /** - * @return {AudioType} - */ + * @return {AudioType} + */ getAudioType () { return this.getObject(AudioType, AudioPassThruCapabilities.KEY_AUDIO_TYPE); } @@ -99,4 +104,4 @@ AudioPassThruCapabilities.KEY_SAMPLING_RATE = 'samplingRate'; AudioPassThruCapabilities.KEY_BITS_PER_SAMPLE = 'bitsPerSample'; AudioPassThruCapabilities.KEY_AUDIO_TYPE = 'audioType'; -export { AudioPassThruCapabilities }; +export { AudioPassThruCapabilities }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/BeltStatus.js b/lib/js/src/rpc/structs/BeltStatus.js new file mode 100644 index 00000000..d499ae9e --- /dev/null +++ b/lib/js/src/rpc/structs/BeltStatus.js @@ -0,0 +1,318 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { VehicleDataEventStatus } from '../enums/VehicleDataEventStatus.js'; + +class BeltStatus extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsDrvBelt_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + setDriverBeltDeployed (deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(BeltStatus.KEY_DRIVER_BELT_DEPLOYED, deployed); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getDriverBeltDeployed () { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_DRIVER_BELT_DEPLOYED); + } + + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsPasBelt_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + setPassengerBeltDeployed (deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(BeltStatus.KEY_PASSENGER_BELT_DEPLOYED, deployed); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getPassengerBeltDeployed () { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_PASSENGER_BELT_DEPLOYED); + } + + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw1PasBckl_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + setPassengerBuckleBelted (belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_PASSENGER_BUCKLE_BELTED, belted); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getPassengerBuckleBelted () { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_PASSENGER_BUCKLE_BELTED); + } + + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw1DrvBckl_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + setDriverBuckleBelted (belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_DRIVER_BUCKLE_BELTED, belted); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getDriverBuckleBelted () { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_DRIVER_BUCKLE_BELTED); + } + + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw2lBckl_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + setLeftRow2BuckleBelted (belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_LEFT_ROW2BUCKLE_BELTED, belted); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getLeftRow2BuckleBelted () { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_LEFT_ROW2BUCKLE_BELTED); + } + + /** + * @param {VehicleDataEventStatus} detected - References signal "VedsRw1PasChld_D_Ltchd". See + * VehicleDataEventStatus. + * @return {BeltStatus} + */ + setPassengerChildDetected (detected) { + this.validateType(VehicleDataEventStatus, detected); + this.setParameter(BeltStatus.KEY_PASSENGER_CHILD_DETECTED, detected); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getPassengerChildDetected () { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_PASSENGER_CHILD_DETECTED); + } + + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw2rBckl_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + setRightRow2BuckleBelted (belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_RIGHT_ROW2BUCKLE_BELTED, belted); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getRightRow2BuckleBelted () { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_RIGHT_ROW2BUCKLE_BELTED); + } + + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw2mBckl_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + setMiddleRow2BuckleBelted (belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_MIDDLE_ROW2BUCKLE_BELTED, belted); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getMiddleRow2BuckleBelted () { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_MIDDLE_ROW2BUCKLE_BELTED); + } + + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw3mBckl_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + setMiddleRow3BuckleBelted (belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_MIDDLE_ROW3BUCKLE_BELTED, belted); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getMiddleRow3BuckleBelted () { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_MIDDLE_ROW3BUCKLE_BELTED); + } + + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw3lBckl_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + setLeftRow3BuckleBelted (belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_LEFT_ROW3BUCKLE_BELTED, belted); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getLeftRow3BuckleBelted () { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_LEFT_ROW3BUCKLE_BELTED); + } + + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw3rBckl_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + setRightRow3BuckleBelted (belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_RIGHT_ROW3BUCKLE_BELTED, belted); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getRightRow3BuckleBelted () { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_RIGHT_ROW3BUCKLE_BELTED); + } + + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw2lRib_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + setLeftRearInflatableBelted (belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_LEFT_REAR_INFLATABLE_BELTED, belted); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getLeftRearInflatableBelted () { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_LEFT_REAR_INFLATABLE_BELTED); + } + + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw2rRib_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + setRightRearInflatableBelted (belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_RIGHT_REAR_INFLATABLE_BELTED, belted); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getRightRearInflatableBelted () { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_RIGHT_REAR_INFLATABLE_BELTED); + } + + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsRw1mBelt_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + setMiddleRow1BeltDeployed (deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(BeltStatus.KEY_MIDDLE_ROW1BELT_DEPLOYED, deployed); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getMiddleRow1BeltDeployed () { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_MIDDLE_ROW1BELT_DEPLOYED); + } + + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw1mBckl_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + setMiddleRow1BuckleBelted (belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_MIDDLE_ROW1BUCKLE_BELTED, belted); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getMiddleRow1BuckleBelted () { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_MIDDLE_ROW1BUCKLE_BELTED); + } +} + +BeltStatus.KEY_DRIVER_BELT_DEPLOYED = 'driverBeltDeployed'; +BeltStatus.KEY_PASSENGER_BELT_DEPLOYED = 'passengerBeltDeployed'; +BeltStatus.KEY_PASSENGER_BUCKLE_BELTED = 'passengerBuckleBelted'; +BeltStatus.KEY_DRIVER_BUCKLE_BELTED = 'driverBuckleBelted'; +BeltStatus.KEY_LEFT_ROW2BUCKLE_BELTED = 'leftRow2BuckleBelted'; +BeltStatus.KEY_PASSENGER_CHILD_DETECTED = 'passengerChildDetected'; +BeltStatus.KEY_RIGHT_ROW2BUCKLE_BELTED = 'rightRow2BuckleBelted'; +BeltStatus.KEY_MIDDLE_ROW2BUCKLE_BELTED = 'middleRow2BuckleBelted'; +BeltStatus.KEY_MIDDLE_ROW3BUCKLE_BELTED = 'middleRow3BuckleBelted'; +BeltStatus.KEY_LEFT_ROW3BUCKLE_BELTED = 'leftRow3BuckleBelted'; +BeltStatus.KEY_RIGHT_ROW3BUCKLE_BELTED = 'rightRow3BuckleBelted'; +BeltStatus.KEY_LEFT_REAR_INFLATABLE_BELTED = 'leftRearInflatableBelted'; +BeltStatus.KEY_RIGHT_REAR_INFLATABLE_BELTED = 'rightRearInflatableBelted'; +BeltStatus.KEY_MIDDLE_ROW1BELT_DEPLOYED = 'middleRow1BeltDeployed'; +BeltStatus.KEY_MIDDLE_ROW1BUCKLE_BELTED = 'middleRow1BuckleBelted'; + +export { BeltStatus }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/BodyInformation.js b/lib/js/src/rpc/structs/BodyInformation.js new file mode 100644 index 00000000..ebd0843f --- /dev/null +++ b/lib/js/src/rpc/structs/BodyInformation.js @@ -0,0 +1,169 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { IgnitionStatus } from '../enums/IgnitionStatus.js'; +import { IgnitionStableStatus } from '../enums/IgnitionStableStatus.js'; + +class BodyInformation extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Boolean} active - References signal "PrkBrkActv_B_Actl". + * @return {BodyInformation} + */ + setParkBrakeActive (active) { + this.setParameter(BodyInformation.KEY_PARK_BRAKE_ACTIVE, active); + return this; + } + + /** + * @return {Boolean} + */ + getParkBrakeActive () { + return this.getParameter(BodyInformation.KEY_PARK_BRAKE_ACTIVE); + } + + /** + * @param {IgnitionStableStatus} status - References signal "Ignition_Switch_Stable". See IgnitionStableStatus. + * @return {BodyInformation} + */ + setIgnitionStableStatus (status) { + this.validateType(IgnitionStableStatus, status); + this.setParameter(BodyInformation.KEY_IGNITION_STABLE_STATUS, status); + return this; + } + + /** + * @return {IgnitionStableStatus} + */ + getIgnitionStableStatus () { + return this.getObject(IgnitionStableStatus, BodyInformation.KEY_IGNITION_STABLE_STATUS); + } + + /** + * @param {IgnitionStatus} status - References signal "Ignition_status". See IgnitionStatus. + * @return {BodyInformation} + */ + setIgnitionStatus (status) { + this.validateType(IgnitionStatus, status); + this.setParameter(BodyInformation.KEY_IGNITION_STATUS, status); + return this; + } + + /** + * @return {IgnitionStatus} + */ + getIgnitionStatus () { + return this.getObject(IgnitionStatus, BodyInformation.KEY_IGNITION_STATUS); + } + + /** + * @param {Boolean} ajar - References signal "DrStatDrv_B_Actl". + * @return {BodyInformation} + */ + setDriverDoorAjar (ajar) { + this.setParameter(BodyInformation.KEY_DRIVER_DOOR_AJAR, ajar); + return this; + } + + /** + * @return {Boolean} + */ + getDriverDoorAjar () { + return this.getParameter(BodyInformation.KEY_DRIVER_DOOR_AJAR); + } + + /** + * @param {Boolean} ajar - References signal "DrStatPsngr_B_Actl". + * @return {BodyInformation} + */ + setPassengerDoorAjar (ajar) { + this.setParameter(BodyInformation.KEY_PASSENGER_DOOR_AJAR, ajar); + return this; + } + + /** + * @return {Boolean} + */ + getPassengerDoorAjar () { + return this.getParameter(BodyInformation.KEY_PASSENGER_DOOR_AJAR); + } + + /** + * @param {Boolean} ajar - References signal "DrStatRl_B_Actl". + * @return {BodyInformation} + */ + setRearLeftDoorAjar (ajar) { + this.setParameter(BodyInformation.KEY_REAR_LEFT_DOOR_AJAR, ajar); + return this; + } + + /** + * @return {Boolean} + */ + getRearLeftDoorAjar () { + return this.getParameter(BodyInformation.KEY_REAR_LEFT_DOOR_AJAR); + } + + /** + * @param {Boolean} ajar - References signal "DrStatRr_B_Actl". + * @return {BodyInformation} + */ + setRearRightDoorAjar (ajar) { + this.setParameter(BodyInformation.KEY_REAR_RIGHT_DOOR_AJAR, ajar); + return this; + } + + /** + * @return {Boolean} + */ + getRearRightDoorAjar () { + return this.getParameter(BodyInformation.KEY_REAR_RIGHT_DOOR_AJAR); + } +} + +BodyInformation.KEY_PARK_BRAKE_ACTIVE = 'parkBrakeActive'; +BodyInformation.KEY_IGNITION_STABLE_STATUS = 'ignitionStableStatus'; +BodyInformation.KEY_IGNITION_STATUS = 'ignitionStatus'; +BodyInformation.KEY_DRIVER_DOOR_AJAR = 'driverDoorAjar'; +BodyInformation.KEY_PASSENGER_DOOR_AJAR = 'passengerDoorAjar'; +BodyInformation.KEY_REAR_LEFT_DOOR_AJAR = 'rearLeftDoorAjar'; +BodyInformation.KEY_REAR_RIGHT_DOOR_AJAR = 'rearRightDoorAjar'; + +export { BodyInformation }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/ButtonCapabilities.js b/lib/js/src/rpc/structs/ButtonCapabilities.js index ed7f742b..9be31b7f 100644 --- a/lib/js/src/rpc/structs/ButtonCapabilities.js +++ b/lib/js/src/rpc/structs/ButtonCapabilities.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -31,94 +32,102 @@ */ import { RpcStruct } from '../RpcStruct.js'; -import { ModuleInfo } from './ModuleInfo'; import { ButtonName } from '../enums/ButtonName.js'; +import { ModuleInfo } from './ModuleInfo.js'; +/** + * Contains information about a button's capabilities. + */ class ButtonCapabilities extends RpcStruct { + /** + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {ButtonName} name - * @return {ButtonCapabilities} - */ + * @param {ButtonName} name - The name of the button. See ButtonName. + * @return {ButtonCapabilities} + */ setName (name) { this.validateType(ButtonName, name); - this.setParameter(ButtonCapabilities.KEY_NAME, name); return this; } /** - * @return {ButtonName} - */ + * @return {ButtonName} + */ getName () { return this.getObject(ButtonName, ButtonCapabilities.KEY_NAME); } /** - * @param {ModuleInfo} moduleInfo - * @return {ButtonCapabilities} - */ - setModuleInfo (moduleInfo) { - this.validateType(ModuleInfo, moduleInfo); - - this.setParameter(ButtonCapabilities.KEY_MODULE_INFO, moduleInfo); + * @param {ModuleInfo} info - Information about a RC module, including its id. + * @return {ButtonCapabilities} + */ + setModuleInfo (info) { + this.validateType(ModuleInfo, info); + this.setParameter(ButtonCapabilities.KEY_MODULE_INFO, info); return this; } /** - * @return {ModuleInfo} - */ + * @return {ModuleInfo} + */ getModuleInfo () { return this.getObject(ModuleInfo, ButtonCapabilities.KEY_MODULE_INFO); } /** - * @param {Boolean} shortPressAvailable - * @return {ButtonCapabilities} - */ - setShortPressAvailable (shortPressAvailable) { - this.setParameter(ButtonCapabilities.KEY_SHORT_PRESS_AVAILABLE, shortPressAvailable); + * @param {Boolean} available - The button supports a short press. Whenever the button is pressed short, + * onButtonPressed( SHORT) will be invoked. + * @return {ButtonCapabilities} + */ + setShortPressAvailable (available) { + this.setParameter(ButtonCapabilities.KEY_SHORT_PRESS_AVAILABLE, available); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getShortPressAvailable () { return this.getParameter(ButtonCapabilities.KEY_SHORT_PRESS_AVAILABLE); } /** - * @param {Boolean} longPressAvailable - * @return {ButtonCapabilities} - */ - setLongPressAvailable (longPressAvailable) { - this.setParameter(ButtonCapabilities.KEY_LONG_PRESS_AVAILABLE, longPressAvailable); + * @param {Boolean} available - The button supports a LONG press. Whenever the button is pressed long, + * onButtonPressed( LONG) will be invoked. + * @return {ButtonCapabilities} + */ + setLongPressAvailable (available) { + this.setParameter(ButtonCapabilities.KEY_LONG_PRESS_AVAILABLE, available); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getLongPressAvailable () { return this.getParameter(ButtonCapabilities.KEY_LONG_PRESS_AVAILABLE); } /** - * @param {Boolean} upDownAvailable - * @return {ButtonCapabilities} - */ - setUpDownAvailable (upDownAvailable) { - this.setParameter(ButtonCapabilities.KEY_UP_DOWN_AVAILABLE, upDownAvailable); + * @param {Boolean} available - The button supports "button down" and "button up". Whenever the button is pressed, + * onButtonEvent( DOWN) will be invoked. Whenever the button is released, + * onButtonEvent( UP) will be invoked. + * @return {ButtonCapabilities} + */ + setUpDownAvailable (available) { + this.setParameter(ButtonCapabilities.KEY_UP_DOWN_AVAILABLE, available); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getUpDownAvailable () { return this.getParameter(ButtonCapabilities.KEY_UP_DOWN_AVAILABLE); } @@ -130,4 +139,4 @@ ButtonCapabilities.KEY_SHORT_PRESS_AVAILABLE = 'shortPressAvailable'; ButtonCapabilities.KEY_LONG_PRESS_AVAILABLE = 'longPressAvailable'; ButtonCapabilities.KEY_UP_DOWN_AVAILABLE = 'upDownAvailable'; -export { ButtonCapabilities }; +export { ButtonCapabilities }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/Choice.js b/lib/js/src/rpc/structs/Choice.js new file mode 100644 index 00000000..a9e31bc7 --- /dev/null +++ b/lib/js/src/rpc/structs/Choice.js @@ -0,0 +1,171 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { Image } from './Image.js'; + +/** + * A choice is an option given to the user, which can be selected either by menu, or through voice recognition system. + */ +class Choice extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Number} id + * @return {Choice} + */ + setChoiceID (id) { + this.setParameter(Choice.KEY_CHOICE_ID, id); + return this; + } + + /** + * @return {Number} + */ + getChoiceID () { + return this.getParameter(Choice.KEY_CHOICE_ID); + } + + /** + * @param {String} name + * @return {Choice} + */ + setMenuName (name) { + this.setParameter(Choice.KEY_MENU_NAME, name); + return this; + } + + /** + * @return {String} + */ + getMenuName () { + return this.getParameter(Choice.KEY_MENU_NAME); + } + + /** + * @param {String[]} commands + * @return {Choice} + */ + setVrCommands (commands) { + this.setParameter(Choice.KEY_VR_COMMANDS, commands); + return this; + } + + /** + * @return {String[]} + */ + getVrCommands () { + return this.getParameter(Choice.KEY_VR_COMMANDS); + } + + /** + * @param {Image} image + * @return {Choice} + */ + setImage (image) { + this.validateType(Image, image); + this.setParameter(Choice.KEY_IMAGE, image); + return this; + } + + /** + * @return {Image} + */ + getImage () { + return this.getObject(Image, Choice.KEY_IMAGE); + } + + /** + * @param {String} text - Optional secondary text to display; e.g. address of POI in a search result entry + * @return {Choice} + */ + setSecondaryText (text) { + this.setParameter(Choice.KEY_SECONDARY_TEXT, text); + return this; + } + + /** + * @return {String} + */ + getSecondaryText () { + return this.getParameter(Choice.KEY_SECONDARY_TEXT); + } + + /** + * @param {String} text - Optional tertiary text to display; e.g. distance to POI for a search result entry + * @return {Choice} + */ + setTertiaryText (text) { + this.setParameter(Choice.KEY_TERTIARY_TEXT, text); + return this; + } + + /** + * @return {String} + */ + getTertiaryText () { + return this.getParameter(Choice.KEY_TERTIARY_TEXT); + } + + /** + * @param {Image} image - Optional secondary image struct for choice + * @return {Choice} + */ + setSecondaryImage (image) { + this.validateType(Image, image); + this.setParameter(Choice.KEY_SECONDARY_IMAGE, image); + return this; + } + + /** + * @return {Image} + */ + getSecondaryImage () { + return this.getObject(Image, Choice.KEY_SECONDARY_IMAGE); + } +} + +Choice.KEY_CHOICE_ID = 'choiceID'; +Choice.KEY_MENU_NAME = 'menuName'; +Choice.KEY_VR_COMMANDS = 'vrCommands'; +Choice.KEY_IMAGE = 'image'; +Choice.KEY_SECONDARY_TEXT = 'secondaryText'; +Choice.KEY_TERTIARY_TEXT = 'tertiaryText'; +Choice.KEY_SECONDARY_IMAGE = 'secondaryImage'; + +export { Choice }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/ClimateControlCapabilities.js b/lib/js/src/rpc/structs/ClimateControlCapabilities.js new file mode 100644 index 00000000..360c27a9 --- /dev/null +++ b/lib/js/src/rpc/structs/ClimateControlCapabilities.js @@ -0,0 +1,394 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { DefrostZone } from '../enums/DefrostZone.js'; +import { VentilationMode } from '../enums/VentilationMode.js'; +import { ModuleInfo } from './ModuleInfo.js'; + +/** + * Contains information about a climate control module's capabilities. + */ +class ClimateControlCapabilities extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {String} name - The short friendly name of the climate control module. It should not be used to identify a + * module by mobile application. + * @return {ClimateControlCapabilities} + */ + setModuleName (name) { + this.setParameter(ClimateControlCapabilities.KEY_MODULE_NAME, name); + return this; + } + + /** + * @return {String} + */ + getModuleName () { + return this.getParameter(ClimateControlCapabilities.KEY_MODULE_NAME); + } + + /** + * @param {ModuleInfo} info - Information about a RC module, including its id. + * @return {ClimateControlCapabilities} + */ + setModuleInfo (info) { + this.validateType(ModuleInfo, info); + this.setParameter(ClimateControlCapabilities.KEY_MODULE_INFO, info); + return this; + } + + /** + * @return {ModuleInfo} + */ + getModuleInfo () { + return this.getObject(ModuleInfo, ClimateControlCapabilities.KEY_MODULE_INFO); + } + + /** + * @param {Boolean} available - Availability of the reading of current temperature. True: Available, False: Not + * Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + setCurrentTemperatureAvailable (available) { + this.setParameter(ClimateControlCapabilities.KEY_CURRENT_TEMPERATURE_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getCurrentTemperatureAvailable () { + return this.getParameter(ClimateControlCapabilities.KEY_CURRENT_TEMPERATURE_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the control of fan speed. True: Available, False: Not Available, Not + * present: Not Available. + * @return {ClimateControlCapabilities} + */ + setFanSpeedAvailable (available) { + this.setParameter(ClimateControlCapabilities.KEY_FAN_SPEED_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getFanSpeedAvailable () { + return this.getParameter(ClimateControlCapabilities.KEY_FAN_SPEED_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the control of desired temperature. True: Available, False: Not + * Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + setDesiredTemperatureAvailable (available) { + this.setParameter(ClimateControlCapabilities.KEY_DESIRED_TEMPERATURE_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getDesiredTemperatureAvailable () { + return this.getParameter(ClimateControlCapabilities.KEY_DESIRED_TEMPERATURE_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the control of turn on/off AC. True: Available, False: Not + * Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + setAcEnableAvailable (available) { + this.setParameter(ClimateControlCapabilities.KEY_AC_ENABLE_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getAcEnableAvailable () { + return this.getParameter(ClimateControlCapabilities.KEY_AC_ENABLE_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the control of enable/disable air conditioning is ON on the maximum + * level. True: Available, False: Not Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + setAcMaxEnableAvailable (available) { + this.setParameter(ClimateControlCapabilities.KEY_AC_MAX_ENABLE_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getAcMaxEnableAvailable () { + return this.getParameter(ClimateControlCapabilities.KEY_AC_MAX_ENABLE_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the control of enable/disable circulate Air mode. True: Available, + * False: Not Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + setCirculateAirEnableAvailable (available) { + this.setParameter(ClimateControlCapabilities.KEY_CIRCULATE_AIR_ENABLE_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getCirculateAirEnableAvailable () { + return this.getParameter(ClimateControlCapabilities.KEY_CIRCULATE_AIR_ENABLE_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the control of enable/disable auto mode. True: Available, False: Not + * Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + setAutoModeEnableAvailable (available) { + this.setParameter(ClimateControlCapabilities.KEY_AUTO_MODE_ENABLE_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getAutoModeEnableAvailable () { + return this.getParameter(ClimateControlCapabilities.KEY_AUTO_MODE_ENABLE_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the control of enable/disable dual mode. True: Available, False: Not + * Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + setDualModeEnableAvailable (available) { + this.setParameter(ClimateControlCapabilities.KEY_DUAL_MODE_ENABLE_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getDualModeEnableAvailable () { + return this.getParameter(ClimateControlCapabilities.KEY_DUAL_MODE_ENABLE_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the control of defrost zones. True: Available, False: Not Available, + * Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + setDefrostZoneAvailable (available) { + this.setParameter(ClimateControlCapabilities.KEY_DEFROST_ZONE_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getDefrostZoneAvailable () { + return this.getParameter(ClimateControlCapabilities.KEY_DEFROST_ZONE_AVAILABLE); + } + + /** + * @param {DefrostZone[]} zone - A set of all defrost zones that are controllable. + * @return {ClimateControlCapabilities} + */ + setDefrostZone (zone) { + this.validateType(DefrostZone, zone, true); + this.setParameter(ClimateControlCapabilities.KEY_DEFROST_ZONE, zone); + return this; + } + + /** + * @return {DefrostZone[]} + */ + getDefrostZone () { + return this.getObject(DefrostZone, ClimateControlCapabilities.KEY_DEFROST_ZONE); + } + + /** + * @param {Boolean} available - Availability of the control of air ventilation mode. True: Available, False: Not + * Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + setVentilationModeAvailable (available) { + this.setParameter(ClimateControlCapabilities.KEY_VENTILATION_MODE_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getVentilationModeAvailable () { + return this.getParameter(ClimateControlCapabilities.KEY_VENTILATION_MODE_AVAILABLE); + } + + /** + * @param {VentilationMode[]} mode - A set of all ventilation modes that are controllable. + * @return {ClimateControlCapabilities} + */ + setVentilationMode (mode) { + this.validateType(VentilationMode, mode, true); + this.setParameter(ClimateControlCapabilities.KEY_VENTILATION_MODE, mode); + return this; + } + + /** + * @return {VentilationMode[]} + */ + getVentilationMode () { + return this.getObject(VentilationMode, ClimateControlCapabilities.KEY_VENTILATION_MODE); + } + + /** + * @param {Boolean} available - Availability of the control (enable/disable) of heated Steering Wheel. True: + * Available, False: Not Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + setHeatedSteeringWheelAvailable (available) { + this.setParameter(ClimateControlCapabilities.KEY_HEATED_STEERING_WHEEL_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getHeatedSteeringWheelAvailable () { + return this.getParameter(ClimateControlCapabilities.KEY_HEATED_STEERING_WHEEL_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the control (enable/disable) of heated Windshield. True: Available, + * False: Not Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + setHeatedWindshieldAvailable (available) { + this.setParameter(ClimateControlCapabilities.KEY_HEATED_WINDSHIELD_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getHeatedWindshieldAvailable () { + return this.getParameter(ClimateControlCapabilities.KEY_HEATED_WINDSHIELD_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the control (enable/disable) of heated Rear Window. True: Available, + * False: Not Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + setHeatedRearWindowAvailable (available) { + this.setParameter(ClimateControlCapabilities.KEY_HEATED_REAR_WINDOW_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getHeatedRearWindowAvailable () { + return this.getParameter(ClimateControlCapabilities.KEY_HEATED_REAR_WINDOW_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the control (enable/disable) of heated Mirrors. True: Available, + * False: Not Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + setHeatedMirrorsAvailable (available) { + this.setParameter(ClimateControlCapabilities.KEY_HEATED_MIRRORS_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getHeatedMirrorsAvailable () { + return this.getParameter(ClimateControlCapabilities.KEY_HEATED_MIRRORS_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the control of enable/disable climate control. True: Available, + * False: Not Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + setClimateEnableAvailable (available) { + this.setParameter(ClimateControlCapabilities.KEY_CLIMATE_ENABLE_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getClimateEnableAvailable () { + return this.getParameter(ClimateControlCapabilities.KEY_CLIMATE_ENABLE_AVAILABLE); + } +} + +ClimateControlCapabilities.KEY_MODULE_NAME = 'moduleName'; +ClimateControlCapabilities.KEY_MODULE_INFO = 'moduleInfo'; +ClimateControlCapabilities.KEY_CURRENT_TEMPERATURE_AVAILABLE = 'currentTemperatureAvailable'; +ClimateControlCapabilities.KEY_FAN_SPEED_AVAILABLE = 'fanSpeedAvailable'; +ClimateControlCapabilities.KEY_DESIRED_TEMPERATURE_AVAILABLE = 'desiredTemperatureAvailable'; +ClimateControlCapabilities.KEY_AC_ENABLE_AVAILABLE = 'acEnableAvailable'; +ClimateControlCapabilities.KEY_AC_MAX_ENABLE_AVAILABLE = 'acMaxEnableAvailable'; +ClimateControlCapabilities.KEY_CIRCULATE_AIR_ENABLE_AVAILABLE = 'circulateAirEnableAvailable'; +ClimateControlCapabilities.KEY_AUTO_MODE_ENABLE_AVAILABLE = 'autoModeEnableAvailable'; +ClimateControlCapabilities.KEY_DUAL_MODE_ENABLE_AVAILABLE = 'dualModeEnableAvailable'; +ClimateControlCapabilities.KEY_DEFROST_ZONE_AVAILABLE = 'defrostZoneAvailable'; +ClimateControlCapabilities.KEY_DEFROST_ZONE = 'defrostZone'; +ClimateControlCapabilities.KEY_VENTILATION_MODE_AVAILABLE = 'ventilationModeAvailable'; +ClimateControlCapabilities.KEY_VENTILATION_MODE = 'ventilationMode'; +ClimateControlCapabilities.KEY_HEATED_STEERING_WHEEL_AVAILABLE = 'heatedSteeringWheelAvailable'; +ClimateControlCapabilities.KEY_HEATED_WINDSHIELD_AVAILABLE = 'heatedWindshieldAvailable'; +ClimateControlCapabilities.KEY_HEATED_REAR_WINDOW_AVAILABLE = 'heatedRearWindowAvailable'; +ClimateControlCapabilities.KEY_HEATED_MIRRORS_AVAILABLE = 'heatedMirrorsAvailable'; +ClimateControlCapabilities.KEY_CLIMATE_ENABLE_AVAILABLE = 'climateEnableAvailable'; + +export { ClimateControlCapabilities }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/ClimateControlData.js b/lib/js/src/rpc/structs/ClimateControlData.js new file mode 100644 index 00000000..2fa8062a --- /dev/null +++ b/lib/js/src/rpc/structs/ClimateControlData.js @@ -0,0 +1,308 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { Temperature } from './Temperature.js'; +import { RpcStruct } from '../RpcStruct.js'; +import { VentilationMode } from '../enums/VentilationMode.js'; +import { DefrostZone } from '../enums/DefrostZone.js'; + +class ClimateControlData extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Number} speed + * @return {ClimateControlData} + */ + setFanSpeed (speed) { + this.setParameter(ClimateControlData.KEY_FAN_SPEED, speed); + return this; + } + + /** + * @return {Number} + */ + getFanSpeed () { + return this.getParameter(ClimateControlData.KEY_FAN_SPEED); + } + + /** + * @param {Temperature} temperature + * @return {ClimateControlData} + */ + setCurrentTemperature (temperature) { + this.validateType(Temperature, temperature); + this.setParameter(ClimateControlData.KEY_CURRENT_TEMPERATURE, temperature); + return this; + } + + /** + * @return {Temperature} + */ + getCurrentTemperature () { + return this.getObject(Temperature, ClimateControlData.KEY_CURRENT_TEMPERATURE); + } + + /** + * @param {Temperature} temperature + * @return {ClimateControlData} + */ + setDesiredTemperature (temperature) { + this.validateType(Temperature, temperature); + this.setParameter(ClimateControlData.KEY_DESIRED_TEMPERATURE, temperature); + return this; + } + + /** + * @return {Temperature} + */ + getDesiredTemperature () { + return this.getObject(Temperature, ClimateControlData.KEY_DESIRED_TEMPERATURE); + } + + /** + * @param {Boolean} enable + * @return {ClimateControlData} + */ + setAcEnable (enable) { + this.setParameter(ClimateControlData.KEY_AC_ENABLE, enable); + return this; + } + + /** + * @return {Boolean} + */ + getAcEnable () { + return this.getParameter(ClimateControlData.KEY_AC_ENABLE); + } + + /** + * @param {Boolean} enable + * @return {ClimateControlData} + */ + setCirculateAirEnable (enable) { + this.setParameter(ClimateControlData.KEY_CIRCULATE_AIR_ENABLE, enable); + return this; + } + + /** + * @return {Boolean} + */ + getCirculateAirEnable () { + return this.getParameter(ClimateControlData.KEY_CIRCULATE_AIR_ENABLE); + } + + /** + * @param {Boolean} enable + * @return {ClimateControlData} + */ + setAutoModeEnable (enable) { + this.setParameter(ClimateControlData.KEY_AUTO_MODE_ENABLE, enable); + return this; + } + + /** + * @return {Boolean} + */ + getAutoModeEnable () { + return this.getParameter(ClimateControlData.KEY_AUTO_MODE_ENABLE); + } + + /** + * @param {DefrostZone} zone + * @return {ClimateControlData} + */ + setDefrostZone (zone) { + this.validateType(DefrostZone, zone); + this.setParameter(ClimateControlData.KEY_DEFROST_ZONE, zone); + return this; + } + + /** + * @return {DefrostZone} + */ + getDefrostZone () { + return this.getObject(DefrostZone, ClimateControlData.KEY_DEFROST_ZONE); + } + + /** + * @param {Boolean} enable + * @return {ClimateControlData} + */ + setDualModeEnable (enable) { + this.setParameter(ClimateControlData.KEY_DUAL_MODE_ENABLE, enable); + return this; + } + + /** + * @return {Boolean} + */ + getDualModeEnable () { + return this.getParameter(ClimateControlData.KEY_DUAL_MODE_ENABLE); + } + + /** + * @param {Boolean} enable + * @return {ClimateControlData} + */ + setAcMaxEnable (enable) { + this.setParameter(ClimateControlData.KEY_AC_MAX_ENABLE, enable); + return this; + } + + /** + * @return {Boolean} + */ + getAcMaxEnable () { + return this.getParameter(ClimateControlData.KEY_AC_MAX_ENABLE); + } + + /** + * @param {VentilationMode} mode + * @return {ClimateControlData} + */ + setVentilationMode (mode) { + this.validateType(VentilationMode, mode); + this.setParameter(ClimateControlData.KEY_VENTILATION_MODE, mode); + return this; + } + + /** + * @return {VentilationMode} + */ + getVentilationMode () { + return this.getObject(VentilationMode, ClimateControlData.KEY_VENTILATION_MODE); + } + + /** + * @param {Boolean} enable - value false means disabled/turn off, value true means enabled/turn on. + * @return {ClimateControlData} + */ + setHeatedSteeringWheelEnable (enable) { + this.setParameter(ClimateControlData.KEY_HEATED_STEERING_WHEEL_ENABLE, enable); + return this; + } + + /** + * @return {Boolean} + */ + getHeatedSteeringWheelEnable () { + return this.getParameter(ClimateControlData.KEY_HEATED_STEERING_WHEEL_ENABLE); + } + + /** + * @param {Boolean} enable - value false means disabled, value true means enabled. + * @return {ClimateControlData} + */ + setHeatedWindshieldEnable (enable) { + this.setParameter(ClimateControlData.KEY_HEATED_WINDSHIELD_ENABLE, enable); + return this; + } + + /** + * @return {Boolean} + */ + getHeatedWindshieldEnable () { + return this.getParameter(ClimateControlData.KEY_HEATED_WINDSHIELD_ENABLE); + } + + /** + * @param {Boolean} enable - value false means disabled, value true means enabled. + * @return {ClimateControlData} + */ + setHeatedRearWindowEnable (enable) { + this.setParameter(ClimateControlData.KEY_HEATED_REAR_WINDOW_ENABLE, enable); + return this; + } + + /** + * @return {Boolean} + */ + getHeatedRearWindowEnable () { + return this.getParameter(ClimateControlData.KEY_HEATED_REAR_WINDOW_ENABLE); + } + + /** + * @param {Boolean} enable - value false means disabled, value true means enabled. + * @return {ClimateControlData} + */ + setHeatedMirrorsEnable (enable) { + this.setParameter(ClimateControlData.KEY_HEATED_MIRRORS_ENABLE, enable); + return this; + } + + /** + * @return {Boolean} + */ + getHeatedMirrorsEnable () { + return this.getParameter(ClimateControlData.KEY_HEATED_MIRRORS_ENABLE); + } + + /** + * @param {Boolean} enable - True if the climate module is on, false if the climate module is off + * @return {ClimateControlData} + */ + setClimateEnable (enable) { + this.setParameter(ClimateControlData.KEY_CLIMATE_ENABLE, enable); + return this; + } + + /** + * @return {Boolean} + */ + getClimateEnable () { + return this.getParameter(ClimateControlData.KEY_CLIMATE_ENABLE); + } +} + +ClimateControlData.KEY_FAN_SPEED = 'fanSpeed'; +ClimateControlData.KEY_CURRENT_TEMPERATURE = 'currentTemperature'; +ClimateControlData.KEY_DESIRED_TEMPERATURE = 'desiredTemperature'; +ClimateControlData.KEY_AC_ENABLE = 'acEnable'; +ClimateControlData.KEY_CIRCULATE_AIR_ENABLE = 'circulateAirEnable'; +ClimateControlData.KEY_AUTO_MODE_ENABLE = 'autoModeEnable'; +ClimateControlData.KEY_DEFROST_ZONE = 'defrostZone'; +ClimateControlData.KEY_DUAL_MODE_ENABLE = 'dualModeEnable'; +ClimateControlData.KEY_AC_MAX_ENABLE = 'acMaxEnable'; +ClimateControlData.KEY_VENTILATION_MODE = 'ventilationMode'; +ClimateControlData.KEY_HEATED_STEERING_WHEEL_ENABLE = 'heatedSteeringWheelEnable'; +ClimateControlData.KEY_HEATED_WINDSHIELD_ENABLE = 'heatedWindshieldEnable'; +ClimateControlData.KEY_HEATED_REAR_WINDOW_ENABLE = 'heatedRearWindowEnable'; +ClimateControlData.KEY_HEATED_MIRRORS_ENABLE = 'heatedMirrorsEnable'; +ClimateControlData.KEY_CLIMATE_ENABLE = 'climateEnable'; + +export { ClimateControlData }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/CloudAppProperties.js b/lib/js/src/rpc/structs/CloudAppProperties.js new file mode 100644 index 00000000..f093b37d --- /dev/null +++ b/lib/js/src/rpc/structs/CloudAppProperties.js @@ -0,0 +1,170 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { HybridAppPreference } from '../enums/HybridAppPreference.js'; + +class CloudAppProperties extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {String[]} nicknames - An array of app names a cloud app is allowed to register with. If included in a + * SetCloudAppProperties request, this value will overwrite the existing "nicknames" + * field in the app policies section of the policy table. + * @return {CloudAppProperties} + */ + setNicknames (nicknames) { + this.setParameter(CloudAppProperties.KEY_NICKNAMES, nicknames); + return this; + } + + /** + * @return {String[]} + */ + getNicknames () { + return this.getParameter(CloudAppProperties.KEY_NICKNAMES); + } + + /** + * @param {String} id + * @return {CloudAppProperties} + */ + setAppID (id) { + this.setParameter(CloudAppProperties.KEY_APP_ID, id); + return this; + } + + /** + * @return {String} + */ + getAppID () { + return this.getParameter(CloudAppProperties.KEY_APP_ID); + } + + /** + * @param {Boolean} enabled - If true, cloud app will be included in HMI RPC UpdateAppList + * @return {CloudAppProperties} + */ + setEnabled (enabled) { + this.setParameter(CloudAppProperties.KEY_ENABLED, enabled); + return this; + } + + /** + * @return {Boolean} + */ + getEnabled () { + return this.getParameter(CloudAppProperties.KEY_ENABLED); + } + + /** + * @param {String} token - Used to authenticate websocket connection on app activation + * @return {CloudAppProperties} + */ + setAuthToken (token) { + this.setParameter(CloudAppProperties.KEY_AUTH_TOKEN, token); + return this; + } + + /** + * @return {String} + */ + getAuthToken () { + return this.getParameter(CloudAppProperties.KEY_AUTH_TOKEN); + } + + /** + * @param {String} type - Specifies the connection type Core should use + * @return {CloudAppProperties} + */ + setCloudTransportType (type) { + this.setParameter(CloudAppProperties.KEY_CLOUD_TRANSPORT_TYPE, type); + return this; + } + + /** + * @return {String} + */ + getCloudTransportType () { + return this.getParameter(CloudAppProperties.KEY_CLOUD_TRANSPORT_TYPE); + } + + /** + * @param {HybridAppPreference} preference - Specifies the user preference to use the cloud app version or mobile + * app version when both are available + * @return {CloudAppProperties} + */ + setHybridAppPreference (preference) { + this.validateType(HybridAppPreference, preference); + this.setParameter(CloudAppProperties.KEY_HYBRID_APP_PREFERENCE, preference); + return this; + } + + /** + * @return {HybridAppPreference} + */ + getHybridAppPreference () { + return this.getObject(HybridAppPreference, CloudAppProperties.KEY_HYBRID_APP_PREFERENCE); + } + + /** + * @param {String} endpoint - Specifies the endpoint which Core will attempt to connect to when this app is selected + * @return {CloudAppProperties} + */ + setEndpoint (endpoint) { + this.setParameter(CloudAppProperties.KEY_ENDPOINT, endpoint); + return this; + } + + /** + * @return {String} + */ + getEndpoint () { + return this.getParameter(CloudAppProperties.KEY_ENDPOINT); + } +} + +CloudAppProperties.KEY_NICKNAMES = 'nicknames'; +CloudAppProperties.KEY_APP_ID = 'appID'; +CloudAppProperties.KEY_ENABLED = 'enabled'; +CloudAppProperties.KEY_AUTH_TOKEN = 'authToken'; +CloudAppProperties.KEY_CLOUD_TRANSPORT_TYPE = 'cloudTransportType'; +CloudAppProperties.KEY_HYBRID_APP_PREFERENCE = 'hybridAppPreference'; +CloudAppProperties.KEY_ENDPOINT = 'endpoint'; + +export { CloudAppProperties }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/ClusterModeStatus.js b/lib/js/src/rpc/structs/ClusterModeStatus.js new file mode 100644 index 00000000..028ea633 --- /dev/null +++ b/lib/js/src/rpc/structs/ClusterModeStatus.js @@ -0,0 +1,120 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { PowerModeStatus } from '../enums/PowerModeStatus.js'; +import { CarModeStatus } from '../enums/CarModeStatus.js'; +import { PowerModeQualificationStatus } from '../enums/PowerModeQualificationStatus.js'; + +class ClusterModeStatus extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Boolean} active - References signal "PowerMode_UB". + * @return {ClusterModeStatus} + */ + setPowerModeActive (active) { + this.setParameter(ClusterModeStatus.KEY_POWER_MODE_ACTIVE, active); + return this; + } + + /** + * @return {Boolean} + */ + getPowerModeActive () { + return this.getParameter(ClusterModeStatus.KEY_POWER_MODE_ACTIVE); + } + + /** + * @param {PowerModeQualificationStatus} status - References signal "PowerModeQF". See PowerModeQualificationStatus. + * @return {ClusterModeStatus} + */ + setPowerModeQualificationStatus (status) { + this.validateType(PowerModeQualificationStatus, status); + this.setParameter(ClusterModeStatus.KEY_POWER_MODE_QUALIFICATION_STATUS, status); + return this; + } + + /** + * @return {PowerModeQualificationStatus} + */ + getPowerModeQualificationStatus () { + return this.getObject(PowerModeQualificationStatus, ClusterModeStatus.KEY_POWER_MODE_QUALIFICATION_STATUS); + } + + /** + * @param {CarModeStatus} status - References signal "CarMode". See CarMode. + * @return {ClusterModeStatus} + */ + setCarModeStatus (status) { + this.validateType(CarModeStatus, status); + this.setParameter(ClusterModeStatus.KEY_CAR_MODE_STATUS, status); + return this; + } + + /** + * @return {CarModeStatus} + */ + getCarModeStatus () { + return this.getObject(CarModeStatus, ClusterModeStatus.KEY_CAR_MODE_STATUS); + } + + /** + * @param {PowerModeStatus} status - References signal "PowerMode". See PowerMode. + * @return {ClusterModeStatus} + */ + setPowerModeStatus (status) { + this.validateType(PowerModeStatus, status); + this.setParameter(ClusterModeStatus.KEY_POWER_MODE_STATUS, status); + return this; + } + + /** + * @return {PowerModeStatus} + */ + getPowerModeStatus () { + return this.getObject(PowerModeStatus, ClusterModeStatus.KEY_POWER_MODE_STATUS); + } +} + +ClusterModeStatus.KEY_POWER_MODE_ACTIVE = 'powerModeActive'; +ClusterModeStatus.KEY_POWER_MODE_QUALIFICATION_STATUS = 'powerModeQualificationStatus'; +ClusterModeStatus.KEY_CAR_MODE_STATUS = 'carModeStatus'; +ClusterModeStatus.KEY_POWER_MODE_STATUS = 'powerModeStatus'; + +export { ClusterModeStatus }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/Coordinate.js b/lib/js/src/rpc/structs/Coordinate.js new file mode 100644 index 00000000..4c80f5ba --- /dev/null +++ b/lib/js/src/rpc/structs/Coordinate.js @@ -0,0 +1,80 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; + +class Coordinate extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Number} degrees - Latitude of the location. + * @return {Coordinate} + */ + setLatitudeDegrees (degrees) { + this.setParameter(Coordinate.KEY_LATITUDE_DEGREES, degrees); + return this; + } + + /** + * @return {Number} + */ + getLatitudeDegrees () { + return this.getParameter(Coordinate.KEY_LATITUDE_DEGREES); + } + + /** + * @param {Number} degrees - Longitude of the location. + * @return {Coordinate} + */ + setLongitudeDegrees (degrees) { + this.setParameter(Coordinate.KEY_LONGITUDE_DEGREES, degrees); + return this; + } + + /** + * @return {Number} + */ + getLongitudeDegrees () { + return this.getParameter(Coordinate.KEY_LONGITUDE_DEGREES); + } +} + +Coordinate.KEY_LATITUDE_DEGREES = 'latitudeDegrees'; +Coordinate.KEY_LONGITUDE_DEGREES = 'longitudeDegrees'; + +export { Coordinate }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/DIDResult.js b/lib/js/src/rpc/structs/DIDResult.js new file mode 100644 index 00000000..a1f666f1 --- /dev/null +++ b/lib/js/src/rpc/structs/DIDResult.js @@ -0,0 +1,102 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { VehicleDataResultCode } from '../enums/VehicleDataResultCode.js'; + +/** + * Individual requested DID result and data + */ +class DIDResult extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {VehicleDataResultCode} code - Individual DID result code. + * @return {DIDResult} + */ + setResultCode (code) { + this.validateType(VehicleDataResultCode, code); + this.setParameter(DIDResult.KEY_RESULT_CODE, code); + return this; + } + + /** + * @return {VehicleDataResultCode} + */ + getResultCode () { + return this.getObject(VehicleDataResultCode, DIDResult.KEY_RESULT_CODE); + } + + /** + * @param {Number} location - Location of raw data from vehicle data DID + * @return {DIDResult} + */ + setDidLocation (location) { + this.setParameter(DIDResult.KEY_DID_LOCATION, location); + return this; + } + + /** + * @return {Number} + */ + getDidLocation () { + return this.getParameter(DIDResult.KEY_DID_LOCATION); + } + + /** + * @param {String} data - Raw DID-based data returned for requested element. + * @return {DIDResult} + */ + setData (data) { + this.setParameter(DIDResult.KEY_DATA, data); + return this; + } + + /** + * @return {String} + */ + getData () { + return this.getParameter(DIDResult.KEY_DATA); + } +} + +DIDResult.KEY_RESULT_CODE = 'resultCode'; +DIDResult.KEY_DID_LOCATION = 'didLocation'; +DIDResult.KEY_DATA = 'data'; + +export { DIDResult }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/DateTime.js b/lib/js/src/rpc/structs/DateTime.js new file mode 100644 index 00000000..3bee1b6d --- /dev/null +++ b/lib/js/src/rpc/structs/DateTime.js @@ -0,0 +1,199 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; + +class DateTime extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Number} millisecond - Milliseconds + * @return {DateTime} + */ + setMillisecond (millisecond) { + this.setParameter(DateTime.KEY_MILLISECOND, millisecond); + return this; + } + + /** + * @return {Number} + */ + getMillisecond () { + return this.getParameter(DateTime.KEY_MILLISECOND); + } + + /** + * @param {Number} second - Seconds part of time + * @return {DateTime} + */ + setSecond (second) { + this.setParameter(DateTime.KEY_SECOND, second); + return this; + } + + /** + * @return {Number} + */ + getSecond () { + return this.getParameter(DateTime.KEY_SECOND); + } + + /** + * @param {Number} minute - Minutes part of time + * @return {DateTime} + */ + setMinute (minute) { + this.setParameter(DateTime.KEY_MINUTE, minute); + return this; + } + + /** + * @return {Number} + */ + getMinute () { + return this.getParameter(DateTime.KEY_MINUTE); + } + + /** + * @param {Number} hour - Hours part of time. Note that this structure accepts time only in 24 Hr format + * @return {DateTime} + */ + setHour (hour) { + this.setParameter(DateTime.KEY_HOUR, hour); + return this; + } + + /** + * @return {Number} + */ + getHour () { + return this.getParameter(DateTime.KEY_HOUR); + } + + /** + * @param {Number} day - Day of the month + * @return {DateTime} + */ + setDay (day) { + this.setParameter(DateTime.KEY_DAY, day); + return this; + } + + /** + * @return {Number} + */ + getDay () { + return this.getParameter(DateTime.KEY_DAY); + } + + /** + * @param {Number} month - Month of the year + * @return {DateTime} + */ + setMonth (month) { + this.setParameter(DateTime.KEY_MONTH, month); + return this; + } + + /** + * @return {Number} + */ + getMonth () { + return this.getParameter(DateTime.KEY_MONTH); + } + + /** + * @param {Number} year - The year in YYYY format + * @return {DateTime} + */ + setYear (year) { + this.setParameter(DateTime.KEY_YEAR, year); + return this; + } + + /** + * @return {Number} + */ + getYear () { + return this.getParameter(DateTime.KEY_YEAR); + } + + /** + * @param {Number} tz_hour - Time zone offset in Hours wrt UTC. + * @return {DateTime} + */ + setTz_hour (tz_hour) { + this.setParameter(DateTime.KEY_TZ_HOUR, tz_hour); + return this; + } + + /** + * @return {Number} + */ + getTz_hour () { + return this.getParameter(DateTime.KEY_TZ_HOUR); + } + + /** + * @param {Number} tz_minute - Time zone offset in Min wrt UTC. + * @return {DateTime} + */ + setTz_minute (tz_minute) { + this.setParameter(DateTime.KEY_TZ_MINUTE, tz_minute); + return this; + } + + /** + * @return {Number} + */ + getTz_minute () { + return this.getParameter(DateTime.KEY_TZ_MINUTE); + } +} + +DateTime.KEY_MILLISECOND = 'millisecond'; +DateTime.KEY_SECOND = 'second'; +DateTime.KEY_MINUTE = 'minute'; +DateTime.KEY_HOUR = 'hour'; +DateTime.KEY_DAY = 'day'; +DateTime.KEY_MONTH = 'month'; +DateTime.KEY_YEAR = 'year'; +DateTime.KEY_TZ_HOUR = 'tz_hour'; +DateTime.KEY_TZ_MINUTE = 'tz_minute'; + +export { DateTime }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/DeviceInfo.js b/lib/js/src/rpc/structs/DeviceInfo.js index 30158137..4f9b1a4e 100644 --- a/lib/js/src/rpc/structs/DeviceInfo.js +++ b/lib/js/src/rpc/structs/DeviceInfo.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -32,119 +33,109 @@ import { RpcStruct } from '../RpcStruct.js'; +/** + * Various information about connecting device. + */ class DeviceInfo extends RpcStruct { + /** + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {String} hardware - * @return {DeviceInfo} - */ + * @param {String} hardware - Device model + * @return {DeviceInfo} + */ setHardware (hardware) { - this.validateType(String, hardware); - this.setParameter(DeviceInfo.KEY_HARDWARE, hardware); return this; } /** - * @return {String} - */ + * @return {String} + */ getHardware () { return this.getParameter(DeviceInfo.KEY_HARDWARE); } - /** - * @param {String} firmwareRev - * @return {DeviceInfo} - */ - setFirmwareRev (firmwareRev) { - this.validateType(String, firmwareRev); - - this.setParameter(DeviceInfo.KEY_FIRMWARE_REV, firmwareRev); + * @param {String} rev - Device firmware revision + * @return {DeviceInfo} + */ + setFirmwareRev (rev) { + this.setParameter(DeviceInfo.KEY_FIRMWARE_REV, rev); return this; } /** - * @return {String} - */ + * @return {String} + */ getFirmwareRev () { return this.getParameter(DeviceInfo.KEY_FIRMWARE_REV); } - /** - * @param {String} os - * @return {DeviceInfo} - */ + * @param {String} os - Device OS + * @return {DeviceInfo} + */ setOs (os) { - this.validateType(String, os); - this.setParameter(DeviceInfo.KEY_OS, os); return this; } /** - * @return {String} - */ + * @return {String} + */ getOs () { return this.getParameter(DeviceInfo.KEY_OS); } /** - * @param {String} osVersion - * @return {DeviceInfo} - */ - setOsVersion (osVersion) { - this.validateType(String, osVersion); - - this.setParameter(DeviceInfo.KEY_OS_VERSION, osVersion); + * @param {String} version - Device OS version + * @return {DeviceInfo} + */ + setOsVersion (version) { + this.setParameter(DeviceInfo.KEY_OS_VERSION, version); return this; } /** - * @return {String} - */ + * @return {String} + */ getOsVersion () { return this.getParameter(DeviceInfo.KEY_OS_VERSION); } - /** - * @param {String} carrier - * @return {DeviceInfo} - */ + * @param {String} carrier - Device mobile carrier (if applicable) + * @return {DeviceInfo} + */ setCarrier (carrier) { - this.validateType(String, carrier); - this.setParameter(DeviceInfo.KEY_CARRIER, carrier); return this; } /** - * @return {String} - */ + * @return {String} + */ getCarrier () { return this.getParameter(DeviceInfo.KEY_CARRIER); } - /** - * @param {Number} maxNumberRFCOMMPorts - * @return {DeviceInfo} - */ - setMaxNumberRFCOMMPorts (maxNumberRFCOMMPorts) { - this.validateType(Number, maxNumberRFCOMMPorts); - - this.setParameter(DeviceInfo.KEY_MAX_NUMBER_RFCOMM_PORTS, maxNumberRFCOMMPorts); + * @param {Number} ports - Omitted if connected not via BT. + * @return {DeviceInfo} + */ + setMaxNumberRFCOMMPorts (ports) { + this.setParameter(DeviceInfo.KEY_MAX_NUMBER_RFCOMM_PORTS, ports); return this; } /** - * @return {Number} - */ + * @return {Number} + */ getMaxNumberRFCOMMPorts () { return this.getParameter(DeviceInfo.KEY_MAX_NUMBER_RFCOMM_PORTS); } @@ -157,4 +148,4 @@ DeviceInfo.KEY_OS_VERSION = 'osVersion'; DeviceInfo.KEY_CARRIER = 'carrier'; DeviceInfo.KEY_MAX_NUMBER_RFCOMM_PORTS = 'maxNumberRFCOMMPorts'; -export { DeviceInfo }; +export { DeviceInfo }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/DeviceStatus.js b/lib/js/src/rpc/structs/DeviceStatus.js new file mode 100644 index 00000000..beb16575 --- /dev/null +++ b/lib/js/src/rpc/structs/DeviceStatus.js @@ -0,0 +1,240 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { PrimaryAudioSource } from '../enums/PrimaryAudioSource.js'; +import { DeviceLevelStatus } from '../enums/DeviceLevelStatus.js'; + +class DeviceStatus extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Boolean} on - References signal "CPM_VoiceRec_STAT". + * @return {DeviceStatus} + */ + setVoiceRecOn (on) { + this.setParameter(DeviceStatus.KEY_VOICE_REC_ON, on); + return this; + } + + /** + * @return {Boolean} + */ + getVoiceRecOn () { + return this.getParameter(DeviceStatus.KEY_VOICE_REC_ON); + } + + /** + * @param {Boolean} on - References signal "BT_ICON". + * @return {DeviceStatus} + */ + setBtIconOn (on) { + this.setParameter(DeviceStatus.KEY_BT_ICON_ON, on); + return this; + } + + /** + * @return {Boolean} + */ + getBtIconOn () { + return this.getParameter(DeviceStatus.KEY_BT_ICON_ON); + } + + /** + * @param {Boolean} active - References signal "CPM_Call_Active_STAT". + * @return {DeviceStatus} + */ + setCallActive (active) { + this.setParameter(DeviceStatus.KEY_CALL_ACTIVE, active); + return this; + } + + /** + * @return {Boolean} + */ + getCallActive () { + return this.getParameter(DeviceStatus.KEY_CALL_ACTIVE); + } + + /** + * @param {Boolean} roaming - References signal "CPM_Phone_Roaming_STAT". + * @return {DeviceStatus} + */ + setPhoneRoaming (roaming) { + this.setParameter(DeviceStatus.KEY_PHONE_ROAMING, roaming); + return this; + } + + /** + * @return {Boolean} + */ + getPhoneRoaming () { + return this.getParameter(DeviceStatus.KEY_PHONE_ROAMING); + } + + /** + * @param {Boolean} available - References signal "CPM_TextMsg_AVAL". + * @return {DeviceStatus} + */ + setTextMsgAvailable (available) { + this.setParameter(DeviceStatus.KEY_TEXT_MSG_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getTextMsgAvailable () { + return this.getParameter(DeviceStatus.KEY_TEXT_MSG_AVAILABLE); + } + + /** + * @param {DeviceLevelStatus} status - Device battery level status. References signal "CPM_Batt_Level_STAT". See + * DeviceLevelStatus. + * @return {DeviceStatus} + */ + setBattLevelStatus (status) { + this.validateType(DeviceLevelStatus, status); + this.setParameter(DeviceStatus.KEY_BATT_LEVEL_STATUS, status); + return this; + } + + /** + * @return {DeviceLevelStatus} + */ + getBattLevelStatus () { + return this.getObject(DeviceLevelStatus, DeviceStatus.KEY_BATT_LEVEL_STATUS); + } + + /** + * @param {Boolean} muted - References signal "CPM_Stereo_Audio_Output". + * @return {DeviceStatus} + */ + setStereoAudioOutputMuted (muted) { + this.setParameter(DeviceStatus.KEY_STEREO_AUDIO_OUTPUT_MUTED, muted); + return this; + } + + /** + * @return {Boolean} + */ + getStereoAudioOutputMuted () { + return this.getParameter(DeviceStatus.KEY_STEREO_AUDIO_OUTPUT_MUTED); + } + + /** + * @param {Boolean} muted - References signal "CPM_Mono_Audio_Output". + * @return {DeviceStatus} + */ + setMonoAudioOutputMuted (muted) { + this.setParameter(DeviceStatus.KEY_MONO_AUDIO_OUTPUT_MUTED, muted); + return this; + } + + /** + * @return {Boolean} + */ + getMonoAudioOutputMuted () { + return this.getParameter(DeviceStatus.KEY_MONO_AUDIO_OUTPUT_MUTED); + } + + /** + * @param {DeviceLevelStatus} status - Device signal level status. References signal "CPM_Signal_Strength_STAT". See + * DeviceLevelStatus. + * @return {DeviceStatus} + */ + setSignalLevelStatus (status) { + this.validateType(DeviceLevelStatus, status); + this.setParameter(DeviceStatus.KEY_SIGNAL_LEVEL_STATUS, status); + return this; + } + + /** + * @return {DeviceLevelStatus} + */ + getSignalLevelStatus () { + return this.getObject(DeviceLevelStatus, DeviceStatus.KEY_SIGNAL_LEVEL_STATUS); + } + + /** + * @param {PrimaryAudioSource} source - References signal "CPM_Stereo_PAS_Source". See PrimaryAudioSource. + * @return {DeviceStatus} + */ + setPrimaryAudioSource (source) { + this.validateType(PrimaryAudioSource, source); + this.setParameter(DeviceStatus.KEY_PRIMARY_AUDIO_SOURCE, source); + return this; + } + + /** + * @return {PrimaryAudioSource} + */ + getPrimaryAudioSource () { + return this.getObject(PrimaryAudioSource, DeviceStatus.KEY_PRIMARY_AUDIO_SOURCE); + } + + /** + * @param {Boolean} active - References signal "eCall_Event". + * @return {DeviceStatus} + */ + setECallEventActive (active) { + this.setParameter(DeviceStatus.KEY_E_CALL_EVENT_ACTIVE, active); + return this; + } + + /** + * @return {Boolean} + */ + getECallEventActive () { + return this.getParameter(DeviceStatus.KEY_E_CALL_EVENT_ACTIVE); + } +} + +DeviceStatus.KEY_VOICE_REC_ON = 'voiceRecOn'; +DeviceStatus.KEY_BT_ICON_ON = 'btIconOn'; +DeviceStatus.KEY_CALL_ACTIVE = 'callActive'; +DeviceStatus.KEY_PHONE_ROAMING = 'phoneRoaming'; +DeviceStatus.KEY_TEXT_MSG_AVAILABLE = 'textMsgAvailable'; +DeviceStatus.KEY_BATT_LEVEL_STATUS = 'battLevelStatus'; +DeviceStatus.KEY_STEREO_AUDIO_OUTPUT_MUTED = 'stereoAudioOutputMuted'; +DeviceStatus.KEY_MONO_AUDIO_OUTPUT_MUTED = 'monoAudioOutputMuted'; +DeviceStatus.KEY_SIGNAL_LEVEL_STATUS = 'signalLevelStatus'; +DeviceStatus.KEY_PRIMARY_AUDIO_SOURCE = 'primaryAudioSource'; +DeviceStatus.KEY_E_CALL_EVENT_ACTIVE = 'eCallEventActive'; + +export { DeviceStatus }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/DisplayCapabilities.js b/lib/js/src/rpc/structs/DisplayCapabilities.js index 834fb3c2..a7c2cc77 100644 --- a/lib/js/src/rpc/structs/DisplayCapabilities.js +++ b/lib/js/src/rpc/structs/DisplayCapabilities.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -30,179 +31,192 @@ * POSSIBILITY OF SUCH DAMAGE. */ -import { RpcStruct } from '../RpcStruct.js'; -import { TextField } from './TextField.js'; -import { ImageField } from './ImageField.js'; +import { MediaClockFormat } from '../enums/MediaClockFormat.js'; import { ScreenParams } from './ScreenParams.js'; +import { ImageField } from './ImageField.js'; +import { RpcStruct } from '../RpcStruct.js'; import { DisplayType } from '../enums/DisplayType.js'; -import { MediaClockFormat } from '../enums/MediaClockFormat.js'; +import { TextField } from './TextField.js'; +/** + * Contains information about the display capabilities. This struct is deprecated; please see the new SystemCapability + * DISPLAYS and corresponding struct DisplayCapability + * @deprecated + */ class DisplayCapabilities extends RpcStruct { + /** + * @deprecated + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {DisplayType} displayType - * @return {DisplayCapabilities} - */ - setDisplayType (displayType) { - this.validateType(DisplayType, displayType); - - this.setParameter(DisplayCapabilities.KEY_DISPLAY_TYPE, displayType); + * @deprecated + * @param {DisplayType} type - The type of the display. See DisplayType + * @return {DisplayCapabilities} + */ + setDisplayType (type) { + this.validateType(DisplayType, type); + this.setParameter(DisplayCapabilities.KEY_DISPLAY_TYPE, type); return this; } /** - * @return {DisplayType} - */ + * @deprecated + * @return {DisplayType} + */ getDisplayType () { return this.getObject(DisplayType, DisplayCapabilities.KEY_DISPLAY_TYPE); } - /** - * @param {String} displayName - * @return {DisplayCapabilities} - */ - setDisplayName (displayName) { - this.setParameter(DisplayCapabilities.KEY_DISPLAY_NAME, displayName); + * @deprecated + * @param {String} name - The name of the display the app is connected to. + * @return {DisplayCapabilities} + */ + setDisplayName (name) { + this.setParameter(DisplayCapabilities.KEY_DISPLAY_NAME, name); return this; } /** - * @return {String} - */ + * @deprecated + * @return {String} + */ getDisplayName () { return this.getParameter(DisplayCapabilities.KEY_DISPLAY_NAME); } /** - * @param {Array} textFields - * @return {DisplayCapabilities} - */ - setTextFields (textFields) { - // TODO make work with arrays - // this.validateType(TextField, textFields); - - this.setParameter(DisplayCapabilities.KEY_TEXT_FIELDS, textFields); + * @deprecated + * @param {TextField[]} fields - A set of all fields that support text data. See TextField + * @return {DisplayCapabilities} + */ + setTextFields (fields) { + this.validateType(TextField, fields, true); + this.setParameter(DisplayCapabilities.KEY_TEXT_FIELDS, fields); return this; } /** - * @return {Array} - */ + * @deprecated + * @return {TextField[]} + */ getTextFields () { return this.getObject(TextField, DisplayCapabilities.KEY_TEXT_FIELDS); } - /** - * @param {Array} imageFields - * @return {DisplayCapabilities} - */ - setImageFields (imageFields) { - // TODO make work with arrays - // this.validateType(ImageField, imageFields); - - this.setParameter(DisplayCapabilities.KEY_IMAGE_FIELDS, imageFields); + * @deprecated + * @param {ImageField[]} fields - A set of all fields that support images. See ImageField + * @return {DisplayCapabilities} + */ + setImageFields (fields) { + this.validateType(ImageField, fields, true); + this.setParameter(DisplayCapabilities.KEY_IMAGE_FIELDS, fields); return this; } /** - * @return {Array} - */ + * @deprecated + * @return {ImageField[]} + */ getImageFields () { return this.getObject(ImageField, DisplayCapabilities.KEY_IMAGE_FIELDS); } /** - * @param {Array} mediaClockFormats - * @return {DisplayCapabilities} - */ - setMediaClockFormats (mediaClockFormats) { - // TODO make work with arrays - // this.validateType(ImageField, mediaClockFormats); - - this.setParameter(DisplayCapabilities.KEY_MEDIA_CLOCK_FORMATS, mediaClockFormats); + * @deprecated + * @param {MediaClockFormat[]} formats - A set of all supported formats of the media clock. See MediaClockFormat + * @return {DisplayCapabilities} + */ + setMediaClockFormats (formats) { + this.validateType(MediaClockFormat, formats, true); + this.setParameter(DisplayCapabilities.KEY_MEDIA_CLOCK_FORMATS, formats); return this; } /** - * @return {Array} - */ + * @deprecated + * @return {MediaClockFormat[]} + */ getMediaClockFormats () { return this.getObject(MediaClockFormat, DisplayCapabilities.KEY_MEDIA_CLOCK_FORMATS); } - /** - * @param {Boolean} graphicSupported - * @return {DisplayCapabilities} - */ - setGraphicsSupported (graphicSupported) { - this.setParameter(DisplayCapabilities.KEY_GRAPHICS_SUPPORTED, graphicSupported); + * @deprecated + * @param {Boolean} supported - The display's persistent screen supports referencing a static or dynamic image. + * @return {DisplayCapabilities} + */ + setGraphicSupported (supported) { + this.setParameter(DisplayCapabilities.KEY_GRAPHIC_SUPPORTED, supported); return this; } /** - * @return {Boolean} - */ - getGraphicsSupported () { - return this.getParameter(DisplayCapabilities.KEY_GRAPHICS_SUPPORTED); + * @deprecated + * @return {Boolean} + */ + getGraphicSupported () { + return this.getParameter(DisplayCapabilities.KEY_GRAPHIC_SUPPORTED); } /** - * @param {Array} templatesAvailable - * @return {DisplayCapabilities} - */ - setTemplatesAvailable (templatesAvailable) { - // TODO make work with arrays - // this.validateType(String, templatesAvailable); - - this.setParameter(DisplayCapabilities.KEY_TEMPLATES_AVAILABLE, templatesAvailable); + * @deprecated + * @param {String[]} available - A set of all predefined persistent display templates available on headunit. To be + * referenced in SetDisplayLayout. + * @return {DisplayCapabilities} + */ + setTemplatesAvailable (available) { + this.setParameter(DisplayCapabilities.KEY_TEMPLATES_AVAILABLE, available); return this; } /** - * @return {Array} - */ + * @deprecated + * @return {String[]} + */ getTemplatesAvailable () { return this.getParameter(DisplayCapabilities.KEY_TEMPLATES_AVAILABLE); } /** - * @param {ScreenParams} screenParams - * @return {DisplayCapabilities} - */ - setScreenParams (screenParams) { - this.validateType(ScreenParams, screenParams); - - this.setParameter(DisplayCapabilities.KEY_SCREEN_PARAMS, screenParams); + * @deprecated + * @param {ScreenParams} params - A set of all parameters related to a prescribed screen area (e.g. for video / + * touch input). + * @return {DisplayCapabilities} + */ + setScreenParams (params) { + this.validateType(ScreenParams, params); + this.setParameter(DisplayCapabilities.KEY_SCREEN_PARAMS, params); return this; } /** - * @return {ScreenParams} - */ + * @deprecated + * @return {ScreenParams} + */ getScreenParams () { return this.getObject(ScreenParams, DisplayCapabilities.KEY_SCREEN_PARAMS); } - /** - * @param {Array} numCustomPresetsAvailable - * @return {DisplayCapabilities} - */ - setNumCustomPresetsAvailable (numCustomPresetsAvailable) { - // TODO make work with arrays - // this.validateType(Number, numCustomPresetsAvailable); - this.setParameter(DisplayCapabilities.KEY_NUM_CUSTOM_PRESETS_AVAILABLE, numCustomPresetsAvailable); + /** + * @deprecated + * @param {Number} available - The number of on-screen custom presets available (if any); otherwise omitted. + * @return {DisplayCapabilities} + */ + setNumCustomPresetsAvailable (available) { + this.setParameter(DisplayCapabilities.KEY_NUM_CUSTOM_PRESETS_AVAILABLE, available); return this; } /** - * @return {Array} - */ + * @deprecated + * @return {Number} + */ getNumCustomPresetsAvailable () { return this.getParameter(DisplayCapabilities.KEY_NUM_CUSTOM_PRESETS_AVAILABLE); } @@ -213,9 +227,9 @@ DisplayCapabilities.KEY_DISPLAY_NAME = 'displayName'; DisplayCapabilities.KEY_TEXT_FIELDS = 'textFields'; DisplayCapabilities.KEY_IMAGE_FIELDS = 'imageFields'; DisplayCapabilities.KEY_MEDIA_CLOCK_FORMATS = 'mediaClockFormats'; -DisplayCapabilities.KEY_GRAPHICS_SUPPORTED = 'graphicSupported'; +DisplayCapabilities.KEY_GRAPHIC_SUPPORTED = 'graphicSupported'; DisplayCapabilities.KEY_TEMPLATES_AVAILABLE = 'templatesAvailable'; DisplayCapabilities.KEY_SCREEN_PARAMS = 'screenParams'; DisplayCapabilities.KEY_NUM_CUSTOM_PRESETS_AVAILABLE = 'numCustomPresetsAvailable'; -export { DisplayCapabilities }; +export { DisplayCapabilities }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/DisplayCapability.js b/lib/js/src/rpc/structs/DisplayCapability.js new file mode 100644 index 00000000..256b58e4 --- /dev/null +++ b/lib/js/src/rpc/structs/DisplayCapability.js @@ -0,0 +1,111 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { WindowTypeCapabilities } from './WindowTypeCapabilities.js'; +import { WindowCapability } from './WindowCapability.js'; +import { RpcStruct } from '../RpcStruct.js'; + +class DisplayCapability extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {String} name + * @return {DisplayCapability} + */ + setDisplayName (name) { + this.setParameter(DisplayCapability.KEY_DISPLAY_NAME, name); + return this; + } + + /** + * @return {String} + */ + getDisplayName () { + return this.getParameter(DisplayCapability.KEY_DISPLAY_NAME); + } + + /** + * @param {WindowTypeCapabilities[]} supported - Informs the application how many windows the app is allowed to + * create per type. + * @return {DisplayCapability} + */ + setWindowTypeSupported (supported) { + this.validateType(WindowTypeCapabilities, supported, true); + this.setParameter(DisplayCapability.KEY_WINDOW_TYPE_SUPPORTED, supported); + return this; + } + + /** + * @return {WindowTypeCapabilities[]} + */ + getWindowTypeSupported () { + return this.getObject(WindowTypeCapabilities, DisplayCapability.KEY_WINDOW_TYPE_SUPPORTED); + } + + /** + * @param {WindowCapability[]} capabilities - Contains a list of capabilities of all windows related to the app. + * Once the app has registered the capabilities of all windows are + * provided. GetSystemCapability still allows requesting window + * capabilities of all windows. After registration, only windows with + * capabilities changed will be included. Following cases will cause only + * affected windows to be included: 1. App creates a new window. After + * the window is created, a system capability notification will be sent + * related only to the created window. 2. App sets a new layout to the + * window. The new layout changes window capabilties. The notification + * will reflect those changes to the single window. + * @return {DisplayCapability} + */ + setWindowCapabilities (capabilities) { + this.validateType(WindowCapability, capabilities, true); + this.setParameter(DisplayCapability.KEY_WINDOW_CAPABILITIES, capabilities); + return this; + } + + /** + * @return {WindowCapability[]} + */ + getWindowCapabilities () { + return this.getObject(WindowCapability, DisplayCapability.KEY_WINDOW_CAPABILITIES); + } +} + +DisplayCapability.KEY_DISPLAY_NAME = 'displayName'; +DisplayCapability.KEY_WINDOW_TYPE_SUPPORTED = 'windowTypeSupported'; +DisplayCapability.KEY_WINDOW_CAPABILITIES = 'windowCapabilities'; + +export { DisplayCapability }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/ECallInfo.js b/lib/js/src/rpc/structs/ECallInfo.js new file mode 100644 index 00000000..f1e0c47f --- /dev/null +++ b/lib/js/src/rpc/structs/ECallInfo.js @@ -0,0 +1,104 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { VehicleDataNotificationStatus } from '../enums/VehicleDataNotificationStatus.js'; +import { ECallConfirmationStatus } from '../enums/ECallConfirmationStatus.js'; + +class ECallInfo extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {VehicleDataNotificationStatus} status - References signal "eCallNotification_4A". See + * VehicleDataNotificationStatus. + * @return {ECallInfo} + */ + setECallNotificationStatus (status) { + this.validateType(VehicleDataNotificationStatus, status); + this.setParameter(ECallInfo.KEY_E_CALL_NOTIFICATION_STATUS, status); + return this; + } + + /** + * @return {VehicleDataNotificationStatus} + */ + getECallNotificationStatus () { + return this.getObject(VehicleDataNotificationStatus, ECallInfo.KEY_E_CALL_NOTIFICATION_STATUS); + } + + /** + * @param {VehicleDataNotificationStatus} status - References signal "eCallNotification". See + * VehicleDataNotificationStatus. + * @return {ECallInfo} + */ + setAuxECallNotificationStatus (status) { + this.validateType(VehicleDataNotificationStatus, status); + this.setParameter(ECallInfo.KEY_AUX_ECALL_NOTIFICATION_STATUS, status); + return this; + } + + /** + * @return {VehicleDataNotificationStatus} + */ + getAuxECallNotificationStatus () { + return this.getObject(VehicleDataNotificationStatus, ECallInfo.KEY_AUX_ECALL_NOTIFICATION_STATUS); + } + + /** + * @param {ECallConfirmationStatus} status - References signal "eCallConfirmation". See ECallConfirmationStatus. + * @return {ECallInfo} + */ + setECallConfirmationStatus (status) { + this.validateType(ECallConfirmationStatus, status); + this.setParameter(ECallInfo.KEY_E_CALL_CONFIRMATION_STATUS, status); + return this; + } + + /** + * @return {ECallConfirmationStatus} + */ + getECallConfirmationStatus () { + return this.getObject(ECallConfirmationStatus, ECallInfo.KEY_E_CALL_CONFIRMATION_STATUS); + } +} + +ECallInfo.KEY_E_CALL_NOTIFICATION_STATUS = 'eCallNotificationStatus'; +ECallInfo.KEY_AUX_ECALL_NOTIFICATION_STATUS = 'auxECallNotificationStatus'; +ECallInfo.KEY_E_CALL_CONFIRMATION_STATUS = 'eCallConfirmationStatus'; + +export { ECallInfo }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/EmergencyEvent.js b/lib/js/src/rpc/structs/EmergencyEvent.js new file mode 100644 index 00000000..04d28e4b --- /dev/null +++ b/lib/js/src/rpc/structs/EmergencyEvent.js @@ -0,0 +1,139 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { FuelCutoffStatus } from '../enums/FuelCutoffStatus.js'; +import { EmergencyEventType } from '../enums/EmergencyEventType.js'; +import { VehicleDataEventStatus } from '../enums/VehicleDataEventStatus.js'; + +class EmergencyEvent extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {EmergencyEventType} type - References signal "VedsEvntType_D_Ltchd". See EmergencyEventType. + * @return {EmergencyEvent} + */ + setEmergencyEventType (type) { + this.validateType(EmergencyEventType, type); + this.setParameter(EmergencyEvent.KEY_EMERGENCY_EVENT_TYPE, type); + return this; + } + + /** + * @return {EmergencyEventType} + */ + getEmergencyEventType () { + return this.getObject(EmergencyEventType, EmergencyEvent.KEY_EMERGENCY_EVENT_TYPE); + } + + /** + * @param {FuelCutoffStatus} status - References signal "RCM_FuelCutoff". See FuelCutoffStatus. + * @return {EmergencyEvent} + */ + setFuelCutoffStatus (status) { + this.validateType(FuelCutoffStatus, status); + this.setParameter(EmergencyEvent.KEY_FUEL_CUTOFF_STATUS, status); + return this; + } + + /** + * @return {FuelCutoffStatus} + */ + getFuelCutoffStatus () { + return this.getObject(FuelCutoffStatus, EmergencyEvent.KEY_FUEL_CUTOFF_STATUS); + } + + /** + * @param {VehicleDataEventStatus} event - References signal "VedsEvntRoll_D_Ltchd". See VehicleDataEventStatus. + * @return {EmergencyEvent} + */ + setRolloverEvent (event) { + this.validateType(VehicleDataEventStatus, event); + this.setParameter(EmergencyEvent.KEY_ROLLOVER_EVENT, event); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getRolloverEvent () { + return this.getObject(VehicleDataEventStatus, EmergencyEvent.KEY_ROLLOVER_EVENT); + } + + /** + * @param {Number} velocity - References signal "VedsMaxDeltaV_D_Ltchd". Change in velocity in KPH. Additional + * reserved values: 0x00 No event 0xFE Not supported 0xFF Fault + * @return {EmergencyEvent} + */ + setMaximumChangeVelocity (velocity) { + this.setParameter(EmergencyEvent.KEY_MAXIMUM_CHANGE_VELOCITY, velocity); + return this; + } + + /** + * @return {Number} + */ + getMaximumChangeVelocity () { + return this.getParameter(EmergencyEvent.KEY_MAXIMUM_CHANGE_VELOCITY); + } + + /** + * @param {VehicleDataEventStatus} events - References signal "VedsMultiEvnt_D_Ltchd". See VehicleDataEventStatus. + * @return {EmergencyEvent} + */ + setMultipleEvents (events) { + this.validateType(VehicleDataEventStatus, events); + this.setParameter(EmergencyEvent.KEY_MULTIPLE_EVENTS, events); + return this; + } + + /** + * @return {VehicleDataEventStatus} + */ + getMultipleEvents () { + return this.getObject(VehicleDataEventStatus, EmergencyEvent.KEY_MULTIPLE_EVENTS); + } +} + +EmergencyEvent.KEY_EMERGENCY_EVENT_TYPE = 'emergencyEventType'; +EmergencyEvent.KEY_FUEL_CUTOFF_STATUS = 'fuelCutoffStatus'; +EmergencyEvent.KEY_ROLLOVER_EVENT = 'rolloverEvent'; +EmergencyEvent.KEY_MAXIMUM_CHANGE_VELOCITY = 'maximumChangeVelocity'; +EmergencyEvent.KEY_MULTIPLE_EVENTS = 'multipleEvents'; + +export { EmergencyEvent }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/EqualizerSettings.js b/lib/js/src/rpc/structs/EqualizerSettings.js new file mode 100644 index 00000000..66de738b --- /dev/null +++ b/lib/js/src/rpc/structs/EqualizerSettings.js @@ -0,0 +1,100 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; + +/** + * Defines the each Equalizer channel settings. + */ +class EqualizerSettings extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Number} id + * @return {EqualizerSettings} + */ + setChannelId (id) { + this.setParameter(EqualizerSettings.KEY_CHANNEL_ID, id); + return this; + } + + /** + * @return {Number} + */ + getChannelId () { + return this.getParameter(EqualizerSettings.KEY_CHANNEL_ID); + } + + /** + * @param {String} name - read-only channel / frequency name (e.i. "Treble, Midrange, Bass" or "125 Hz") + * @return {EqualizerSettings} + */ + setChannelName (name) { + this.setParameter(EqualizerSettings.KEY_CHANNEL_NAME, name); + return this; + } + + /** + * @return {String} + */ + getChannelName () { + return this.getParameter(EqualizerSettings.KEY_CHANNEL_NAME); + } + + /** + * @param {Number} setting - Reflects the setting, from 0%-100%. + * @return {EqualizerSettings} + */ + setChannelSetting (setting) { + this.setParameter(EqualizerSettings.KEY_CHANNEL_SETTING, setting); + return this; + } + + /** + * @return {Number} + */ + getChannelSetting () { + return this.getParameter(EqualizerSettings.KEY_CHANNEL_SETTING); + } +} + +EqualizerSettings.KEY_CHANNEL_ID = 'channelId'; +EqualizerSettings.KEY_CHANNEL_NAME = 'channelName'; +EqualizerSettings.KEY_CHANNEL_SETTING = 'channelSetting'; + +export { EqualizerSettings }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/FuelRange.js b/lib/js/src/rpc/structs/FuelRange.js new file mode 100644 index 00000000..85be6e6d --- /dev/null +++ b/lib/js/src/rpc/structs/FuelRange.js @@ -0,0 +1,82 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { FuelType } from '../enums/FuelType.js'; + +class FuelRange extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {FuelType} type + * @return {FuelRange} + */ + setType (type) { + this.validateType(FuelType, type); + this.setParameter(FuelRange.KEY_TYPE, type); + return this; + } + + /** + * @return {FuelType} + */ + getType () { + return this.getObject(FuelType, FuelRange.KEY_TYPE); + } + + /** + * @param {Number} range - The estimate range in KM the vehicle can travel based on fuel level and consumption. + * @return {FuelRange} + */ + setRange (range) { + this.setParameter(FuelRange.KEY_RANGE, range); + return this; + } + + /** + * @return {Number} + */ + getRange () { + return this.getParameter(FuelRange.KEY_RANGE); + } +} + +FuelRange.KEY_TYPE = 'type'; +FuelRange.KEY_RANGE = 'range'; + +export { FuelRange }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/GPSData.js b/lib/js/src/rpc/structs/GPSData.js new file mode 100644 index 00000000..36323c69 --- /dev/null +++ b/lib/js/src/rpc/structs/GPSData.js @@ -0,0 +1,378 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { CompassDirection } from '../enums/CompassDirection.js'; +import { Dimension } from '../enums/Dimension.js'; + +/** + * Struct with the GPS data. + */ +class GPSData extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Number} degrees + * @return {GPSData} + */ + setLongitudeDegrees (degrees) { + this.setParameter(GPSData.KEY_LONGITUDE_DEGREES, degrees); + return this; + } + + /** + * @return {Number} + */ + getLongitudeDegrees () { + return this.getParameter(GPSData.KEY_LONGITUDE_DEGREES); + } + + /** + * @param {Number} degrees + * @return {GPSData} + */ + setLatitudeDegrees (degrees) { + this.setParameter(GPSData.KEY_LATITUDE_DEGREES, degrees); + return this; + } + + /** + * @return {Number} + */ + getLatitudeDegrees () { + return this.getParameter(GPSData.KEY_LATITUDE_DEGREES); + } + + /** + * @param {Number} year - The current UTC year. + * @return {GPSData} + */ + setUtcYear (year) { + this.setParameter(GPSData.KEY_UTC_YEAR, year); + return this; + } + + /** + * @return {Number} + */ + getUtcYear () { + return this.getParameter(GPSData.KEY_UTC_YEAR); + } + + /** + * @param {Number} month - The current UTC month. + * @return {GPSData} + */ + setUtcMonth (month) { + this.setParameter(GPSData.KEY_UTC_MONTH, month); + return this; + } + + /** + * @return {Number} + */ + getUtcMonth () { + return this.getParameter(GPSData.KEY_UTC_MONTH); + } + + /** + * @param {Number} day - The current UTC day. + * @return {GPSData} + */ + setUtcDay (day) { + this.setParameter(GPSData.KEY_UTC_DAY, day); + return this; + } + + /** + * @return {Number} + */ + getUtcDay () { + return this.getParameter(GPSData.KEY_UTC_DAY); + } + + /** + * @param {Number} hours - The current UTC hour. + * @return {GPSData} + */ + setUtcHours (hours) { + this.setParameter(GPSData.KEY_UTC_HOURS, hours); + return this; + } + + /** + * @return {Number} + */ + getUtcHours () { + return this.getParameter(GPSData.KEY_UTC_HOURS); + } + + /** + * @param {Number} minutes - The current UTC minute. + * @return {GPSData} + */ + setUtcMinutes (minutes) { + this.setParameter(GPSData.KEY_UTC_MINUTES, minutes); + return this; + } + + /** + * @return {Number} + */ + getUtcMinutes () { + return this.getParameter(GPSData.KEY_UTC_MINUTES); + } + + /** + * @param {Number} seconds - The current UTC second. + * @return {GPSData} + */ + setUtcSeconds (seconds) { + this.setParameter(GPSData.KEY_UTC_SECONDS, seconds); + return this; + } + + /** + * @return {Number} + */ + getUtcSeconds () { + return this.getParameter(GPSData.KEY_UTC_SECONDS); + } + + /** + * @param {CompassDirection} direction - See CompassDirection. + * @return {GPSData} + */ + setCompassDirection (direction) { + this.validateType(CompassDirection, direction); + this.setParameter(GPSData.KEY_COMPASS_DIRECTION, direction); + return this; + } + + /** + * @return {CompassDirection} + */ + getCompassDirection () { + return this.getObject(CompassDirection, GPSData.KEY_COMPASS_DIRECTION); + } + + /** + * @param {Number} pdop - PDOP. If undefined or unavailable, then value shall be set to 0. + * @return {GPSData} + */ + setPdop (pdop) { + this.setParameter(GPSData.KEY_PDOP, pdop); + return this; + } + + /** + * @return {Number} + */ + getPdop () { + return this.getParameter(GPSData.KEY_PDOP); + } + + /** + * @param {Number} hdop - HDOP. If value is unknown, value shall be set to 0. + * @return {GPSData} + */ + setHdop (hdop) { + this.setParameter(GPSData.KEY_HDOP, hdop); + return this; + } + + /** + * @return {Number} + */ + getHdop () { + return this.getParameter(GPSData.KEY_HDOP); + } + + /** + * @param {Number} vdop - VDOP. If value is unknown, value shall be set to 0. + * @return {GPSData} + */ + setVdop (vdop) { + this.setParameter(GPSData.KEY_VDOP, vdop); + return this; + } + + /** + * @return {Number} + */ + getVdop () { + return this.getParameter(GPSData.KEY_VDOP); + } + + /** + * @param {Boolean} actual - True, if actual. False, if inferred. + * @return {GPSData} + */ + setActual (actual) { + this.setParameter(GPSData.KEY_ACTUAL, actual); + return this; + } + + /** + * @return {Boolean} + */ + getActual () { + return this.getParameter(GPSData.KEY_ACTUAL); + } + + /** + * @param {Number} satellites - Number of satellites in view + * @return {GPSData} + */ + setSatellites (satellites) { + this.setParameter(GPSData.KEY_SATELLITES, satellites); + return this; + } + + /** + * @return {Number} + */ + getSatellites () { + return this.getParameter(GPSData.KEY_SATELLITES); + } + + /** + * @param {Dimension} dimension - See Dimension + * @return {GPSData} + */ + setDimension (dimension) { + this.validateType(Dimension, dimension); + this.setParameter(GPSData.KEY_DIMENSION, dimension); + return this; + } + + /** + * @return {Dimension} + */ + getDimension () { + return this.getObject(Dimension, GPSData.KEY_DIMENSION); + } + + /** + * @param {Number} altitude - Altitude in meters + * @return {GPSData} + */ + setAltitude (altitude) { + this.setParameter(GPSData.KEY_ALTITUDE, altitude); + return this; + } + + /** + * @return {Number} + */ + getAltitude () { + return this.getParameter(GPSData.KEY_ALTITUDE); + } + + /** + * @param {Number} heading - The heading. North is 0. Resolution is 0.01 + * @return {GPSData} + */ + setHeading (heading) { + this.setParameter(GPSData.KEY_HEADING, heading); + return this; + } + + /** + * @return {Number} + */ + getHeading () { + return this.getParameter(GPSData.KEY_HEADING); + } + + /** + * @param {Number} speed - The speed in KPH + * @return {GPSData} + */ + setSpeed (speed) { + this.setParameter(GPSData.KEY_SPEED, speed); + return this; + } + + /** + * @return {Number} + */ + getSpeed () { + return this.getParameter(GPSData.KEY_SPEED); + } + + /** + * @param {Boolean} shifted - True, if GPS lat/long, time, and altitude have been purposefully shifted (requires a + * proprietary algorithm to unshift). False, if the GPS data is raw and un-shifted. If + * not provided, then value is assumed False. + * @return {GPSData} + */ + setShifted (shifted) { + this.setParameter(GPSData.KEY_SHIFTED, shifted); + return this; + } + + /** + * @return {Boolean} + */ + getShifted () { + return this.getParameter(GPSData.KEY_SHIFTED); + } +} + +GPSData.KEY_LONGITUDE_DEGREES = 'longitudeDegrees'; +GPSData.KEY_LATITUDE_DEGREES = 'latitudeDegrees'; +GPSData.KEY_UTC_YEAR = 'utcYear'; +GPSData.KEY_UTC_MONTH = 'utcMonth'; +GPSData.KEY_UTC_DAY = 'utcDay'; +GPSData.KEY_UTC_HOURS = 'utcHours'; +GPSData.KEY_UTC_MINUTES = 'utcMinutes'; +GPSData.KEY_UTC_SECONDS = 'utcSeconds'; +GPSData.KEY_COMPASS_DIRECTION = 'compassDirection'; +GPSData.KEY_PDOP = 'pdop'; +GPSData.KEY_HDOP = 'hdop'; +GPSData.KEY_VDOP = 'vdop'; +GPSData.KEY_ACTUAL = 'actual'; +GPSData.KEY_SATELLITES = 'satellites'; +GPSData.KEY_DIMENSION = 'dimension'; +GPSData.KEY_ALTITUDE = 'altitude'; +GPSData.KEY_HEADING = 'heading'; +GPSData.KEY_SPEED = 'speed'; +GPSData.KEY_SHIFTED = 'shifted'; + +export { GPSData }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/Grid.js b/lib/js/src/rpc/structs/Grid.js index 61494ba6..e3d855b2 100644 --- a/lib/js/src/rpc/structs/Grid.js +++ b/lib/js/src/rpc/structs/Grid.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -32,103 +33,109 @@ import { RpcStruct } from '../RpcStruct.js'; +/** + * Describes a location (origin coordinates and span) of a vehicle component. + */ class Grid extends RpcStruct { + /** + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {Number} column - * @return {Grid} - */ - setColumn (column) { - this.setParameter(Grid.KEY_COLUMN, column); + * @param {Number} col + * @return {Grid} + */ + setColumn (col) { + this.setParameter(Grid.KEY_COLUMN, col); return this; } /** - * @return {Number} - */ + * @return {Number} + */ getColumn () { return this.getParameter(Grid.KEY_COLUMN); } /** - * @param {Number} row - * @return {Grid} - */ + * @param {Number} row + * @return {Grid} + */ setRow (row) { this.setParameter(Grid.KEY_ROW, row); return this; } /** - * @return {Number} - */ + * @return {Number} + */ getRow () { return this.getParameter(Grid.KEY_ROW); } /** - * @param {Number} level - * @return {Grid} - */ + * @param {Number} level + * @return {Grid} + */ setLevel (level) { this.setParameter(Grid.KEY_LEVEL, level); return this; } /** - * @return {Number} - */ + * @return {Number} + */ getLevel () { return this.getParameter(Grid.KEY_LEVEL); } /** - * @param {Number} columnSpan - * @return {Grid} - */ - setColumnSpan (columnSpan) { - this.setParameter(Grid.KEY_COLUMN_SPAN, columnSpan); + * @param {Number} colspan + * @return {Grid} + */ + setColumnSpan (colspan) { + this.setParameter(Grid.KEY_COLUMN_SPAN, colspan); return this; } /** - * @return {Number} - */ + * @return {Number} + */ getColumnSpan () { return this.getParameter(Grid.KEY_COLUMN_SPAN); } /** - * @param {Number} rowSpan - * @return {Grid} - */ - setRowSpan (rowSpan) { - this.setParameter(Grid.KEY_ROW_SPAN, rowSpan); + * @param {Number} rowspan + * @return {Grid} + */ + setRowSpan (rowspan) { + this.setParameter(Grid.KEY_ROW_SPAN, rowspan); return this; } /** - * @return {Number} - */ + * @return {Number} + */ getRowSpan () { return this.getParameter(Grid.KEY_ROW_SPAN); } /** - * @param {Number} levelSpan - * @return {Grid} - */ - setLevelSpan (levelSpan) { - this.setParameter(Grid.KEY_LEVEL_SPAN, levelSpan); + * @param {Number} levelspan + * @return {Grid} + */ + setLevelSpan (levelspan) { + this.setParameter(Grid.KEY_LEVEL_SPAN, levelspan); return this; } /** - * @return {Number} - */ + * @return {Number} + */ getLevelSpan () { return this.getParameter(Grid.KEY_LEVEL_SPAN); } @@ -141,4 +148,4 @@ Grid.KEY_COLUMN_SPAN = 'colspan'; Grid.KEY_ROW_SPAN = 'rowspan'; Grid.KEY_LEVEL_SPAN = 'levelspan'; -export { Grid }; +export { Grid }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/HMICapabilities.js b/lib/js/src/rpc/structs/HMICapabilities.js index 5953d56b..757d3452 100644 --- a/lib/js/src/rpc/structs/HMICapabilities.js +++ b/lib/js/src/rpc/structs/HMICapabilities.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -32,122 +33,122 @@ import { RpcStruct } from '../RpcStruct.js'; - class HMICapabilities extends RpcStruct { + /** + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {Boolean} navigation - * @return {HMICapabilities} - */ + * @param {Boolean} navigation - Availability of build in Nav. True: Available, False: Not Available + * @return {HMICapabilities} + */ setNavigation (navigation) { this.setParameter(HMICapabilities.KEY_NAVIGATION, navigation); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getNavigation () { return this.getParameter(HMICapabilities.KEY_NAVIGATION); } /** - * @param {Boolean} phoneCall - * @return {HMICapabilities} - */ - setPhoneCall (phoneCall) { - this.setParameter(HMICapabilities.KEY_PHONE_CALL, phoneCall); + * @param {Boolean} call - Availability of build in phone. True: Available, False: Not Available + * @return {HMICapabilities} + */ + setPhoneCall (call) { + this.setParameter(HMICapabilities.KEY_PHONE_CALL, call); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getPhoneCall () { return this.getParameter(HMICapabilities.KEY_PHONE_CALL); } /** - * @param {Boolean} videoStreaming - * @return {HMICapabilities} - */ - setVideoStreaming (videoStreaming) { - this.setParameter(HMICapabilities.KEY_VIDEO_STREAMING, videoStreaming); + * @param {Boolean} streaming - Availability of video streaming. + * @return {HMICapabilities} + */ + setVideoStreaming (streaming) { + this.setParameter(HMICapabilities.KEY_VIDEO_STREAMING, streaming); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getVideoStreaming () { return this.getParameter(HMICapabilities.KEY_VIDEO_STREAMING); } /** - * @param {Boolean} remoteControl - * @return {HMICapabilities} - */ - setRemoteControl (remoteControl) { - this.setParameter(HMICapabilities.KEY_REMOTE_CONTROL, remoteControl); + * @param {Boolean} control - Availability of remote control feature. True: Available, False: Not Available + * @return {HMICapabilities} + */ + setRemoteControl (control) { + this.setParameter(HMICapabilities.KEY_REMOTE_CONTROL, control); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getRemoteControl () { return this.getParameter(HMICapabilities.KEY_REMOTE_CONTROL); } /** - * @param {Boolean} appServices - * @return {HMICapabilities} - */ - setAppService (appServices) { - this.setParameter(HMICapabilities.KEY_APP_SERVICES, appServices); + * @param {Boolean} services - Availability of App Services functionality. True: Available, False: Not Available + * @return {HMICapabilities} + */ + setAppServices (services) { + this.setParameter(HMICapabilities.KEY_APP_SERVICES, services); return this; } /** - * @return {Boolean} - */ - getAppService () { + * @return {Boolean} + */ + getAppServices () { return this.getParameter(HMICapabilities.KEY_APP_SERVICES); } - /** - * @param {Boolean} displays - * @return {HMICapabilities} - */ + * @param {Boolean} displays - Availability of displays capability. True: Available, False: Not Available + * @return {HMICapabilities} + */ setDisplays (displays) { this.setParameter(HMICapabilities.KEY_DISPLAYS, displays); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getDisplays () { return this.getParameter(HMICapabilities.KEY_DISPLAYS); } - /** - * @param {Boolean} seatLocation - * @return {HMICapabilities} - */ - setSeatLocation (seatLocation) { - this.setParameter(HMICapabilities.KEY_SEAT_LOCATION, seatLocation); + * @param {Boolean} location - Availability of seat location feature. True: Available, False: Not Available + * @return {HMICapabilities} + */ + setSeatLocation (location) { + this.setParameter(HMICapabilities.KEY_SEAT_LOCATION, location); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getSeatLocation () { return this.getParameter(HMICapabilities.KEY_SEAT_LOCATION); } @@ -161,4 +162,4 @@ HMICapabilities.KEY_APP_SERVICES = 'appServices'; HMICapabilities.KEY_DISPLAYS = 'displays'; HMICapabilities.KEY_SEAT_LOCATION = 'seatLocation'; -export { HMICapabilities }; +export { HMICapabilities }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/HMIPermissions.js b/lib/js/src/rpc/structs/HMIPermissions.js new file mode 100644 index 00000000..7fab06c9 --- /dev/null +++ b/lib/js/src/rpc/structs/HMIPermissions.js @@ -0,0 +1,83 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { HMILevel } from '../enums/HMILevel.js'; +import { RpcStruct } from '../RpcStruct.js'; + +class HMIPermissions extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {HMILevel[]} allowed - A set of all HMI levels that are permitted for this given RPC. + * @return {HMIPermissions} + */ + setAllowed (allowed) { + this.validateType(HMILevel, allowed, true); + this.setParameter(HMIPermissions.KEY_ALLOWED, allowed); + return this; + } + + /** + * @return {HMILevel[]} + */ + getAllowed () { + return this.getObject(HMILevel, HMIPermissions.KEY_ALLOWED); + } + + /** + * @param {HMILevel[]} disallowed - A set of all HMI levels that are prohibited for this given RPC. + * @return {HMIPermissions} + */ + setUserDisallowed (disallowed) { + this.validateType(HMILevel, disallowed, true); + this.setParameter(HMIPermissions.KEY_USER_DISALLOWED, disallowed); + return this; + } + + /** + * @return {HMILevel[]} + */ + getUserDisallowed () { + return this.getObject(HMILevel, HMIPermissions.KEY_USER_DISALLOWED); + } +} + +HMIPermissions.KEY_ALLOWED = 'allowed'; +HMIPermissions.KEY_USER_DISALLOWED = 'userDisallowed'; + +export { HMIPermissions }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/HMISettingsControlCapabilities.js b/lib/js/src/rpc/structs/HMISettingsControlCapabilities.js new file mode 100644 index 00000000..50707982 --- /dev/null +++ b/lib/js/src/rpc/structs/HMISettingsControlCapabilities.js @@ -0,0 +1,134 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { ModuleInfo } from './ModuleInfo.js'; + +class HMISettingsControlCapabilities extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {String} name - The short friendly name of the hmi setting module. It should not be used to identify a + * module by mobile application. + * @return {HMISettingsControlCapabilities} + */ + setModuleName (name) { + this.setParameter(HMISettingsControlCapabilities.KEY_MODULE_NAME, name); + return this; + } + + /** + * @return {String} + */ + getModuleName () { + return this.getParameter(HMISettingsControlCapabilities.KEY_MODULE_NAME); + } + + /** + * @param {ModuleInfo} info - Information about a RC module, including its id. + * @return {HMISettingsControlCapabilities} + */ + setModuleInfo (info) { + this.validateType(ModuleInfo, info); + this.setParameter(HMISettingsControlCapabilities.KEY_MODULE_INFO, info); + return this; + } + + /** + * @return {ModuleInfo} + */ + getModuleInfo () { + return this.getObject(ModuleInfo, HMISettingsControlCapabilities.KEY_MODULE_INFO); + } + + /** + * @param {Boolean} available - Availability of the control of distance unit. + * @return {HMISettingsControlCapabilities} + */ + setDistanceUnitAvailable (available) { + this.setParameter(HMISettingsControlCapabilities.KEY_DISTANCE_UNIT_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getDistanceUnitAvailable () { + return this.getParameter(HMISettingsControlCapabilities.KEY_DISTANCE_UNIT_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the control of temperature unit. + * @return {HMISettingsControlCapabilities} + */ + setTemperatureUnitAvailable (available) { + this.setParameter(HMISettingsControlCapabilities.KEY_TEMPERATURE_UNIT_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getTemperatureUnitAvailable () { + return this.getParameter(HMISettingsControlCapabilities.KEY_TEMPERATURE_UNIT_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the control of HMI display mode. + * @return {HMISettingsControlCapabilities} + */ + setDisplayModeUnitAvailable (available) { + this.setParameter(HMISettingsControlCapabilities.KEY_DISPLAY_MODE_UNIT_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getDisplayModeUnitAvailable () { + return this.getParameter(HMISettingsControlCapabilities.KEY_DISPLAY_MODE_UNIT_AVAILABLE); + } +} + +HMISettingsControlCapabilities.KEY_MODULE_NAME = 'moduleName'; +HMISettingsControlCapabilities.KEY_MODULE_INFO = 'moduleInfo'; +HMISettingsControlCapabilities.KEY_DISTANCE_UNIT_AVAILABLE = 'distanceUnitAvailable'; +HMISettingsControlCapabilities.KEY_TEMPERATURE_UNIT_AVAILABLE = 'temperatureUnitAvailable'; +HMISettingsControlCapabilities.KEY_DISPLAY_MODE_UNIT_AVAILABLE = 'displayModeUnitAvailable'; + +export { HMISettingsControlCapabilities }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/HMISettingsControlData.js b/lib/js/src/rpc/structs/HMISettingsControlData.js new file mode 100644 index 00000000..6fc066be --- /dev/null +++ b/lib/js/src/rpc/structs/HMISettingsControlData.js @@ -0,0 +1,106 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { DisplayMode } from '../enums/DisplayMode.js'; +import { RpcStruct } from '../RpcStruct.js'; +import { DistanceUnit } from '../enums/DistanceUnit.js'; +import { TemperatureUnit } from '../enums/TemperatureUnit.js'; + +/** + * Corresponds to "HMI_SETTINGS" ModuleType + */ +class HMISettingsControlData extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {DisplayMode} mode + * @return {HMISettingsControlData} + */ + setDisplayMode (mode) { + this.validateType(DisplayMode, mode); + this.setParameter(HMISettingsControlData.KEY_DISPLAY_MODE, mode); + return this; + } + + /** + * @return {DisplayMode} + */ + getDisplayMode () { + return this.getObject(DisplayMode, HMISettingsControlData.KEY_DISPLAY_MODE); + } + + /** + * @param {TemperatureUnit} unit + * @return {HMISettingsControlData} + */ + setTemperatureUnit (unit) { + this.validateType(TemperatureUnit, unit); + this.setParameter(HMISettingsControlData.KEY_TEMPERATURE_UNIT, unit); + return this; + } + + /** + * @return {TemperatureUnit} + */ + getTemperatureUnit () { + return this.getObject(TemperatureUnit, HMISettingsControlData.KEY_TEMPERATURE_UNIT); + } + + /** + * @param {DistanceUnit} unit + * @return {HMISettingsControlData} + */ + setDistanceUnit (unit) { + this.validateType(DistanceUnit, unit); + this.setParameter(HMISettingsControlData.KEY_DISTANCE_UNIT, unit); + return this; + } + + /** + * @return {DistanceUnit} + */ + getDistanceUnit () { + return this.getObject(DistanceUnit, HMISettingsControlData.KEY_DISTANCE_UNIT); + } +} + +HMISettingsControlData.KEY_DISPLAY_MODE = 'displayMode'; +HMISettingsControlData.KEY_TEMPERATURE_UNIT = 'temperatureUnit'; +HMISettingsControlData.KEY_DISTANCE_UNIT = 'distanceUnit'; + +export { HMISettingsControlData }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/HapticRect.js b/lib/js/src/rpc/structs/HapticRect.js new file mode 100644 index 00000000..1f91bd10 --- /dev/null +++ b/lib/js/src/rpc/structs/HapticRect.js @@ -0,0 +1,86 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { Rectangle } from './Rectangle.js'; +import { RpcStruct } from '../RpcStruct.js'; + +/** + * Defines haptic data for each user control object for video streaming application + */ +class HapticRect extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Number} id - A user control spatial identifier + * @return {HapticRect} + */ + setId (id) { + this.setParameter(HapticRect.KEY_ID, id); + return this; + } + + /** + * @return {Number} + */ + getId () { + return this.getParameter(HapticRect.KEY_ID); + } + + /** + * @param {Rectangle} rect - The position of the haptic rectangle to be highlighted. The center of this rectangle + * will be "touched" when a press occurs. + * @return {HapticRect} + */ + setRect (rect) { + this.validateType(Rectangle, rect); + this.setParameter(HapticRect.KEY_RECT, rect); + return this; + } + + /** + * @return {Rectangle} + */ + getRect () { + return this.getObject(Rectangle, HapticRect.KEY_RECT); + } +} + +HapticRect.KEY_ID = 'id'; +HapticRect.KEY_RECT = 'rect'; + +export { HapticRect }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/HeadLampStatus.js b/lib/js/src/rpc/structs/HeadLampStatus.js new file mode 100644 index 00000000..a6bbd3bb --- /dev/null +++ b/lib/js/src/rpc/structs/HeadLampStatus.js @@ -0,0 +1,99 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { AmbientLightStatus } from '../enums/AmbientLightStatus.js'; + +class HeadLampStatus extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Boolean} on - Status of the low beam lamps. References signal "HeadLampLoActv_B_Stat". + * @return {HeadLampStatus} + */ + setLowBeamsOn (on) { + this.setParameter(HeadLampStatus.KEY_LOW_BEAMS_ON, on); + return this; + } + + /** + * @return {Boolean} + */ + getLowBeamsOn () { + return this.getParameter(HeadLampStatus.KEY_LOW_BEAMS_ON); + } + + /** + * @param {Boolean} on - Status of the high beam lamps. References signal "HeadLghtHiOn_B_Stat". + * @return {HeadLampStatus} + */ + setHighBeamsOn (on) { + this.setParameter(HeadLampStatus.KEY_HIGH_BEAMS_ON, on); + return this; + } + + /** + * @return {Boolean} + */ + getHighBeamsOn () { + return this.getParameter(HeadLampStatus.KEY_HIGH_BEAMS_ON); + } + + /** + * @param {AmbientLightStatus} status - Status of the ambient light sensor. + * @return {HeadLampStatus} + */ + setAmbientLightSensorStatus (status) { + this.validateType(AmbientLightStatus, status); + this.setParameter(HeadLampStatus.KEY_AMBIENT_LIGHT_SENSOR_STATUS, status); + return this; + } + + /** + * @return {AmbientLightStatus} + */ + getAmbientLightSensorStatus () { + return this.getObject(AmbientLightStatus, HeadLampStatus.KEY_AMBIENT_LIGHT_SENSOR_STATUS); + } +} + +HeadLampStatus.KEY_LOW_BEAMS_ON = 'lowBeamsOn'; +HeadLampStatus.KEY_HIGH_BEAMS_ON = 'highBeamsOn'; +HeadLampStatus.KEY_AMBIENT_LIGHT_SENSOR_STATUS = 'ambientLightSensorStatus'; + +export { HeadLampStatus }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/Image.js b/lib/js/src/rpc/structs/Image.js index 49c70264..0a9bfae1 100644 --- a/lib/js/src/rpc/structs/Image.js +++ b/lib/js/src/rpc/structs/Image.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -35,58 +36,58 @@ import { ImageType } from '../enums/ImageType.js'; class Image extends RpcStruct { /** - * @constructor - */ + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {String} value - * @return {Image} - */ + * @param {String} value - Either the static hex icon value or the binary image file name identifier (sent by + * PutFile). + * @return {Image} + */ setValue (value) { this.setParameter(Image.KEY_VALUE, value); return this; } /** - * @return {String} - */ + * @return {String} + */ getValue () { return this.getParameter(Image.KEY_VALUE); } /** - * @param {ImageType} type - * @return {Image} - */ + * @param {ImageType} type - Describes, whether it is a static or dynamic image. + * @return {Image} + */ setImageType (type) { this.validateType(ImageType, type); - this.setParameter(Image.KEY_IMAGE_TYPE, type); return this; } /** - * @return {ImageType} - */ + * @return {ImageType} + */ getImageType () { return this.getObject(ImageType, Image.KEY_IMAGE_TYPE); } /** - * @param {Boolean} isTemplate - * @return {Image} - */ - setIsTemplate (isTemplate) { - this.setParameter(Image.KEY_IS_TEMPLATE, isTemplate); + * @param {Boolean} template - If true, the image is a template image and can be recolored by the HMI + * @return {Image} + */ + setIsTemplate (template) { + this.setParameter(Image.KEY_IS_TEMPLATE, template); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getIsTemplate () { return this.getParameter(Image.KEY_IS_TEMPLATE); } @@ -96,4 +97,4 @@ Image.KEY_VALUE = 'value'; Image.KEY_IMAGE_TYPE = 'imageType'; Image.KEY_IS_TEMPLATE = 'isTemplate'; -export { Image }; +export { Image }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/ImageField.js b/lib/js/src/rpc/structs/ImageField.js index bba8e1f3..0060d680 100644 --- a/lib/js/src/rpc/structs/ImageField.js +++ b/lib/js/src/rpc/structs/ImageField.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -32,64 +33,64 @@ import { RpcStruct } from '../RpcStruct.js'; import { ImageResolution } from './ImageResolution.js'; -import { FileType } from '../enums/FileType.js'; import { ImageFieldName } from '../enums/ImageFieldName.js'; +import { FileType } from '../enums/FileType.js'; class ImageField extends RpcStruct { + /** + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {ImageFieldName} imageFieldName - * @return {ImageField} - */ - setImageFieldName (imageFieldName) { - this.validateType(ImageFieldName, imageFieldName); - - this.setParameter(ImageField.KEY_NAME, imageFieldName); + * @param {ImageFieldName} name - The name that identifies the field. See ImageFieldName. + * @return {ImageField} + */ + setName (name) { + this.validateType(ImageFieldName, name); + this.setParameter(ImageField.KEY_NAME, name); return this; } /** - * @return {ImageFieldName} - */ - getImageFieldName () { + * @return {ImageFieldName} + */ + getName () { return this.getObject(ImageFieldName, ImageField.KEY_NAME); } /** - * @param {FileType[]} imageTypeSupported - * @return {ImageField} - */ - setImageTypeSupported (imageTypeSupported) { - this.validateType(FileType, imageTypeSupported, true); - - this.setParameter(ImageField.KEY_IMAGE_TYPE_SUPPORTED, imageTypeSupported); + * @param {FileType[]} supported - The image types that are supported in this field. See FileType. + * @return {ImageField} + */ + setImageTypeSupported (supported) { + this.validateType(FileType, supported, true); + this.setParameter(ImageField.KEY_IMAGE_TYPE_SUPPORTED, supported); return this; } /** - * @return {FileType} - */ + * @return {FileType[]} + */ getImageTypeSupported () { return this.getObject(FileType, ImageField.KEY_IMAGE_TYPE_SUPPORTED); } /** - * @param {ImageResolution} imageResolution - * @return {ImageField} - */ - setImageResolution (imageResolution) { - this.validateType(ImageResolution, imageResolution); - - this.setParameter(ImageField.KEY_IMAGE_RESOLUTION, imageResolution); + * @param {ImageResolution} resolution - The image resolution of this field. + * @return {ImageField} + */ + setImageResolution (resolution) { + this.validateType(ImageResolution, resolution); + this.setParameter(ImageField.KEY_IMAGE_RESOLUTION, resolution); return this; } /** - * @return {ImageResolution} - */ + * @return {ImageResolution} + */ getImageResolution () { return this.getObject(ImageResolution, ImageField.KEY_IMAGE_RESOLUTION); } @@ -99,4 +100,4 @@ ImageField.KEY_NAME = 'name'; ImageField.KEY_IMAGE_TYPE_SUPPORTED = 'imageTypeSupported'; ImageField.KEY_IMAGE_RESOLUTION = 'imageResolution'; -export { ImageField }; +export { ImageField }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/ImageResolution.js b/lib/js/src/rpc/structs/ImageResolution.js index 59a93fd9..7ed7e2ac 100644 --- a/lib/js/src/rpc/structs/ImageResolution.js +++ b/lib/js/src/rpc/structs/ImageResolution.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -33,38 +34,41 @@ import { RpcStruct } from '../RpcStruct.js'; class ImageResolution extends RpcStruct { + /** + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {Number} resolutionWidth - * @return {ImageResolution} - */ - setResolutionWidth (resolutionWidth) { - this.setParameter(ImageResolution.KEY_RESOLUTION_WIDTH, resolutionWidth); + * @param {Number} width - The image resolution width. + * @return {ImageResolution} + */ + setResolutionWidth (width) { + this.setParameter(ImageResolution.KEY_RESOLUTION_WIDTH, width); return this; } /** - * @return {Number} - */ + * @return {Number} + */ getResolutionWidth () { return this.getParameter(ImageResolution.KEY_RESOLUTION_WIDTH); } /** - * @param {Number} resolutionHeight - * @return {ImageResolution} - */ - setResolutionHeight (resolutionHeight) { - this.setParameter(ImageResolution.KEY_RESOLUTION_HEIGHT, resolutionHeight); + * @param {Number} height - The image resolution height. + * @return {ImageResolution} + */ + setResolutionHeight (height) { + this.setParameter(ImageResolution.KEY_RESOLUTION_HEIGHT, height); return this; } /** - * @return {Number} - */ + * @return {Number} + */ getResolutionHeight () { return this.getParameter(ImageResolution.KEY_RESOLUTION_HEIGHT); } @@ -73,4 +77,4 @@ class ImageResolution extends RpcStruct { ImageResolution.KEY_RESOLUTION_WIDTH = 'resolutionWidth'; ImageResolution.KEY_RESOLUTION_HEIGHT = 'resolutionHeight'; -export { ImageResolution }; +export { ImageResolution }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/KeyboardProperties.js b/lib/js/src/rpc/structs/KeyboardProperties.js new file mode 100644 index 00000000..4a373ebb --- /dev/null +++ b/lib/js/src/rpc/structs/KeyboardProperties.js @@ -0,0 +1,160 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { KeyboardLayout } from '../enums/KeyboardLayout.js'; +import { Language } from '../enums/Language.js'; +import { KeypressMode } from '../enums/KeypressMode.js'; + +/** + * Configuration of on-screen keyboard (if available). + */ +class KeyboardProperties extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Language} language - The keyboard language. + * @return {KeyboardProperties} + */ + setLanguage (language) { + this.validateType(Language, language); + this.setParameter(KeyboardProperties.KEY_LANGUAGE, language); + return this; + } + + /** + * @return {Language} + */ + getLanguage () { + return this.getObject(Language, KeyboardProperties.KEY_LANGUAGE); + } + + /** + * @param {KeyboardLayout} layout - Desired keyboard layout. + * @return {KeyboardProperties} + */ + setKeyboardLayout (layout) { + this.validateType(KeyboardLayout, layout); + this.setParameter(KeyboardProperties.KEY_KEYBOARD_LAYOUT, layout); + return this; + } + + /** + * @return {KeyboardLayout} + */ + getKeyboardLayout () { + return this.getObject(KeyboardLayout, KeyboardProperties.KEY_KEYBOARD_LAYOUT); + } + + /** + * @param {KeypressMode} mode - Desired keypress mode. If omitted, this value will be set to RESEND_CURRENT_ENTRY. + * @return {KeyboardProperties} + */ + setKeypressMode (mode) { + this.validateType(KeypressMode, mode); + this.setParameter(KeyboardProperties.KEY_KEYPRESS_MODE, mode); + return this; + } + + /** + * @return {KeypressMode} + */ + getKeypressMode () { + return this.getObject(KeypressMode, KeyboardProperties.KEY_KEYPRESS_MODE); + } + + /** + * @param {String[]} list - Array of keyboard characters to enable. All omitted characters will be greyed out + * (disabled) on the keyboard. If omitted, the entire keyboard will be enabled. + * @return {KeyboardProperties} + */ + setLimitedCharacterList (list) { + this.setParameter(KeyboardProperties.KEY_LIMITED_CHARACTER_LIST, list); + return this; + } + + /** + * @return {String[]} + */ + getLimitedCharacterList () { + return this.getParameter(KeyboardProperties.KEY_LIMITED_CHARACTER_LIST); + } + + /** + * @param {String} text - Deprecated, use autoCompleteList instead. + * @return {KeyboardProperties} + */ + setAutoCompleteText (text) { + this.setParameter(KeyboardProperties.KEY_AUTO_COMPLETE_TEXT, text); + return this; + } + + /** + * @return {String} + */ + getAutoCompleteText () { + return this.getParameter(KeyboardProperties.KEY_AUTO_COMPLETE_TEXT); + } + + /** + * @param {String[]} list - Allows an app to prepopulate the text field with a list of suggested or completed + * entries as the user types. If empty, the auto-complete list will be removed from the + * screen. + * @return {KeyboardProperties} + */ + setAutoCompleteList (list) { + this.setParameter(KeyboardProperties.KEY_AUTO_COMPLETE_LIST, list); + return this; + } + + /** + * @return {String[]} + */ + getAutoCompleteList () { + return this.getParameter(KeyboardProperties.KEY_AUTO_COMPLETE_LIST); + } +} + +KeyboardProperties.KEY_LANGUAGE = 'language'; +KeyboardProperties.KEY_KEYBOARD_LAYOUT = 'keyboardLayout'; +KeyboardProperties.KEY_KEYPRESS_MODE = 'keypressMode'; +KeyboardProperties.KEY_LIMITED_CHARACTER_LIST = 'limitedCharacterList'; +KeyboardProperties.KEY_AUTO_COMPLETE_TEXT = 'autoCompleteText'; +KeyboardProperties.KEY_AUTO_COMPLETE_LIST = 'autoCompleteList'; + +export { KeyboardProperties }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/LightCapabilities.js b/lib/js/src/rpc/structs/LightCapabilities.js new file mode 100644 index 00000000..0ee890be --- /dev/null +++ b/lib/js/src/rpc/structs/LightCapabilities.js @@ -0,0 +1,117 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { LightName } from '../enums/LightName.js'; + +class LightCapabilities extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {LightName} name + * @return {LightCapabilities} + */ + setName (name) { + this.validateType(LightName, name); + this.setParameter(LightCapabilities.KEY_NAME, name); + return this; + } + + /** + * @return {LightName} + */ + getName () { + return this.getObject(LightName, LightCapabilities.KEY_NAME); + } + + /** + * @param {Boolean} available - Indicates if the status (ON/OFF) can be set remotely. App shall not use read-only + * values (RAMP_UP/RAMP_DOWN/UNKNOWN/INVALID) in a setInteriorVehicleData request. + * @return {LightCapabilities} + */ + setStatusAvailable (available) { + this.setParameter(LightCapabilities.KEY_STATUS_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getStatusAvailable () { + return this.getParameter(LightCapabilities.KEY_STATUS_AVAILABLE); + } + + /** + * @param {Boolean} available - Indicates if the light's density can be set remotely (similar to a dimmer). + * @return {LightCapabilities} + */ + setDensityAvailable (available) { + this.setParameter(LightCapabilities.KEY_DENSITY_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getDensityAvailable () { + return this.getParameter(LightCapabilities.KEY_DENSITY_AVAILABLE); + } + + /** + * @param {Boolean} available - Indicates if the light's color can be set remotely by using the sRGB color space. + * @return {LightCapabilities} + */ + setRgbColorSpaceAvailable (available) { + this.setParameter(LightCapabilities.KEY_RGB_COLOR_SPACE_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getRgbColorSpaceAvailable () { + return this.getParameter(LightCapabilities.KEY_RGB_COLOR_SPACE_AVAILABLE); + } +} + +LightCapabilities.KEY_NAME = 'name'; +LightCapabilities.KEY_STATUS_AVAILABLE = 'statusAvailable'; +LightCapabilities.KEY_DENSITY_AVAILABLE = 'densityAvailable'; +LightCapabilities.KEY_RGB_COLOR_SPACE_AVAILABLE = 'rgbColorSpaceAvailable'; + +export { LightCapabilities }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/LightControlCapabilities.js b/lib/js/src/rpc/structs/LightControlCapabilities.js new file mode 100644 index 00000000..94571be7 --- /dev/null +++ b/lib/js/src/rpc/structs/LightControlCapabilities.js @@ -0,0 +1,102 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { LightCapabilities } from './LightCapabilities.js'; +import { ModuleInfo } from './ModuleInfo.js'; + +class LightControlCapabilities extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {String} name - The short friendly name of the light control module. It should not be used to identify a + * module by mobile application. + * @return {LightControlCapabilities} + */ + setModuleName (name) { + this.setParameter(LightControlCapabilities.KEY_MODULE_NAME, name); + return this; + } + + /** + * @return {String} + */ + getModuleName () { + return this.getParameter(LightControlCapabilities.KEY_MODULE_NAME); + } + + /** + * @param {ModuleInfo} info - Information about a RC module, including its id. + * @return {LightControlCapabilities} + */ + setModuleInfo (info) { + this.validateType(ModuleInfo, info); + this.setParameter(LightControlCapabilities.KEY_MODULE_INFO, info); + return this; + } + + /** + * @return {ModuleInfo} + */ + getModuleInfo () { + return this.getObject(ModuleInfo, LightControlCapabilities.KEY_MODULE_INFO); + } + + /** + * @param {LightCapabilities[]} lights - An array of available LightCapabilities that are controllable. + * @return {LightControlCapabilities} + */ + setSupportedLights (lights) { + this.validateType(LightCapabilities, lights, true); + this.setParameter(LightControlCapabilities.KEY_SUPPORTED_LIGHTS, lights); + return this; + } + + /** + * @return {LightCapabilities[]} + */ + getSupportedLights () { + return this.getObject(LightCapabilities, LightControlCapabilities.KEY_SUPPORTED_LIGHTS); + } +} + +LightControlCapabilities.KEY_MODULE_NAME = 'moduleName'; +LightControlCapabilities.KEY_MODULE_INFO = 'moduleInfo'; +LightControlCapabilities.KEY_SUPPORTED_LIGHTS = 'supportedLights'; + +export { LightControlCapabilities }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/LightControlData.js b/lib/js/src/rpc/structs/LightControlData.js new file mode 100644 index 00000000..5a968d7c --- /dev/null +++ b/lib/js/src/rpc/structs/LightControlData.js @@ -0,0 +1,66 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { LightState } from './LightState.js'; + +class LightControlData extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {LightState[]} state - An array of LightNames and their current or desired status. No change to the status + * of the LightNames that are not listed in the array. + * @return {LightControlData} + */ + setLightState (state) { + this.validateType(LightState, state, true); + this.setParameter(LightControlData.KEY_LIGHT_STATE, state); + return this; + } + + /** + * @return {LightState[]} + */ + getLightState () { + return this.getObject(LightState, LightControlData.KEY_LIGHT_STATE); + } +} + +LightControlData.KEY_LIGHT_STATE = 'lightState'; + +export { LightControlData }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/LightState.js b/lib/js/src/rpc/structs/LightState.js new file mode 100644 index 00000000..af2fc8d7 --- /dev/null +++ b/lib/js/src/rpc/structs/LightState.js @@ -0,0 +1,120 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { LightStatus } from '../enums/LightStatus.js'; +import { LightName } from '../enums/LightName.js'; +import { RGBColor } from './RGBColor.js'; + +class LightState extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {LightName} id - The name of a light or a group of lights. + * @return {LightState} + */ + setId (id) { + this.validateType(LightName, id); + this.setParameter(LightState.KEY_ID, id); + return this; + } + + /** + * @return {LightName} + */ + getId () { + return this.getObject(LightName, LightState.KEY_ID); + } + + /** + * @param {LightStatus} status + * @return {LightState} + */ + setStatus (status) { + this.validateType(LightStatus, status); + this.setParameter(LightState.KEY_STATUS, status); + return this; + } + + /** + * @return {LightStatus} + */ + getStatus () { + return this.getObject(LightStatus, LightState.KEY_STATUS); + } + + /** + * @param {Number} density + * @return {LightState} + */ + setDensity (density) { + this.setParameter(LightState.KEY_DENSITY, density); + return this; + } + + /** + * @return {Number} + */ + getDensity () { + return this.getParameter(LightState.KEY_DENSITY); + } + + /** + * @param {RGBColor} color + * @return {LightState} + */ + setColor (color) { + this.validateType(RGBColor, color); + this.setParameter(LightState.KEY_COLOR, color); + return this; + } + + /** + * @return {RGBColor} + */ + getColor () { + return this.getObject(RGBColor, LightState.KEY_COLOR); + } +} + +LightState.KEY_ID = 'id'; +LightState.KEY_STATUS = 'status'; +LightState.KEY_DENSITY = 'density'; +LightState.KEY_COLOR = 'color'; + +export { LightState }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/LocationDetails.js b/lib/js/src/rpc/structs/LocationDetails.js new file mode 100644 index 00000000..0b5a368e --- /dev/null +++ b/lib/js/src/rpc/structs/LocationDetails.js @@ -0,0 +1,171 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { Coordinate } from './Coordinate.js'; +import { Image } from './Image.js'; +import { OASISAddress } from './OASISAddress.js'; +import { RpcStruct } from '../RpcStruct.js'; + +class LocationDetails extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Coordinate} coordinate - Latitude/Longitude of the location. + * @return {LocationDetails} + */ + setCoordinate (coordinate) { + this.validateType(Coordinate, coordinate); + this.setParameter(LocationDetails.KEY_COORDINATE, coordinate); + return this; + } + + /** + * @return {Coordinate} + */ + getCoordinate () { + return this.getObject(Coordinate, LocationDetails.KEY_COORDINATE); + } + + /** + * @param {String} name - Name of location. + * @return {LocationDetails} + */ + setLocationName (name) { + this.setParameter(LocationDetails.KEY_LOCATION_NAME, name); + return this; + } + + /** + * @return {String} + */ + getLocationName () { + return this.getParameter(LocationDetails.KEY_LOCATION_NAME); + } + + /** + * @param {String[]} lines - Location address for display purposes only + * @return {LocationDetails} + */ + setAddressLines (lines) { + this.setParameter(LocationDetails.KEY_ADDRESS_LINES, lines); + return this; + } + + /** + * @return {String[]} + */ + getAddressLines () { + return this.getParameter(LocationDetails.KEY_ADDRESS_LINES); + } + + /** + * @param {String} description - Description intended location / establishment (if applicable) + * @return {LocationDetails} + */ + setLocationDescription (description) { + this.setParameter(LocationDetails.KEY_LOCATION_DESCRIPTION, description); + return this; + } + + /** + * @return {String} + */ + getLocationDescription () { + return this.getParameter(LocationDetails.KEY_LOCATION_DESCRIPTION); + } + + /** + * @param {String} number - Phone number of location / establishment. + * @return {LocationDetails} + */ + setPhoneNumber (number) { + this.setParameter(LocationDetails.KEY_PHONE_NUMBER, number); + return this; + } + + /** + * @return {String} + */ + getPhoneNumber () { + return this.getParameter(LocationDetails.KEY_PHONE_NUMBER); + } + + /** + * @param {Image} image - Image / icon of intended location. + * @return {LocationDetails} + */ + setLocationImage (image) { + this.validateType(Image, image); + this.setParameter(LocationDetails.KEY_LOCATION_IMAGE, image); + return this; + } + + /** + * @return {Image} + */ + getLocationImage () { + return this.getObject(Image, LocationDetails.KEY_LOCATION_IMAGE); + } + + /** + * @param {OASISAddress} address - Address to be used by navigation engines for search + * @return {LocationDetails} + */ + setSearchAddress (address) { + this.validateType(OASISAddress, address); + this.setParameter(LocationDetails.KEY_SEARCH_ADDRESS, address); + return this; + } + + /** + * @return {OASISAddress} + */ + getSearchAddress () { + return this.getObject(OASISAddress, LocationDetails.KEY_SEARCH_ADDRESS); + } +} + +LocationDetails.KEY_COORDINATE = 'coordinate'; +LocationDetails.KEY_LOCATION_NAME = 'locationName'; +LocationDetails.KEY_ADDRESS_LINES = 'addressLines'; +LocationDetails.KEY_LOCATION_DESCRIPTION = 'locationDescription'; +LocationDetails.KEY_PHONE_NUMBER = 'phoneNumber'; +LocationDetails.KEY_LOCATION_IMAGE = 'locationImage'; +LocationDetails.KEY_SEARCH_ADDRESS = 'searchAddress'; + +export { LocationDetails }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/MassageCushionFirmness.js b/lib/js/src/rpc/structs/MassageCushionFirmness.js new file mode 100644 index 00000000..98424231 --- /dev/null +++ b/lib/js/src/rpc/structs/MassageCushionFirmness.js @@ -0,0 +1,85 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { MassageCushion } from '../enums/MassageCushion.js'; + +/** + * The intensity or firmness of a cushion. + */ +class MassageCushionFirmness extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {MassageCushion} cushion - List possible cushions of a multi-contour massage seat. + * @return {MassageCushionFirmness} + */ + setCushion (cushion) { + this.validateType(MassageCushion, cushion); + this.setParameter(MassageCushionFirmness.KEY_CUSHION, cushion); + return this; + } + + /** + * @return {MassageCushion} + */ + getCushion () { + return this.getObject(MassageCushion, MassageCushionFirmness.KEY_CUSHION); + } + + /** + * @param {Number} firmness + * @return {MassageCushionFirmness} + */ + setFirmness (firmness) { + this.setParameter(MassageCushionFirmness.KEY_FIRMNESS, firmness); + return this; + } + + /** + * @return {Number} + */ + getFirmness () { + return this.getParameter(MassageCushionFirmness.KEY_FIRMNESS); + } +} + +MassageCushionFirmness.KEY_CUSHION = 'cushion'; +MassageCushionFirmness.KEY_FIRMNESS = 'firmness'; + +export { MassageCushionFirmness }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/MassageModeData.js b/lib/js/src/rpc/structs/MassageModeData.js new file mode 100644 index 00000000..681f9d96 --- /dev/null +++ b/lib/js/src/rpc/structs/MassageModeData.js @@ -0,0 +1,87 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { MassageZone } from '../enums/MassageZone.js'; +import { MassageMode } from '../enums/MassageMode.js'; + +/** + * Specify the mode of a massage zone. + */ +class MassageModeData extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {MassageZone} zone - List possible zones of a multi-contour massage seat. + * @return {MassageModeData} + */ + setMassageZone (zone) { + this.validateType(MassageZone, zone); + this.setParameter(MassageModeData.KEY_MASSAGE_ZONE, zone); + return this; + } + + /** + * @return {MassageZone} + */ + getMassageZone () { + return this.getObject(MassageZone, MassageModeData.KEY_MASSAGE_ZONE); + } + + /** + * @param {MassageMode} mode - List possible modes of a massage zone. + * @return {MassageModeData} + */ + setMassageMode (mode) { + this.validateType(MassageMode, mode); + this.setParameter(MassageModeData.KEY_MASSAGE_MODE, mode); + return this; + } + + /** + * @return {MassageMode} + */ + getMassageMode () { + return this.getObject(MassageMode, MassageModeData.KEY_MASSAGE_MODE); + } +} + +MassageModeData.KEY_MASSAGE_ZONE = 'massageZone'; +MassageModeData.KEY_MASSAGE_MODE = 'massageMode'; + +export { MassageModeData }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/MediaServiceData.js b/lib/js/src/rpc/structs/MediaServiceData.js new file mode 100644 index 00000000..0e3a0b75 --- /dev/null +++ b/lib/js/src/rpc/structs/MediaServiceData.js @@ -0,0 +1,295 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { Image } from './Image.js'; +import { MediaType } from '../enums/MediaType.js'; + +/** + * This data is related to what a media service should provide + */ +class MediaServiceData extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {MediaType} type - The type of the currently playing or paused track. + * @return {MediaServiceData} + */ + setMediaType (type) { + this.validateType(MediaType, type); + this.setParameter(MediaServiceData.KEY_MEDIA_TYPE, type); + return this; + } + + /** + * @return {MediaType} + */ + getMediaType () { + return this.getObject(MediaType, MediaServiceData.KEY_MEDIA_TYPE); + } + + /** + * @param {String} title - Music: The name of the current track Podcast: The name of the current episode Audiobook: + * The name of the current chapter + * @return {MediaServiceData} + */ + setMediaTitle (title) { + this.setParameter(MediaServiceData.KEY_MEDIA_TITLE, title); + return this; + } + + /** + * @return {String} + */ + getMediaTitle () { + return this.getParameter(MediaServiceData.KEY_MEDIA_TITLE); + } + + /** + * @param {String} artist - Music: The name of the current album artist Podcast: The provider of the podcast (hosts, + * network, company) Audiobook: The book author's name + * @return {MediaServiceData} + */ + setMediaArtist (artist) { + this.setParameter(MediaServiceData.KEY_MEDIA_ARTIST, artist); + return this; + } + + /** + * @return {String} + */ + getMediaArtist () { + return this.getParameter(MediaServiceData.KEY_MEDIA_ARTIST); + } + + /** + * @param {String} album - Music: The name of the current album Podcast: The name of the current podcast show + * Audiobook: The name of the current book + * @return {MediaServiceData} + */ + setMediaAlbum (album) { + this.setParameter(MediaServiceData.KEY_MEDIA_ALBUM, album); + return this; + } + + /** + * @return {String} + */ + getMediaAlbum () { + return this.getParameter(MediaServiceData.KEY_MEDIA_ALBUM); + } + + /** + * @param {String} name - Music: The name of the playlist or radio station, if the user is playing from a playlist, + * otherwise, Null Podcast: The name of the playlist, if the user is playing from a playlist, + * otherwise, Null Audiobook: Likely not applicable, possibly a collection or "playlist" of + * books + * @return {MediaServiceData} + */ + setPlaylistName (name) { + this.setParameter(MediaServiceData.KEY_PLAYLIST_NAME, name); + return this; + } + + /** + * @return {String} + */ + getPlaylistName () { + return this.getParameter(MediaServiceData.KEY_PLAYLIST_NAME); + } + + /** + * @param {Boolean} explicit - Whether or not the content currently playing (e.g. the track, episode, or book) + * contains explicit content + * @return {MediaServiceData} + */ + setIsExplicit (explicit) { + this.setParameter(MediaServiceData.KEY_IS_EXPLICIT, explicit); + return this; + } + + /** + * @return {Boolean} + */ + getIsExplicit () { + return this.getParameter(MediaServiceData.KEY_IS_EXPLICIT); + } + + /** + * @param {Number} progress - Music: The current progress of the track in seconds Podcast: The current progress of + * the episode in seconds Audiobook: The current progress of the current segment (e.g. + * the chapter) in seconds + * @return {MediaServiceData} + */ + setTrackPlaybackProgress (progress) { + this.setParameter(MediaServiceData.KEY_TRACK_PLAYBACK_PROGRESS, progress); + return this; + } + + /** + * @return {Number} + */ + getTrackPlaybackProgress () { + return this.getParameter(MediaServiceData.KEY_TRACK_PLAYBACK_PROGRESS); + } + + /** + * @param {Number} duration - Music: The total duration of the track in seconds Podcast: The total duration of the + * episode in seconds Audiobook: The total duration of the current segment (e.g. the + * chapter) in seconds + * @return {MediaServiceData} + */ + setTrackPlaybackDuration (duration) { + this.setParameter(MediaServiceData.KEY_TRACK_PLAYBACK_DURATION, duration); + return this; + } + + /** + * @return {Number} + */ + getTrackPlaybackDuration () { + return this.getParameter(MediaServiceData.KEY_TRACK_PLAYBACK_DURATION); + } + + /** + * @param {Number} progress - Music: The current progress of the playback queue in seconds Podcast: The current + * progress of the playback queue in seconds Audiobook: The current progress of the + * playback queue (e.g. the book) in seconds + * @return {MediaServiceData} + */ + setQueuePlaybackProgress (progress) { + this.setParameter(MediaServiceData.KEY_QUEUE_PLAYBACK_PROGRESS, progress); + return this; + } + + /** + * @return {Number} + */ + getQueuePlaybackProgress () { + return this.getParameter(MediaServiceData.KEY_QUEUE_PLAYBACK_PROGRESS); + } + + /** + * @param {Number} duration - Music: The total duration of the playback queue in seconds Podcast: The total duration + * of the playback queue in seconds Audiobook: The total duration of the playback queue + * (e.g. the book) in seconds + * @return {MediaServiceData} + */ + setQueuePlaybackDuration (duration) { + this.setParameter(MediaServiceData.KEY_QUEUE_PLAYBACK_DURATION, duration); + return this; + } + + /** + * @return {Number} + */ + getQueuePlaybackDuration () { + return this.getParameter(MediaServiceData.KEY_QUEUE_PLAYBACK_DURATION); + } + + /** + * @param {Number} number - Music: The current number (1 based) of the track in the playback queue Podcast: The + * current number (1 based) of the episode in the playback queue Audiobook: The current + * number (1 based) of the episode in the playback queue (e.g. the chapter number in the + * book) + * @return {MediaServiceData} + */ + setQueueCurrentTrackNumber (number) { + this.setParameter(MediaServiceData.KEY_QUEUE_CURRENT_TRACK_NUMBER, number); + return this; + } + + /** + * @return {Number} + */ + getQueueCurrentTrackNumber () { + return this.getParameter(MediaServiceData.KEY_QUEUE_CURRENT_TRACK_NUMBER); + } + + /** + * @param {Number} count - Music: The total number of tracks in the playback queue Podcast: The total number of + * episodes in the playback queue Audiobook: The total number of sections in the playback + * queue (e.g. the number of chapters in the book) + * @return {MediaServiceData} + */ + setQueueTotalTrackCount (count) { + this.setParameter(MediaServiceData.KEY_QUEUE_TOTAL_TRACK_COUNT, count); + return this; + } + + /** + * @return {Number} + */ + getQueueTotalTrackCount () { + return this.getParameter(MediaServiceData.KEY_QUEUE_TOTAL_TRACK_COUNT); + } + + /** + * @param {Image} image - Music: The album art of the current track Podcast: The podcast or chapter artwork of the + * current podcast episode Audiobook: The book or chapter artwork of the current audiobook + * @return {MediaServiceData} + */ + setMediaImage (image) { + this.validateType(Image, image); + this.setParameter(MediaServiceData.KEY_MEDIA_IMAGE, image); + return this; + } + + /** + * @return {Image} + */ + getMediaImage () { + return this.getObject(Image, MediaServiceData.KEY_MEDIA_IMAGE); + } +} + +MediaServiceData.KEY_MEDIA_TYPE = 'mediaType'; +MediaServiceData.KEY_MEDIA_TITLE = 'mediaTitle'; +MediaServiceData.KEY_MEDIA_ARTIST = 'mediaArtist'; +MediaServiceData.KEY_MEDIA_ALBUM = 'mediaAlbum'; +MediaServiceData.KEY_PLAYLIST_NAME = 'playlistName'; +MediaServiceData.KEY_IS_EXPLICIT = 'isExplicit'; +MediaServiceData.KEY_TRACK_PLAYBACK_PROGRESS = 'trackPlaybackProgress'; +MediaServiceData.KEY_TRACK_PLAYBACK_DURATION = 'trackPlaybackDuration'; +MediaServiceData.KEY_QUEUE_PLAYBACK_PROGRESS = 'queuePlaybackProgress'; +MediaServiceData.KEY_QUEUE_PLAYBACK_DURATION = 'queuePlaybackDuration'; +MediaServiceData.KEY_QUEUE_CURRENT_TRACK_NUMBER = 'queueCurrentTrackNumber'; +MediaServiceData.KEY_QUEUE_TOTAL_TRACK_COUNT = 'queueTotalTrackCount'; +MediaServiceData.KEY_MEDIA_IMAGE = 'mediaImage'; + +export { MediaServiceData }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/MediaServiceManifest.js b/lib/js/src/rpc/structs/MediaServiceManifest.js new file mode 100644 index 00000000..5d12776e --- /dev/null +++ b/lib/js/src/rpc/structs/MediaServiceManifest.js @@ -0,0 +1,46 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; + +class MediaServiceManifest extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } +} + + +export { MediaServiceManifest }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/MenuParams.js b/lib/js/src/rpc/structs/MenuParams.js index 17a89187..fe68f6fc 100644 --- a/lib/js/src/rpc/structs/MenuParams.js +++ b/lib/js/src/rpc/structs/MenuParams.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -34,63 +35,67 @@ import { RpcStruct } from '../RpcStruct.js'; class MenuParams extends RpcStruct { /** - * @constructor - */ + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {Number} id - * @return {MenuParams} - */ + * @param {Number} id - unique ID of the sub menu, the command will be added to. If not provided, it will be + * provided to the top level of the in application menu. + * @return {MenuParams} + */ setParentID (id) { this.setParameter(MenuParams.KEY_PARENT_ID, id); return this; } /** - * @return {Number} - */ + * @return {Number} + */ getParentID () { return this.getParameter(MenuParams.KEY_PARENT_ID); } /** - * @param {Number} position - * @return {MenuParams} - */ + * @param {Number} position - Position within the items that are are at top level of the in application menu. 0 will + * insert at the front. 1 will insert at the second position. if position is greater or + * equal than the number of items on top level, the sub menu will be appended to the end. + * If this param was omitted the entry will be added at the end. + * @return {MenuParams} + */ setPosition (position) { this.setParameter(MenuParams.KEY_POSITION, position); return this; } /** - * @return {Number} - */ + * @return {Number} + */ getPosition () { return this.getParameter(MenuParams.KEY_POSITION); } /** - * @param {String} menuName - * @return {MenuParams} - */ - setMenuName (menuName) { - this.setParameter(MenuParams.KEY_MENU_NAME, menuName); + * @param {String} name - Text to show in the menu for this sub menu. + * @return {MenuParams} + */ + setMenuName (name) { + this.setParameter(MenuParams.KEY_MENU_NAME, name); return this; } /** - * @param {String} - */ + * @return {String} + */ getMenuName () { return this.getParameter(MenuParams.KEY_MENU_NAME); } } MenuParams.KEY_PARENT_ID = 'parentID'; -MenuParams.KEY_POSITION = 'position'; +MenuParams.KEY_POSITION = 'position'; MenuParams.KEY_MENU_NAME = 'menuName'; -export { MenuParams }; +export { MenuParams }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/MetadataTags.js b/lib/js/src/rpc/structs/MetadataTags.js index 66bd7ea0..34a13d93 100644 --- a/lib/js/src/rpc/structs/MetadataTags.js +++ b/lib/js/src/rpc/structs/MetadataTags.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -35,72 +36,76 @@ import { MetadataType } from '../enums/MetadataType.js'; class MetadataTags extends RpcStruct { /** - * @constructor - */ + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {Array} mainField1 - * @return {MetadataTags} - */ - setMainField1 (mainField1) { - this.setParameter(MetadataTags.KEY_MAIN_FIELD_1, mainField1); + * @param {MetadataType[]} field1 - The type of data contained in the "mainField1" text field. + * @return {MetadataTags} + */ + setMainField1 (field1) { + this.validateType(MetadataType, field1, true); + this.setParameter(MetadataTags.KEY_MAIN_FIELD_1, field1); return this; } /** - * @return {Array} - */ + * @return {MetadataType[]} + */ getMainField1 () { return this.getObject(MetadataType, MetadataTags.KEY_MAIN_FIELD_1); } /** - * @param {Array} mainField2 - * @return {MetadataTags} - */ - setMainField2 (mainField2) { - this.setParameter(MetadataTags.KEY_MAIN_FIELD_2, mainField2); + * @param {MetadataType[]} field2 - The type of data contained in the "mainField2" text field. + * @return {MetadataTags} + */ + setMainField2 (field2) { + this.validateType(MetadataType, field2, true); + this.setParameter(MetadataTags.KEY_MAIN_FIELD_2, field2); return this; } /** - * @return {Array} - */ + * @return {MetadataType[]} + */ getMainField2 () { return this.getObject(MetadataType, MetadataTags.KEY_MAIN_FIELD_2); } /** - * @param {Array} mainField3 - * @return {MetadataTags} - */ - setMainField3 (mainField3) { - this.setParameter(MetadataTags.KEY_MAIN_FIELD_3, mainField3); + * @param {MetadataType[]} field3 - The type of data contained in the "mainField3" text field. + * @return {MetadataTags} + */ + setMainField3 (field3) { + this.validateType(MetadataType, field3, true); + this.setParameter(MetadataTags.KEY_MAIN_FIELD_3, field3); return this; } /** - * @return {Array} - */ + * @return {MetadataType[]} + */ getMainField3 () { return this.getObject(MetadataType, MetadataTags.KEY_MAIN_FIELD_3); } /** - * @param {Array} mainField4 - * @return {MetadataTags} - */ - setMainField4 (mainField4) { - this.setParameter(MetadataTags.KEY_MAIN_FIELD_4, mainField4); + * @param {MetadataType[]} field4 - The type of data contained in the "mainField4" text field. + * @return {MetadataTags} + */ + setMainField4 (field4) { + this.validateType(MetadataType, field4, true); + this.setParameter(MetadataTags.KEY_MAIN_FIELD_4, field4); return this; } /** - * @return {Array} - */ + * @return {MetadataType[]} + */ getMainField4 () { return this.getObject(MetadataType, MetadataTags.KEY_MAIN_FIELD_4); } @@ -111,4 +116,4 @@ MetadataTags.KEY_MAIN_FIELD_2 = 'mainField2'; MetadataTags.KEY_MAIN_FIELD_3 = 'mainField3'; MetadataTags.KEY_MAIN_FIELD_4 = 'mainField4'; -export { MetadataTags }; +export { MetadataTags }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/ModuleData.js b/lib/js/src/rpc/structs/ModuleData.js new file mode 100644 index 00000000..4ac7f92d --- /dev/null +++ b/lib/js/src/rpc/structs/ModuleData.js @@ -0,0 +1,200 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { HMISettingsControlData } from './HMISettingsControlData.js'; +import { RadioControlData } from './RadioControlData.js'; +import { ModuleType } from '../enums/ModuleType.js'; +import { ClimateControlData } from './ClimateControlData.js'; +import { AudioControlData } from './AudioControlData.js'; +import { SeatControlData } from './SeatControlData.js'; +import { RpcStruct } from '../RpcStruct.js'; +import { LightControlData } from './LightControlData.js'; + +/** + * The moduleType indicates which type of data should be changed and identifies which data object exists in this + * struct. For example, if the moduleType is CLIMATE then a "climateControlData" should exist + */ +class ModuleData extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {ModuleType} type + * @return {ModuleData} + */ + setModuleType (type) { + this.validateType(ModuleType, type); + this.setParameter(ModuleData.KEY_MODULE_TYPE, type); + return this; + } + + /** + * @return {ModuleType} + */ + getModuleType () { + return this.getObject(ModuleType, ModuleData.KEY_MODULE_TYPE); + } + + /** + * @param {String} id - Id of a module, published by System Capability. + * @return {ModuleData} + */ + setModuleId (id) { + this.setParameter(ModuleData.KEY_MODULE_ID, id); + return this; + } + + /** + * @return {String} + */ + getModuleId () { + return this.getParameter(ModuleData.KEY_MODULE_ID); + } + + /** + * @param {RadioControlData} data + * @return {ModuleData} + */ + setRadioControlData (data) { + this.validateType(RadioControlData, data); + this.setParameter(ModuleData.KEY_RADIO_CONTROL_DATA, data); + return this; + } + + /** + * @return {RadioControlData} + */ + getRadioControlData () { + return this.getObject(RadioControlData, ModuleData.KEY_RADIO_CONTROL_DATA); + } + + /** + * @param {ClimateControlData} data + * @return {ModuleData} + */ + setClimateControlData (data) { + this.validateType(ClimateControlData, data); + this.setParameter(ModuleData.KEY_CLIMATE_CONTROL_DATA, data); + return this; + } + + /** + * @return {ClimateControlData} + */ + getClimateControlData () { + return this.getObject(ClimateControlData, ModuleData.KEY_CLIMATE_CONTROL_DATA); + } + + /** + * @param {SeatControlData} data - Seat control data corresponds to "SEAT" ModuleType. + * @return {ModuleData} + */ + setSeatControlData (data) { + this.validateType(SeatControlData, data); + this.setParameter(ModuleData.KEY_SEAT_CONTROL_DATA, data); + return this; + } + + /** + * @return {SeatControlData} + */ + getSeatControlData () { + return this.getObject(SeatControlData, ModuleData.KEY_SEAT_CONTROL_DATA); + } + + /** + * @param {AudioControlData} data + * @return {ModuleData} + */ + setAudioControlData (data) { + this.validateType(AudioControlData, data); + this.setParameter(ModuleData.KEY_AUDIO_CONTROL_DATA, data); + return this; + } + + /** + * @return {AudioControlData} + */ + getAudioControlData () { + return this.getObject(AudioControlData, ModuleData.KEY_AUDIO_CONTROL_DATA); + } + + /** + * @param {LightControlData} data + * @return {ModuleData} + */ + setLightControlData (data) { + this.validateType(LightControlData, data); + this.setParameter(ModuleData.KEY_LIGHT_CONTROL_DATA, data); + return this; + } + + /** + * @return {LightControlData} + */ + getLightControlData () { + return this.getObject(LightControlData, ModuleData.KEY_LIGHT_CONTROL_DATA); + } + + /** + * @param {HMISettingsControlData} data - Corresponds to "HMI_SETTINGS" ModuleType + * @return {ModuleData} + */ + setHmiSettingsControlData (data) { + this.validateType(HMISettingsControlData, data); + this.setParameter(ModuleData.KEY_HMI_SETTINGS_CONTROL_DATA, data); + return this; + } + + /** + * @return {HMISettingsControlData} + */ + getHmiSettingsControlData () { + return this.getObject(HMISettingsControlData, ModuleData.KEY_HMI_SETTINGS_CONTROL_DATA); + } +} + +ModuleData.KEY_MODULE_TYPE = 'moduleType'; +ModuleData.KEY_MODULE_ID = 'moduleId'; +ModuleData.KEY_RADIO_CONTROL_DATA = 'radioControlData'; +ModuleData.KEY_CLIMATE_CONTROL_DATA = 'climateControlData'; +ModuleData.KEY_SEAT_CONTROL_DATA = 'seatControlData'; +ModuleData.KEY_AUDIO_CONTROL_DATA = 'audioControlData'; +ModuleData.KEY_LIGHT_CONTROL_DATA = 'lightControlData'; +ModuleData.KEY_HMI_SETTINGS_CONTROL_DATA = 'hmiSettingsControlData'; + +export { ModuleData }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/ModuleInfo.js b/lib/js/src/rpc/structs/ModuleInfo.js index 692b2d0f..7817315c 100644 --- a/lib/js/src/rpc/structs/ModuleInfo.js +++ b/lib/js/src/rpc/structs/ModuleInfo.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -33,76 +34,79 @@ import { RpcStruct } from '../RpcStruct.js'; import { Grid } from './Grid.js'; +/** + * Information about a RC module + */ class ModuleInfo extends RpcStruct { + /** + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {String} moduleId - * @return {ModuleInfo} - */ - setModuleId (moduleId) { - this.setParameter(ModuleInfo.KEY_MODULE_ID, moduleId); + * @param {String} id - uuid of a module. "moduleId + moduleType" uniquely identify a module. + * @return {ModuleInfo} + */ + setModuleId (id) { + this.setParameter(ModuleInfo.KEY_MODULE_ID, id); return this; } /** - * @return {String} - */ + * @return {String} + */ getModuleId () { return this.getParameter(ModuleInfo.KEY_MODULE_ID); } - /** - * @param {Grid} location - * @return {ModuleInfo} - */ + * @param {Grid} location - Location of a module. + * @return {ModuleInfo} + */ setLocation (location) { this.validateType(Grid, location); - this.setParameter(ModuleInfo.KEY_LOCATION, location); return this; } /** - * @return {Grid} - */ + * @return {Grid} + */ getLocation () { return this.getObject(Grid, ModuleInfo.KEY_LOCATION); } /** - * @param {Grid} serviceArea - * @return {ModuleInfo} - */ - setServiceArea (serviceArea) { - this.validateType(Grid, serviceArea); - - this.setParameter(ModuleInfo.KEY_SERVICE_AREA, serviceArea); + * @param {Grid} area - Service area of a module. + * @return {ModuleInfo} + */ + setServiceArea (area) { + this.validateType(Grid, area); + this.setParameter(ModuleInfo.KEY_SERVICE_AREA, area); return this; } /** - * @return {Grid} - */ + * @return {Grid} + */ getServiceArea () { return this.getObject(Grid, ModuleInfo.KEY_SERVICE_AREA); } /** - * @param {Boolean} allowMultipleAccess - * @return {ModuleInfo} - */ - setAllowMultipleAccess (allowMultipleAccess) { - this.setParameter(ModuleInfo.KEY_ALLOW_MULTIPLE_ACCESS, allowMultipleAccess); + * @param {Boolean} access - allow multiple users/apps to access the module or not + * @return {ModuleInfo} + */ + setAllowMultipleAccess (access) { + this.setParameter(ModuleInfo.KEY_ALLOW_MULTIPLE_ACCESS, access); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getAllowMultipleAccess () { return this.getParameter(ModuleInfo.KEY_ALLOW_MULTIPLE_ACCESS); } @@ -113,4 +117,4 @@ ModuleInfo.KEY_LOCATION = 'location'; ModuleInfo.KEY_SERVICE_AREA = 'serviceArea'; ModuleInfo.KEY_ALLOW_MULTIPLE_ACCESS = 'allowMultipleAccess'; -export { ModuleInfo }; +export { ModuleInfo }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/MyKey.js b/lib/js/src/rpc/structs/MyKey.js new file mode 100644 index 00000000..de0069bf --- /dev/null +++ b/lib/js/src/rpc/structs/MyKey.js @@ -0,0 +1,66 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { VehicleDataStatus } from '../enums/VehicleDataStatus.js'; + +class MyKey extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {VehicleDataStatus} e911override - Indicates whether e911 override is on. References signal + * "MyKey_e911Override_St". See VehicleDataStatus. + * @return {MyKey} + */ + setE911Override (e911override) { + this.validateType(VehicleDataStatus, e911override); + this.setParameter(MyKey.KEY_E911OVERRIDE, e911override); + return this; + } + + /** + * @return {VehicleDataStatus} + */ + getE911Override () { + return this.getObject(VehicleDataStatus, MyKey.KEY_E911OVERRIDE); + } +} + +MyKey.KEY_E911OVERRIDE = 'e911Override'; + +export { MyKey }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/NavigationCapability.js b/lib/js/src/rpc/structs/NavigationCapability.js new file mode 100644 index 00000000..5051abdf --- /dev/null +++ b/lib/js/src/rpc/structs/NavigationCapability.js @@ -0,0 +1,83 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; + +/** + * Extended capabilities for an onboard navigation system + */ +class NavigationCapability extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Boolean} enabled - If the module has the ability to add locations to the onboard nav + * @return {NavigationCapability} + */ + setSendLocationEnabled (enabled) { + this.setParameter(NavigationCapability.KEY_SEND_LOCATION_ENABLED, enabled); + return this; + } + + /** + * @return {Boolean} + */ + getSendLocationEnabled () { + return this.getParameter(NavigationCapability.KEY_SEND_LOCATION_ENABLED); + } + + /** + * @param {Boolean} enabled - If the module has the ability to return way points from onboard nav + * @return {NavigationCapability} + */ + setGetWayPointsEnabled (enabled) { + this.setParameter(NavigationCapability.KEY_GET_WAY_POINTS_ENABLED, enabled); + return this; + } + + /** + * @return {Boolean} + */ + getGetWayPointsEnabled () { + return this.getParameter(NavigationCapability.KEY_GET_WAY_POINTS_ENABLED); + } +} + +NavigationCapability.KEY_SEND_LOCATION_ENABLED = 'sendLocationEnabled'; +NavigationCapability.KEY_GET_WAY_POINTS_ENABLED = 'getWayPointsEnabled'; + +export { NavigationCapability }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/NavigationInstruction.js b/lib/js/src/rpc/structs/NavigationInstruction.js new file mode 100644 index 00000000..aba2eaf8 --- /dev/null +++ b/lib/js/src/rpc/structs/NavigationInstruction.js @@ -0,0 +1,200 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { Image } from './Image.js'; +import { DateTime } from './DateTime.js'; +import { RpcStruct } from '../RpcStruct.js'; +import { NavigationJunction } from '../enums/NavigationJunction.js'; +import { Direction } from '../enums/Direction.js'; +import { LocationDetails } from './LocationDetails.js'; +import { NavigationAction } from '../enums/NavigationAction.js'; + +class NavigationInstruction extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {LocationDetails} details + * @return {NavigationInstruction} + */ + setLocationDetails (details) { + this.validateType(LocationDetails, details); + this.setParameter(NavigationInstruction.KEY_LOCATION_DETAILS, details); + return this; + } + + /** + * @return {LocationDetails} + */ + getLocationDetails () { + return this.getObject(LocationDetails, NavigationInstruction.KEY_LOCATION_DETAILS); + } + + /** + * @param {NavigationAction} action + * @return {NavigationInstruction} + */ + setAction (action) { + this.validateType(NavigationAction, action); + this.setParameter(NavigationInstruction.KEY_ACTION, action); + return this; + } + + /** + * @return {NavigationAction} + */ + getAction () { + return this.getObject(NavigationAction, NavigationInstruction.KEY_ACTION); + } + + /** + * @param {DateTime} eta + * @return {NavigationInstruction} + */ + setEta (eta) { + this.validateType(DateTime, eta); + this.setParameter(NavigationInstruction.KEY_ETA, eta); + return this; + } + + /** + * @return {DateTime} + */ + getEta () { + return this.getObject(DateTime, NavigationInstruction.KEY_ETA); + } + + /** + * @param {Number} bearing - The angle at which this instruction takes place. For example, 0 would mean straight, + * less than 45 is bearing right, greater than 135 is sharp right, between 45 and 135 is a + * regular right, and 180 is a U-Turn, etc. + * @return {NavigationInstruction} + */ + setBearing (bearing) { + this.setParameter(NavigationInstruction.KEY_BEARING, bearing); + return this; + } + + /** + * @return {Number} + */ + getBearing () { + return this.getParameter(NavigationInstruction.KEY_BEARING); + } + + /** + * @param {NavigationJunction} type + * @return {NavigationInstruction} + */ + setJunctionType (type) { + this.validateType(NavigationJunction, type); + this.setParameter(NavigationInstruction.KEY_JUNCTION_TYPE, type); + return this; + } + + /** + * @return {NavigationJunction} + */ + getJunctionType () { + return this.getObject(NavigationJunction, NavigationInstruction.KEY_JUNCTION_TYPE); + } + + /** + * @param {Direction} side - Used to infer which side of the road this instruction takes place. For a U-Turn + * (action=TURN, bearing=180) this will determine which direction the turn should take + * place. + * @return {NavigationInstruction} + */ + setDrivingSide (side) { + this.validateType(Direction, side); + this.setParameter(NavigationInstruction.KEY_DRIVING_SIDE, side); + return this; + } + + /** + * @return {Direction} + */ + getDrivingSide () { + return this.getObject(Direction, NavigationInstruction.KEY_DRIVING_SIDE); + } + + /** + * @param {String} details - This is a string representation of this instruction, used to display instructions to + * the users. This is not intended to be read aloud to the users, see the param prompt in + * NavigationServiceData for that. + * @return {NavigationInstruction} + */ + setDetails (details) { + this.setParameter(NavigationInstruction.KEY_DETAILS, details); + return this; + } + + /** + * @return {String} + */ + getDetails () { + return this.getParameter(NavigationInstruction.KEY_DETAILS); + } + + /** + * @param {Image} image - An image representation of this instruction. + * @return {NavigationInstruction} + */ + setImage (image) { + this.validateType(Image, image); + this.setParameter(NavigationInstruction.KEY_IMAGE, image); + return this; + } + + /** + * @return {Image} + */ + getImage () { + return this.getObject(Image, NavigationInstruction.KEY_IMAGE); + } +} + +NavigationInstruction.KEY_LOCATION_DETAILS = 'locationDetails'; +NavigationInstruction.KEY_ACTION = 'action'; +NavigationInstruction.KEY_ETA = 'eta'; +NavigationInstruction.KEY_BEARING = 'bearing'; +NavigationInstruction.KEY_JUNCTION_TYPE = 'junctionType'; +NavigationInstruction.KEY_DRIVING_SIDE = 'drivingSide'; +NavigationInstruction.KEY_DETAILS = 'details'; +NavigationInstruction.KEY_IMAGE = 'image'; + +export { NavigationInstruction }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/NavigationServiceData.js b/lib/js/src/rpc/structs/NavigationServiceData.js new file mode 100644 index 00000000..1046e16a --- /dev/null +++ b/lib/js/src/rpc/structs/NavigationServiceData.js @@ -0,0 +1,218 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { DateTime } from './DateTime.js'; +import { LocationDetails } from './LocationDetails.js'; +import { RpcStruct } from '../RpcStruct.js'; +import { NavigationInstruction } from './NavigationInstruction.js'; + +/** + * This data is related to what a navigation service would provide. + */ +class NavigationServiceData extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {DateTime} stamp - This is the timestamp of when the data was generated. This is to ensure any time or + * distance given in the data can accurately be adjusted if necessary. + * @return {NavigationServiceData} + */ + setTimeStamp (stamp) { + this.validateType(DateTime, stamp); + this.setParameter(NavigationServiceData.KEY_TIME_STAMP, stamp); + return this; + } + + /** + * @return {DateTime} + */ + getTimeStamp () { + return this.getObject(DateTime, NavigationServiceData.KEY_TIME_STAMP); + } + + /** + * @param {LocationDetails} origin + * @return {NavigationServiceData} + */ + setOrigin (origin) { + this.validateType(LocationDetails, origin); + this.setParameter(NavigationServiceData.KEY_ORIGIN, origin); + return this; + } + + /** + * @return {LocationDetails} + */ + getOrigin () { + return this.getObject(LocationDetails, NavigationServiceData.KEY_ORIGIN); + } + + /** + * @param {LocationDetails} destination + * @return {NavigationServiceData} + */ + setDestination (destination) { + this.validateType(LocationDetails, destination); + this.setParameter(NavigationServiceData.KEY_DESTINATION, destination); + return this; + } + + /** + * @return {LocationDetails} + */ + getDestination () { + return this.getObject(LocationDetails, NavigationServiceData.KEY_DESTINATION); + } + + /** + * @param {DateTime} eta + * @return {NavigationServiceData} + */ + setDestinationETA (eta) { + this.validateType(DateTime, eta); + this.setParameter(NavigationServiceData.KEY_DESTINATION_ETA, eta); + return this; + } + + /** + * @return {DateTime} + */ + getDestinationETA () { + return this.getObject(DateTime, NavigationServiceData.KEY_DESTINATION_ETA); + } + + /** + * @param {NavigationInstruction[]} instructions - This array should be ordered with all remaining instructions. The + * start of this array should always contain the next instruction. + * @return {NavigationServiceData} + */ + setInstructions (instructions) { + this.validateType(NavigationInstruction, instructions, true); + this.setParameter(NavigationServiceData.KEY_INSTRUCTIONS, instructions); + return this; + } + + /** + * @return {NavigationInstruction[]} + */ + getInstructions () { + return this.getObject(NavigationInstruction, NavigationServiceData.KEY_INSTRUCTIONS); + } + + /** + * @param {DateTime} eta + * @return {NavigationServiceData} + */ + setNextInstructionETA (eta) { + this.validateType(DateTime, eta); + this.setParameter(NavigationServiceData.KEY_NEXT_INSTRUCTION_ETA, eta); + return this; + } + + /** + * @return {DateTime} + */ + getNextInstructionETA () { + return this.getObject(DateTime, NavigationServiceData.KEY_NEXT_INSTRUCTION_ETA); + } + + /** + * @param {Number} distance - The distance to this instruction from current location. This should only be updated + * ever .1 unit of distance. For more accuracy the consumer can use the GPS location of + * itself and the next instruction. + * @return {NavigationServiceData} + */ + setNextInstructionDistance (distance) { + this.setParameter(NavigationServiceData.KEY_NEXT_INSTRUCTION_DISTANCE, distance); + return this; + } + + /** + * @return {Number} + */ + getNextInstructionDistance () { + return this.getParameter(NavigationServiceData.KEY_NEXT_INSTRUCTION_DISTANCE); + } + + /** + * @param {Number} scale - Distance till next maneuver (starting from) from previous maneuver. + * @return {NavigationServiceData} + */ + setNextInstructionDistanceScale (scale) { + this.setParameter(NavigationServiceData.KEY_NEXT_INSTRUCTION_DISTANCE_SCALE, scale); + return this; + } + + /** + * @return {Number} + */ + getNextInstructionDistanceScale () { + return this.getParameter(NavigationServiceData.KEY_NEXT_INSTRUCTION_DISTANCE_SCALE); + } + + /** + * @param {String} prompt - This is a prompt message that should be conveyed to the user through either display or + * voice (TTS). This param will change often as it should represent the following: + * approaching instruction, post instruction, alerts that affect the current navigation + * session, etc. + * @return {NavigationServiceData} + */ + setPrompt (prompt) { + this.setParameter(NavigationServiceData.KEY_PROMPT, prompt); + return this; + } + + /** + * @return {String} + */ + getPrompt () { + return this.getParameter(NavigationServiceData.KEY_PROMPT); + } +} + +NavigationServiceData.KEY_TIME_STAMP = 'timeStamp'; +NavigationServiceData.KEY_ORIGIN = 'origin'; +NavigationServiceData.KEY_DESTINATION = 'destination'; +NavigationServiceData.KEY_DESTINATION_ETA = 'destinationETA'; +NavigationServiceData.KEY_INSTRUCTIONS = 'instructions'; +NavigationServiceData.KEY_NEXT_INSTRUCTION_ETA = 'nextInstructionETA'; +NavigationServiceData.KEY_NEXT_INSTRUCTION_DISTANCE = 'nextInstructionDistance'; +NavigationServiceData.KEY_NEXT_INSTRUCTION_DISTANCE_SCALE = 'nextInstructionDistanceScale'; +NavigationServiceData.KEY_PROMPT = 'prompt'; + +export { NavigationServiceData }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/NavigationServiceManifest.js b/lib/js/src/rpc/structs/NavigationServiceManifest.js new file mode 100644 index 00000000..31ceabb2 --- /dev/null +++ b/lib/js/src/rpc/structs/NavigationServiceManifest.js @@ -0,0 +1,63 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; + +class NavigationServiceManifest extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Boolean} points - Informs the subscriber if this service can actually accept way points. + * @return {NavigationServiceManifest} + */ + setAcceptsWayPoints (points) { + this.setParameter(NavigationServiceManifest.KEY_ACCEPTS_WAY_POINTS, points); + return this; + } + + /** + * @return {Boolean} + */ + getAcceptsWayPoints () { + return this.getParameter(NavigationServiceManifest.KEY_ACCEPTS_WAY_POINTS); + } +} + +NavigationServiceManifest.KEY_ACCEPTS_WAY_POINTS = 'acceptsWayPoints'; + +export { NavigationServiceManifest }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/OASISAddress.js b/lib/js/src/rpc/structs/OASISAddress.js new file mode 100644 index 00000000..1bc522fa --- /dev/null +++ b/lib/js/src/rpc/structs/OASISAddress.js @@ -0,0 +1,199 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; + +class OASISAddress extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {String} name - Name of the country (localized) + * @return {OASISAddress} + */ + setCountryName (name) { + this.setParameter(OASISAddress.KEY_COUNTRY_NAME, name); + return this; + } + + /** + * @return {String} + */ + getCountryName () { + return this.getParameter(OASISAddress.KEY_COUNTRY_NAME); + } + + /** + * @param {String} code - Name of country (ISO 3166-2) + * @return {OASISAddress} + */ + setCountryCode (code) { + this.setParameter(OASISAddress.KEY_COUNTRY_CODE, code); + return this; + } + + /** + * @return {String} + */ + getCountryCode () { + return this.getParameter(OASISAddress.KEY_COUNTRY_CODE); + } + + /** + * @param {String} code - (PLZ, ZIP, PIN, CAP etc.) + * @return {OASISAddress} + */ + setPostalCode (code) { + this.setParameter(OASISAddress.KEY_POSTAL_CODE, code); + return this; + } + + /** + * @return {String} + */ + getPostalCode () { + return this.getParameter(OASISAddress.KEY_POSTAL_CODE); + } + + /** + * @param {String} area - Portion of country (e.g. state) + * @return {OASISAddress} + */ + setAdministrativeArea (area) { + this.setParameter(OASISAddress.KEY_ADMINISTRATIVE_AREA, area); + return this; + } + + /** + * @return {String} + */ + getAdministrativeArea () { + return this.getParameter(OASISAddress.KEY_ADMINISTRATIVE_AREA); + } + + /** + * @param {String} area - Portion of e.g. state (e.g. county) + * @return {OASISAddress} + */ + setSubAdministrativeArea (area) { + this.setParameter(OASISAddress.KEY_SUB_ADMINISTRATIVE_AREA, area); + return this; + } + + /** + * @return {String} + */ + getSubAdministrativeArea () { + return this.getParameter(OASISAddress.KEY_SUB_ADMINISTRATIVE_AREA); + } + + /** + * @param {String} locality - Hypernym for e.g. city/village + * @return {OASISAddress} + */ + setLocality (locality) { + this.setParameter(OASISAddress.KEY_LOCALITY, locality); + return this; + } + + /** + * @return {String} + */ + getLocality () { + return this.getParameter(OASISAddress.KEY_LOCALITY); + } + + /** + * @param {String} locality - Hypernym for e.g. district + * @return {OASISAddress} + */ + setSubLocality (locality) { + this.setParameter(OASISAddress.KEY_SUB_LOCALITY, locality); + return this; + } + + /** + * @return {String} + */ + getSubLocality () { + return this.getParameter(OASISAddress.KEY_SUB_LOCALITY); + } + + /** + * @param {String} thoroughfare - Hypernym for street, road etc. + * @return {OASISAddress} + */ + setThoroughfare (thoroughfare) { + this.setParameter(OASISAddress.KEY_THOROUGHFARE, thoroughfare); + return this; + } + + /** + * @return {String} + */ + getThoroughfare () { + return this.getParameter(OASISAddress.KEY_THOROUGHFARE); + } + + /** + * @param {String} thoroughfare - Portion of thoroughfare e.g. house number + * @return {OASISAddress} + */ + setSubThoroughfare (thoroughfare) { + this.setParameter(OASISAddress.KEY_SUB_THOROUGHFARE, thoroughfare); + return this; + } + + /** + * @return {String} + */ + getSubThoroughfare () { + return this.getParameter(OASISAddress.KEY_SUB_THOROUGHFARE); + } +} + +OASISAddress.KEY_COUNTRY_NAME = 'countryName'; +OASISAddress.KEY_COUNTRY_CODE = 'countryCode'; +OASISAddress.KEY_POSTAL_CODE = 'postalCode'; +OASISAddress.KEY_ADMINISTRATIVE_AREA = 'administrativeArea'; +OASISAddress.KEY_SUB_ADMINISTRATIVE_AREA = 'subAdministrativeArea'; +OASISAddress.KEY_LOCALITY = 'locality'; +OASISAddress.KEY_SUB_LOCALITY = 'subLocality'; +OASISAddress.KEY_THOROUGHFARE = 'thoroughfare'; +OASISAddress.KEY_SUB_THOROUGHFARE = 'subThoroughfare'; + +export { OASISAddress }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/ParameterPermissions.js b/lib/js/src/rpc/structs/ParameterPermissions.js new file mode 100644 index 00000000..d2cfbd3d --- /dev/null +++ b/lib/js/src/rpc/structs/ParameterPermissions.js @@ -0,0 +1,80 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; + +class ParameterPermissions extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {String[]} allowed - A set of all parameters that are permitted for this given RPC. + * @return {ParameterPermissions} + */ + setAllowed (allowed) { + this.setParameter(ParameterPermissions.KEY_ALLOWED, allowed); + return this; + } + + /** + * @return {String[]} + */ + getAllowed () { + return this.getParameter(ParameterPermissions.KEY_ALLOWED); + } + + /** + * @param {String[]} disallowed - A set of all parameters that are prohibited for this given RPC. + * @return {ParameterPermissions} + */ + setUserDisallowed (disallowed) { + this.setParameter(ParameterPermissions.KEY_USER_DISALLOWED, disallowed); + return this; + } + + /** + * @return {String[]} + */ + getUserDisallowed () { + return this.getParameter(ParameterPermissions.KEY_USER_DISALLOWED); + } +} + +ParameterPermissions.KEY_ALLOWED = 'allowed'; +ParameterPermissions.KEY_USER_DISALLOWED = 'userDisallowed'; + +export { ParameterPermissions }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/PermissionItem.js b/lib/js/src/rpc/structs/PermissionItem.js new file mode 100644 index 00000000..999946c6 --- /dev/null +++ b/lib/js/src/rpc/structs/PermissionItem.js @@ -0,0 +1,118 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { HMIPermissions } from './HMIPermissions.js'; +import { ParameterPermissions } from './ParameterPermissions.js'; + +class PermissionItem extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {String} name - Name of the individual RPC in the policy table. + * @return {PermissionItem} + */ + setRpcName (name) { + this.setParameter(PermissionItem.KEY_RPC_NAME, name); + return this; + } + + /** + * @return {String} + */ + getRpcName () { + return this.getParameter(PermissionItem.KEY_RPC_NAME); + } + + /** + * @param {HMIPermissions} permissions + * @return {PermissionItem} + */ + setHmiPermissions (permissions) { + this.validateType(HMIPermissions, permissions); + this.setParameter(PermissionItem.KEY_HMI_PERMISSIONS, permissions); + return this; + } + + /** + * @return {HMIPermissions} + */ + getHmiPermissions () { + return this.getObject(HMIPermissions, PermissionItem.KEY_HMI_PERMISSIONS); + } + + /** + * @param {ParameterPermissions} permissions + * @return {PermissionItem} + */ + setParameterPermissions (permissions) { + this.validateType(ParameterPermissions, permissions); + this.setParameter(PermissionItem.KEY_PARAMETER_PERMISSIONS, permissions); + return this; + } + + /** + * @return {ParameterPermissions} + */ + getParameterPermissions () { + return this.getObject(ParameterPermissions, PermissionItem.KEY_PARAMETER_PERMISSIONS); + } + + /** + * @param {Boolean} encryption + * @return {PermissionItem} + */ + setRequireEncryption (encryption) { + this.setParameter(PermissionItem.KEY_REQUIRE_ENCRYPTION, encryption); + return this; + } + + /** + * @return {Boolean} + */ + getRequireEncryption () { + return this.getParameter(PermissionItem.KEY_REQUIRE_ENCRYPTION); + } +} + +PermissionItem.KEY_RPC_NAME = 'rpcName'; +PermissionItem.KEY_HMI_PERMISSIONS = 'hmiPermissions'; +PermissionItem.KEY_PARAMETER_PERMISSIONS = 'parameterPermissions'; +PermissionItem.KEY_REQUIRE_ENCRYPTION = 'requireEncryption'; + +export { PermissionItem }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/PhoneCapability.js b/lib/js/src/rpc/structs/PhoneCapability.js new file mode 100644 index 00000000..735e3ec1 --- /dev/null +++ b/lib/js/src/rpc/structs/PhoneCapability.js @@ -0,0 +1,66 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; + +/** + * Extended capabilities of the module's phone feature + */ +class PhoneCapability extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Boolean} enabled - If the module has the ability to perform dial number + * @return {PhoneCapability} + */ + setDialNumberEnabled (enabled) { + this.setParameter(PhoneCapability.KEY_DIAL_NUMBER_ENABLED, enabled); + return this; + } + + /** + * @return {Boolean} + */ + getDialNumberEnabled () { + return this.getParameter(PhoneCapability.KEY_DIAL_NUMBER_ENABLED); + } +} + +PhoneCapability.KEY_DIAL_NUMBER_ENABLED = 'dialNumberEnabled'; + +export { PhoneCapability }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/PresetBankCapabilities.js b/lib/js/src/rpc/structs/PresetBankCapabilities.js index 845793c5..c13a3940 100644 --- a/lib/js/src/rpc/structs/PresetBankCapabilities.js +++ b/lib/js/src/rpc/structs/PresetBankCapabilities.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -32,23 +33,29 @@ import { RpcStruct } from '../RpcStruct.js'; +/** + * Contains information about on-screen preset capabilities. + */ class PresetBankCapabilities extends RpcStruct { + /** + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {Boolean} onScreenPresetsAvailable - * @return {PresetBankCapabilities} - */ - setOnScreenPresetsAvailable (onScreenPresetsAvailable) { - this.setParameter(PresetBankCapabilities.KEY_ON_SCREEN_PRESETS_AVAILABLE, onScreenPresetsAvailable); + * @param {Boolean} available - Onscreen custom presets are available. + * @return {PresetBankCapabilities} + */ + setOnScreenPresetsAvailable (available) { + this.setParameter(PresetBankCapabilities.KEY_ON_SCREEN_PRESETS_AVAILABLE, available); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getOnScreenPresetsAvailable () { return this.getParameter(PresetBankCapabilities.KEY_ON_SCREEN_PRESETS_AVAILABLE); } @@ -56,4 +63,4 @@ class PresetBankCapabilities extends RpcStruct { PresetBankCapabilities.KEY_ON_SCREEN_PRESETS_AVAILABLE = 'onScreenPresetsAvailable'; -export { PresetBankCapabilities }; +export { PresetBankCapabilities }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/RGBColor.js b/lib/js/src/rpc/structs/RGBColor.js index 2b4c9f94..a0d034f5 100644 --- a/lib/js/src/rpc/structs/RGBColor.js +++ b/lib/js/src/rpc/structs/RGBColor.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -33,57 +34,58 @@ import { RpcStruct } from '../RpcStruct.js'; class RGBColor extends RpcStruct { + /** + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {Number} redValue - * @return {RGBColor} - */ - setRedValue (redValue) { - this.setParameter(RGBColor.KEY_RED, redValue); + * @param {Number} red + * @return {RGBColor} + */ + setRed (red) { + this.setParameter(RGBColor.KEY_RED, red); return this; } /** - * @return {Number} - */ - getRedValue () { + * @return {Number} + */ + getRed () { return this.getParameter(RGBColor.KEY_RED); } - /** - * @param {Number} greenValue - * @return {RGBColor} - */ - setGreenValue (greenValue) { - this.setParameter(RGBColor.KEY_GREEN, greenValue); + * @param {Number} green + * @return {RGBColor} + */ + setGreen (green) { + this.setParameter(RGBColor.KEY_GREEN, green); return this; } /** - * @return {Number} - */ - getGreenValue () { + * @return {Number} + */ + getGreen () { return this.getParameter(RGBColor.KEY_GREEN); } - /** - * @param {Number} blueValue - * @return {RGBColor} - */ - setBlueValue (blueValue) { - this.setParameter(RGBColor.KEY_BLUE, blueValue); + * @param {Number} blue + * @return {RGBColor} + */ + setBlue (blue) { + this.setParameter(RGBColor.KEY_BLUE, blue); return this; } /** - * @return {Number} - */ - getBlueValue () { + * @return {Number} + */ + getBlue () { return this.getParameter(RGBColor.KEY_BLUE); } } @@ -92,4 +94,4 @@ RGBColor.KEY_RED = 'red'; RGBColor.KEY_GREEN = 'green'; RGBColor.KEY_BLUE = 'blue'; -export { RGBColor }; +export { RGBColor }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/RadioControlCapabilities.js b/lib/js/src/rpc/structs/RadioControlCapabilities.js new file mode 100644 index 00000000..bd10ddd9 --- /dev/null +++ b/lib/js/src/rpc/structs/RadioControlCapabilities.js @@ -0,0 +1,320 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { ModuleInfo } from './ModuleInfo.js'; + +/** + * Contains information about a radio control module's capabilities. + */ +class RadioControlCapabilities extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {String} name - The short friendly name of the climate control module. It should not be used to identify a + * module by mobile application. + * @return {RadioControlCapabilities} + */ + setModuleName (name) { + this.setParameter(RadioControlCapabilities.KEY_MODULE_NAME, name); + return this; + } + + /** + * @return {String} + */ + getModuleName () { + return this.getParameter(RadioControlCapabilities.KEY_MODULE_NAME); + } + + /** + * @param {ModuleInfo} info - Information about a RC module, including its id. + * @return {RadioControlCapabilities} + */ + setModuleInfo (info) { + this.validateType(ModuleInfo, info); + this.setParameter(RadioControlCapabilities.KEY_MODULE_INFO, info); + return this; + } + + /** + * @return {ModuleInfo} + */ + getModuleInfo () { + return this.getObject(ModuleInfo, RadioControlCapabilities.KEY_MODULE_INFO); + } + + /** + * @param {Boolean} available - Availability of the control of enable/disable radio. True: Available, False: Not + * Available, Not present: Not Available. + * @return {RadioControlCapabilities} + */ + setRadioEnableAvailable (available) { + this.setParameter(RadioControlCapabilities.KEY_RADIO_ENABLE_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getRadioEnableAvailable () { + return this.getParameter(RadioControlCapabilities.KEY_RADIO_ENABLE_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the control of radio band. True: Available, False: Not Available, + * Not present: Not Available. + * @return {RadioControlCapabilities} + */ + setRadioBandAvailable (available) { + this.setParameter(RadioControlCapabilities.KEY_RADIO_BAND_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getRadioBandAvailable () { + return this.getParameter(RadioControlCapabilities.KEY_RADIO_BAND_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the control of radio frequency. True: Available, False: Not + * Available, Not present: Not Available. + * @return {RadioControlCapabilities} + */ + setRadioFrequencyAvailable (available) { + this.setParameter(RadioControlCapabilities.KEY_RADIO_FREQUENCY_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getRadioFrequencyAvailable () { + return this.getParameter(RadioControlCapabilities.KEY_RADIO_FREQUENCY_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the control of HD radio channel. True: Available, False: Not + * Available, Not present: Not Available. + * @return {RadioControlCapabilities} + */ + setHdChannelAvailable (available) { + this.setParameter(RadioControlCapabilities.KEY_HD_CHANNEL_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getHdChannelAvailable () { + return this.getParameter(RadioControlCapabilities.KEY_HD_CHANNEL_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the getting Radio Data System (RDS) data. True: Available, False: + * Not Available, Not present: Not Available. + * @return {RadioControlCapabilities} + */ + setRdsDataAvailable (available) { + this.setParameter(RadioControlCapabilities.KEY_RDS_DATA_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getRdsDataAvailable () { + return this.getParameter(RadioControlCapabilities.KEY_RDS_DATA_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the getting the number of available HD channels. True: Available, + * False: Not Available, Not present: Not Available. + * @return {RadioControlCapabilities} + */ + setAvailableHDsAvailable (available) { + this.setParameter(RadioControlCapabilities.KEY_AVAILABLE_HDS_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getAvailableHDsAvailable () { + return this.getParameter(RadioControlCapabilities.KEY_AVAILABLE_HDS_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the list of available HD sub-channel indexes. True: Available, + * False: Not Available, Not present: Not Available. + * @return {RadioControlCapabilities} + */ + setAvailableHdChannelsAvailable (available) { + this.setParameter(RadioControlCapabilities.KEY_AVAILABLE_HD_CHANNELS_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getAvailableHdChannelsAvailable () { + return this.getParameter(RadioControlCapabilities.KEY_AVAILABLE_HD_CHANNELS_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the getting the Radio state. True: Available, False: Not Available, + * Not present: Not Available. + * @return {RadioControlCapabilities} + */ + setStateAvailable (available) { + this.setParameter(RadioControlCapabilities.KEY_STATE_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getStateAvailable () { + return this.getParameter(RadioControlCapabilities.KEY_STATE_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the getting the signal strength. True: Available, False: Not + * Available, Not present: Not Available. + * @return {RadioControlCapabilities} + */ + setSignalStrengthAvailable (available) { + this.setParameter(RadioControlCapabilities.KEY_SIGNAL_STRENGTH_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getSignalStrengthAvailable () { + return this.getParameter(RadioControlCapabilities.KEY_SIGNAL_STRENGTH_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the getting the signal Change Threshold. True: Available, False: Not + * Available, Not present: Not Available. + * @return {RadioControlCapabilities} + */ + setSignalChangeThresholdAvailable (available) { + this.setParameter(RadioControlCapabilities.KEY_SIGNAL_CHANGE_THRESHOLD_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getSignalChangeThresholdAvailable () { + return this.getParameter(RadioControlCapabilities.KEY_SIGNAL_CHANGE_THRESHOLD_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the getting HD radio Station Information Service (SIS) data. True: + * Available, False: Not Available, Not present: Not Available. + * @return {RadioControlCapabilities} + */ + setSisDataAvailable (available) { + this.setParameter(RadioControlCapabilities.KEY_SIS_DATA_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getSisDataAvailable () { + return this.getParameter(RadioControlCapabilities.KEY_SIS_DATA_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of the control of enable/disable HD radio. True: Available, False: Not + * Available, Not present: Not Available. + * @return {RadioControlCapabilities} + */ + setHdRadioEnableAvailable (available) { + this.setParameter(RadioControlCapabilities.KEY_HD_RADIO_ENABLE_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getHdRadioEnableAvailable () { + return this.getParameter(RadioControlCapabilities.KEY_HD_RADIO_ENABLE_AVAILABLE); + } + + /** + * @param {Boolean} available - Availability of sirius XM radio. True: Available, False: Not Available, Not present: + * Not Available. + * @return {RadioControlCapabilities} + */ + setSiriusxmRadioAvailable (available) { + this.setParameter(RadioControlCapabilities.KEY_SIRIUSXM_RADIO_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getSiriusxmRadioAvailable () { + return this.getParameter(RadioControlCapabilities.KEY_SIRIUSXM_RADIO_AVAILABLE); + } +} + +RadioControlCapabilities.KEY_MODULE_NAME = 'moduleName'; +RadioControlCapabilities.KEY_MODULE_INFO = 'moduleInfo'; +RadioControlCapabilities.KEY_RADIO_ENABLE_AVAILABLE = 'radioEnableAvailable'; +RadioControlCapabilities.KEY_RADIO_BAND_AVAILABLE = 'radioBandAvailable'; +RadioControlCapabilities.KEY_RADIO_FREQUENCY_AVAILABLE = 'radioFrequencyAvailable'; +RadioControlCapabilities.KEY_HD_CHANNEL_AVAILABLE = 'hdChannelAvailable'; +RadioControlCapabilities.KEY_RDS_DATA_AVAILABLE = 'rdsDataAvailable'; +RadioControlCapabilities.KEY_AVAILABLE_HDS_AVAILABLE = 'availableHDsAvailable'; +RadioControlCapabilities.KEY_AVAILABLE_HD_CHANNELS_AVAILABLE = 'availableHdChannelsAvailable'; +RadioControlCapabilities.KEY_STATE_AVAILABLE = 'stateAvailable'; +RadioControlCapabilities.KEY_SIGNAL_STRENGTH_AVAILABLE = 'signalStrengthAvailable'; +RadioControlCapabilities.KEY_SIGNAL_CHANGE_THRESHOLD_AVAILABLE = 'signalChangeThresholdAvailable'; +RadioControlCapabilities.KEY_SIS_DATA_AVAILABLE = 'sisDataAvailable'; +RadioControlCapabilities.KEY_HD_RADIO_ENABLE_AVAILABLE = 'hdRadioEnableAvailable'; +RadioControlCapabilities.KEY_SIRIUSXM_RADIO_AVAILABLE = 'siriusxmRadioAvailable'; + +export { RadioControlCapabilities }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/RadioControlData.js b/lib/js/src/rpc/structs/RadioControlData.js new file mode 100644 index 00000000..c90540cf --- /dev/null +++ b/lib/js/src/rpc/structs/RadioControlData.js @@ -0,0 +1,280 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RadioBand } from '../enums/RadioBand.js'; +import { RpcStruct } from '../RpcStruct.js'; +import { RdsData } from './RdsData.js'; +import { RadioState } from '../enums/RadioState.js'; +import { SisData } from './SisData.js'; + +class RadioControlData extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Number} integer - The integer part of the frequency ie for 101.7 this value should be 101 + * @return {RadioControlData} + */ + setFrequencyInteger (integer) { + this.setParameter(RadioControlData.KEY_FREQUENCY_INTEGER, integer); + return this; + } + + /** + * @return {Number} + */ + getFrequencyInteger () { + return this.getParameter(RadioControlData.KEY_FREQUENCY_INTEGER); + } + + /** + * @param {Number} fraction - The fractional part of the frequency for 101.7 is 7 + * @return {RadioControlData} + */ + setFrequencyFraction (fraction) { + this.setParameter(RadioControlData.KEY_FREQUENCY_FRACTION, fraction); + return this; + } + + /** + * @return {Number} + */ + getFrequencyFraction () { + return this.getParameter(RadioControlData.KEY_FREQUENCY_FRACTION); + } + + /** + * @param {RadioBand} band + * @return {RadioControlData} + */ + setBand (band) { + this.validateType(RadioBand, band); + this.setParameter(RadioControlData.KEY_BAND, band); + return this; + } + + /** + * @return {RadioBand} + */ + getBand () { + return this.getObject(RadioBand, RadioControlData.KEY_BAND); + } + + /** + * @param {RdsData} data + * @return {RadioControlData} + */ + setRdsData (data) { + this.validateType(RdsData, data); + this.setParameter(RadioControlData.KEY_RDS_DATA, data); + return this; + } + + /** + * @return {RdsData} + */ + getRdsData () { + return this.getObject(RdsData, RadioControlData.KEY_RDS_DATA); + } + + /** + * @param {Boolean} enable - True if the hd radio is on, false if the radio is off + * @return {RadioControlData} + */ + setHdRadioEnable (enable) { + this.setParameter(RadioControlData.KEY_HD_RADIO_ENABLE, enable); + return this; + } + + /** + * @return {Boolean} + */ + getHdRadioEnable () { + return this.getParameter(RadioControlData.KEY_HD_RADIO_ENABLE); + } + + /** + * @param {Number} ds - Number of HD sub-channels if available + * @return {RadioControlData} + */ + setAvailableHDs (ds) { + this.setParameter(RadioControlData.KEY_AVAILABLE_HDS, ds); + return this; + } + + /** + * @return {Number} + */ + getAvailableHDs () { + return this.getParameter(RadioControlData.KEY_AVAILABLE_HDS); + } + + /** + * @param {Number[]} channels - The list of available HD sub-channel indexes. Empty list means no Hd channel is + * available. Read-only. + * @return {RadioControlData} + */ + setAvailableHdChannels (channels) { + this.setParameter(RadioControlData.KEY_AVAILABLE_HD_CHANNELS, channels); + return this; + } + + /** + * @return {Number[]} + */ + getAvailableHdChannels () { + return this.getParameter(RadioControlData.KEY_AVAILABLE_HD_CHANNELS); + } + + /** + * @param {Number} channel - Current HD sub-channel if available + * @return {RadioControlData} + */ + setHdChannel (channel) { + this.setParameter(RadioControlData.KEY_HD_CHANNEL, channel); + return this; + } + + /** + * @return {Number} + */ + getHdChannel () { + return this.getParameter(RadioControlData.KEY_HD_CHANNEL); + } + + /** + * @param {Number} strength + * @return {RadioControlData} + */ + setSignalStrength (strength) { + this.setParameter(RadioControlData.KEY_SIGNAL_STRENGTH, strength); + return this; + } + + /** + * @return {Number} + */ + getSignalStrength () { + return this.getParameter(RadioControlData.KEY_SIGNAL_STRENGTH); + } + + /** + * @param {Number} threshold - If the signal strength falls below the set value for this parameter, the radio will + * tune to an alternative frequency + * @return {RadioControlData} + */ + setSignalChangeThreshold (threshold) { + this.setParameter(RadioControlData.KEY_SIGNAL_CHANGE_THRESHOLD, threshold); + return this; + } + + /** + * @return {Number} + */ + getSignalChangeThreshold () { + return this.getParameter(RadioControlData.KEY_SIGNAL_CHANGE_THRESHOLD); + } + + /** + * @param {Boolean} enable - True if the radio is on, false if the radio is off. If set to false, no other data will + * be included. + * @return {RadioControlData} + */ + setRadioEnable (enable) { + this.setParameter(RadioControlData.KEY_RADIO_ENABLE, enable); + return this; + } + + /** + * @return {Boolean} + */ + getRadioEnable () { + return this.getParameter(RadioControlData.KEY_RADIO_ENABLE); + } + + /** + * @param {RadioState} state + * @return {RadioControlData} + */ + setState (state) { + this.validateType(RadioState, state); + this.setParameter(RadioControlData.KEY_STATE, state); + return this; + } + + /** + * @return {RadioState} + */ + getState () { + return this.getObject(RadioState, RadioControlData.KEY_STATE); + } + + /** + * @param {SisData} data - Read-only Station Information Service (SIS) data provides basic information about the + * station such as call sign, as well as information not displayable to the consumer such as + * the station identification number + * @return {RadioControlData} + */ + setSisData (data) { + this.validateType(SisData, data); + this.setParameter(RadioControlData.KEY_SIS_DATA, data); + return this; + } + + /** + * @return {SisData} + */ + getSisData () { + return this.getObject(SisData, RadioControlData.KEY_SIS_DATA); + } +} + +RadioControlData.KEY_FREQUENCY_INTEGER = 'frequencyInteger'; +RadioControlData.KEY_FREQUENCY_FRACTION = 'frequencyFraction'; +RadioControlData.KEY_BAND = 'band'; +RadioControlData.KEY_RDS_DATA = 'rdsData'; +RadioControlData.KEY_HD_RADIO_ENABLE = 'hdRadioEnable'; +RadioControlData.KEY_AVAILABLE_HDS = 'availableHDs'; +RadioControlData.KEY_AVAILABLE_HD_CHANNELS = 'availableHdChannels'; +RadioControlData.KEY_HD_CHANNEL = 'hdChannel'; +RadioControlData.KEY_SIGNAL_STRENGTH = 'signalStrength'; +RadioControlData.KEY_SIGNAL_CHANGE_THRESHOLD = 'signalChangeThreshold'; +RadioControlData.KEY_RADIO_ENABLE = 'radioEnable'; +RadioControlData.KEY_STATE = 'state'; +RadioControlData.KEY_SIS_DATA = 'sisData'; + +export { RadioControlData }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/RdsData.js b/lib/js/src/rpc/structs/RdsData.js new file mode 100644 index 00000000..2a17b7f7 --- /dev/null +++ b/lib/js/src/rpc/structs/RdsData.js @@ -0,0 +1,183 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; + +class RdsData extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {String} ps - Program Service Name + * @return {RdsData} + */ + setPS (ps) { + this.setParameter(RdsData.KEY_PS, ps); + return this; + } + + /** + * @return {String} + */ + getPS () { + return this.getParameter(RdsData.KEY_PS); + } + + /** + * @param {String} rt - Radio Text + * @return {RdsData} + */ + setRT (rt) { + this.setParameter(RdsData.KEY_RT, rt); + return this; + } + + /** + * @return {String} + */ + getRT () { + return this.getParameter(RdsData.KEY_RT); + } + + /** + * @param {String} ct - The clock text in UTC format as YYYY-MM-DDThh:mm:ss.sTZD + * @return {RdsData} + */ + setCT (ct) { + this.setParameter(RdsData.KEY_CT, ct); + return this; + } + + /** + * @return {String} + */ + getCT () { + return this.getParameter(RdsData.KEY_CT); + } + + /** + * @param {String} pi - Program Identification - the call sign for the radio station + * @return {RdsData} + */ + setPI (pi) { + this.setParameter(RdsData.KEY_PI, pi); + return this; + } + + /** + * @return {String} + */ + getPI () { + return this.getParameter(RdsData.KEY_PI); + } + + /** + * @param {Number} pty - The program type - The region should be used to differentiate between EU and North America + * program types + * @return {RdsData} + */ + setPTY (pty) { + this.setParameter(RdsData.KEY_PTY, pty); + return this; + } + + /** + * @return {Number} + */ + getPTY () { + return this.getParameter(RdsData.KEY_PTY); + } + + /** + * @param {Boolean} tp - Traffic Program Identification - Identifies a station that offers traffic + * @return {RdsData} + */ + setTP (tp) { + this.setParameter(RdsData.KEY_TP, tp); + return this; + } + + /** + * @return {Boolean} + */ + getTP () { + return this.getParameter(RdsData.KEY_TP); + } + + /** + * @param {Boolean} ta - Traffic Announcement Identification - Indicates an ongoing traffic announcement + * @return {RdsData} + */ + setTA (ta) { + this.setParameter(RdsData.KEY_TA, ta); + return this; + } + + /** + * @return {Boolean} + */ + getTA () { + return this.getParameter(RdsData.KEY_TA); + } + + /** + * @param {String} reg - Region + * @return {RdsData} + */ + setREG (reg) { + this.setParameter(RdsData.KEY_REG, reg); + return this; + } + + /** + * @return {String} + */ + getREG () { + return this.getParameter(RdsData.KEY_REG); + } +} + +RdsData.KEY_PS = 'PS'; +RdsData.KEY_RT = 'RT'; +RdsData.KEY_CT = 'CT'; +RdsData.KEY_PI = 'PI'; +RdsData.KEY_PTY = 'PTY'; +RdsData.KEY_TP = 'TP'; +RdsData.KEY_TA = 'TA'; +RdsData.KEY_REG = 'REG'; + +export { RdsData }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/Rectangle.js b/lib/js/src/rpc/structs/Rectangle.js new file mode 100644 index 00000000..67e91447 --- /dev/null +++ b/lib/js/src/rpc/structs/Rectangle.js @@ -0,0 +1,114 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; + +class Rectangle extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Number} x - The upper left X-coordinate of the rectangle + * @return {Rectangle} + */ + setX (x) { + this.setParameter(Rectangle.KEY_X, x); + return this; + } + + /** + * @return {Number} + */ + getX () { + return this.getParameter(Rectangle.KEY_X); + } + + /** + * @param {Number} y - The upper left Y-coordinate of the rectangle + * @return {Rectangle} + */ + setY (y) { + this.setParameter(Rectangle.KEY_Y, y); + return this; + } + + /** + * @return {Number} + */ + getY () { + return this.getParameter(Rectangle.KEY_Y); + } + + /** + * @param {Number} width - The width of the rectangle + * @return {Rectangle} + */ + setWidth (width) { + this.setParameter(Rectangle.KEY_WIDTH, width); + return this; + } + + /** + * @return {Number} + */ + getWidth () { + return this.getParameter(Rectangle.KEY_WIDTH); + } + + /** + * @param {Number} height - The height of the rectangle + * @return {Rectangle} + */ + setHeight (height) { + this.setParameter(Rectangle.KEY_HEIGHT, height); + return this; + } + + /** + * @return {Number} + */ + getHeight () { + return this.getParameter(Rectangle.KEY_HEIGHT); + } +} + +Rectangle.KEY_X = 'x'; +Rectangle.KEY_Y = 'y'; +Rectangle.KEY_WIDTH = 'width'; +Rectangle.KEY_HEIGHT = 'height'; + +export { Rectangle }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/RemoteControlCapabilities.js b/lib/js/src/rpc/structs/RemoteControlCapabilities.js new file mode 100644 index 00000000..89c5f444 --- /dev/null +++ b/lib/js/src/rpc/structs/RemoteControlCapabilities.js @@ -0,0 +1,184 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { AudioControlCapabilities } from './AudioControlCapabilities.js'; +import { LightControlCapabilities } from './LightControlCapabilities.js'; +import { ClimateControlCapabilities } from './ClimateControlCapabilities.js'; +import { RpcStruct } from '../RpcStruct.js'; +import { ButtonCapabilities } from './ButtonCapabilities.js'; +import { SeatControlCapabilities } from './SeatControlCapabilities.js'; +import { RadioControlCapabilities } from './RadioControlCapabilities.js'; +import { HMISettingsControlCapabilities } from './HMISettingsControlCapabilities.js'; + +class RemoteControlCapabilities extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {ClimateControlCapabilities[]} capabilities - If included, the platform supports RC climate controls. For + * this baseline version, maxsize=1. i.e. only one climate + * control module is supported. + * @return {RemoteControlCapabilities} + */ + setClimateControlCapabilities (capabilities) { + this.validateType(ClimateControlCapabilities, capabilities, true); + this.setParameter(RemoteControlCapabilities.KEY_CLIMATE_CONTROL_CAPABILITIES, capabilities); + return this; + } + + /** + * @return {ClimateControlCapabilities[]} + */ + getClimateControlCapabilities () { + return this.getObject(ClimateControlCapabilities, RemoteControlCapabilities.KEY_CLIMATE_CONTROL_CAPABILITIES); + } + + /** + * @param {RadioControlCapabilities[]} capabilities - If included, the platform supports RC radio controls.For this + * baseline version, maxsize=1. i.e. only one radio control + * module is supported. + * @return {RemoteControlCapabilities} + */ + setRadioControlCapabilities (capabilities) { + this.validateType(RadioControlCapabilities, capabilities, true); + this.setParameter(RemoteControlCapabilities.KEY_RADIO_CONTROL_CAPABILITIES, capabilities); + return this; + } + + /** + * @return {RadioControlCapabilities[]} + */ + getRadioControlCapabilities () { + return this.getObject(RadioControlCapabilities, RemoteControlCapabilities.KEY_RADIO_CONTROL_CAPABILITIES); + } + + /** + * @param {ButtonCapabilities[]} capabilities - If included, the platform supports RC button controls with the + * included button names. + * @return {RemoteControlCapabilities} + */ + setButtonCapabilities (capabilities) { + this.validateType(ButtonCapabilities, capabilities, true); + this.setParameter(RemoteControlCapabilities.KEY_BUTTON_CAPABILITIES, capabilities); + return this; + } + + /** + * @return {ButtonCapabilities[]} + */ + getButtonCapabilities () { + return this.getObject(ButtonCapabilities, RemoteControlCapabilities.KEY_BUTTON_CAPABILITIES); + } + + /** + * @param {AudioControlCapabilities[]} capabilities - If included, the platform supports audio controls. + * @return {RemoteControlCapabilities} + */ + setAudioControlCapabilities (capabilities) { + this.validateType(AudioControlCapabilities, capabilities, true); + this.setParameter(RemoteControlCapabilities.KEY_AUDIO_CONTROL_CAPABILITIES, capabilities); + return this; + } + + /** + * @return {AudioControlCapabilities[]} + */ + getAudioControlCapabilities () { + return this.getObject(AudioControlCapabilities, RemoteControlCapabilities.KEY_AUDIO_CONTROL_CAPABILITIES); + } + + /** + * @param {HMISettingsControlCapabilities} capabilities - If included, the platform supports hmi setting controls. + * @return {RemoteControlCapabilities} + */ + setHmiSettingsControlCapabilities (capabilities) { + this.validateType(HMISettingsControlCapabilities, capabilities); + this.setParameter(RemoteControlCapabilities.KEY_HMI_SETTINGS_CONTROL_CAPABILITIES, capabilities); + return this; + } + + /** + * @return {HMISettingsControlCapabilities} + */ + getHmiSettingsControlCapabilities () { + return this.getObject(HMISettingsControlCapabilities, RemoteControlCapabilities.KEY_HMI_SETTINGS_CONTROL_CAPABILITIES); + } + + /** + * @param {LightControlCapabilities} capabilities - If included, the platform supports light controls. + * @return {RemoteControlCapabilities} + */ + setLightControlCapabilities (capabilities) { + this.validateType(LightControlCapabilities, capabilities); + this.setParameter(RemoteControlCapabilities.KEY_LIGHT_CONTROL_CAPABILITIES, capabilities); + return this; + } + + /** + * @return {LightControlCapabilities} + */ + getLightControlCapabilities () { + return this.getObject(LightControlCapabilities, RemoteControlCapabilities.KEY_LIGHT_CONTROL_CAPABILITIES); + } + + /** + * @param {SeatControlCapabilities[]} capabilities - If included, the platform supports seat controls. + * @return {RemoteControlCapabilities} + */ + setSeatControlCapabilities (capabilities) { + this.validateType(SeatControlCapabilities, capabilities, true); + this.setParameter(RemoteControlCapabilities.KEY_SEAT_CONTROL_CAPABILITIES, capabilities); + return this; + } + + /** + * @return {SeatControlCapabilities[]} + */ + getSeatControlCapabilities () { + return this.getObject(SeatControlCapabilities, RemoteControlCapabilities.KEY_SEAT_CONTROL_CAPABILITIES); + } +} + +RemoteControlCapabilities.KEY_CLIMATE_CONTROL_CAPABILITIES = 'climateControlCapabilities'; +RemoteControlCapabilities.KEY_RADIO_CONTROL_CAPABILITIES = 'radioControlCapabilities'; +RemoteControlCapabilities.KEY_BUTTON_CAPABILITIES = 'buttonCapabilities'; +RemoteControlCapabilities.KEY_AUDIO_CONTROL_CAPABILITIES = 'audioControlCapabilities'; +RemoteControlCapabilities.KEY_HMI_SETTINGS_CONTROL_CAPABILITIES = 'hmiSettingsControlCapabilities'; +RemoteControlCapabilities.KEY_LIGHT_CONTROL_CAPABILITIES = 'lightControlCapabilities'; +RemoteControlCapabilities.KEY_SEAT_CONTROL_CAPABILITIES = 'seatControlCapabilities'; + +export { RemoteControlCapabilities }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/ScreenParams.js b/lib/js/src/rpc/structs/ScreenParams.js index cd82d4b6..d53f2c28 100644 --- a/lib/js/src/rpc/structs/ScreenParams.js +++ b/lib/js/src/rpc/structs/ScreenParams.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -35,43 +36,43 @@ import { ImageResolution } from './ImageResolution.js'; import { TouchEventCapabilities } from './TouchEventCapabilities.js'; class ScreenParams extends RpcStruct { + /** + * @constructor + */ constructor (parameters) { super(parameters); } - /** - * @param {ImageResolution} resolution - * @return {ScreenParams} - */ + * @param {ImageResolution} resolution - The resolution of the prescribed screen area. + * @return {ScreenParams} + */ setResolution (resolution) { this.validateType(ImageResolution, resolution); - this.setParameter(ScreenParams.KEY_RESOLUTION, resolution); return this; } /** - * @return {ImageResolution} - */ + * @return {ImageResolution} + */ getResolution () { return this.getObject(ImageResolution, ScreenParams.KEY_RESOLUTION); } /** - * @param {TouchEventCapabilities} touchEventCapabilities - * @return {ScreenParams} - */ - setTouchEventAvailable (touchEventCapabilities) { - this.validateType(TouchEventCapabilities, touchEventCapabilities); - - this.setParameter(ScreenParams.KEY_TOUCH_EVENT_AVAILABLE, touchEventCapabilities); + * @param {TouchEventCapabilities} available - Types of screen touch events available in screen area. + * @return {ScreenParams} + */ + setTouchEventAvailable (available) { + this.validateType(TouchEventCapabilities, available); + this.setParameter(ScreenParams.KEY_TOUCH_EVENT_AVAILABLE, available); return this; } /** - * @return {TouchEventCapabilities} - */ + * @return {TouchEventCapabilities} + */ getTouchEventAvailable () { return this.getObject(TouchEventCapabilities, ScreenParams.KEY_TOUCH_EVENT_AVAILABLE); } @@ -80,4 +81,4 @@ class ScreenParams extends RpcStruct { ScreenParams.KEY_RESOLUTION = 'resolution'; ScreenParams.KEY_TOUCH_EVENT_AVAILABLE = 'touchEventAvailable'; -export { ScreenParams }; +export { ScreenParams }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/SdlMsgVersion.js b/lib/js/src/rpc/structs/SdlMsgVersion.js index 99f103b5..6e1ea261 100644 --- a/lib/js/src/rpc/structs/SdlMsgVersion.js +++ b/lib/js/src/rpc/structs/SdlMsgVersion.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -32,55 +33,63 @@ import { RpcStruct } from '../RpcStruct.js'; +/** + * Specifies the version number of the SmartDeviceLink protocol that is supported by the mobile application + */ class SdlMsgVersion extends RpcStruct { + /** + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {Number} the major version of this object - * @return {SdlMsgVersion} - */ - setMajorVersion (value) { - this.setParameter(SdlMsgVersion.KEY_MAJOR_VERSION, value); + * @param {Number} version - The major version indicates versions that is not-compatible to previous versions. + * @return {SdlMsgVersion} + */ + setMajorVersion (version) { + this.setParameter(SdlMsgVersion.KEY_MAJOR_VERSION, version); return this; } /** - * @return {Number} the major version of this object - */ + * @return {Number} + */ getMajorVersion () { return this.getParameter(SdlMsgVersion.KEY_MAJOR_VERSION); } /** - * @param {Number} the minor version of this object - * @return {SdlMsgVersion} - */ - setMinorVersion (value) { - this.setParameter(SdlMsgVersion.KEY_MINOR_VERSION, value); + * @param {Number} version - The minor version indicates a change to a previous version that should still allow to + * be run on an older version (with limited functionality) + * @return {SdlMsgVersion} + */ + setMinorVersion (version) { + this.setParameter(SdlMsgVersion.KEY_MINOR_VERSION, version); return this; } /** - * @return {Number} the minor version of this object - */ + * @return {Number} + */ getMinorVersion () { return this.getParameter(SdlMsgVersion.KEY_MINOR_VERSION); } /** - * @param {Number} the patch version of this object - * @return {SdlMsgVersion} - */ - setPatchVersion (value) { - this.setParameter(SdlMsgVersion.KEY_PATCH_VERSION, value); + * @param {Number} version - The patch version indicates a fix to existing functionality in a previous version that + * should still be able to be run on an older version + * @return {SdlMsgVersion} + */ + setPatchVersion (version) { + this.setParameter(SdlMsgVersion.KEY_PATCH_VERSION, version); return this; } /** - * @return {Number} the patch version of this objects - */ + * @return {Number} + */ getPatchVersion () { return this.getParameter(SdlMsgVersion.KEY_PATCH_VERSION); } @@ -90,4 +99,4 @@ SdlMsgVersion.KEY_MAJOR_VERSION = 'majorVersion'; SdlMsgVersion.KEY_MINOR_VERSION = 'minorVersion'; SdlMsgVersion.KEY_PATCH_VERSION = 'patchVersion'; -export { SdlMsgVersion }; +export { SdlMsgVersion }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/SeatControlCapabilities.js b/lib/js/src/rpc/structs/SeatControlCapabilities.js new file mode 100644 index 00000000..ed2953bc --- /dev/null +++ b/lib/js/src/rpc/structs/SeatControlCapabilities.js @@ -0,0 +1,338 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { ModuleInfo } from './ModuleInfo.js'; + +class SeatControlCapabilities extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {String} name - The short friendly name of the light control module. It should not be used to identify a + * module by mobile application. + * @return {SeatControlCapabilities} + */ + setModuleName (name) { + this.setParameter(SeatControlCapabilities.KEY_MODULE_NAME, name); + return this; + } + + /** + * @return {String} + */ + getModuleName () { + return this.getParameter(SeatControlCapabilities.KEY_MODULE_NAME); + } + + /** + * @param {ModuleInfo} info - Information about a RC module, including its id. + * @return {SeatControlCapabilities} + */ + setModuleInfo (info) { + this.validateType(ModuleInfo, info); + this.setParameter(SeatControlCapabilities.KEY_MODULE_INFO, info); + return this; + } + + /** + * @return {ModuleInfo} + */ + getModuleInfo () { + return this.getObject(ModuleInfo, SeatControlCapabilities.KEY_MODULE_INFO); + } + + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + setHeatingEnabledAvailable (available) { + this.setParameter(SeatControlCapabilities.KEY_HEATING_ENABLED_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getHeatingEnabledAvailable () { + return this.getParameter(SeatControlCapabilities.KEY_HEATING_ENABLED_AVAILABLE); + } + + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + setCoolingEnabledAvailable (available) { + this.setParameter(SeatControlCapabilities.KEY_COOLING_ENABLED_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getCoolingEnabledAvailable () { + return this.getParameter(SeatControlCapabilities.KEY_COOLING_ENABLED_AVAILABLE); + } + + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + setHeatingLevelAvailable (available) { + this.setParameter(SeatControlCapabilities.KEY_HEATING_LEVEL_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getHeatingLevelAvailable () { + return this.getParameter(SeatControlCapabilities.KEY_HEATING_LEVEL_AVAILABLE); + } + + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + setCoolingLevelAvailable (available) { + this.setParameter(SeatControlCapabilities.KEY_COOLING_LEVEL_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getCoolingLevelAvailable () { + return this.getParameter(SeatControlCapabilities.KEY_COOLING_LEVEL_AVAILABLE); + } + + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + setHorizontalPositionAvailable (available) { + this.setParameter(SeatControlCapabilities.KEY_HORIZONTAL_POSITION_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getHorizontalPositionAvailable () { + return this.getParameter(SeatControlCapabilities.KEY_HORIZONTAL_POSITION_AVAILABLE); + } + + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + setVerticalPositionAvailable (available) { + this.setParameter(SeatControlCapabilities.KEY_VERTICAL_POSITION_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getVerticalPositionAvailable () { + return this.getParameter(SeatControlCapabilities.KEY_VERTICAL_POSITION_AVAILABLE); + } + + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + setFrontVerticalPositionAvailable (available) { + this.setParameter(SeatControlCapabilities.KEY_FRONT_VERTICAL_POSITION_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getFrontVerticalPositionAvailable () { + return this.getParameter(SeatControlCapabilities.KEY_FRONT_VERTICAL_POSITION_AVAILABLE); + } + + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + setBackVerticalPositionAvailable (available) { + this.setParameter(SeatControlCapabilities.KEY_BACK_VERTICAL_POSITION_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getBackVerticalPositionAvailable () { + return this.getParameter(SeatControlCapabilities.KEY_BACK_VERTICAL_POSITION_AVAILABLE); + } + + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + setBackTiltAngleAvailable (available) { + this.setParameter(SeatControlCapabilities.KEY_BACK_TILT_ANGLE_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getBackTiltAngleAvailable () { + return this.getParameter(SeatControlCapabilities.KEY_BACK_TILT_ANGLE_AVAILABLE); + } + + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + setHeadSupportHorizontalPositionAvailable (available) { + this.setParameter(SeatControlCapabilities.KEY_HEAD_SUPPORT_HORIZONTAL_POSITION_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getHeadSupportHorizontalPositionAvailable () { + return this.getParameter(SeatControlCapabilities.KEY_HEAD_SUPPORT_HORIZONTAL_POSITION_AVAILABLE); + } + + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + setHeadSupportVerticalPositionAvailable (available) { + this.setParameter(SeatControlCapabilities.KEY_HEAD_SUPPORT_VERTICAL_POSITION_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getHeadSupportVerticalPositionAvailable () { + return this.getParameter(SeatControlCapabilities.KEY_HEAD_SUPPORT_VERTICAL_POSITION_AVAILABLE); + } + + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + setMassageEnabledAvailable (available) { + this.setParameter(SeatControlCapabilities.KEY_MASSAGE_ENABLED_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getMassageEnabledAvailable () { + return this.getParameter(SeatControlCapabilities.KEY_MASSAGE_ENABLED_AVAILABLE); + } + + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + setMassageModeAvailable (available) { + this.setParameter(SeatControlCapabilities.KEY_MASSAGE_MODE_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getMassageModeAvailable () { + return this.getParameter(SeatControlCapabilities.KEY_MASSAGE_MODE_AVAILABLE); + } + + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + setMassageCushionFirmnessAvailable (available) { + this.setParameter(SeatControlCapabilities.KEY_MASSAGE_CUSHION_FIRMNESS_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getMassageCushionFirmnessAvailable () { + return this.getParameter(SeatControlCapabilities.KEY_MASSAGE_CUSHION_FIRMNESS_AVAILABLE); + } + + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + setMemoryAvailable (available) { + this.setParameter(SeatControlCapabilities.KEY_MEMORY_AVAILABLE, available); + return this; + } + + /** + * @return {Boolean} + */ + getMemoryAvailable () { + return this.getParameter(SeatControlCapabilities.KEY_MEMORY_AVAILABLE); + } +} + +SeatControlCapabilities.KEY_MODULE_NAME = 'moduleName'; +SeatControlCapabilities.KEY_MODULE_INFO = 'moduleInfo'; +SeatControlCapabilities.KEY_HEATING_ENABLED_AVAILABLE = 'heatingEnabledAvailable'; +SeatControlCapabilities.KEY_COOLING_ENABLED_AVAILABLE = 'coolingEnabledAvailable'; +SeatControlCapabilities.KEY_HEATING_LEVEL_AVAILABLE = 'heatingLevelAvailable'; +SeatControlCapabilities.KEY_COOLING_LEVEL_AVAILABLE = 'coolingLevelAvailable'; +SeatControlCapabilities.KEY_HORIZONTAL_POSITION_AVAILABLE = 'horizontalPositionAvailable'; +SeatControlCapabilities.KEY_VERTICAL_POSITION_AVAILABLE = 'verticalPositionAvailable'; +SeatControlCapabilities.KEY_FRONT_VERTICAL_POSITION_AVAILABLE = 'frontVerticalPositionAvailable'; +SeatControlCapabilities.KEY_BACK_VERTICAL_POSITION_AVAILABLE = 'backVerticalPositionAvailable'; +SeatControlCapabilities.KEY_BACK_TILT_ANGLE_AVAILABLE = 'backTiltAngleAvailable'; +SeatControlCapabilities.KEY_HEAD_SUPPORT_HORIZONTAL_POSITION_AVAILABLE = 'headSupportHorizontalPositionAvailable'; +SeatControlCapabilities.KEY_HEAD_SUPPORT_VERTICAL_POSITION_AVAILABLE = 'headSupportVerticalPositionAvailable'; +SeatControlCapabilities.KEY_MASSAGE_ENABLED_AVAILABLE = 'massageEnabledAvailable'; +SeatControlCapabilities.KEY_MASSAGE_MODE_AVAILABLE = 'massageModeAvailable'; +SeatControlCapabilities.KEY_MASSAGE_CUSHION_FIRMNESS_AVAILABLE = 'massageCushionFirmnessAvailable'; +SeatControlCapabilities.KEY_MEMORY_AVAILABLE = 'memoryAvailable'; + +export { SeatControlCapabilities }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/SeatControlData.js b/lib/js/src/rpc/structs/SeatControlData.js new file mode 100644 index 00000000..70a8e36f --- /dev/null +++ b/lib/js/src/rpc/structs/SeatControlData.js @@ -0,0 +1,329 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { MassageCushionFirmness } from './MassageCushionFirmness.js'; +import { SupportedSeat } from '../enums/SupportedSeat.js'; +import { RpcStruct } from '../RpcStruct.js'; +import { SeatMemoryAction } from './SeatMemoryAction.js'; +import { MassageModeData } from './MassageModeData.js'; + +/** + * Seat control data corresponds to "SEAT" ModuleType. + */ +class SeatControlData extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {SupportedSeat} id - List possible seats that is a remote controllable seat. + * @return {SeatControlData} + */ + setId (id) { + this.validateType(SupportedSeat, id); + this.setParameter(SeatControlData.KEY_ID, id); + return this; + } + + /** + * @return {SupportedSeat} + */ + getId () { + return this.getObject(SupportedSeat, SeatControlData.KEY_ID); + } + + /** + * @param {Boolean} enabled + * @return {SeatControlData} + */ + setHeatingEnabled (enabled) { + this.setParameter(SeatControlData.KEY_HEATING_ENABLED, enabled); + return this; + } + + /** + * @return {Boolean} + */ + getHeatingEnabled () { + return this.getParameter(SeatControlData.KEY_HEATING_ENABLED); + } + + /** + * @param {Boolean} enabled + * @return {SeatControlData} + */ + setCoolingEnabled (enabled) { + this.setParameter(SeatControlData.KEY_COOLING_ENABLED, enabled); + return this; + } + + /** + * @return {Boolean} + */ + getCoolingEnabled () { + return this.getParameter(SeatControlData.KEY_COOLING_ENABLED); + } + + /** + * @param {Number} level + * @return {SeatControlData} + */ + setHeatingLevel (level) { + this.setParameter(SeatControlData.KEY_HEATING_LEVEL, level); + return this; + } + + /** + * @return {Number} + */ + getHeatingLevel () { + return this.getParameter(SeatControlData.KEY_HEATING_LEVEL); + } + + /** + * @param {Number} level + * @return {SeatControlData} + */ + setCoolingLevel (level) { + this.setParameter(SeatControlData.KEY_COOLING_LEVEL, level); + return this; + } + + /** + * @return {Number} + */ + getCoolingLevel () { + return this.getParameter(SeatControlData.KEY_COOLING_LEVEL); + } + + /** + * @param {Number} position + * @return {SeatControlData} + */ + setHorizontalPosition (position) { + this.setParameter(SeatControlData.KEY_HORIZONTAL_POSITION, position); + return this; + } + + /** + * @return {Number} + */ + getHorizontalPosition () { + return this.getParameter(SeatControlData.KEY_HORIZONTAL_POSITION); + } + + /** + * @param {Number} position + * @return {SeatControlData} + */ + setVerticalPosition (position) { + this.setParameter(SeatControlData.KEY_VERTICAL_POSITION, position); + return this; + } + + /** + * @return {Number} + */ + getVerticalPosition () { + return this.getParameter(SeatControlData.KEY_VERTICAL_POSITION); + } + + /** + * @param {Number} position + * @return {SeatControlData} + */ + setFrontVerticalPosition (position) { + this.setParameter(SeatControlData.KEY_FRONT_VERTICAL_POSITION, position); + return this; + } + + /** + * @return {Number} + */ + getFrontVerticalPosition () { + return this.getParameter(SeatControlData.KEY_FRONT_VERTICAL_POSITION); + } + + /** + * @param {Number} position + * @return {SeatControlData} + */ + setBackVerticalPosition (position) { + this.setParameter(SeatControlData.KEY_BACK_VERTICAL_POSITION, position); + return this; + } + + /** + * @return {Number} + */ + getBackVerticalPosition () { + return this.getParameter(SeatControlData.KEY_BACK_VERTICAL_POSITION); + } + + /** + * @param {Number} angle + * @return {SeatControlData} + */ + setBackTiltAngle (angle) { + this.setParameter(SeatControlData.KEY_BACK_TILT_ANGLE, angle); + return this; + } + + /** + * @return {Number} + */ + getBackTiltAngle () { + return this.getParameter(SeatControlData.KEY_BACK_TILT_ANGLE); + } + + /** + * @param {Number} position + * @return {SeatControlData} + */ + setHeadSupportHorizontalPosition (position) { + this.setParameter(SeatControlData.KEY_HEAD_SUPPORT_HORIZONTAL_POSITION, position); + return this; + } + + /** + * @return {Number} + */ + getHeadSupportHorizontalPosition () { + return this.getParameter(SeatControlData.KEY_HEAD_SUPPORT_HORIZONTAL_POSITION); + } + + /** + * @param {Number} position + * @return {SeatControlData} + */ + setHeadSupportVerticalPosition (position) { + this.setParameter(SeatControlData.KEY_HEAD_SUPPORT_VERTICAL_POSITION, position); + return this; + } + + /** + * @return {Number} + */ + getHeadSupportVerticalPosition () { + return this.getParameter(SeatControlData.KEY_HEAD_SUPPORT_VERTICAL_POSITION); + } + + /** + * @param {Boolean} enabled + * @return {SeatControlData} + */ + setMassageEnabled (enabled) { + this.setParameter(SeatControlData.KEY_MASSAGE_ENABLED, enabled); + return this; + } + + /** + * @return {Boolean} + */ + getMassageEnabled () { + return this.getParameter(SeatControlData.KEY_MASSAGE_ENABLED); + } + + /** + * @param {MassageModeData[]} mode - Specify the mode of a massage zone. + * @return {SeatControlData} + */ + setMassageMode (mode) { + this.validateType(MassageModeData, mode, true); + this.setParameter(SeatControlData.KEY_MASSAGE_MODE, mode); + return this; + } + + /** + * @return {MassageModeData[]} + */ + getMassageMode () { + return this.getObject(MassageModeData, SeatControlData.KEY_MASSAGE_MODE); + } + + /** + * @param {MassageCushionFirmness[]} firmness - The intensity or firmness of a cushion. + * @return {SeatControlData} + */ + setMassageCushionFirmness (firmness) { + this.validateType(MassageCushionFirmness, firmness, true); + this.setParameter(SeatControlData.KEY_MASSAGE_CUSHION_FIRMNESS, firmness); + return this; + } + + /** + * @return {MassageCushionFirmness[]} + */ + getMassageCushionFirmness () { + return this.getObject(MassageCushionFirmness, SeatControlData.KEY_MASSAGE_CUSHION_FIRMNESS); + } + + /** + * @param {SeatMemoryAction} memory + * @return {SeatControlData} + */ + setMemory (memory) { + this.validateType(SeatMemoryAction, memory); + this.setParameter(SeatControlData.KEY_MEMORY, memory); + return this; + } + + /** + * @return {SeatMemoryAction} + */ + getMemory () { + return this.getObject(SeatMemoryAction, SeatControlData.KEY_MEMORY); + } +} + +SeatControlData.KEY_ID = 'id'; +SeatControlData.KEY_HEATING_ENABLED = 'heatingEnabled'; +SeatControlData.KEY_COOLING_ENABLED = 'coolingEnabled'; +SeatControlData.KEY_HEATING_LEVEL = 'heatingLevel'; +SeatControlData.KEY_COOLING_LEVEL = 'coolingLevel'; +SeatControlData.KEY_HORIZONTAL_POSITION = 'horizontalPosition'; +SeatControlData.KEY_VERTICAL_POSITION = 'verticalPosition'; +SeatControlData.KEY_FRONT_VERTICAL_POSITION = 'frontVerticalPosition'; +SeatControlData.KEY_BACK_VERTICAL_POSITION = 'backVerticalPosition'; +SeatControlData.KEY_BACK_TILT_ANGLE = 'backTiltAngle'; +SeatControlData.KEY_HEAD_SUPPORT_HORIZONTAL_POSITION = 'headSupportHorizontalPosition'; +SeatControlData.KEY_HEAD_SUPPORT_VERTICAL_POSITION = 'headSupportVerticalPosition'; +SeatControlData.KEY_MASSAGE_ENABLED = 'massageEnabled'; +SeatControlData.KEY_MASSAGE_MODE = 'massageMode'; +SeatControlData.KEY_MASSAGE_CUSHION_FIRMNESS = 'massageCushionFirmness'; +SeatControlData.KEY_MEMORY = 'memory'; + +export { SeatControlData }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/SeatLocation.js b/lib/js/src/rpc/structs/SeatLocation.js new file mode 100644 index 00000000..3fe46eab --- /dev/null +++ b/lib/js/src/rpc/structs/SeatLocation.js @@ -0,0 +1,68 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { Grid } from './Grid.js'; + +/** + * Describes the location of a seat. + */ +class SeatLocation extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Grid} grid - Describes a location (origin coordinates and span) of a vehicle component. + * @return {SeatLocation} + */ + setGrid (grid) { + this.validateType(Grid, grid); + this.setParameter(SeatLocation.KEY_GRID, grid); + return this; + } + + /** + * @return {Grid} + */ + getGrid () { + return this.getObject(Grid, SeatLocation.KEY_GRID); + } +} + +SeatLocation.KEY_GRID = 'grid'; + +export { SeatLocation }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/SeatLocationCapability.js b/lib/js/src/rpc/structs/SeatLocationCapability.js new file mode 100644 index 00000000..d70c3db7 --- /dev/null +++ b/lib/js/src/rpc/structs/SeatLocationCapability.js @@ -0,0 +1,119 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { SeatLocation } from './SeatLocation.js'; + +/** + * Contains information about the locations of each seat + */ +class SeatLocationCapability extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Number} rows + * @return {SeatLocationCapability} + */ + setRows (rows) { + this.setParameter(SeatLocationCapability.KEY_ROWS, rows); + return this; + } + + /** + * @return {Number} + */ + getRows () { + return this.getParameter(SeatLocationCapability.KEY_ROWS); + } + + /** + * @param {Number} columns + * @return {SeatLocationCapability} + */ + setColumns (columns) { + this.setParameter(SeatLocationCapability.KEY_COLUMNS, columns); + return this; + } + + /** + * @return {Number} + */ + getColumns () { + return this.getParameter(SeatLocationCapability.KEY_COLUMNS); + } + + /** + * @param {Number} levels + * @return {SeatLocationCapability} + */ + setLevels (levels) { + this.setParameter(SeatLocationCapability.KEY_LEVELS, levels); + return this; + } + + /** + * @return {Number} + */ + getLevels () { + return this.getParameter(SeatLocationCapability.KEY_LEVELS); + } + + /** + * @param {SeatLocation[]} seats - Contains a list of SeatLocation in the vehicle + * @return {SeatLocationCapability} + */ + setSeats (seats) { + this.validateType(SeatLocation, seats, true); + this.setParameter(SeatLocationCapability.KEY_SEATS, seats); + return this; + } + + /** + * @return {SeatLocation[]} + */ + getSeats () { + return this.getObject(SeatLocation, SeatLocationCapability.KEY_SEATS); + } +} + +SeatLocationCapability.KEY_ROWS = 'rows'; +SeatLocationCapability.KEY_COLUMNS = 'columns'; +SeatLocationCapability.KEY_LEVELS = 'levels'; +SeatLocationCapability.KEY_SEATS = 'seats'; + +export { SeatLocationCapability }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/SeatMemoryAction.js b/lib/js/src/rpc/structs/SeatMemoryAction.js new file mode 100644 index 00000000..f8148fb6 --- /dev/null +++ b/lib/js/src/rpc/structs/SeatMemoryAction.js @@ -0,0 +1,99 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { SeatMemoryActionType } from '../enums/SeatMemoryActionType.js'; + +class SeatMemoryAction extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Number} id + * @return {SeatMemoryAction} + */ + setId (id) { + this.setParameter(SeatMemoryAction.KEY_ID, id); + return this; + } + + /** + * @return {Number} + */ + getId () { + return this.getParameter(SeatMemoryAction.KEY_ID); + } + + /** + * @param {String} label + * @return {SeatMemoryAction} + */ + setLabel (label) { + this.setParameter(SeatMemoryAction.KEY_LABEL, label); + return this; + } + + /** + * @return {String} + */ + getLabel () { + return this.getParameter(SeatMemoryAction.KEY_LABEL); + } + + /** + * @param {SeatMemoryActionType} action + * @return {SeatMemoryAction} + */ + setAction (action) { + this.validateType(SeatMemoryActionType, action); + this.setParameter(SeatMemoryAction.KEY_ACTION, action); + return this; + } + + /** + * @return {SeatMemoryActionType} + */ + getAction () { + return this.getObject(SeatMemoryActionType, SeatMemoryAction.KEY_ACTION); + } +} + +SeatMemoryAction.KEY_ID = 'id'; +SeatMemoryAction.KEY_LABEL = 'label'; +SeatMemoryAction.KEY_ACTION = 'action'; + +export { SeatMemoryAction }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/SingleTireStatus.js b/lib/js/src/rpc/structs/SingleTireStatus.js new file mode 100644 index 00000000..3299370c --- /dev/null +++ b/lib/js/src/rpc/structs/SingleTireStatus.js @@ -0,0 +1,101 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { ComponentVolumeStatus } from '../enums/ComponentVolumeStatus.js'; +import { RpcStruct } from '../RpcStruct.js'; +import { TPMS } from '../enums/TPMS.js'; + +class SingleTireStatus extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {ComponentVolumeStatus} status - See ComponentVolumeStatus. + * @return {SingleTireStatus} + */ + setStatus (status) { + this.validateType(ComponentVolumeStatus, status); + this.setParameter(SingleTireStatus.KEY_STATUS, status); + return this; + } + + /** + * @return {ComponentVolumeStatus} + */ + getStatus () { + return this.getObject(ComponentVolumeStatus, SingleTireStatus.KEY_STATUS); + } + + /** + * @param {TPMS} tpms - The status of TPMS according to the particular tire. + * @return {SingleTireStatus} + */ + setTpms (tpms) { + this.validateType(TPMS, tpms); + this.setParameter(SingleTireStatus.KEY_TPMS, tpms); + return this; + } + + /** + * @return {TPMS} + */ + getTpms () { + return this.getObject(TPMS, SingleTireStatus.KEY_TPMS); + } + + /** + * @param {Number} pressure - The pressure value of the particular tire in kilo pascal. + * @return {SingleTireStatus} + */ + setPressure (pressure) { + this.setParameter(SingleTireStatus.KEY_PRESSURE, pressure); + return this; + } + + /** + * @return {Number} + */ + getPressure () { + return this.getParameter(SingleTireStatus.KEY_PRESSURE); + } +} + +SingleTireStatus.KEY_STATUS = 'status'; +SingleTireStatus.KEY_TPMS = 'tpms'; +SingleTireStatus.KEY_PRESSURE = 'pressure'; + +export { SingleTireStatus }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/SisData.js b/lib/js/src/rpc/structs/SisData.js new file mode 100644 index 00000000..d8d3272d --- /dev/null +++ b/lib/js/src/rpc/structs/SisData.js @@ -0,0 +1,137 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { GPSData } from './GPSData.js'; +import { RpcStruct } from '../RpcStruct.js'; +import { StationIDNumber } from './StationIDNumber.js'; + +class SisData extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {String} name - Identifies the 4-alpha-character station call sign plus an optional (-FM) extension + * @return {SisData} + */ + setStationShortName (name) { + this.setParameter(SisData.KEY_STATION_SHORT_NAME, name); + return this; + } + + /** + * @return {String} + */ + getStationShortName () { + return this.getParameter(SisData.KEY_STATION_SHORT_NAME); + } + + /** + * @param {StationIDNumber} number - Used for network Application. Consists of Country Code and FCC Facility ID. + * @return {SisData} + */ + setStationIDNumber (number) { + this.validateType(StationIDNumber, number); + this.setParameter(SisData.KEY_STATION_IDNUMBER, number); + return this; + } + + /** + * @return {StationIDNumber} + */ + getStationIDNumber () { + return this.getObject(StationIDNumber, SisData.KEY_STATION_IDNUMBER); + } + + /** + * @param {String} name - Identifies the station call sign or other identifying information in the long format. + * @return {SisData} + */ + setStationLongName (name) { + this.setParameter(SisData.KEY_STATION_LONG_NAME, name); + return this; + } + + /** + * @return {String} + */ + getStationLongName () { + return this.getParameter(SisData.KEY_STATION_LONG_NAME); + } + + /** + * @param {GPSData} location - Provides the 3-dimensional geographic station location. + * @return {SisData} + */ + setStationLocation (location) { + this.validateType(GPSData, location); + this.setParameter(SisData.KEY_STATION_LOCATION, location); + return this; + } + + /** + * @return {GPSData} + */ + getStationLocation () { + return this.getObject(GPSData, SisData.KEY_STATION_LOCATION); + } + + /** + * @param {String} message - May be used to convey textual information of general interest to the consumer such as + * weather forecasts or public service announcements. Includes a high priority delivery + * feature to convey emergencies that may be in the listening area. + * @return {SisData} + */ + setStationMessage (message) { + this.setParameter(SisData.KEY_STATION_MESSAGE, message); + return this; + } + + /** + * @return {String} + */ + getStationMessage () { + return this.getParameter(SisData.KEY_STATION_MESSAGE); + } +} + +SisData.KEY_STATION_SHORT_NAME = 'stationShortName'; +SisData.KEY_STATION_IDNUMBER = 'stationIDNumber'; +SisData.KEY_STATION_LONG_NAME = 'stationLongName'; +SisData.KEY_STATION_LOCATION = 'stationLocation'; +SisData.KEY_STATION_MESSAGE = 'stationMessage'; + +export { SisData }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/SoftButton.js b/lib/js/src/rpc/structs/SoftButton.js index fb875de4..14398b6d 100644 --- a/lib/js/src/rpc/structs/SoftButton.js +++ b/lib/js/src/rpc/structs/SoftButton.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -32,114 +33,116 @@ import { RpcStruct } from '../RpcStruct.js'; import { SoftButtonType } from '../enums/SoftButtonType.js'; -import { SystemAction } from '../enums/SystemAction.js'; import { Image } from './Image.js'; - +import { SystemAction } from '../enums/SystemAction.js'; class SoftButton extends RpcStruct { + /** + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {SoftButtonType} type - * @return {SoftButton} - */ + * @param {SoftButtonType} type - Describes, whether it is text, highlighted text, icon, or dynamic image. See + * softButtonType + * @return {SoftButton} + */ setType (type) { this.validateType(SoftButtonType, type); - this.setParameter(SoftButton.KEY_TYPE, type); return this; } /** - * @return {SoftButtonType} - */ + * @return {SoftButtonType} + */ getType () { return this.getObject(SoftButtonType, SoftButton.KEY_TYPE); } /** - * @param {String} text - * @return {SoftButton} - */ + * @param {String} text - Optional text to display (if defined as TEXT or BOTH) + * @return {SoftButton} + */ setText (text) { this.setParameter(SoftButton.KEY_TEXT, text); return this; } /** - * @return {String} - */ + * @return {String} + */ getText () { return this.getParameter(SoftButton.KEY_TEXT); } /** - * @param {Image} image - * @return {SoftButton} - */ + * @param {Image} image - Optional image struct for SoftButton (if defined as IMAGE or BOTH) + * @return {SoftButton} + */ setImage (image) { this.validateType(Image, image); - this.setParameter(SoftButton.KEY_IMAGE, image); return this; } /** - * @return {Image} - */ + * @return {Image} + */ getImage () { return this.getObject(Image, SoftButton.KEY_IMAGE); } /** - * @param {Boolean} isHighlighted - * @return {SoftButton} - */ - setIsHighlighted (isHighlighted) { - this.setParameter(SoftButton.KEY_IS_HIGHLIGHTED, isHighlighted); + * @param {Boolean} highlighted - True, if highlighted False, if not highlighted + * @return {SoftButton} + */ + setIsHighlighted (highlighted) { + this.setParameter(SoftButton.KEY_IS_HIGHLIGHTED, highlighted); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getIsHighlighted () { return this.getParameter(SoftButton.KEY_IS_HIGHLIGHTED); } /** - * @param {Number} softButtonID - * @return {SoftButton} - */ - setSoftButtonID (softButtonID) { - this.setParameter(SoftButton.KEY_SOFT_BUTTON_ID, softButtonID); + * @param {Number} id - Value which is returned via OnButtonPress / OnButtonEvent + * @return {SoftButton} + */ + setSoftButtonID (id) { + this.setParameter(SoftButton.KEY_SOFT_BUTTON_ID, id); return this; } /** - * @return {Number} - */ + * @return {Number} + */ getSoftButtonID () { return this.getParameter(SoftButton.KEY_SOFT_BUTTON_ID); } - /** - * @param {SystemAction} systemAction - * @return {SoftButton} - */ - setSystemAction (systemAction) { - this.validateType(SystemAction, systemAction); - - this.setParameter(SoftButton.KEY_SYSTEM_ACTION, systemAction); + * @param {SystemAction} action - Parameter indicating whether selecting a SoftButton shall call a specific system + * action. This is intended to allow Notifications to bring the callee into full / + * focus; or in the case of persistent overlays, the overlay can persist when a + * SoftButton is pressed. + * @return {SoftButton} + */ + setSystemAction (action) { + this.validateType(SystemAction, action); + this.setParameter(SoftButton.KEY_SYSTEM_ACTION, action); return this; } /** - * @return {SystemAction} - */ + * @return {SystemAction} + */ getSystemAction () { return this.getObject(SystemAction, SoftButton.KEY_SYSTEM_ACTION); } @@ -152,4 +155,4 @@ SoftButton.KEY_IS_HIGHLIGHTED = 'isHighlighted'; SoftButton.KEY_SOFT_BUTTON_ID = 'softButtonID'; SoftButton.KEY_SYSTEM_ACTION = 'systemAction'; -export { SoftButton }; +export { SoftButton }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/SoftButtonCapabilities.js b/lib/js/src/rpc/structs/SoftButtonCapabilities.js index d76f975d..7c97360e 100644 --- a/lib/js/src/rpc/structs/SoftButtonCapabilities.js +++ b/lib/js/src/rpc/structs/SoftButtonCapabilities.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -32,87 +33,98 @@ import { RpcStruct } from '../RpcStruct.js'; +/** + * Contains information about a SoftButton's capabilities. + */ class SoftButtonCapabilities extends RpcStruct { + /** + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {Boolean} shortPressAvailable - * @return {SoftButtonCapabilities} - */ - setShortPressAvailable (shortPressAvailable) { - this.setParameter(SoftButtonCapabilities.KEY_SHORT_PRESS_AVAILABLE, shortPressAvailable); + * @param {Boolean} available - The button supports a short press. Whenever the button is pressed short, + * onButtonPressed( SHORT) will be invoked. + * @return {SoftButtonCapabilities} + */ + setShortPressAvailable (available) { + this.setParameter(SoftButtonCapabilities.KEY_SHORT_PRESS_AVAILABLE, available); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getShortPressAvailable () { return this.getParameter(SoftButtonCapabilities.KEY_SHORT_PRESS_AVAILABLE); } /** - * @param {Boolean} longPressAvailable - * @return {SoftButtonCapabilities} - */ - setLongPressAvailable (longPressAvailable) { - this.setParameter(SoftButtonCapabilities.KEY_LONG_PRESS_AVAILABLE, longPressAvailable); + * @param {Boolean} available - The button supports a LONG press. Whenever the button is pressed long, + * onButtonPressed( LONG) will be invoked. + * @return {SoftButtonCapabilities} + */ + setLongPressAvailable (available) { + this.setParameter(SoftButtonCapabilities.KEY_LONG_PRESS_AVAILABLE, available); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getLongPressAvailable () { return this.getParameter(SoftButtonCapabilities.KEY_LONG_PRESS_AVAILABLE); } /** - * @param {Boolean} upDownAvailable - * @return {SoftButtonCapabilities} - */ - setUpDownAvailable (upDownAvailable) { - this.setParameter(SoftButtonCapabilities.KEY_UP_DOWN_AVAILABLE, upDownAvailable); + * @param {Boolean} available - The button supports "button down" and "button up". Whenever the button is pressed, + * onButtonEvent( DOWN) will be invoked. Whenever the button is released, + * onButtonEvent( UP) will be invoked. + * @return {SoftButtonCapabilities} + */ + setUpDownAvailable (available) { + this.setParameter(SoftButtonCapabilities.KEY_UP_DOWN_AVAILABLE, available); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getUpDownAvailable () { return this.getParameter(SoftButtonCapabilities.KEY_UP_DOWN_AVAILABLE); } /** - * @param {Boolean} imageSupported - * @return {SoftButtonCapabilities} - */ - setImageSupported (imageSupported) { - this.setParameter(SoftButtonCapabilities.KEY_IMAGE_SUPPORTED, imageSupported); + * @param {Boolean} supported - The button supports referencing a static or dynamic image. + * @return {SoftButtonCapabilities} + */ + setImageSupported (supported) { + this.setParameter(SoftButtonCapabilities.KEY_IMAGE_SUPPORTED, supported); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getImageSupported () { return this.getParameter(SoftButtonCapabilities.KEY_IMAGE_SUPPORTED); } /** - * @param {Boolean} textSupported - * @return {SoftButtonCapabilities} - */ - setTextSupported (textSupported) { - this.setParameter(SoftButtonCapabilities.KEY_TEXT_SUPPORTED, textSupported); + * @param {Boolean} supported - The button supports the use of text. If not included, the default value should be + * considered true that the button will support text. + * @return {SoftButtonCapabilities} + */ + setTextSupported (supported) { + this.setParameter(SoftButtonCapabilities.KEY_TEXT_SUPPORTED, supported); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getTextSupported () { return this.getParameter(SoftButtonCapabilities.KEY_TEXT_SUPPORTED); } @@ -124,4 +136,4 @@ SoftButtonCapabilities.KEY_UP_DOWN_AVAILABLE = 'upDownAvailable'; SoftButtonCapabilities.KEY_IMAGE_SUPPORTED = 'imageSupported'; SoftButtonCapabilities.KEY_TEXT_SUPPORTED = 'textSupported'; -export { SoftButtonCapabilities }; +export { SoftButtonCapabilities }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/StartTime.js b/lib/js/src/rpc/structs/StartTime.js new file mode 100644 index 00000000..d046ff64 --- /dev/null +++ b/lib/js/src/rpc/structs/StartTime.js @@ -0,0 +1,98 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; + +class StartTime extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Number} hours - The hour of the media clock. Some radios only support a max of 19 hours. If out of range, + * it will be rejected. + * @return {StartTime} + */ + setHours (hours) { + this.setParameter(StartTime.KEY_HOURS, hours); + return this; + } + + /** + * @return {Number} + */ + getHours () { + return this.getParameter(StartTime.KEY_HOURS); + } + + /** + * @param {Number} minutes + * @return {StartTime} + */ + setMinutes (minutes) { + this.setParameter(StartTime.KEY_MINUTES, minutes); + return this; + } + + /** + * @return {Number} + */ + getMinutes () { + return this.getParameter(StartTime.KEY_MINUTES); + } + + /** + * @param {Number} seconds + * @return {StartTime} + */ + setSeconds (seconds) { + this.setParameter(StartTime.KEY_SECONDS, seconds); + return this; + } + + /** + * @return {Number} + */ + getSeconds () { + return this.getParameter(StartTime.KEY_SECONDS); + } +} + +StartTime.KEY_HOURS = 'hours'; +StartTime.KEY_MINUTES = 'minutes'; +StartTime.KEY_SECONDS = 'seconds'; + +export { StartTime }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/StationIDNumber.js b/lib/js/src/rpc/structs/StationIDNumber.js new file mode 100644 index 00000000..c952db81 --- /dev/null +++ b/lib/js/src/rpc/structs/StationIDNumber.js @@ -0,0 +1,81 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; + +class StationIDNumber extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Number} code - Binary Representation of ITU Country Code. USA Code is 001. + * @return {StationIDNumber} + */ + setCountryCode (code) { + this.setParameter(StationIDNumber.KEY_COUNTRY_CODE, code); + return this; + } + + /** + * @return {Number} + */ + getCountryCode () { + return this.getParameter(StationIDNumber.KEY_COUNTRY_CODE); + } + + /** + * @param {Number} id - Binary representation of unique facility ID assigned by the FCC; FCC controlled for U.S. + * territory + * @return {StationIDNumber} + */ + setFccFacilityId (id) { + this.setParameter(StationIDNumber.KEY_FCC_FACILITY_ID, id); + return this; + } + + /** + * @return {Number} + */ + getFccFacilityId () { + return this.getParameter(StationIDNumber.KEY_FCC_FACILITY_ID); + } +} + +StationIDNumber.KEY_COUNTRY_CODE = 'countryCode'; +StationIDNumber.KEY_FCC_FACILITY_ID = 'fccFacilityId'; + +export { StationIDNumber }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/SystemCapability.js b/lib/js/src/rpc/structs/SystemCapability.js new file mode 100644 index 00000000..270614a7 --- /dev/null +++ b/lib/js/src/rpc/structs/SystemCapability.js @@ -0,0 +1,206 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { VideoStreamingCapability } from './VideoStreamingCapability.js'; +import { PhoneCapability } from './PhoneCapability.js'; +import { DisplayCapability } from './DisplayCapability.js'; +import { RemoteControlCapabilities } from './RemoteControlCapabilities.js'; +import { SeatLocationCapability } from './SeatLocationCapability.js'; +import { SystemCapabilityType } from '../enums/SystemCapabilityType.js'; +import { AppServicesCapabilities } from './AppServicesCapabilities.js'; +import { NavigationCapability } from './NavigationCapability.js'; +import { RpcStruct } from '../RpcStruct.js'; + +/** + * The systemCapabilityType identifies which data object exists in this struct. For example, if the SystemCapability + * Type is NAVIGATION then a "navigationCapability" should exist + */ +class SystemCapability extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {SystemCapabilityType} type - Used as a descriptor of what data to expect in this struct. The + * corresponding param to this enum should be included and the only other param + * included. + * @return {SystemCapability} + */ + setSystemCapabilityType (type) { + this.validateType(SystemCapabilityType, type); + this.setParameter(SystemCapability.KEY_SYSTEM_CAPABILITY_TYPE, type); + return this; + } + + /** + * @return {SystemCapabilityType} + */ + getSystemCapabilityType () { + return this.getObject(SystemCapabilityType, SystemCapability.KEY_SYSTEM_CAPABILITY_TYPE); + } + + /** + * @param {NavigationCapability} capability - Describes extended capabilities for onboard navigation system + * @return {SystemCapability} + */ + setNavigationCapability (capability) { + this.validateType(NavigationCapability, capability); + this.setParameter(SystemCapability.KEY_NAVIGATION_CAPABILITY, capability); + return this; + } + + /** + * @return {NavigationCapability} + */ + getNavigationCapability () { + return this.getObject(NavigationCapability, SystemCapability.KEY_NAVIGATION_CAPABILITY); + } + + /** + * @param {PhoneCapability} capability - Describes extended capabilities of the module's phone feature + * @return {SystemCapability} + */ + setPhoneCapability (capability) { + this.validateType(PhoneCapability, capability); + this.setParameter(SystemCapability.KEY_PHONE_CAPABILITY, capability); + return this; + } + + /** + * @return {PhoneCapability} + */ + getPhoneCapability () { + return this.getObject(PhoneCapability, SystemCapability.KEY_PHONE_CAPABILITY); + } + + /** + * @param {VideoStreamingCapability} capability - Describes extended capabilities of the module's phone feature + * @return {SystemCapability} + */ + setVideoStreamingCapability (capability) { + this.validateType(VideoStreamingCapability, capability); + this.setParameter(SystemCapability.KEY_VIDEO_STREAMING_CAPABILITY, capability); + return this; + } + + /** + * @return {VideoStreamingCapability} + */ + getVideoStreamingCapability () { + return this.getObject(VideoStreamingCapability, SystemCapability.KEY_VIDEO_STREAMING_CAPABILITY); + } + + /** + * @param {RemoteControlCapabilities} capability - Describes extended capabilities of the module's phone feature + * @return {SystemCapability} + */ + setRemoteControlCapability (capability) { + this.validateType(RemoteControlCapabilities, capability); + this.setParameter(SystemCapability.KEY_REMOTE_CONTROL_CAPABILITY, capability); + return this; + } + + /** + * @return {RemoteControlCapabilities} + */ + getRemoteControlCapability () { + return this.getObject(RemoteControlCapabilities, SystemCapability.KEY_REMOTE_CONTROL_CAPABILITY); + } + + /** + * @param {AppServicesCapabilities} capabilities - An array of currently available services. If this is an update to + * the capability the affected services will include an update + * reason in that item + * @return {SystemCapability} + */ + setAppServicesCapabilities (capabilities) { + this.validateType(AppServicesCapabilities, capabilities); + this.setParameter(SystemCapability.KEY_APP_SERVICES_CAPABILITIES, capabilities); + return this; + } + + /** + * @return {AppServicesCapabilities} + */ + getAppServicesCapabilities () { + return this.getObject(AppServicesCapabilities, SystemCapability.KEY_APP_SERVICES_CAPABILITIES); + } + + /** + * @param {SeatLocationCapability} capability - Contains information about the locations of each seat + * @return {SystemCapability} + */ + setSeatLocationCapability (capability) { + this.validateType(SeatLocationCapability, capability); + this.setParameter(SystemCapability.KEY_SEAT_LOCATION_CAPABILITY, capability); + return this; + } + + /** + * @return {SeatLocationCapability} + */ + getSeatLocationCapability () { + return this.getObject(SeatLocationCapability, SystemCapability.KEY_SEAT_LOCATION_CAPABILITY); + } + + /** + * @param {DisplayCapability[]} capabilities + * @return {SystemCapability} + */ + setDisplayCapabilities (capabilities) { + this.validateType(DisplayCapability, capabilities, true); + this.setParameter(SystemCapability.KEY_DISPLAY_CAPABILITIES, capabilities); + return this; + } + + /** + * @return {DisplayCapability[]} + */ + getDisplayCapabilities () { + return this.getObject(DisplayCapability, SystemCapability.KEY_DISPLAY_CAPABILITIES); + } +} + +SystemCapability.KEY_SYSTEM_CAPABILITY_TYPE = 'systemCapabilityType'; +SystemCapability.KEY_NAVIGATION_CAPABILITY = 'navigationCapability'; +SystemCapability.KEY_PHONE_CAPABILITY = 'phoneCapability'; +SystemCapability.KEY_VIDEO_STREAMING_CAPABILITY = 'videoStreamingCapability'; +SystemCapability.KEY_REMOTE_CONTROL_CAPABILITY = 'remoteControlCapability'; +SystemCapability.KEY_APP_SERVICES_CAPABILITIES = 'appServicesCapabilities'; +SystemCapability.KEY_SEAT_LOCATION_CAPABILITY = 'seatLocationCapability'; +SystemCapability.KEY_DISPLAY_CAPABILITIES = 'displayCapabilities'; + +export { SystemCapability }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/TTSChunk.js b/lib/js/src/rpc/structs/TTSChunk.js index f9f299ff..d63a55d4 100644 --- a/lib/js/src/rpc/structs/TTSChunk.js +++ b/lib/js/src/rpc/structs/TTSChunk.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -33,41 +34,48 @@ import { RpcStruct } from '../RpcStruct.js'; import { SpeechCapabilities } from '../enums/SpeechCapabilities.js'; +/** + * A TTS chunk, that consists of text/phonemes to speak or the name of a file to play, and a TTS type (like text or + * SAPI) + */ class TTSChunk extends RpcStruct { + /** + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {String} text - * @return {TTSChunk} - */ + * @param {String} text - The text or phonemes to speak, or the name of the audio file to play. May not be empty. + * @return {TTSChunk} + */ setText (text) { this.setParameter(TTSChunk.KEY_TEXT, text); return this; } /** - * @return {Number} - */ + * @return {String} + */ getText () { return this.getParameter(TTSChunk.KEY_TEXT); } /** - * @param {SpeechCapabilities} type - * @return {TTSChunk} - */ + * @param {SpeechCapabilities} type - Describes whether the TTS chunk is plain text, a specific phoneme set, or an + * audio file. See SpeechCapabilities + * @return {TTSChunk} + */ setType (type) { this.validateType(SpeechCapabilities, type); - this.setParameter(TTSChunk.KEY_TYPE, type); return this; } /** - * @return {SpeechCapabilities} - */ + * @return {SpeechCapabilities} + */ getType () { return this.getObject(SpeechCapabilities, TTSChunk.KEY_TYPE); } @@ -76,4 +84,4 @@ class TTSChunk extends RpcStruct { TTSChunk.KEY_TEXT = 'text'; TTSChunk.KEY_TYPE = 'type'; -export { TTSChunk }; +export { TTSChunk }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/Temperature.js b/lib/js/src/rpc/structs/Temperature.js new file mode 100644 index 00000000..692ce7c0 --- /dev/null +++ b/lib/js/src/rpc/structs/Temperature.js @@ -0,0 +1,83 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { TemperatureUnit } from '../enums/TemperatureUnit.js'; + +class Temperature extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {TemperatureUnit} unit - Temperature Unit + * @return {Temperature} + */ + setUnit (unit) { + this.validateType(TemperatureUnit, unit); + this.setParameter(Temperature.KEY_UNIT, unit); + return this; + } + + /** + * @return {TemperatureUnit} + */ + getUnit () { + return this.getObject(TemperatureUnit, Temperature.KEY_UNIT); + } + + /** + * @param {Number} value - Temperature Value in TemperatureUnit specified unit. Range depends on OEM and is not + * checked by SDL. + * @return {Temperature} + */ + setValue (value) { + this.setParameter(Temperature.KEY_VALUE, value); + return this; + } + + /** + * @return {Number} + */ + getValue () { + return this.getParameter(Temperature.KEY_VALUE); + } +} + +Temperature.KEY_UNIT = 'unit'; +Temperature.KEY_VALUE = 'value'; + +export { Temperature }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/TemplateColorScheme.js b/lib/js/src/rpc/structs/TemplateColorScheme.js index bc84641f..a6a26587 100644 --- a/lib/js/src/rpc/structs/TemplateColorScheme.js +++ b/lib/js/src/rpc/structs/TemplateColorScheme.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -33,61 +34,64 @@ import { RpcStruct } from '../RpcStruct.js'; import { RGBColor } from './RGBColor.js'; +/** + * A color scheme for all display layout templates. + */ class TemplateColorScheme extends RpcStruct { + /** + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {RGBColor} primaryColor - * @return {TemplateColorScheme} - */ - setPrimaryColor (primaryColor) { - this.validateType(RGBColor, primaryColor); - - this.setParameter(TemplateColorScheme.KEY_PRIMARY_COLOR, primaryColor); + * @param {RGBColor} color - The primary "accent" color + * @return {TemplateColorScheme} + */ + setPrimaryColor (color) { + this.validateType(RGBColor, color); + this.setParameter(TemplateColorScheme.KEY_PRIMARY_COLOR, color); return this; } /** - * @return {RGBColor} - */ + * @return {RGBColor} + */ getPrimaryColor () { return this.getObject(RGBColor, TemplateColorScheme.KEY_PRIMARY_COLOR); } /** - * @param {RGBColor} secondaryColor - * @return {TemplateColorScheme} - */ - setSecondaryColor (secondaryColor) { - this.validateType(RGBColor, secondaryColor); - - this.setParameter(TemplateColorScheme.KEY_SECONDARY_COLOR, secondaryColor); + * @param {RGBColor} color - The secondary "accent" color + * @return {TemplateColorScheme} + */ + setSecondaryColor (color) { + this.validateType(RGBColor, color); + this.setParameter(TemplateColorScheme.KEY_SECONDARY_COLOR, color); return this; } /** - * @return {RGBColor} - */ + * @return {RGBColor} + */ getSecondaryColor () { return this.getObject(RGBColor, TemplateColorScheme.KEY_SECONDARY_COLOR); } /** - * @param {RGBColor} backgroundColor - * @return {TemplateColorScheme} - */ - setBackgroundColor (backgroundColor) { - this.validateType(RGBColor, backgroundColor); - - this.setParameter(TemplateColorScheme.KEY_BACKGROUND_COLOR, backgroundColor); + * @param {RGBColor} color - The color of the background + * @return {TemplateColorScheme} + */ + setBackgroundColor (color) { + this.validateType(RGBColor, color); + this.setParameter(TemplateColorScheme.KEY_BACKGROUND_COLOR, color); return this; } /** - * @return {RGBColor} - */ + * @return {RGBColor} + */ getBackgroundColor () { return this.getObject(RGBColor, TemplateColorScheme.KEY_BACKGROUND_COLOR); } @@ -97,4 +101,4 @@ TemplateColorScheme.KEY_PRIMARY_COLOR = 'primaryColor'; TemplateColorScheme.KEY_SECONDARY_COLOR = 'secondaryColor'; TemplateColorScheme.KEY_BACKGROUND_COLOR = 'backgroundColor'; -export { TemplateColorScheme }; +export { TemplateColorScheme }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/TemplateConfiguration.js b/lib/js/src/rpc/structs/TemplateConfiguration.js new file mode 100644 index 00000000..a63db77e --- /dev/null +++ b/lib/js/src/rpc/structs/TemplateConfiguration.js @@ -0,0 +1,101 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { TemplateColorScheme } from './TemplateColorScheme.js'; + +class TemplateConfiguration extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {String} template - Predefined or dynamically created window template. Currently only predefined window + * template layouts are defined. + * @return {TemplateConfiguration} + */ + setTemplate (template) { + this.setParameter(TemplateConfiguration.KEY_TEMPLATE, template); + return this; + } + + /** + * @return {String} + */ + getTemplate () { + return this.getParameter(TemplateConfiguration.KEY_TEMPLATE); + } + + /** + * @param {TemplateColorScheme} scheme - A color scheme for all display layout templates. + * @return {TemplateConfiguration} + */ + setDayColorScheme (scheme) { + this.validateType(TemplateColorScheme, scheme); + this.setParameter(TemplateConfiguration.KEY_DAY_COLOR_SCHEME, scheme); + return this; + } + + /** + * @return {TemplateColorScheme} + */ + getDayColorScheme () { + return this.getObject(TemplateColorScheme, TemplateConfiguration.KEY_DAY_COLOR_SCHEME); + } + + /** + * @param {TemplateColorScheme} scheme - A color scheme for all display layout templates. + * @return {TemplateConfiguration} + */ + setNightColorScheme (scheme) { + this.validateType(TemplateColorScheme, scheme); + this.setParameter(TemplateConfiguration.KEY_NIGHT_COLOR_SCHEME, scheme); + return this; + } + + /** + * @return {TemplateColorScheme} + */ + getNightColorScheme () { + return this.getObject(TemplateColorScheme, TemplateConfiguration.KEY_NIGHT_COLOR_SCHEME); + } +} + +TemplateConfiguration.KEY_TEMPLATE = 'template'; +TemplateConfiguration.KEY_DAY_COLOR_SCHEME = 'dayColorScheme'; +TemplateConfiguration.KEY_NIGHT_COLOR_SCHEME = 'nightColorScheme'; + +export { TemplateConfiguration }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/TextField.js b/lib/js/src/rpc/structs/TextField.js index bb2332f9..4f7d4d72 100644 --- a/lib/js/src/rpc/structs/TextField.js +++ b/lib/js/src/rpc/structs/TextField.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -30,80 +31,80 @@ * POSSIBILITY OF SUCH DAMAGE. */ -import { RpcStruct } from '../RpcStruct.js'; import { TextFieldName } from '../enums/TextFieldName.js'; import { CharacterSet } from '../enums/CharacterSet.js'; +import { RpcStruct } from '../RpcStruct.js'; class TextField extends RpcStruct { + /** + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {TextFieldName} textFieldName - * @return {TextField} - */ - setTextFieldName (textFieldName) { - this.validateType(TextFieldName, textFieldName); - - this.setParameter(TextField.KEY_NAME, textFieldName); + * @param {TextFieldName} name - The name that identifies the field. See TextFieldName. + * @return {TextField} + */ + setName (name) { + this.validateType(TextFieldName, name); + this.setParameter(TextField.KEY_NAME, name); return this; } /** - * @return {TextFieldName} - */ - getTextFieldName () { + * @return {TextFieldName} + */ + getName () { return this.getObject(TextFieldName, TextField.KEY_NAME); } - /** - * @param {CharacterSet} textFieldName - * @return {TextField} - */ - setCharacterSet (characterSet) { - this.validateType(CharacterSet, characterSet); - - this.setParameter(TextField.KEY_CHARACTER_SET, characterSet); + * @param {CharacterSet} set - The character set that is supported in this field. See CharacterSet. + * @return {TextField} + */ + setCharacterSet (set) { + this.validateType(CharacterSet, set); + this.setParameter(TextField.KEY_CHARACTER_SET, set); return this; } /** - * @return {CharacterSet} - */ + * @return {CharacterSet} + */ getCharacterSet () { return this.getObject(CharacterSet, TextField.KEY_CHARACTER_SET); } /** - * @param {Number} width - * @return {TextField} - */ + * @param {Number} width - The number of characters in one row of this field. + * @return {TextField} + */ setWidth (width) { this.setParameter(TextField.KEY_WIDTH, width); return this; } /** - * @return {Number} - */ + * @return {Number} + */ getWidth () { return this.getParameter(TextField.KEY_WIDTH); } /** - * @param {Number} rows - * @return {TextField} - */ + * @param {Number} rows - The number of rows of this field. + * @return {TextField} + */ setRows (rows) { this.setParameter(TextField.KEY_ROWS, rows); return this; } /** - * @return {Number} - */ + * @return {Number} + */ getRows () { return this.getParameter(TextField.KEY_ROWS); } @@ -114,4 +115,4 @@ TextField.KEY_CHARACTER_SET = 'characterSet'; TextField.KEY_WIDTH = 'width'; TextField.KEY_ROWS = 'rows'; -export { TextField }; +export { TextField }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/TireStatus.js b/lib/js/src/rpc/structs/TireStatus.js new file mode 100644 index 00000000..183c7182 --- /dev/null +++ b/lib/js/src/rpc/structs/TireStatus.js @@ -0,0 +1,177 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { SingleTireStatus } from './SingleTireStatus.js'; +import { WarningLightStatus } from '../enums/WarningLightStatus.js'; + +/** + * The status and pressure of the tires. + */ +class TireStatus extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {WarningLightStatus} telltale - Status of the Tire Pressure Telltale. See WarningLightStatus. + * @return {TireStatus} + */ + setPressureTelltale (telltale) { + this.validateType(WarningLightStatus, telltale); + this.setParameter(TireStatus.KEY_PRESSURE_TELLTALE, telltale); + return this; + } + + /** + * @return {WarningLightStatus} + */ + getPressureTelltale () { + return this.getObject(WarningLightStatus, TireStatus.KEY_PRESSURE_TELLTALE); + } + + /** + * @param {SingleTireStatus} front - The status of the left front tire. + * @return {TireStatus} + */ + setLeftFront (front) { + this.validateType(SingleTireStatus, front); + this.setParameter(TireStatus.KEY_LEFT_FRONT, front); + return this; + } + + /** + * @return {SingleTireStatus} + */ + getLeftFront () { + return this.getObject(SingleTireStatus, TireStatus.KEY_LEFT_FRONT); + } + + /** + * @param {SingleTireStatus} front - The status of the right front tire. + * @return {TireStatus} + */ + setRightFront (front) { + this.validateType(SingleTireStatus, front); + this.setParameter(TireStatus.KEY_RIGHT_FRONT, front); + return this; + } + + /** + * @return {SingleTireStatus} + */ + getRightFront () { + return this.getObject(SingleTireStatus, TireStatus.KEY_RIGHT_FRONT); + } + + /** + * @param {SingleTireStatus} rear - The status of the left rear tire. + * @return {TireStatus} + */ + setLeftRear (rear) { + this.validateType(SingleTireStatus, rear); + this.setParameter(TireStatus.KEY_LEFT_REAR, rear); + return this; + } + + /** + * @return {SingleTireStatus} + */ + getLeftRear () { + return this.getObject(SingleTireStatus, TireStatus.KEY_LEFT_REAR); + } + + /** + * @param {SingleTireStatus} rear - The status of the right rear tire. + * @return {TireStatus} + */ + setRightRear (rear) { + this.validateType(SingleTireStatus, rear); + this.setParameter(TireStatus.KEY_RIGHT_REAR, rear); + return this; + } + + /** + * @return {SingleTireStatus} + */ + getRightRear () { + return this.getObject(SingleTireStatus, TireStatus.KEY_RIGHT_REAR); + } + + /** + * @param {SingleTireStatus} rear - The status of the inner left rear. + * @return {TireStatus} + */ + setInnerLeftRear (rear) { + this.validateType(SingleTireStatus, rear); + this.setParameter(TireStatus.KEY_INNER_LEFT_REAR, rear); + return this; + } + + /** + * @return {SingleTireStatus} + */ + getInnerLeftRear () { + return this.getObject(SingleTireStatus, TireStatus.KEY_INNER_LEFT_REAR); + } + + /** + * @param {SingleTireStatus} rear - The status of the inner right rear. + * @return {TireStatus} + */ + setInnerRightRear (rear) { + this.validateType(SingleTireStatus, rear); + this.setParameter(TireStatus.KEY_INNER_RIGHT_REAR, rear); + return this; + } + + /** + * @return {SingleTireStatus} + */ + getInnerRightRear () { + return this.getObject(SingleTireStatus, TireStatus.KEY_INNER_RIGHT_REAR); + } +} + +TireStatus.KEY_PRESSURE_TELLTALE = 'pressureTelltale'; +TireStatus.KEY_LEFT_FRONT = 'leftFront'; +TireStatus.KEY_RIGHT_FRONT = 'rightFront'; +TireStatus.KEY_LEFT_REAR = 'leftRear'; +TireStatus.KEY_RIGHT_REAR = 'rightRear'; +TireStatus.KEY_INNER_LEFT_REAR = 'innerLeftRear'; +TireStatus.KEY_INNER_RIGHT_REAR = 'innerRightRear'; + +export { TireStatus }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/TouchCoord.js b/lib/js/src/rpc/structs/TouchCoord.js new file mode 100644 index 00000000..000abbc4 --- /dev/null +++ b/lib/js/src/rpc/structs/TouchCoord.js @@ -0,0 +1,80 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; + +class TouchCoord extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Number} x - The x coordinate of the touch. + * @return {TouchCoord} + */ + setX (x) { + this.setParameter(TouchCoord.KEY_X, x); + return this; + } + + /** + * @return {Number} + */ + getX () { + return this.getParameter(TouchCoord.KEY_X); + } + + /** + * @param {Number} y - The y coordinate of the touch. + * @return {TouchCoord} + */ + setY (y) { + this.setParameter(TouchCoord.KEY_Y, y); + return this; + } + + /** + * @return {Number} + */ + getY () { + return this.getParameter(TouchCoord.KEY_Y); + } +} + +TouchCoord.KEY_X = 'x'; +TouchCoord.KEY_Y = 'y'; + +export { TouchCoord }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/TouchEvent.js b/lib/js/src/rpc/structs/TouchEvent.js new file mode 100644 index 00000000..d1558d4a --- /dev/null +++ b/lib/js/src/rpc/structs/TouchEvent.js @@ -0,0 +1,106 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { TouchCoord } from './TouchCoord.js'; + +class TouchEvent extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Number} id - A touch's unique identifier. The application can track the current touch events by id. If a + * touch event has type begin, the id should be added to the set of touches. If a touch event + * has type end, the id should be removed from the set of touches. + * @return {TouchEvent} + */ + setId (id) { + this.setParameter(TouchEvent.KEY_ID, id); + return this; + } + + /** + * @return {Number} + */ + getId () { + return this.getParameter(TouchEvent.KEY_ID); + } + + /** + * @param {Number[]} ts - The time that the touch was recorded. This number can the time since the beginning of the + * session or something else as long as the units are in milliseconds. The timestamp is used + * to determined the rate of change of position of a touch. The application also uses the + * time to verify whether two touches, with different ids, are part of a single action by the + * user. If there is only a single timestamp in this array, it is the same for every + * coordinate in the coordinates array. + * @return {TouchEvent} + */ + setTs (ts) { + this.setParameter(TouchEvent.KEY_TS, ts); + return this; + } + + /** + * @return {Number[]} + */ + getTs () { + return this.getParameter(TouchEvent.KEY_TS); + } + + /** + * @param {TouchCoord[]} c + * @return {TouchEvent} + */ + setC (c) { + this.validateType(TouchCoord, c, true); + this.setParameter(TouchEvent.KEY_C, c); + return this; + } + + /** + * @return {TouchCoord[]} + */ + getC () { + return this.getObject(TouchCoord, TouchEvent.KEY_C); + } +} + +TouchEvent.KEY_ID = 'id'; +TouchEvent.KEY_TS = 'ts'; +TouchEvent.KEY_C = 'c'; + +export { TouchEvent }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/TouchEventCapabilities.js b/lib/js/src/rpc/structs/TouchEventCapabilities.js index ab0a4760..b686d702 100644 --- a/lib/js/src/rpc/structs/TouchEventCapabilities.js +++ b/lib/js/src/rpc/structs/TouchEventCapabilities.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -33,57 +34,57 @@ import { RpcStruct } from '../RpcStruct.js'; class TouchEventCapabilities extends RpcStruct { + /** + * @constructor + */ constructor (parameters) { super(parameters); } - /** - * @param {Boolean} pressAvailable - * @return {TouchEventCapabilities} - */ - setPressAvailable (pressAvailable) { - this.setParameter(TouchEventCapabilities.KEY_PRESS_AVAILABLE, pressAvailable); + * @param {Boolean} available + * @return {TouchEventCapabilities} + */ + setPressAvailable (available) { + this.setParameter(TouchEventCapabilities.KEY_PRESS_AVAILABLE, available); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getPressAvailable () { return this.getParameter(TouchEventCapabilities.KEY_PRESS_AVAILABLE); } /** - * @param {Boolean} multiTouchAvailable - * @return {TouchEventCapabilities} - */ - setMultiTouchAvailable (multiTouchAvailable) { - this.setParameter(TouchEventCapabilities.KEY_MULTI_TOUCH_AVAILABLE, multiTouchAvailable); + * @param {Boolean} available + * @return {TouchEventCapabilities} + */ + setMultiTouchAvailable (available) { + this.setParameter(TouchEventCapabilities.KEY_MULTI_TOUCH_AVAILABLE, available); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getMultiTouchAvailable () { return this.getParameter(TouchEventCapabilities.KEY_MULTI_TOUCH_AVAILABLE); } - - /** - * @param {Boolean} doublePressAvailable - * @return {TouchEventCapabilities} - */ - setDoublePressAvailable (doublePressAvailable) { - this.setParameter(TouchEventCapabilities.KEY_DOUBLE_PRESS_AVAILABLE, doublePressAvailable); + * @param {Boolean} available + * @return {TouchEventCapabilities} + */ + setDoublePressAvailable (available) { + this.setParameter(TouchEventCapabilities.KEY_DOUBLE_PRESS_AVAILABLE, available); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getDoublePressAvailable () { return this.getParameter(TouchEventCapabilities.KEY_DOUBLE_PRESS_AVAILABLE); } @@ -93,4 +94,4 @@ TouchEventCapabilities.KEY_PRESS_AVAILABLE = 'pressAvailable'; TouchEventCapabilities.KEY_MULTI_TOUCH_AVAILABLE = 'multiTouchAvailable'; TouchEventCapabilities.KEY_DOUBLE_PRESS_AVAILABLE = 'doublePressAvailable'; -export { TouchEventCapabilities }; +export { TouchEventCapabilities }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/Turn.js b/lib/js/src/rpc/structs/Turn.js new file mode 100644 index 00000000..e139cbae --- /dev/null +++ b/lib/js/src/rpc/structs/Turn.js @@ -0,0 +1,82 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { Image } from './Image.js'; + +class Turn extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {String} text - Individual turn text. Must provide at least text or icon for a given turn. + * @return {Turn} + */ + setNavigationText (text) { + this.setParameter(Turn.KEY_NAVIGATION_TEXT, text); + return this; + } + + /** + * @return {String} + */ + getNavigationText () { + return this.getParameter(Turn.KEY_NAVIGATION_TEXT); + } + + /** + * @param {Image} icon - Individual turn icon. Must provide at least text or icon for a given turn. + * @return {Turn} + */ + setTurnIcon (icon) { + this.validateType(Image, icon); + this.setParameter(Turn.KEY_TURN_ICON, icon); + return this; + } + + /** + * @return {Image} + */ + getTurnIcon () { + return this.getObject(Image, Turn.KEY_TURN_ICON); + } +} + +Turn.KEY_NAVIGATION_TEXT = 'navigationText'; +Turn.KEY_TURN_ICON = 'turnIcon'; + +export { Turn }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/VehicleDataResult.js b/lib/js/src/rpc/structs/VehicleDataResult.js new file mode 100644 index 00000000..700e29b3 --- /dev/null +++ b/lib/js/src/rpc/structs/VehicleDataResult.js @@ -0,0 +1,104 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { VehicleDataResultCode } from '../enums/VehicleDataResultCode.js'; +import { VehicleDataType } from '../enums/VehicleDataType.js'; + +/** + * Individual published data request result + */ +class VehicleDataResult extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {VehicleDataType} type - Defined published data element type. + * @return {VehicleDataResult} + */ + setDataType (type) { + this.validateType(VehicleDataType, type); + this.setParameter(VehicleDataResult.KEY_DATA_TYPE, type); + return this; + } + + /** + * @return {VehicleDataType} + */ + getDataType () { + return this.getObject(VehicleDataType, VehicleDataResult.KEY_DATA_TYPE); + } + + /** + * @param {VehicleDataResultCode} code - Published data result code. + * @return {VehicleDataResult} + */ + setResultCode (code) { + this.validateType(VehicleDataResultCode, code); + this.setParameter(VehicleDataResult.KEY_RESULT_CODE, code); + return this; + } + + /** + * @return {VehicleDataResultCode} + */ + getResultCode () { + return this.getObject(VehicleDataResultCode, VehicleDataResult.KEY_RESULT_CODE); + } + + /** + * @param {String} type - Type of requested oem specific parameter + * @return {VehicleDataResult} + */ + setOemCustomDataType (type) { + this.setParameter(VehicleDataResult.KEY_OEM_CUSTOM_DATA_TYPE, type); + return this; + } + + /** + * @return {String} + */ + getOemCustomDataType () { + return this.getParameter(VehicleDataResult.KEY_OEM_CUSTOM_DATA_TYPE); + } +} + +VehicleDataResult.KEY_DATA_TYPE = 'dataType'; +VehicleDataResult.KEY_RESULT_CODE = 'resultCode'; +VehicleDataResult.KEY_OEM_CUSTOM_DATA_TYPE = 'oemCustomDataType'; + +export { VehicleDataResult }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/VehicleType.js b/lib/js/src/rpc/structs/VehicleType.js index d80b4e92..ce4b3ff1 100644 --- a/lib/js/src/rpc/structs/VehicleType.js +++ b/lib/js/src/rpc/structs/VehicleType.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -33,71 +34,73 @@ import { RpcStruct } from '../RpcStruct.js'; class VehicleType extends RpcStruct { + /** + * @constructor + */ constructor (parameters) { super(parameters); } /** - * @param {String} make - * @return {VehicleType} - */ + * @param {String} make - Make of the vehicle, e.g. Ford + * @return {VehicleType} + */ setMake (make) { this.setParameter(VehicleType.KEY_MAKE, make); return this; } /** - * @return {String} - */ + * @return {String} + */ getMake () { return this.getParameter(VehicleType.KEY_MAKE); } /** - * @param {String} model - * @return {VehicleType} - */ + * @param {String} model - Model of the vehicle, e.g. Fiesta + * @return {VehicleType} + */ setModel (model) { this.setParameter(VehicleType.KEY_MODEL, model); return this; } /** - * @return {String} - */ + * @return {String} + */ getModel () { return this.getParameter(VehicleType.KEY_MODEL); } /** - * @param {String} modelYear - * @return {VehicleType} - */ - setModelYear (modelYear) { - this.setParameter(VehicleType.KEY_MODEL_YEAR, modelYear); + * @param {String} year - Model Year of the vehicle, e.g. 2013 + * @return {VehicleType} + */ + setModelYear (year) { + this.setParameter(VehicleType.KEY_MODEL_YEAR, year); return this; } /** - * @return {String} - */ + * @return {String} + */ getModelYear () { return this.getParameter(VehicleType.KEY_MODEL_YEAR); } - /** - * @param {String} trim - * @return {VehicleType} - */ + * @param {String} trim - Trim of the vehicle, e.g. SE + * @return {VehicleType} + */ setTrim (trim) { this.setParameter(VehicleType.KEY_TRIM, trim); return this; } /** - * @return {String} - */ + * @return {String} + */ getTrim () { return this.getParameter(VehicleType.KEY_TRIM); } @@ -108,4 +111,4 @@ VehicleType.KEY_MODEL = 'model'; VehicleType.KEY_MODEL_YEAR = 'modelYear'; VehicleType.KEY_TRIM = 'trim'; -export { VehicleType }; +export { VehicleType }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/VideoStreamingCapability.js b/lib/js/src/rpc/structs/VideoStreamingCapability.js index 345584da..73ab6b1c 100644 --- a/lib/js/src/rpc/structs/VideoStreamingCapability.js +++ b/lib/js/src/rpc/structs/VideoStreamingCapability.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -31,127 +32,136 @@ */ import { RpcStruct } from '../RpcStruct.js'; -import { VideoStreamingFormat } from './VideoStreamingFormat.js'; import { ImageResolution } from './ImageResolution.js'; +import { VideoStreamingFormat } from './VideoStreamingFormat.js'; +/** + * Contains information about this system's video streaming capabilities. + */ class VideoStreamingCapability extends RpcStruct { /** - * @constructor - */ - constructor () { - super(); + * @constructor + */ + constructor (parameters) { + super(parameters); } /** - * @param {ImageResolution} val - * @return {VideoStreamingCapability} - */ - setPreferredResolution (val) { - this.validateType(ImageResolution, val); - this.setParameter(VideoStreamingCapability.KEY_PREFERRED_RESOLUTION, val); + * @param {ImageResolution} resolution - The preferred resolution of a video stream for decoding and rendering on + * HMI. + * @return {VideoStreamingCapability} + */ + setPreferredResolution (resolution) { + this.validateType(ImageResolution, resolution); + this.setParameter(VideoStreamingCapability.KEY_PREFERRED_RESOLUTION, resolution); return this; } /** - * @return {ImageResolution} - */ + * @return {ImageResolution} + */ getPreferredResolution () { return this.getObject(ImageResolution, VideoStreamingCapability.KEY_PREFERRED_RESOLUTION); } /** - * @param {number} val - * @return {VideoStreamingCapability} - */ - setMaxBitrate (val) { - this.setParameter(VideoStreamingCapability.KEY_MAX_BITRATE, val); + * @param {Number} bitrate - The maximum bitrate of video stream that is supported, in kbps. + * @return {VideoStreamingCapability} + */ + setMaxBitrate (bitrate) { + this.setParameter(VideoStreamingCapability.KEY_MAX_BITRATE, bitrate); return this; } /** - * @return {number} - */ + * @return {Number} + */ getMaxBitrate () { return this.getParameter(VideoStreamingCapability.KEY_MAX_BITRATE); } - /** - * @param {VideoStreamingFormat[]} val - * @return {VideoStreamingCapability} - */ - setSupportedFormats (val) { - this.validateType(VideoStreamingFormat, val, true); - this.setParameter(VideoStreamingCapability.KEY_SUPPORTED_FORMATS, val); + * @param {VideoStreamingFormat[]} formats - Detailed information on each format supported by this system, in its + * preferred order (i.e. the first element in the array is most preferable + * to the system). Each object will contain a VideoStreamingFormat that + * describes what can be expected. + * @return {VideoStreamingCapability} + */ + setSupportedFormats (formats) { + this.validateType(VideoStreamingFormat, formats, true); + this.setParameter(VideoStreamingCapability.KEY_SUPPORTED_FORMATS, formats); + return this; } /** - * @return {VideoStreamingFormat[]} - */ + * @return {VideoStreamingFormat[]} + */ getSupportedFormats () { return this.getObject(VideoStreamingFormat, VideoStreamingCapability.KEY_SUPPORTED_FORMATS); } /** - * @param {Boolean} val - * @return {VideoStreamingCapability} - */ - setHapticSpatialDataSupported (val) { - this.setParameter(VideoStreamingCapability.KEY_HAPTIC_SPATIAL_DATA_SUPPORTED, val); + * @param {Boolean} supported - True if the system can utilize the haptic spatial data from the source being + * streamed. If not included, it can be assumed the module doesn't support haptic + * spatial data'. + * @return {VideoStreamingCapability} + */ + setHapticSpatialDataSupported (supported) { + this.setParameter(VideoStreamingCapability.KEY_HAPTIC_SPATIAL_DATA_SUPPORTED, supported); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getHapticSpatialDataSupported () { return this.getParameter(VideoStreamingCapability.KEY_HAPTIC_SPATIAL_DATA_SUPPORTED); } /** - * @param {number} val - * @return {VideoStreamingCapability} - */ - setDiagonalScreenSize (val) { - this.setParameter(VideoStreamingCapability.KEY_DIAGONAL_SCREEN_SIZE, val); + * @param {Number} size - The diagonal screen size in inches. + * @return {VideoStreamingCapability} + */ + setDiagonalScreenSize (size) { + this.setParameter(VideoStreamingCapability.KEY_DIAGONAL_SCREEN_SIZE, size); return this; } /** - * @return {number} - */ + * @return {Number} + */ getDiagonalScreenSize () { return this.getParameter(VideoStreamingCapability.KEY_DIAGONAL_SCREEN_SIZE); } /** - * @param {number} val - * @return {VideoStreamingCapability} - */ - setPixelPerInch (val) { - this.setParameter(VideoStreamingCapability.KEY_PIXEL_PER_INCH, val); + * @param {Number} inch - PPI is the diagonal resolution in pixels divided by the diagonal screen size in inches. + * @return {VideoStreamingCapability} + */ + setPixelPerInch (inch) { + this.setParameter(VideoStreamingCapability.KEY_PIXEL_PER_INCH, inch); return this; } /** - * @return {number} - */ + * @return {Number} + */ getPixelPerInch () { return this.getParameter(VideoStreamingCapability.KEY_PIXEL_PER_INCH); } /** - * @param {number} val - * @return {VideoStreamingCapability} - */ - setScale (val) { - this.setParameter(VideoStreamingCapability.KEY_SCALE, val); + * @param {Number} scale - The scaling factor the app should use to change the size of the projecting view. + * @return {VideoStreamingCapability} + */ + setScale (scale) { + this.setParameter(VideoStreamingCapability.KEY_SCALE, scale); return this; } /** - * @return {number} - */ + * @return {Number} + */ getScale () { return this.getParameter(VideoStreamingCapability.KEY_SCALE); } @@ -165,4 +175,4 @@ VideoStreamingCapability.KEY_DIAGONAL_SCREEN_SIZE = 'diagonalScreenSize'; VideoStreamingCapability.KEY_PIXEL_PER_INCH = 'pixelPerInch'; VideoStreamingCapability.KEY_SCALE = 'scale'; -export { VideoStreamingCapability }; +export { VideoStreamingCapability }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/VideoStreamingFormat.js b/lib/js/src/rpc/structs/VideoStreamingFormat.js index ede6a114..22520c62 100644 --- a/lib/js/src/rpc/structs/VideoStreamingFormat.js +++ b/lib/js/src/rpc/structs/VideoStreamingFormat.js @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ /* -* Copyright (c) 2019, Livio, Inc. +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -13,9 +14,9 @@ * disclaimer in the documentation and/or other materials provided with the * distribution. * -* Neither the name of the Livio Inc. nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -31,52 +32,56 @@ */ import { RpcStruct } from '../RpcStruct.js'; -import { VideoStreamingProtocol } from '../enums/VideoStreamingProtocol.js'; import { VideoStreamingCodec } from '../enums/VideoStreamingCodec.js'; +import { VideoStreamingProtocol } from '../enums/VideoStreamingProtocol.js'; +/** + * Video streaming formats and their specifications. + */ class VideoStreamingFormat extends RpcStruct { /** - * @constructor - */ - constructor () { - super(); + * @constructor + */ + constructor (parameters) { + super(parameters); } + /** - * @param {VideoStreamingProtocol} val - * @return {VideoStreamingFormat} - */ - setProtocol (val) { - this.validateType(VideoStreamingProtocol, val); - this.setParameter(VideoStreamingFormat.KEY_PROTOCOL, val); + * @param {VideoStreamingProtocol} protocol - Protocol type, see VideoStreamingProtocol + * @return {VideoStreamingFormat} + */ + setProtocol (protocol) { + this.validateType(VideoStreamingProtocol, protocol); + this.setParameter(VideoStreamingFormat.KEY_PROTOCOL, protocol); return this; } /** - * @return {VideoStreamingProtocol} - */ + * @return {VideoStreamingProtocol} + */ getProtocol () { - return this.getParameter(VideoStreamingFormat.KEY_PROTOCOL); + return this.getObject(VideoStreamingProtocol, VideoStreamingFormat.KEY_PROTOCOL); } /** - * @param {VideoStreamingCodec} val - * @return {VideoStreamingFormat} - */ - setCodec (val) { - this.validateType(VideoStreamingCodec, val); - this.setParameter(VideoStreamingFormat.KEY_CODEC, val); + * @param {VideoStreamingCodec} codec - Codec type, see VideoStreamingCodec + * @return {VideoStreamingFormat} + */ + setCodec (codec) { + this.validateType(VideoStreamingCodec, codec); + this.setParameter(VideoStreamingFormat.KEY_CODEC, codec); return this; } /** - * @return {VideoStreamingCodec} - */ + * @return {VideoStreamingCodec} + */ getCodec () { - return this.getParameter(VideoStreamingFormat.KEY_CODEC); + return this.getObject(VideoStreamingCodec, VideoStreamingFormat.KEY_CODEC); } } VideoStreamingFormat.KEY_PROTOCOL = 'protocol'; VideoStreamingFormat.KEY_CODEC = 'codec'; -export { VideoStreamingFormat }; +export { VideoStreamingFormat }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/VrHelpItem.js b/lib/js/src/rpc/structs/VrHelpItem.js new file mode 100644 index 00000000..8103308c --- /dev/null +++ b/lib/js/src/rpc/structs/VrHelpItem.js @@ -0,0 +1,99 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; +import { Image } from './Image.js'; + +class VrHelpItem extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {String} text - Text to display for VR Help item + * @return {VrHelpItem} + */ + setText (text) { + this.setParameter(VrHelpItem.KEY_TEXT, text); + return this; + } + + /** + * @return {String} + */ + getText () { + return this.getParameter(VrHelpItem.KEY_TEXT); + } + + /** + * @param {Image} image - Image struct for VR Help item + * @return {VrHelpItem} + */ + setImage (image) { + this.validateType(Image, image); + this.setParameter(VrHelpItem.KEY_IMAGE, image); + return this; + } + + /** + * @return {Image} + */ + getImage () { + return this.getObject(Image, VrHelpItem.KEY_IMAGE); + } + + /** + * @param {Number} position - Position to display item in VR Help list + * @return {VrHelpItem} + */ + setPosition (position) { + this.setParameter(VrHelpItem.KEY_POSITION, position); + return this; + } + + /** + * @return {Number} + */ + getPosition () { + return this.getParameter(VrHelpItem.KEY_POSITION); + } +} + +VrHelpItem.KEY_TEXT = 'text'; +VrHelpItem.KEY_IMAGE = 'image'; +VrHelpItem.KEY_POSITION = 'position'; + +export { VrHelpItem }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/WeatherAlert.js b/lib/js/src/rpc/structs/WeatherAlert.js new file mode 100644 index 00000000..6520340b --- /dev/null +++ b/lib/js/src/rpc/structs/WeatherAlert.js @@ -0,0 +1,151 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { DateTime } from './DateTime.js'; +import { RpcStruct } from '../RpcStruct.js'; + +class WeatherAlert extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {String} title + * @return {WeatherAlert} + */ + setTitle (title) { + this.setParameter(WeatherAlert.KEY_TITLE, title); + return this; + } + + /** + * @return {String} + */ + getTitle () { + return this.getParameter(WeatherAlert.KEY_TITLE); + } + + /** + * @param {String} summary + * @return {WeatherAlert} + */ + setSummary (summary) { + this.setParameter(WeatherAlert.KEY_SUMMARY, summary); + return this; + } + + /** + * @return {String} + */ + getSummary () { + return this.getParameter(WeatherAlert.KEY_SUMMARY); + } + + /** + * @param {DateTime} expires + * @return {WeatherAlert} + */ + setExpires (expires) { + this.validateType(DateTime, expires); + this.setParameter(WeatherAlert.KEY_EXPIRES, expires); + return this; + } + + /** + * @return {DateTime} + */ + getExpires () { + return this.getObject(DateTime, WeatherAlert.KEY_EXPIRES); + } + + /** + * @param {String[]} regions + * @return {WeatherAlert} + */ + setRegions (regions) { + this.setParameter(WeatherAlert.KEY_REGIONS, regions); + return this; + } + + /** + * @return {String[]} + */ + getRegions () { + return this.getParameter(WeatherAlert.KEY_REGIONS); + } + + /** + * @param {String} severity + * @return {WeatherAlert} + */ + setSeverity (severity) { + this.setParameter(WeatherAlert.KEY_SEVERITY, severity); + return this; + } + + /** + * @return {String} + */ + getSeverity () { + return this.getParameter(WeatherAlert.KEY_SEVERITY); + } + + /** + * @param {DateTime} issued + * @return {WeatherAlert} + */ + setTimeIssued (issued) { + this.validateType(DateTime, issued); + this.setParameter(WeatherAlert.KEY_TIME_ISSUED, issued); + return this; + } + + /** + * @return {DateTime} + */ + getTimeIssued () { + return this.getObject(DateTime, WeatherAlert.KEY_TIME_ISSUED); + } +} + +WeatherAlert.KEY_TITLE = 'title'; +WeatherAlert.KEY_SUMMARY = 'summary'; +WeatherAlert.KEY_EXPIRES = 'expires'; +WeatherAlert.KEY_REGIONS = 'regions'; +WeatherAlert.KEY_SEVERITY = 'severity'; +WeatherAlert.KEY_TIME_ISSUED = 'timeIssued'; + +export { WeatherAlert }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/WeatherData.js b/lib/js/src/rpc/structs/WeatherData.js new file mode 100644 index 00000000..a85161bc --- /dev/null +++ b/lib/js/src/rpc/structs/WeatherData.js @@ -0,0 +1,431 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { Temperature } from './Temperature.js'; +import { Image } from './Image.js'; +import { RpcStruct } from '../RpcStruct.js'; +import { DateTime } from './DateTime.js'; + +class WeatherData extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Temperature} temperature + * @return {WeatherData} + */ + setCurrentTemperature (temperature) { + this.validateType(Temperature, temperature); + this.setParameter(WeatherData.KEY_CURRENT_TEMPERATURE, temperature); + return this; + } + + /** + * @return {Temperature} + */ + getCurrentTemperature () { + return this.getObject(Temperature, WeatherData.KEY_CURRENT_TEMPERATURE); + } + + /** + * @param {Temperature} high + * @return {WeatherData} + */ + setTemperatureHigh (high) { + this.validateType(Temperature, high); + this.setParameter(WeatherData.KEY_TEMPERATURE_HIGH, high); + return this; + } + + /** + * @return {Temperature} + */ + getTemperatureHigh () { + return this.getObject(Temperature, WeatherData.KEY_TEMPERATURE_HIGH); + } + + /** + * @param {Temperature} low + * @return {WeatherData} + */ + setTemperatureLow (low) { + this.validateType(Temperature, low); + this.setParameter(WeatherData.KEY_TEMPERATURE_LOW, low); + return this; + } + + /** + * @return {Temperature} + */ + getTemperatureLow () { + return this.getObject(Temperature, WeatherData.KEY_TEMPERATURE_LOW); + } + + /** + * @param {Temperature} temperature + * @return {WeatherData} + */ + setApparentTemperature (temperature) { + this.validateType(Temperature, temperature); + this.setParameter(WeatherData.KEY_APPARENT_TEMPERATURE, temperature); + return this; + } + + /** + * @return {Temperature} + */ + getApparentTemperature () { + return this.getObject(Temperature, WeatherData.KEY_APPARENT_TEMPERATURE); + } + + /** + * @param {Temperature} high + * @return {WeatherData} + */ + setApparentTemperatureHigh (high) { + this.validateType(Temperature, high); + this.setParameter(WeatherData.KEY_APPARENT_TEMPERATURE_HIGH, high); + return this; + } + + /** + * @return {Temperature} + */ + getApparentTemperatureHigh () { + return this.getObject(Temperature, WeatherData.KEY_APPARENT_TEMPERATURE_HIGH); + } + + /** + * @param {Temperature} low + * @return {WeatherData} + */ + setApparentTemperatureLow (low) { + this.validateType(Temperature, low); + this.setParameter(WeatherData.KEY_APPARENT_TEMPERATURE_LOW, low); + return this; + } + + /** + * @return {Temperature} + */ + getApparentTemperatureLow () { + return this.getObject(Temperature, WeatherData.KEY_APPARENT_TEMPERATURE_LOW); + } + + /** + * @param {String} summary + * @return {WeatherData} + */ + setWeatherSummary (summary) { + this.setParameter(WeatherData.KEY_WEATHER_SUMMARY, summary); + return this; + } + + /** + * @return {String} + */ + getWeatherSummary () { + return this.getParameter(WeatherData.KEY_WEATHER_SUMMARY); + } + + /** + * @param {DateTime} time + * @return {WeatherData} + */ + setTime (time) { + this.validateType(DateTime, time); + this.setParameter(WeatherData.KEY_TIME, time); + return this; + } + + /** + * @return {DateTime} + */ + getTime () { + return this.getObject(DateTime, WeatherData.KEY_TIME); + } + + /** + * @param {Number} humidity - 0 to 1, percentage humidity + * @return {WeatherData} + */ + setHumidity (humidity) { + this.setParameter(WeatherData.KEY_HUMIDITY, humidity); + return this; + } + + /** + * @return {Number} + */ + getHumidity () { + return this.getParameter(WeatherData.KEY_HUMIDITY); + } + + /** + * @param {Number} cover - 0 to 1, percentage cloud cover + * @return {WeatherData} + */ + setCloudCover (cover) { + this.setParameter(WeatherData.KEY_CLOUD_COVER, cover); + return this; + } + + /** + * @return {Number} + */ + getCloudCover () { + return this.getParameter(WeatherData.KEY_CLOUD_COVER); + } + + /** + * @param {Number} phase - 0 to 1, percentage of the moon seen, e.g. 0 = no moon, 0.25 = quarter moon + * @return {WeatherData} + */ + setMoonPhase (phase) { + this.setParameter(WeatherData.KEY_MOON_PHASE, phase); + return this; + } + + /** + * @return {Number} + */ + getMoonPhase () { + return this.getParameter(WeatherData.KEY_MOON_PHASE); + } + + /** + * @param {Number} bearing - In degrees, true north at 0 degrees + * @return {WeatherData} + */ + setWindBearing (bearing) { + this.setParameter(WeatherData.KEY_WIND_BEARING, bearing); + return this; + } + + /** + * @return {Number} + */ + getWindBearing () { + return this.getParameter(WeatherData.KEY_WIND_BEARING); + } + + /** + * @param {Number} gust - km/hr + * @return {WeatherData} + */ + setWindGust (gust) { + this.setParameter(WeatherData.KEY_WIND_GUST, gust); + return this; + } + + /** + * @return {Number} + */ + getWindGust () { + return this.getParameter(WeatherData.KEY_WIND_GUST); + } + + /** + * @param {Number} speed - km/hr + * @return {WeatherData} + */ + setWindSpeed (speed) { + this.setParameter(WeatherData.KEY_WIND_SPEED, speed); + return this; + } + + /** + * @return {Number} + */ + getWindSpeed () { + return this.getParameter(WeatherData.KEY_WIND_SPEED); + } + + /** + * @param {Number} bearing - In degrees, true north at 0 degrees + * @return {WeatherData} + */ + setNearestStormBearing (bearing) { + this.setParameter(WeatherData.KEY_NEAREST_STORM_BEARING, bearing); + return this; + } + + /** + * @return {Number} + */ + getNearestStormBearing () { + return this.getParameter(WeatherData.KEY_NEAREST_STORM_BEARING); + } + + /** + * @param {Number} distance - In km + * @return {WeatherData} + */ + setNearestStormDistance (distance) { + this.setParameter(WeatherData.KEY_NEAREST_STORM_DISTANCE, distance); + return this; + } + + /** + * @return {Number} + */ + getNearestStormDistance () { + return this.getParameter(WeatherData.KEY_NEAREST_STORM_DISTANCE); + } + + /** + * @param {Number} accumulation - cm + * @return {WeatherData} + */ + setPrecipAccumulation (accumulation) { + this.setParameter(WeatherData.KEY_PRECIP_ACCUMULATION, accumulation); + return this; + } + + /** + * @return {Number} + */ + getPrecipAccumulation () { + return this.getParameter(WeatherData.KEY_PRECIP_ACCUMULATION); + } + + /** + * @param {Number} intensity - cm of water per hour + * @return {WeatherData} + */ + setPrecipIntensity (intensity) { + this.setParameter(WeatherData.KEY_PRECIP_INTENSITY, intensity); + return this; + } + + /** + * @return {Number} + */ + getPrecipIntensity () { + return this.getParameter(WeatherData.KEY_PRECIP_INTENSITY); + } + + /** + * @param {Number} probability - 0 to 1, percentage chance + * @return {WeatherData} + */ + setPrecipProbability (probability) { + this.setParameter(WeatherData.KEY_PRECIP_PROBABILITY, probability); + return this; + } + + /** + * @return {Number} + */ + getPrecipProbability () { + return this.getParameter(WeatherData.KEY_PRECIP_PROBABILITY); + } + + /** + * @param {String} type - e.g. "rain", "snow", "sleet", "hail" + * @return {WeatherData} + */ + setPrecipType (type) { + this.setParameter(WeatherData.KEY_PRECIP_TYPE, type); + return this; + } + + /** + * @return {String} + */ + getPrecipType () { + return this.getParameter(WeatherData.KEY_PRECIP_TYPE); + } + + /** + * @param {Number} visibility - In km + * @return {WeatherData} + */ + setVisibility (visibility) { + this.setParameter(WeatherData.KEY_VISIBILITY, visibility); + return this; + } + + /** + * @return {Number} + */ + getVisibility () { + return this.getParameter(WeatherData.KEY_VISIBILITY); + } + + /** + * @param {Image} icon + * @return {WeatherData} + */ + setWeatherIcon (icon) { + this.validateType(Image, icon); + this.setParameter(WeatherData.KEY_WEATHER_ICON, icon); + return this; + } + + /** + * @return {Image} + */ + getWeatherIcon () { + return this.getObject(Image, WeatherData.KEY_WEATHER_ICON); + } +} + +WeatherData.KEY_CURRENT_TEMPERATURE = 'currentTemperature'; +WeatherData.KEY_TEMPERATURE_HIGH = 'temperatureHigh'; +WeatherData.KEY_TEMPERATURE_LOW = 'temperatureLow'; +WeatherData.KEY_APPARENT_TEMPERATURE = 'apparentTemperature'; +WeatherData.KEY_APPARENT_TEMPERATURE_HIGH = 'apparentTemperatureHigh'; +WeatherData.KEY_APPARENT_TEMPERATURE_LOW = 'apparentTemperatureLow'; +WeatherData.KEY_WEATHER_SUMMARY = 'weatherSummary'; +WeatherData.KEY_TIME = 'time'; +WeatherData.KEY_HUMIDITY = 'humidity'; +WeatherData.KEY_CLOUD_COVER = 'cloudCover'; +WeatherData.KEY_MOON_PHASE = 'moonPhase'; +WeatherData.KEY_WIND_BEARING = 'windBearing'; +WeatherData.KEY_WIND_GUST = 'windGust'; +WeatherData.KEY_WIND_SPEED = 'windSpeed'; +WeatherData.KEY_NEAREST_STORM_BEARING = 'nearestStormBearing'; +WeatherData.KEY_NEAREST_STORM_DISTANCE = 'nearestStormDistance'; +WeatherData.KEY_PRECIP_ACCUMULATION = 'precipAccumulation'; +WeatherData.KEY_PRECIP_INTENSITY = 'precipIntensity'; +WeatherData.KEY_PRECIP_PROBABILITY = 'precipProbability'; +WeatherData.KEY_PRECIP_TYPE = 'precipType'; +WeatherData.KEY_VISIBILITY = 'visibility'; +WeatherData.KEY_WEATHER_ICON = 'weatherIcon'; + +export { WeatherData }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/WeatherServiceData.js b/lib/js/src/rpc/structs/WeatherServiceData.js new file mode 100644 index 00000000..2c93b8d5 --- /dev/null +++ b/lib/js/src/rpc/structs/WeatherServiceData.js @@ -0,0 +1,160 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { WeatherData } from './WeatherData.js'; +import { LocationDetails } from './LocationDetails.js'; +import { RpcStruct } from '../RpcStruct.js'; +import { WeatherAlert } from './WeatherAlert.js'; + +/** + * This data is related to what a weather service would provide + */ +class WeatherServiceData extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {LocationDetails} location + * @return {WeatherServiceData} + */ + setLocation (location) { + this.validateType(LocationDetails, location); + this.setParameter(WeatherServiceData.KEY_LOCATION, location); + return this; + } + + /** + * @return {LocationDetails} + */ + getLocation () { + return this.getObject(LocationDetails, WeatherServiceData.KEY_LOCATION); + } + + /** + * @param {WeatherData} forecast + * @return {WeatherServiceData} + */ + setCurrentForecast (forecast) { + this.validateType(WeatherData, forecast); + this.setParameter(WeatherServiceData.KEY_CURRENT_FORECAST, forecast); + return this; + } + + /** + * @return {WeatherData} + */ + getCurrentForecast () { + return this.getObject(WeatherData, WeatherServiceData.KEY_CURRENT_FORECAST); + } + + /** + * @param {WeatherData[]} forecast + * @return {WeatherServiceData} + */ + setMinuteForecast (forecast) { + this.validateType(WeatherData, forecast, true); + this.setParameter(WeatherServiceData.KEY_MINUTE_FORECAST, forecast); + return this; + } + + /** + * @return {WeatherData[]} + */ + getMinuteForecast () { + return this.getObject(WeatherData, WeatherServiceData.KEY_MINUTE_FORECAST); + } + + /** + * @param {WeatherData[]} forecast + * @return {WeatherServiceData} + */ + setHourlyForecast (forecast) { + this.validateType(WeatherData, forecast, true); + this.setParameter(WeatherServiceData.KEY_HOURLY_FORECAST, forecast); + return this; + } + + /** + * @return {WeatherData[]} + */ + getHourlyForecast () { + return this.getObject(WeatherData, WeatherServiceData.KEY_HOURLY_FORECAST); + } + + /** + * @param {WeatherData[]} forecast + * @return {WeatherServiceData} + */ + setMultidayForecast (forecast) { + this.validateType(WeatherData, forecast, true); + this.setParameter(WeatherServiceData.KEY_MULTIDAY_FORECAST, forecast); + return this; + } + + /** + * @return {WeatherData[]} + */ + getMultidayForecast () { + return this.getObject(WeatherData, WeatherServiceData.KEY_MULTIDAY_FORECAST); + } + + /** + * @param {WeatherAlert[]} alerts - This array should be ordered with the first object being the current day + * @return {WeatherServiceData} + */ + setAlerts (alerts) { + this.validateType(WeatherAlert, alerts, true); + this.setParameter(WeatherServiceData.KEY_ALERTS, alerts); + return this; + } + + /** + * @return {WeatherAlert[]} + */ + getAlerts () { + return this.getObject(WeatherAlert, WeatherServiceData.KEY_ALERTS); + } +} + +WeatherServiceData.KEY_LOCATION = 'location'; +WeatherServiceData.KEY_CURRENT_FORECAST = 'currentForecast'; +WeatherServiceData.KEY_MINUTE_FORECAST = 'minuteForecast'; +WeatherServiceData.KEY_HOURLY_FORECAST = 'hourlyForecast'; +WeatherServiceData.KEY_MULTIDAY_FORECAST = 'multidayForecast'; +WeatherServiceData.KEY_ALERTS = 'alerts'; + +export { WeatherServiceData }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/WeatherServiceManifest.js b/lib/js/src/rpc/structs/WeatherServiceManifest.js new file mode 100644 index 00000000..b3cbc6a3 --- /dev/null +++ b/lib/js/src/rpc/structs/WeatherServiceManifest.js @@ -0,0 +1,131 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { RpcStruct } from '../RpcStruct.js'; + +class WeatherServiceManifest extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Boolean} supported + * @return {WeatherServiceManifest} + */ + setCurrentForecastSupported (supported) { + this.setParameter(WeatherServiceManifest.KEY_CURRENT_FORECAST_SUPPORTED, supported); + return this; + } + + /** + * @return {Boolean} + */ + getCurrentForecastSupported () { + return this.getParameter(WeatherServiceManifest.KEY_CURRENT_FORECAST_SUPPORTED); + } + + /** + * @param {Number} amount + * @return {WeatherServiceManifest} + */ + setMaxMultidayForecastAmount (amount) { + this.setParameter(WeatherServiceManifest.KEY_MAX_MULTIDAY_FORECAST_AMOUNT, amount); + return this; + } + + /** + * @return {Number} + */ + getMaxMultidayForecastAmount () { + return this.getParameter(WeatherServiceManifest.KEY_MAX_MULTIDAY_FORECAST_AMOUNT); + } + + /** + * @param {Number} amount + * @return {WeatherServiceManifest} + */ + setMaxHourlyForecastAmount (amount) { + this.setParameter(WeatherServiceManifest.KEY_MAX_HOURLY_FORECAST_AMOUNT, amount); + return this; + } + + /** + * @return {Number} + */ + getMaxHourlyForecastAmount () { + return this.getParameter(WeatherServiceManifest.KEY_MAX_HOURLY_FORECAST_AMOUNT); + } + + /** + * @param {Number} amount + * @return {WeatherServiceManifest} + */ + setMaxMinutelyForecastAmount (amount) { + this.setParameter(WeatherServiceManifest.KEY_MAX_MINUTELY_FORECAST_AMOUNT, amount); + return this; + } + + /** + * @return {Number} + */ + getMaxMinutelyForecastAmount () { + return this.getParameter(WeatherServiceManifest.KEY_MAX_MINUTELY_FORECAST_AMOUNT); + } + + /** + * @param {Boolean} supported + * @return {WeatherServiceManifest} + */ + setWeatherForLocationSupported (supported) { + this.setParameter(WeatherServiceManifest.KEY_WEATHER_FOR_LOCATION_SUPPORTED, supported); + return this; + } + + /** + * @return {Boolean} + */ + getWeatherForLocationSupported () { + return this.getParameter(WeatherServiceManifest.KEY_WEATHER_FOR_LOCATION_SUPPORTED); + } +} + +WeatherServiceManifest.KEY_CURRENT_FORECAST_SUPPORTED = 'currentForecastSupported'; +WeatherServiceManifest.KEY_MAX_MULTIDAY_FORECAST_AMOUNT = 'maxMultidayForecastAmount'; +WeatherServiceManifest.KEY_MAX_HOURLY_FORECAST_AMOUNT = 'maxHourlyForecastAmount'; +WeatherServiceManifest.KEY_MAX_MINUTELY_FORECAST_AMOUNT = 'maxMinutelyForecastAmount'; +WeatherServiceManifest.KEY_WEATHER_FOR_LOCATION_SUPPORTED = 'weatherForLocationSupported'; + +export { WeatherServiceManifest }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/WindowCapability.js b/lib/js/src/rpc/structs/WindowCapability.js new file mode 100644 index 00000000..2e78c30b --- /dev/null +++ b/lib/js/src/rpc/structs/WindowCapability.js @@ -0,0 +1,215 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { ImageField } from './ImageField.js'; +import { TextField } from './TextField.js'; +import { ImageType } from '../enums/ImageType.js'; +import { MenuLayout } from '../enums/MenuLayout.js'; +import { RpcStruct } from '../RpcStruct.js'; +import { ButtonCapabilities } from './ButtonCapabilities.js'; +import { SoftButtonCapabilities } from './SoftButtonCapabilities.js'; + +class WindowCapability extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {Number} id - The specified ID of the window. This ID is either one used when sending the CreateWindow + * request, or one of the predefined window ID values from the enum PredefinedWindows. If + * ommited, value is assumed to be the main window on the main display. + * @return {WindowCapability} + */ + setWindowID (id) { + this.setParameter(WindowCapability.KEY_WINDOW_ID, id); + return this; + } + + /** + * @return {Number} + */ + getWindowID () { + return this.getParameter(WindowCapability.KEY_WINDOW_ID); + } + + /** + * @param {TextField[]} fields - A set of all fields that support text data. See TextField + * @return {WindowCapability} + */ + setTextFields (fields) { + this.validateType(TextField, fields, true); + this.setParameter(WindowCapability.KEY_TEXT_FIELDS, fields); + return this; + } + + /** + * @return {TextField[]} + */ + getTextFields () { + return this.getObject(TextField, WindowCapability.KEY_TEXT_FIELDS); + } + + /** + * @param {ImageField[]} fields - A set of all fields that support images. See ImageField + * @return {WindowCapability} + */ + setImageFields (fields) { + this.validateType(ImageField, fields, true); + this.setParameter(WindowCapability.KEY_IMAGE_FIELDS, fields); + return this; + } + + /** + * @return {ImageField[]} + */ + getImageFields () { + return this.getObject(ImageField, WindowCapability.KEY_IMAGE_FIELDS); + } + + /** + * @param {ImageType[]} supported - Provides information about image types supported by the system. + * @return {WindowCapability} + */ + setImageTypeSupported (supported) { + this.validateType(ImageType, supported, true); + this.setParameter(WindowCapability.KEY_IMAGE_TYPE_SUPPORTED, supported); + return this; + } + + /** + * @return {ImageType[]} + */ + getImageTypeSupported () { + return this.getObject(ImageType, WindowCapability.KEY_IMAGE_TYPE_SUPPORTED); + } + + /** + * @param {String[]} available - A set of all window templates available on the head unit. + * @return {WindowCapability} + */ + setTemplatesAvailable (available) { + this.setParameter(WindowCapability.KEY_TEMPLATES_AVAILABLE, available); + return this; + } + + /** + * @return {String[]} + */ + getTemplatesAvailable () { + return this.getParameter(WindowCapability.KEY_TEMPLATES_AVAILABLE); + } + + /** + * @param {Number} available - The number of on-window custom presets available (if any); otherwise omitted. + * @return {WindowCapability} + */ + setNumCustomPresetsAvailable (available) { + this.setParameter(WindowCapability.KEY_NUM_CUSTOM_PRESETS_AVAILABLE, available); + return this; + } + + /** + * @return {Number} + */ + getNumCustomPresetsAvailable () { + return this.getParameter(WindowCapability.KEY_NUM_CUSTOM_PRESETS_AVAILABLE); + } + + /** + * @param {ButtonCapabilities[]} capabilities - The number of buttons and the capabilities of each on-window button. + * @return {WindowCapability} + */ + setButtonCapabilities (capabilities) { + this.validateType(ButtonCapabilities, capabilities, true); + this.setParameter(WindowCapability.KEY_BUTTON_CAPABILITIES, capabilities); + return this; + } + + /** + * @return {ButtonCapabilities[]} + */ + getButtonCapabilities () { + return this.getObject(ButtonCapabilities, WindowCapability.KEY_BUTTON_CAPABILITIES); + } + + /** + * @param {SoftButtonCapabilities[]} capabilities - The number of soft buttons available on-window and the + * capabilities for each button. + * @return {WindowCapability} + */ + setSoftButtonCapabilities (capabilities) { + this.validateType(SoftButtonCapabilities, capabilities, true); + this.setParameter(WindowCapability.KEY_SOFT_BUTTON_CAPABILITIES, capabilities); + return this; + } + + /** + * @return {SoftButtonCapabilities[]} + */ + getSoftButtonCapabilities () { + return this.getObject(SoftButtonCapabilities, WindowCapability.KEY_SOFT_BUTTON_CAPABILITIES); + } + + /** + * @param {MenuLayout[]} available - An array of available menu layouts. If this parameter is not provided, only the + * `LIST` layout is assumed to be available + * @return {WindowCapability} + */ + setMenuLayoutsAvailable (available) { + this.validateType(MenuLayout, available, true); + this.setParameter(WindowCapability.KEY_MENU_LAYOUTS_AVAILABLE, available); + return this; + } + + /** + * @return {MenuLayout[]} + */ + getMenuLayoutsAvailable () { + return this.getObject(MenuLayout, WindowCapability.KEY_MENU_LAYOUTS_AVAILABLE); + } +} + +WindowCapability.KEY_WINDOW_ID = 'windowID'; +WindowCapability.KEY_TEXT_FIELDS = 'textFields'; +WindowCapability.KEY_IMAGE_FIELDS = 'imageFields'; +WindowCapability.KEY_IMAGE_TYPE_SUPPORTED = 'imageTypeSupported'; +WindowCapability.KEY_TEMPLATES_AVAILABLE = 'templatesAvailable'; +WindowCapability.KEY_NUM_CUSTOM_PRESETS_AVAILABLE = 'numCustomPresetsAvailable'; +WindowCapability.KEY_BUTTON_CAPABILITIES = 'buttonCapabilities'; +WindowCapability.KEY_SOFT_BUTTON_CAPABILITIES = 'softButtonCapabilities'; +WindowCapability.KEY_MENU_LAYOUTS_AVAILABLE = 'menuLayoutsAvailable'; + +export { WindowCapability }; \ No newline at end of file diff --git a/lib/js/src/rpc/structs/WindowTypeCapabilities.js b/lib/js/src/rpc/structs/WindowTypeCapabilities.js new file mode 100644 index 00000000..7b72a675 --- /dev/null +++ b/lib/js/src/rpc/structs/WindowTypeCapabilities.js @@ -0,0 +1,82 @@ +/* eslint-disable camelcase */ +/* +* Copyright (c) 2020, SmartDeviceLink Consortium, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following +* disclaimer in the documentation and/or other materials provided with the +* distribution. +* +* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import { WindowType } from '../enums/WindowType.js'; +import { RpcStruct } from '../RpcStruct.js'; + +class WindowTypeCapabilities extends RpcStruct { + /** + * @constructor + */ + constructor (parameters) { + super(parameters); + } + + /** + * @param {WindowType} type + * @return {WindowTypeCapabilities} + */ + setType (type) { + this.validateType(WindowType, type); + this.setParameter(WindowTypeCapabilities.KEY_TYPE, type); + return this; + } + + /** + * @return {WindowType} + */ + getType () { + return this.getObject(WindowType, WindowTypeCapabilities.KEY_TYPE); + } + + /** + * @param {Number} windows + * @return {WindowTypeCapabilities} + */ + setMaximumNumberOfWindows (windows) { + this.setParameter(WindowTypeCapabilities.KEY_MAXIMUM_NUMBER_OF_WINDOWS, windows); + return this; + } + + /** + * @return {Number} + */ + getMaximumNumberOfWindows () { + return this.getParameter(WindowTypeCapabilities.KEY_MAXIMUM_NUMBER_OF_WINDOWS); + } +} + +WindowTypeCapabilities.KEY_TYPE = 'type'; +WindowTypeCapabilities.KEY_MAXIMUM_NUMBER_OF_WINDOWS = 'maximumNumberOfWindows'; + +export { WindowTypeCapabilities }; \ No newline at end of file diff --git a/lib/node/dist/index.js b/lib/node/dist/index.js index da552885..c5f0cdc0 100644 --- a/lib/node/dist/index.js +++ b/lib/node/dist/index.js @@ -726,38 +726,251 @@ } - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ + /** + * Contains detailed information about the registered application. + */ + + class AppInfo extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {String} name - The name displayed for the mobile application on the mobile device (can differ from the + * app name set in the initial RAI request). + * @return {AppInfo} + */ + + + setAppDisplayName(name) { + this.setParameter(AppInfo.KEY_APP_DISPLAY_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getAppDisplayName() { + return this.getParameter(AppInfo.KEY_APP_DISPLAY_NAME); + } + /** + * @param {String} id - The AppBundleID of an iOS application or package name of the Android application. This + * supports App Launch strategies for each platform. + * @return {AppInfo} + */ + + + setAppBundleID(id) { + this.setParameter(AppInfo.KEY_APP_BUNDLE_ID, id); + return this; + } + /** + * @return {String} + */ + + + getAppBundleID() { + return this.getParameter(AppInfo.KEY_APP_BUNDLE_ID); + } + /** + * @param {String} version - Represents the build version number of this particular mobile app. + * @return {AppInfo} + */ + + + setAppVersion(version) { + this.setParameter(AppInfo.KEY_APP_VERSION, version); + return this; + } + /** + * @return {String} + */ + + + getAppVersion() { + return this.getParameter(AppInfo.KEY_APP_VERSION); + } + /** + * @param {String} icon - A file reference to the icon utilized by this app (simplifies the process of setting an + * app icon during app registration). + * @return {AppInfo} + */ + + + setAppIcon(icon) { + this.setParameter(AppInfo.KEY_APP_ICON, icon); + return this; + } + /** + * @return {String} + */ + + + getAppIcon() { + return this.getParameter(AppInfo.KEY_APP_ICON); + } + + } + + AppInfo.KEY_APP_DISPLAY_NAME = 'appDisplayName'; + AppInfo.KEY_APP_BUNDLE_ID = 'appBundleID'; + AppInfo.KEY_APP_VERSION = 'appVersion'; + AppInfo.KEY_APP_ICON = 'appIcon'; + + /* eslint-disable camelcase */ + + class RGBColor extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Number} red + * @return {RGBColor} + */ + + + setRed(red) { + this.setParameter(RGBColor.KEY_RED, red); + return this; + } + /** + * @return {Number} + */ + + + getRed() { + return this.getParameter(RGBColor.KEY_RED); + } + /** + * @param {Number} green + * @return {RGBColor} + */ + + + setGreen(green) { + this.setParameter(RGBColor.KEY_GREEN, green); + return this; + } + /** + * @return {Number} + */ + + + getGreen() { + return this.getParameter(RGBColor.KEY_GREEN); + } + /** + * @param {Number} blue + * @return {RGBColor} + */ + + + setBlue(blue) { + this.setParameter(RGBColor.KEY_BLUE, blue); + return this; + } + /** + * @return {Number} + */ + + + getBlue() { + return this.getParameter(RGBColor.KEY_BLUE); + } + + } + + RGBColor.KEY_RED = 'red'; + RGBColor.KEY_GREEN = 'green'; + RGBColor.KEY_BLUE = 'blue'; + + /* eslint-disable camelcase */ + /** + * A color scheme for all display layout templates. + */ + + class TemplateColorScheme extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {RGBColor} color - The primary "accent" color + * @return {TemplateColorScheme} + */ + + + setPrimaryColor(color) { + this.validateType(RGBColor, color); + this.setParameter(TemplateColorScheme.KEY_PRIMARY_COLOR, color); + return this; + } + /** + * @return {RGBColor} + */ + + + getPrimaryColor() { + return this.getObject(RGBColor, TemplateColorScheme.KEY_PRIMARY_COLOR); + } + /** + * @param {RGBColor} color - The secondary "accent" color + * @return {TemplateColorScheme} + */ + + + setSecondaryColor(color) { + this.validateType(RGBColor, color); + this.setParameter(TemplateColorScheme.KEY_SECONDARY_COLOR, color); + return this; + } + /** + * @return {RGBColor} + */ + + + getSecondaryColor() { + return this.getObject(RGBColor, TemplateColorScheme.KEY_SECONDARY_COLOR); + } + /** + * @param {RGBColor} color - The color of the background + * @return {TemplateColorScheme} + */ + + + setBackgroundColor(color) { + this.validateType(RGBColor, color); + this.setParameter(TemplateColorScheme.KEY_BACKGROUND_COLOR, color); + return this; + } + /** + * @return {RGBColor} + */ + + + getBackgroundColor() { + return this.getObject(RGBColor, TemplateColorScheme.KEY_BACKGROUND_COLOR); + } + + } + + TemplateColorScheme.KEY_PRIMARY_COLOR = 'primaryColor'; + TemplateColorScheme.KEY_SECONDARY_COLOR = 'secondaryColor'; + TemplateColorScheme.KEY_BACKGROUND_COLOR = 'backgroundColor'; + + /* eslint-disable camelcase */ /** + * Enumeration linking function names with function IDs in SmartDeviceLink protocol. Assumes enumeration starts at + * value 0. * @typedef {Enum} FunctionID * @property {Object} _MAP */ @@ -770,676 +983,716 @@ super(); } /** - * @return {Number} - */ + * @return {Number} + */ + + + static get RESERVED() { + return FunctionID._MAP.RESERVED; + } + /** + * @return {Number} + */ static get RegisterAppInterface() { return FunctionID._MAP.RegisterAppInterface; } /** - * @return {Number} - */ + * @return {Number} + */ static get UnregisterAppInterface() { return FunctionID._MAP.UnregisterAppInterface; } /** - * @return {Number} - */ + * @return {Number} + */ static get SetGlobalProperties() { return FunctionID._MAP.SetGlobalProperties; } /** - * @return {Number} - */ + * @return {Number} + */ static get ResetGlobalProperties() { return FunctionID._MAP.ResetGlobalProperties; } /** - * @return {Number} - */ + * @return {Number} + */ static get AddCommand() { return FunctionID._MAP.AddCommand; } /** - * @return {Number} - */ + * @return {Number} + */ static get DeleteCommand() { return FunctionID._MAP.DeleteCommand; } /** - * @return {Number} - */ + * @return {Number} + */ static get AddSubMenu() { return FunctionID._MAP.AddSubMenu; } /** - * @return {Number} - */ + * @return {Number} + */ static get DeleteSubMenu() { return FunctionID._MAP.DeleteSubMenu; } /** - * @return {Number} - */ + * @return {Number} + */ static get CreateInteractionChoiceSet() { return FunctionID._MAP.CreateInteractionChoiceSet; } /** - * @return {Number} - */ + * @return {Number} + */ static get PerformInteraction() { return FunctionID._MAP.PerformInteraction; } /** - * @return {Number} - */ + * @return {Number} + */ static get DeleteInteractionChoiceSet() { return FunctionID._MAP.DeleteInteractionChoiceSet; } /** - * @return {Number} - */ + * @return {Number} + */ static get Alert() { return FunctionID._MAP.Alert; } /** - * @return {Number} - */ + * @return {Number} + */ static get Show() { return FunctionID._MAP.Show; } /** - * @return {Number} - */ + * @return {Number} + */ static get Speak() { return FunctionID._MAP.Speak; } /** - * @return {Number} - */ + * @return {Number} + */ static get SetMediaClockTimer() { return FunctionID._MAP.SetMediaClockTimer; } /** - * @return {Number} - */ + * @return {Number} + */ static get PerformAudioPassThru() { return FunctionID._MAP.PerformAudioPassThru; } /** - * @return {Number} - */ + * @return {Number} + */ static get EndAudioPassThru() { return FunctionID._MAP.EndAudioPassThru; } /** - * @return {Number} - */ + * @return {Number} + */ static get SubscribeButton() { return FunctionID._MAP.SubscribeButton; } /** - * @return {Number} - */ + * @return {Number} + */ static get UnsubscribeButton() { return FunctionID._MAP.UnsubscribeButton; } /** - * @return {Number} - */ + * @return {Number} + */ static get SubscribeVehicleData() { return FunctionID._MAP.SubscribeVehicleData; } /** - * @return {Number} - */ + * @return {Number} + */ static get UnsubscribeVehicleData() { return FunctionID._MAP.UnsubscribeVehicleData; } /** - * @return {Number} - */ + * @return {Number} + */ static get GetVehicleData() { return FunctionID._MAP.GetVehicleData; } /** - * @return {Number} - */ + * @return {Number} + */ static get ReadDID() { return FunctionID._MAP.ReadDID; } /** - * @return {Number} - */ + * @return {Number} + */ static get GetDTCs() { return FunctionID._MAP.GetDTCs; } /** - * @return {Number} - */ + * @return {Number} + */ static get ScrollableMessage() { return FunctionID._MAP.ScrollableMessage; } /** - * @return {Number} - */ + * @return {Number} + */ static get Slider() { return FunctionID._MAP.Slider; } /** - * @return {Number} - */ + * @return {Number} + */ static get ShowConstantTBT() { return FunctionID._MAP.ShowConstantTBT; } /** - * @return {Number} - */ + * @return {Number} + */ static get AlertManeuver() { return FunctionID._MAP.AlertManeuver; } /** - * @return {Number} - */ + * @return {Number} + */ static get UpdateTurnList() { return FunctionID._MAP.UpdateTurnList; } /** - * @return {Number} - */ + * @return {Number} + */ static get ChangeRegistration() { return FunctionID._MAP.ChangeRegistration; } /** - * @return {Number} - */ + * @return {Number} + */ static get GenericResponse() { return FunctionID._MAP.GenericResponse; } /** - * @return {Number} - */ + * @return {Number} + */ static get PutFile() { return FunctionID._MAP.PutFile; } /** - * @return {Number} - */ + * @return {Number} + */ static get DeleteFile() { return FunctionID._MAP.DeleteFile; } /** - * @return {Number} - */ + * @return {Number} + */ static get ListFiles() { return FunctionID._MAP.ListFiles; } /** - * @return {Number} - */ + * @return {Number} + */ static get SetAppIcon() { return FunctionID._MAP.SetAppIcon; } /** - * @return {Number} - */ + * @return {Number} + */ static get SetDisplayLayout() { return FunctionID._MAP.SetDisplayLayout; } /** - * @return {Number} - */ + * @return {Number} + */ static get DiagnosticMessage() { return FunctionID._MAP.DiagnosticMessage; } /** - * @return {Number} - */ + * @return {Number} + */ static get SystemRequest() { return FunctionID._MAP.SystemRequest; } /** - * @return {Number} - */ + * @return {Number} + */ static get SendLocation() { return FunctionID._MAP.SendLocation; } /** - * @return {Number} - */ + * @return {Number} + */ static get DialNumber() { return FunctionID._MAP.DialNumber; } /** - * @return {Number} - */ + * @return {Number} + */ static get ButtonPress() { return FunctionID._MAP.ButtonPress; } /** - * @return {Number} - */ + * @return {Number} + */ static get GetInteriorVehicleData() { return FunctionID._MAP.GetInteriorVehicleData; } /** - * @return {Number} - */ + * @return {Number} + */ static get SetInteriorVehicleData() { return FunctionID._MAP.SetInteriorVehicleData; } /** - * @return {Number} - */ + * @return {Number} + */ static get GetWayPoints() { return FunctionID._MAP.GetWayPoints; } /** - * @return {Number} - */ + * @return {Number} + */ static get SubscribeWayPoints() { return FunctionID._MAP.SubscribeWayPoints; } /** - * @return {Number} - */ + * @return {Number} + */ static get UnsubscribeWayPoints() { return FunctionID._MAP.UnsubscribeWayPoints; } /** - * @return {Number} - */ + * @return {Number} + */ static get GetSystemCapability() { return FunctionID._MAP.GetSystemCapability; } /** - * @return {Number} - */ + * @return {Number} + */ static get SendHapticData() { return FunctionID._MAP.SendHapticData; } /** - * @return {Number} - */ + * @return {Number} + */ static get SetCloudAppProperties() { return FunctionID._MAP.SetCloudAppProperties; } /** - * @return {Number} - */ + * @return {Number} + */ static get GetCloudAppProperties() { return FunctionID._MAP.GetCloudAppProperties; } /** - * @return {Number} - */ + * @return {Number} + */ static get PublishAppService() { return FunctionID._MAP.PublishAppService; } /** - * @return {Number} - */ + * @return {Number} + */ static get GetAppServiceData() { return FunctionID._MAP.GetAppServiceData; } /** - * @return {Number} - */ + * @return {Number} + */ static get GetFile() { return FunctionID._MAP.GetFile; } /** - * @return {Number} - */ + * @return {Number} + */ static get PerformAppServiceInteraction() { return FunctionID._MAP.PerformAppServiceInteraction; } /** - * @return {Number} - */ + * @return {Number} + */ static get UnpublishAppService() { return FunctionID._MAP.UnpublishAppService; } /** - * @return {Number} - */ + * @return {Number} + */ static get CancelInteraction() { return FunctionID._MAP.CancelInteraction; } /** - * @return {Number} - */ + * @return {Number} + */ static get CloseApplication() { return FunctionID._MAP.CloseApplication; } /** - * @return {Number} - */ + * @return {Number} + */ static get ShowAppMenu() { return FunctionID._MAP.ShowAppMenu; } /** - * @return {Number} - */ + * @return {Number} + */ static get CreateWindow() { return FunctionID._MAP.CreateWindow; } /** - * @return {Number} - */ + * @return {Number} + */ static get DeleteWindow() { return FunctionID._MAP.DeleteWindow; } /** - * @return {Number} - */ + * @return {Number} + */ static get GetInteriorVehicleDataConsent() { return FunctionID._MAP.GetInteriorVehicleDataConsent; } /** - * @return {Number} - */ + * @return {Number} + */ static get ReleaseInteriorVehicleDataModule() { return FunctionID._MAP.ReleaseInteriorVehicleDataModule; } /** - * @return {Number} - */ + * @return {Number} + */ static get OnHMIStatus() { return FunctionID._MAP.OnHMIStatus; } /** - * @return {Number} - */ + * @return {Number} + */ static get OnAppInterfaceUnregistered() { return FunctionID._MAP.OnAppInterfaceUnregistered; } /** - * @return {Number} - */ + * @return {Number} + */ static get OnButtonEvent() { return FunctionID._MAP.OnButtonEvent; } /** - * @return {Number} - */ + * @return {Number} + */ static get OnButtonPress() { return FunctionID._MAP.OnButtonPress; } /** - * @return {Number} - */ + * @return {Number} + */ static get OnVehicleData() { return FunctionID._MAP.OnVehicleData; } /** - * @return {Number} - */ + * @return {Number} + */ static get OnCommand() { return FunctionID._MAP.OnCommand; } /** - * @return {Number} - */ + * @return {Number} + */ static get OnTBTClientState() { return FunctionID._MAP.OnTBTClientState; } /** - * @return {Number} - */ + * @return {Number} + */ static get OnDriverDistraction() { return FunctionID._MAP.OnDriverDistraction; } /** - * @return {Number} - */ + * @return {Number} + */ static get OnPermissionsChange() { return FunctionID._MAP.OnPermissionsChange; } /** - * @return {Number} - */ + * @return {Number} + */ static get OnAudioPassThru() { return FunctionID._MAP.OnAudioPassThru; } /** - * @return {Number} - */ - + * @return {Number} + */ + static get OnLanguageChange() { return FunctionID._MAP.OnLanguageChange; } /** - * @return {Number} - */ + * @return {Number} + */ static get OnKeyboardInput() { return FunctionID._MAP.OnKeyboardInput; } /** - * @return {Number} - */ + * @return {Number} + */ static get OnTouchEvent() { return FunctionID._MAP.OnTouchEvent; } /** - * @return {Number} - */ + * @return {Number} + */ static get OnSystemRequest() { return FunctionID._MAP.OnSystemRequest; } /** - * @return {Number} - */ + * @return {Number} + */ static get OnHashChange() { return FunctionID._MAP.OnHashChange; } /** - * @return {Number} - */ + * @return {Number} + */ static get OnInteriorVehicleData() { return FunctionID._MAP.OnInteriorVehicleData; } /** - * @return {Number} - */ + * @return {Number} + */ static get OnWayPointChange() { return FunctionID._MAP.OnWayPointChange; } /** - * @return {Number} - */ + * @return {Number} + */ static get OnRCStatus() { return FunctionID._MAP.OnRCStatus; } /** - * @return {Number} - */ + * @return {Number} + */ static get OnAppServiceData() { return FunctionID._MAP.OnAppServiceData; } /** - * @return {Number} - */ + * @return {Number} + */ static get OnSystemCapabilityUpdated() { return FunctionID._MAP.OnSystemCapabilityUpdated; } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * @return {Number} + */ + + + static get EncodedSyncPData() { + return FunctionID._MAP.EncodedSyncPData; + } + /** + * @return {Number} + */ + + + static get SdlPData() { + return FunctionID._MAP.SdlPData; + } + /** + * @return {Number} + */ + + + static get OnEncodedSyncPData() { + return FunctionID._MAP.OnEncodedSyncPData; + } + /** + * @return {Number} + */ + + + static get OnSyncPData() { + return FunctionID._MAP.OnSyncPData; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ static valueForKey(key) { return FunctionID._valueForKey(key, FunctionID._MAP); } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ static keyForValue(value) { @@ -1449,6 +1702,7 @@ } FunctionID._MAP = Object.freeze({ + 'RESERVED': 0, 'RegisterAppInterface': 0x01, 'UnregisterAppInterface': 0x02, 'SetGlobalProperties': 0x03, @@ -1530,417 +1784,227 @@ 'OnWayPointChange': 0x8010, 'OnRCStatus': 0x8011, 'OnAppServiceData': 0x8012, - 'OnSystemCapabilityUpdated': 0x8013 + 'OnSystemCapabilityUpdated': 0x8013, + 'EncodedSyncPData': 0x10000, + 'SyncPData': 0x10001, + 'OnEncodedSyncPData': 0x18000, + 'OnSyncPData': 0x18001 }); - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ /** - * @typedef {Object} RpcMessage - * @property {RpcType} rpcType + * Contains information about the TTS capabilities. + * @typedef {Enum} SpeechCapabilities + * @property {Object} _MAP */ - class RpcMessage extends RpcStruct { - /* - { - "rpcType": "Request", - "functionName": "RegisterAppInterface", - "coorelationID": "320948", - "isEncrypted": false, - "parameters": { - "appName": "Hello" - }, - "bulkData": "...", - } - */ - - /** - * @constructor - */ - constructor(store = {}) { - super(store.parameters); - this._isEncrypted = false; - this._rpcType = store.rpcType; - this._functionName = store.functionName; - this._correlationID = store.correlationID; - this.setBulkData(store.bulkData); - } - /** - * @return {RpcType} - */ - - - getRPCType() { - return this._rpcType; - } + class SpeechCapabilities extends Enum { /** - * @param {RpcType} type - * @return {RpcMessage} - */ - - - setRPCType(type) { - this._rpcType = type; - return this; + * @constructor + */ + constructor() { + super(); } /** - * @return {FunctionID} type - */ + * @return {String} + */ - getFunctionName() { - return this._functionName; + static get SC_TEXT() { + return SpeechCapabilities._MAP.SC_TEXT; } /** - * @param {FunctionID} name - * @return {RpcMessage} - */ - + * @return {String} + */ - setFunctionName(name) { - if (typeof name !== 'string') { - this._functionName = FunctionID.keyForValue(name); - } else { - this._functionName = name; - } - return this; + static get SAPI_PHONEMES() { + return SpeechCapabilities._MAP.SAPI_PHONEMES; } /** - * @return {String} type - */ + * @return {String} + */ - getCorrelationId() { - return this._correlationID; + static get LHPLUS_PHONEMES() { + return SpeechCapabilities._MAP.LHPLUS_PHONEMES; } /** - * @param {String} name - * @return {RpcMessage} - */ + * @return {String} + */ - setCorrelationId(id) { - this._correlationID = id; - return this; + static get PRE_RECORDED() { + return SpeechCapabilities._MAP.PRE_RECORDED; } /** - * @return {Uint8Array} data - */ + * @return {String} + */ - getBulkData() { - return this._bulkData; + static get SILENCE() { + return SpeechCapabilities._MAP.SILENCE; } /** - * @param {UInt8Array} data - * @return {RpcMessage} - */ - + * @return {String} + */ - setBulkData(data = null) { - if (data !== null) { - this._bulkData = data.slice(0); - } else { - this._bulkData = null; - } - return this; + static get FILE() { + return SpeechCapabilities._MAP.FILE; } /** - * @return {Boolean} - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ - getIsEncrypted() { - return this._isEncrypted; + static valueForKey(key) { + return SpeechCapabilities._valueForKey(key, SpeechCapabilities._MAP); } /** - * @param {Boolean} bool - * @return {RpcMessage} - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ - setIsEncrypted(bool) { - this._isEncrypted = bool; - return this; + static keyForValue(value) { + return SpeechCapabilities._keyForValue(value, SpeechCapabilities._MAP); } } - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + SpeechCapabilities._MAP = Object.freeze({ + 'SC_TEXT': 'TEXT', + 'SAPI_PHONEMES': 'SAPI_PHONEMES', + 'LHPLUS_PHONEMES': 'LHPLUS_PHONEMES', + 'PRE_RECORDED': 'PRE_RECORDED', + 'SILENCE': 'SILENCE', + 'FILE': 'FILE' + }); + + /* eslint-disable camelcase */ /** - * @typedef {Enum} RpcType - * @property {Object} _MAP + * A TTS chunk, that consists of text/phonemes to speak or the name of a file to play, and a TTS type (like text or + * SAPI) */ - class RpcType extends Enum { - /** - * @constructor - */ - constructor() { - super(); - } + class TTSChunk extends RpcStruct { /** - * @return {Number} + * @constructor */ - - - static get NOTIFICATION() { - return RpcType._MAP.NOTIFICATION; + constructor(parameters) { + super(parameters); } /** - * @return {Number} + * @param {String} text - The text or phonemes to speak, or the name of the audio file to play. May not be empty. + * @return {TTSChunk} */ - static get RESPONSE() { - return RpcType._MAP.RESPONSE; + setText(text) { + this.setParameter(TTSChunk.KEY_TEXT, text); + return this; } /** - * @return {Number} + * @return {String} */ - static get REQUEST() { - return RpcType._MAP.REQUEST; + getText() { + return this.getParameter(TTSChunk.KEY_TEXT); } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * @param {SpeechCapabilities} type - Describes whether the TTS chunk is plain text, a specific phoneme set, or an + * audio file. See SpeechCapabilities + * @return {TTSChunk} + */ - static valueForKey(key) { - return RpcType._valueForKey(key, RpcType._MAP); + setType(type) { + this.validateType(SpeechCapabilities, type); + this.setParameter(TTSChunk.KEY_TYPE, type); + return this; } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * @return {SpeechCapabilities} + */ - static keyForValue(value) { - return RpcType._keyForValue(value, RpcType._MAP); + getType() { + return this.getObject(SpeechCapabilities, TTSChunk.KEY_TYPE); } } - RpcType._MAP = Object.freeze({ - 'NOTIFICATION': 0x2, - 'RESPONSE': 0x1, - 'REQUEST': 0x0 - }); - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - class RpcRequest extends RpcMessage { - /** - * @constructor - */ - constructor(store) { - super(store); - this.setRPCType(RpcType.REQUEST); - this._promise = null; - } - /** - * @return {Promise} - */ - - - getOnRPCResponsePromise() { - return this._promise; - } - /** - * @param {Promise} promise - * @return {RpcMessage} - */ - - - setOnRPCResponsePromise(promise) { - this.validateType(Promise, promise); - this._promise = promise; - return this; - } - - } + TTSChunk.KEY_TEXT = 'text'; + TTSChunk.KEY_TYPE = 'type'; - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ + /** + * Specifies the version number of the SmartDeviceLink protocol that is supported by the mobile application + */ class SdlMsgVersion extends RpcStruct { + /** + * @constructor + */ constructor(parameters) { super(parameters); } /** - * @param {Number} the major version of this object - * @return {SdlMsgVersion} - */ + * @param {Number} version - The major version indicates versions that is not-compatible to previous versions. + * @return {SdlMsgVersion} + */ - setMajorVersion(value) { - this.setParameter(SdlMsgVersion.KEY_MAJOR_VERSION, value); + setMajorVersion(version) { + this.setParameter(SdlMsgVersion.KEY_MAJOR_VERSION, version); return this; } /** - * @return {Number} the major version of this object - */ + * @return {Number} + */ getMajorVersion() { return this.getParameter(SdlMsgVersion.KEY_MAJOR_VERSION); } /** - * @param {Number} the minor version of this object - * @return {SdlMsgVersion} - */ + * @param {Number} version - The minor version indicates a change to a previous version that should still allow to + * be run on an older version (with limited functionality) + * @return {SdlMsgVersion} + */ - setMinorVersion(value) { - this.setParameter(SdlMsgVersion.KEY_MINOR_VERSION, value); + setMinorVersion(version) { + this.setParameter(SdlMsgVersion.KEY_MINOR_VERSION, version); return this; } /** - * @return {Number} the minor version of this object - */ + * @return {Number} + */ getMinorVersion() { return this.getParameter(SdlMsgVersion.KEY_MINOR_VERSION); } /** - * @param {Number} the patch version of this object - * @return {SdlMsgVersion} - */ + * @param {Number} version - The patch version indicates a fix to existing functionality in a previous version that + * should still be able to be run on an older version + * @return {SdlMsgVersion} + */ - setPatchVersion(value) { - this.setParameter(SdlMsgVersion.KEY_PATCH_VERSION, value); + setPatchVersion(version) { + this.setParameter(SdlMsgVersion.KEY_PATCH_VERSION, version); return this; } /** - * @return {Number} the patch version of this objects - */ + * @return {Number} + */ getPatchVersion() { @@ -1953,43 +2017,17 @@ SdlMsgVersion.KEY_MINOR_VERSION = 'minorVersion'; SdlMsgVersion.KEY_PATCH_VERSION = 'patchVersion'; - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ /** - * @typedef {Enum} SpeechCapabilities + * Enumeration listing possible app types. + * @typedef {Enum} AppHMIType * @property {Object} _MAP */ - class SpeechCapabilities extends Enum { + class AppHMIType extends Enum { + /** + * @constructor + */ constructor() { super(); } @@ -1998,632 +2036,563 @@ */ - static get SC_TEXT() { - return SpeechCapabilities._MAP.SC_TEXT; + static get DEFAULT() { + return AppHMIType._MAP.DEFAULT; } /** * @return {String} */ - static get SAPI_PHONEMES() { - return SpeechCapabilities._MAP.SAPI_PHONEMES; + static get COMMUNICATION() { + return AppHMIType._MAP.COMMUNICATION; } /** * @return {String} */ - static get LHPLUS_PHONEMES() { - return SpeechCapabilities._MAP.LHPLUS_PHONEMES; + static get MEDIA() { + return AppHMIType._MAP.MEDIA; } /** * @return {String} */ - static get PRE_RECORDED() { - return SpeechCapabilities._MAP.PRE_RECORDED; + static get MESSAGING() { + return AppHMIType._MAP.MESSAGING; } /** * @return {String} */ - static get SILENCE() { - return SpeechCapabilities._MAP.SILENCE; + static get NAVIGATION() { + return AppHMIType._MAP.NAVIGATION; } /** * @return {String} */ - static get FILE() { - return SpeechCapabilities._MAP.FILE; + static get INFORMATION() { + return AppHMIType._MAP.INFORMATION; } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ - + * @return {String} + */ - static valueForKey(key) { - return SpeechCapabilities._valueForKey(key, SpeechCapabilities._MAP); + + static get SOCIAL() { + return AppHMIType._MAP.SOCIAL; } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * @return {String} + */ - static keyForValue(value) { - return SpeechCapabilities._keyForValue(value, SpeechCapabilities._MAP); + static get BACKGROUND_PROCESS() { + return AppHMIType._MAP.BACKGROUND_PROCESS; } + /** + * @return {String} + */ - } - SpeechCapabilities._MAP = Object.freeze({ - 'SC_TEXT': 'TEXT', - 'SAPI_PHONEMES': 'SAPI_PHONEMES', - 'LHPLUS_PHONEMES': 'LHPLUS_PHONEMES', - 'PRE_RECORDED': 'PRE_RECORDED', - 'SILENCE': 'SILENCE', - 'FILE': 'FILE' - }); + static get TESTING() { + return AppHMIType._MAP.TESTING; + } + /** + * @return {String} + */ - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - class TTSChunk extends RpcStruct { - constructor(parameters) { - super(parameters); + static get SYSTEM() { + return AppHMIType._MAP.SYSTEM; } /** - * @param {String} text - * @return {TTSChunk} - */ + * @return {String} + */ - setText(text) { - this.setParameter(TTSChunk.KEY_TEXT, text); - return this; + static get PROJECTION() { + return AppHMIType._MAP.PROJECTION; } /** - * @return {Number} - */ + * @return {String} + */ - getText() { - return this.getParameter(TTSChunk.KEY_TEXT); + static get REMOTE_CONTROL() { + return AppHMIType._MAP.REMOTE_CONTROL; } /** - * @param {SpeechCapabilities} type - * @return {TTSChunk} - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ - setType(type) { - this.validateType(SpeechCapabilities, type); - this.setParameter(TTSChunk.KEY_TYPE, type); - return this; + static valueForKey(key) { + return AppHMIType._valueForKey(key, AppHMIType._MAP); } /** - * @return {SpeechCapabilities} - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ - getType() { - return this.getObject(SpeechCapabilities, TTSChunk.KEY_TYPE); + static keyForValue(value) { + return AppHMIType._keyForValue(value, AppHMIType._MAP); } } - TTSChunk.KEY_TEXT = 'text'; - TTSChunk.KEY_TYPE = 'type'; + AppHMIType._MAP = Object.freeze({ + 'DEFAULT': 'DEFAULT', + 'COMMUNICATION': 'COMMUNICATION', + 'MEDIA': 'MEDIA', + 'MESSAGING': 'MESSAGING', + 'NAVIGATION': 'NAVIGATION', + 'INFORMATION': 'INFORMATION', + 'SOCIAL': 'SOCIAL', + 'BACKGROUND_PROCESS': 'BACKGROUND_PROCESS', + 'TESTING': 'TESTING', + 'SYSTEM': 'SYSTEM', + 'PROJECTION': 'PROJECTION', + 'REMOTE_CONTROL': 'REMOTE_CONTROL' + }); - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ + /** + * @typedef {Enum} Language + * @property {Object} _MAP + */ - class DeviceInfo extends RpcStruct { - constructor(parameters) { - super(parameters); + class Language extends Enum { + /** + * @constructor + */ + constructor() { + super(); } /** - * @param {String} hardware - * @return {DeviceInfo} - */ + * English - US + * @return {String} + */ - setHardware(hardware) { - this.validateType(String, hardware); - this.setParameter(DeviceInfo.KEY_HARDWARE, hardware); - return this; + static get EN_US() { + return Language._MAP.EN_US; } /** - * @return {String} - */ + * Spanish - Mexico + * @return {String} + */ - getHardware() { - return this.getParameter(DeviceInfo.KEY_HARDWARE); + static get ES_MX() { + return Language._MAP.ES_MX; } /** - * @param {String} firmwareRev - * @return {DeviceInfo} - */ + * French - Canada + * @return {String} + */ - setFirmwareRev(firmwareRev) { - this.validateType(String, firmwareRev); - this.setParameter(DeviceInfo.KEY_FIRMWARE_REV, firmwareRev); - return this; + static get FR_CA() { + return Language._MAP.FR_CA; } /** - * @return {String} - */ + * German - Germany + * @return {String} + */ - getFirmwareRev() { - return this.getParameter(DeviceInfo.KEY_FIRMWARE_REV); + static get DE_DE() { + return Language._MAP.DE_DE; } /** - * @param {String} os - * @return {DeviceInfo} - */ + * Spanish - Spain + * @return {String} + */ - setOs(os) { - this.validateType(String, os); - this.setParameter(DeviceInfo.KEY_OS, os); - return this; + static get ES_ES() { + return Language._MAP.ES_ES; } /** - * @return {String} - */ + * English - GB + * @return {String} + */ - getOs() { - return this.getParameter(DeviceInfo.KEY_OS); + static get EN_GB() { + return Language._MAP.EN_GB; } /** - * @param {String} osVersion - * @return {DeviceInfo} - */ + * Russian - Russia + * @return {String} + */ - setOsVersion(osVersion) { - this.validateType(String, osVersion); - this.setParameter(DeviceInfo.KEY_OS_VERSION, osVersion); - return this; + static get RU_RU() { + return Language._MAP.RU_RU; } /** - * @return {String} - */ + * Turkish - Turkey + * @return {String} + */ - getOsVersion() { - return this.getParameter(DeviceInfo.KEY_OS_VERSION); + static get TR_TR() { + return Language._MAP.TR_TR; } /** - * @param {String} carrier - * @return {DeviceInfo} - */ + * Polish - Poland + * @return {String} + */ - setCarrier(carrier) { - this.validateType(String, carrier); - this.setParameter(DeviceInfo.KEY_CARRIER, carrier); - return this; + static get PL_PL() { + return Language._MAP.PL_PL; } /** - * @return {String} - */ + * French - France + * @return {String} + */ - getCarrier() { - return this.getParameter(DeviceInfo.KEY_CARRIER); + static get FR_FR() { + return Language._MAP.FR_FR; } /** - * @param {Number} maxNumberRFCOMMPorts - * @return {DeviceInfo} - */ + * Italian - Italy + * @return {String} + */ - setMaxNumberRFCOMMPorts(maxNumberRFCOMMPorts) { - this.validateType(Number, maxNumberRFCOMMPorts); - this.setParameter(DeviceInfo.KEY_MAX_NUMBER_RFCOMM_PORTS, maxNumberRFCOMMPorts); - return this; + static get IT_IT() { + return Language._MAP.IT_IT; } /** - * @return {Number} - */ + * Swedish - Sweden + * @return {String} + */ - getMaxNumberRFCOMMPorts() { - return this.getParameter(DeviceInfo.KEY_MAX_NUMBER_RFCOMM_PORTS); + static get SV_SE() { + return Language._MAP.SV_SE; } + /** + * Portuguese - Portugal + * @return {String} + */ - } - - DeviceInfo.KEY_HARDWARE = 'hardware'; - DeviceInfo.KEY_FIRMWARE_REV = 'firmwareRev'; - DeviceInfo.KEY_OS = 'os'; - DeviceInfo.KEY_OS_VERSION = 'osVersion'; - DeviceInfo.KEY_CARRIER = 'carrier'; - DeviceInfo.KEY_MAX_NUMBER_RFCOMM_PORTS = 'maxNumberRFCOMMPorts'; - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - class AppInfo extends RpcStruct { - constructor(parameters) { - super(parameters); + static get PT_PT() { + return Language._MAP.PT_PT; } /** - * @param {String} appDisplayName - * @return {AppInfo} - */ + * Dutch (Standard) - Netherlands + * @return {String} + */ - setAppDisplayName(appDisplayName) { - this.setParameter(AppInfo.KEY_APP_DISPLAY_NAME, appDisplayName); - return this; + static get NL_NL() { + return Language._MAP.NL_NL; } /** - * @return {String} - */ + * English - Australia + * @return {String} + */ - getAppDisplayName() { - return this.getParameter(AppInfo.KEY_APP_DISPLAY_NAME); + static get EN_AU() { + return Language._MAP.EN_AU; } /** - * @param {String} appBundleID - * @return {AppInfo} - */ + * Mandarin - China + * @return {String} + */ - setAppBundleID(appBundleID) { - this.setParameter(AppInfo.KEY_APP_BUNDLE_ID, appBundleID); - return this; + static get ZH_CN() { + return Language._MAP.ZH_CN; } /** - * @return {String} - */ + * Mandarin - Taiwan + * @return {String} + */ - getAppBundleID() { - return this.getParameter(AppInfo.KEY_APP_BUNDLE_ID); + static get ZH_TW() { + return Language._MAP.ZH_TW; } /** - * @param {String} appVersion - * @return {AppInfo} - */ + * Japanese - Japan + * @return {String} + */ - setAppVersion(appVersion) { - this.setParameter(AppInfo.KEY_APP_VERSION, appVersion); - return this; + static get JA_JP() { + return Language._MAP.JA_JP; } /** - * @return {String} - */ + * Arabic - Saudi Arabia + * @return {String} + */ - getAppVersion() { - return this.getParameter(AppInfo.KEY_APP_VERSION); + static get AR_SA() { + return Language._MAP.AR_SA; } /** - * @param {String} appIcon string of the app icon file name - * @return {AppInfo} - */ + * Korean - South Korea + * @return {String} + */ - setAppIcon(appIcon) { - this.setParameter(AppInfo.KEY_APP_ICON, appIcon); - return this; + static get KO_KR() { + return Language._MAP.KO_KR; } /** - * @return {String} - */ + * Portuguese - Brazil + * @return {String} + */ - getAppIcon() { - return this.getParameter(AppInfo.KEY_APP_ICON); + static get PT_BR() { + return Language._MAP.PT_BR; } + /** + * Czech - Czech Republic + * @return {String} + */ - } - - AppInfo.KEY_APP_DISPLAY_NAME = 'appDisplayName'; - AppInfo.KEY_APP_BUNDLE_ID = 'appBundleID'; - AppInfo.KEY_APP_VERSION = 'appVersion'; - AppInfo.KEY_APP_ICON = 'appIcon'; - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - class RGBColor extends RpcStruct { - constructor(parameters) { - super(parameters); + static get CS_CZ() { + return Language._MAP.CS_CZ; } /** - * @param {Number} redValue - * @return {RGBColor} - */ + * Danish - Denmark + * @return {String} + */ - setRedValue(redValue) { - this.setParameter(RGBColor.KEY_RED, redValue); - return this; + static get DA_DK() { + return Language._MAP.DA_DK; } /** - * @return {Number} - */ + * Norwegian - Norway + * @return {String} + */ - getRedValue() { - return this.getParameter(RGBColor.KEY_RED); + static get NO_NO() { + return Language._MAP.NO_NO; } /** - * @param {Number} greenValue - * @return {RGBColor} - */ + * Dutch (Flemish) - Belgium + * @return {String} + */ - setGreenValue(greenValue) { - this.setParameter(RGBColor.KEY_GREEN, greenValue); - return this; + static get NL_BE() { + return Language._MAP.NL_BE; } /** - * @return {Number} - */ + * Greek - Greece + * @return {String} + */ - getGreenValue() { - return this.getParameter(RGBColor.KEY_GREEN); + static get EL_GR() { + return Language._MAP.EL_GR; } /** - * @param {Number} blueValue - * @return {RGBColor} - */ + * Hungarian - Hungary + * @return {String} + */ - setBlueValue(blueValue) { - this.setParameter(RGBColor.KEY_BLUE, blueValue); - return this; + static get HU_HU() { + return Language._MAP.HU_HU; } /** - * @return {Number} - */ + * Finnish - Finland + * @return {String} + */ - getBlueValue() { - return this.getParameter(RGBColor.KEY_BLUE); + static get FI_FI() { + return Language._MAP.FI_FI; } + /** + * Slovak - Slovakia + * @return {String} + */ - } - - RGBColor.KEY_RED = 'red'; - RGBColor.KEY_GREEN = 'green'; - RGBColor.KEY_BLUE = 'blue'; - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - class TemplateColorScheme extends RpcStruct { - constructor(parameters) { - super(parameters); + static get SK_SK() { + return Language._MAP.SK_SK; } /** - * @param {RGBColor} primaryColor - * @return {TemplateColorScheme} - */ + * English - India + * @return {String} + */ - setPrimaryColor(primaryColor) { - this.validateType(RGBColor, primaryColor); - this.setParameter(TemplateColorScheme.KEY_PRIMARY_COLOR, primaryColor); - return this; + static get EN_IN() { + return Language._MAP.EN_IN; } /** - * @return {RGBColor} - */ + * Thai - Thailand + * @return {String} + */ - getPrimaryColor() { - return this.getObject(RGBColor, TemplateColorScheme.KEY_PRIMARY_COLOR); + static get TH_TH() { + return Language._MAP.TH_TH; } /** - * @param {RGBColor} secondaryColor - * @return {TemplateColorScheme} - */ + * English - Middle East + * @return {String} + */ - setSecondaryColor(secondaryColor) { - this.validateType(RGBColor, secondaryColor); - this.setParameter(TemplateColorScheme.KEY_SECONDARY_COLOR, secondaryColor); - return this; + static get EN_SA() { + return Language._MAP.EN_SA; } /** - * @return {RGBColor} - */ + * Hebrew - Israel + * @return {String} + */ - getSecondaryColor() { - return this.getObject(RGBColor, TemplateColorScheme.KEY_SECONDARY_COLOR); - } + static get HE_IL() { + return Language._MAP.HE_IL; + } /** - * @param {RGBColor} backgroundColor - * @return {TemplateColorScheme} - */ + * Romanian - Romania + * @return {String} + */ - setBackgroundColor(backgroundColor) { - this.validateType(RGBColor, backgroundColor); - this.setParameter(TemplateColorScheme.KEY_BACKGROUND_COLOR, backgroundColor); - return this; + static get RO_RO() { + return Language._MAP.RO_RO; } /** - * @return {RGBColor} - */ + * Ukrainian - Ukraine + * @return {String} + */ - getBackgroundColor() { - return this.getObject(RGBColor, TemplateColorScheme.KEY_BACKGROUND_COLOR); + static get UK_UA() { + return Language._MAP.UK_UA; + } + /** + * Indonesian - Indonesia + * @return {String} + */ + + + static get ID_ID() { + return Language._MAP.ID_ID; + } + /** + * Vietnamese - Vietnam + * @return {String} + */ + + + static get VI_VN() { + return Language._MAP.VI_VN; + } + /** + * Malay - Malaysia + * @return {String} + */ + + + static get MS_MY() { + return Language._MAP.MS_MY; + } + /** + * Hindi - India + * @return {String} + */ + + + static get HI_IN() { + return Language._MAP.HI_IN; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return Language._valueForKey(key, Language._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return Language._keyForValue(value, Language._MAP); } } - TemplateColorScheme.KEY_PRIMARY_COLOR = 'primaryColor'; - TemplateColorScheme.KEY_SECONDARY_COLOR = 'secondaryColor'; - TemplateColorScheme.KEY_BACKGROUND_COLOR = 'backgroundColor'; + Language._MAP = Object.freeze({ + 'EN_US': 'EN-US', + 'ES_MX': 'ES-MX', + 'FR_CA': 'FR-CA', + 'DE_DE': 'DE-DE', + 'ES_ES': 'ES-ES', + 'EN_GB': 'EN-GB', + 'RU_RU': 'RU-RU', + 'TR_TR': 'TR-TR', + 'PL_PL': 'PL-PL', + 'FR_FR': 'FR-FR', + 'IT_IT': 'IT-IT', + 'SV_SE': 'SV-SE', + 'PT_PT': 'PT-PT', + 'NL_NL': 'NL-NL', + 'EN_AU': 'EN-AU', + 'ZH_CN': 'ZH-CN', + 'ZH_TW': 'ZH-TW', + 'JA_JP': 'JA-JP', + 'AR_SA': 'AR-SA', + 'KO_KR': 'KO-KR', + 'PT_BR': 'PT-BR', + 'CS_CZ': 'CS-CZ', + 'DA_DK': 'DA-DK', + 'NO_NO': 'NO-NO', + 'NL_BE': 'NL-BE', + 'EL_GR': 'EL-GR', + 'HU_HU': 'HU-HU', + 'FI_FI': 'FI-FI', + 'SK_SK': 'SK-SK', + 'EN_IN': 'EN-IN', + 'TH_TH': 'TH-TH', + 'EN_SA': 'EN-SA', + 'HE_IL': 'HE-IL', + 'RO_RO': 'RO-RO', + 'UK_UA': 'UK-UA', + 'ID_ID': 'ID-ID', + 'VI_VN': 'VI-VN', + 'MS_MY': 'MS-MY', + 'HI_IN': 'HI-IN' + }); /* * Copyright (c) 2019, Livio, Inc. @@ -2657,928 +2626,793 @@ * POSSIBILITY OF SUCH DAMAGE. */ /** - * @typedef {Enum} Language - * @property {Object} _MAP + * @typedef {Object} RpcMessage + * @property {RpcType} rpcType */ - class Language extends Enum { - /** - * @constructor - */ - constructor() { - super(); + class RpcMessage extends RpcStruct { + /* + { + "rpcType": "Request", + "functionName": "RegisterAppInterface", + "coorelationID": "320948", + "isEncrypted": false, + "parameters": { + "appName": "Hello" + }, + "bulkData": "...", } - /** - * @return {String} - */ - + */ - static get EN_SA() { - return Language._MAP.EN_SA; + /** + * @constructor + */ + constructor(store = {}) { + super(store.parameters); + this._isEncrypted = false; + this._rpcType = store.rpcType; + this._functionName = store.functionName; + this._correlationID = store.correlationID; + this.setBulkData(store.bulkData); } /** - * @return {String} - */ + * @return {RpcType} + */ - static get HE_IL() { - return Language._MAP.HE_IL; + getRPCType() { + return this._rpcType; } /** - * @return {String} - */ + * @param {RpcType} type + * @return {RpcMessage} + */ - static get RO_RO() { - return Language._MAP.RO_RO; + setRPCType(type) { + this._rpcType = type; + return this; } /** - * @return {String} - */ + * @return {FunctionID} type + */ - static get UK_UA() { - return Language._MAP.UK_UA; + getFunctionName() { + return this._functionName; } /** - * @return {String} - */ + * @param {FunctionID} name + * @return {RpcMessage} + */ - static get ID_ID() { - return Language._MAP.ID_ID; + setFunctionName(name) { + if (typeof name !== 'string') { + this._functionName = FunctionID.keyForValue(name); + } else { + this._functionName = name; + } + + return this; } /** - * @return {String} - */ + * @return {String} type + */ - static get VI_VN() { - return Language._MAP.VI_VN; + getCorrelationId() { + return this._correlationID; } /** - * @return {String} - */ + * @param {String} name + * @return {RpcMessage} + */ - static get MS_MY() { - return Language._MAP.MS_MY; + setCorrelationId(id) { + this._correlationID = id; + return this; } /** - * @return {String} - */ + * @return {Uint8Array} data + */ - static get HI_IN() { - return Language._MAP.HI_IN; + getBulkData() { + return this._bulkData; } /** - * @return {String} - */ + * @param {UInt8Array} data + * @return {RpcMessage} + */ - static get NL_BE() { - return Language._MAP.NL_BE; + setBulkData(data = null) { + if (data !== null) { + this._bulkData = data.slice(0); + } else { + this._bulkData = null; + } + + return this; } /** - * @return {String} - */ + * @return {Boolean} + */ - static get EL_GR() { - return Language._MAP.EL_GR; + getIsEncrypted() { + return this._isEncrypted; } /** - * @return {String} - */ + * @param {Boolean} bool + * @return {RpcMessage} + */ - static get HU_HU() { - return Language._MAP.HU_HU; + setIsEncrypted(bool) { + this._isEncrypted = bool; + return this; } - /** - * @return {String} - */ + } - static get FI_FI() { - return Language._MAP.FI_FI; + /* + * Copyright (c) 2019, Livio, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Livio Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + /** + * @typedef {Enum} RpcType + * @property {Object} _MAP + */ + + class RpcType extends Enum { + /** + * @constructor + */ + constructor() { + super(); } /** - * @return {String} + * @return {Number} */ - static get SK_SK() { - return Language._MAP.SK_SK; + static get NOTIFICATION() { + return RpcType._MAP.NOTIFICATION; } /** - * @return {String} + * @return {Number} */ - static get EN_US() { - return Language._MAP.EN_US; + static get RESPONSE() { + return RpcType._MAP.RESPONSE; } /** - * @return {String} + * @return {Number} */ - static get ES_MX() { - return Language._MAP.ES_MX; + static get REQUEST() { + return RpcType._MAP.REQUEST; } /** - * @return {String} - */ + * Get the value for the given enum key + * @param value - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ - static get FR_CA() { - return Language._MAP.FR_CA; + static valueForKey(key) { + return RpcType._valueForKey(key, RpcType._MAP); } /** - * @return {String} - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ - static get DE_DE() { - return Language._MAP.DE_DE; + static keyForValue(value) { + return RpcType._keyForValue(value, RpcType._MAP); } - /** - * @return {String} - */ + } - static get ES_ES() { - return Language._MAP.ES_ES; - } - /** - * @return {String} - */ + RpcType._MAP = Object.freeze({ + 'NOTIFICATION': 0x2, + 'RESPONSE': 0x1, + 'REQUEST': 0x0 + }); + /* + * Copyright (c) 2019, Livio, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Livio Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ - static get EN_GB() { - return Language._MAP.EN_GB; + class RpcRequest extends RpcMessage { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setRPCType(RpcType.REQUEST); + this._promise = null; } /** - * @return {String} - */ + * @return {Promise} + */ - static get RU_RU() { - return Language._MAP.RU_RU; + getOnRPCResponsePromise() { + return this._promise; } /** - * @return {String} - */ + * @param {Promise} promise + * @return {RpcMessage} + */ - static get TR_TR() { - return Language._MAP.TR_TR; + setOnRPCResponsePromise(promise) { + this.validateType(Promise, promise); + this._promise = promise; + return this; } - /** - * @return {String} - */ + } + + /* eslint-disable camelcase */ + /** + * Various information about connecting device. + */ - static get PL_PL() { - return Language._MAP.PL_PL; - } + class DeviceInfo extends RpcStruct { /** - * @return {String} + * @constructor */ - - - static get FR_FR() { - return Language._MAP.FR_FR; + constructor(parameters) { + super(parameters); } /** - * @return {String} + * @param {String} hardware - Device model + * @return {DeviceInfo} */ - static get IT_IT() { - return Language._MAP.IT_IT; + setHardware(hardware) { + this.setParameter(DeviceInfo.KEY_HARDWARE, hardware); + return this; } /** * @return {String} */ - static get SV_SE() { - return Language._MAP.SV_SE; + getHardware() { + return this.getParameter(DeviceInfo.KEY_HARDWARE); } /** - * @return {String} + * @param {String} rev - Device firmware revision + * @return {DeviceInfo} */ - static get PT_PT() { - return Language._MAP.PT_PT; + setFirmwareRev(rev) { + this.setParameter(DeviceInfo.KEY_FIRMWARE_REV, rev); + return this; } /** * @return {String} */ - static get NL_NL() { - return Language._MAP.NL_NL; + getFirmwareRev() { + return this.getParameter(DeviceInfo.KEY_FIRMWARE_REV); } /** - * @return {String} + * @param {String} os - Device OS + * @return {DeviceInfo} */ - static get EN_AU() { - return Language._MAP.EN_AU; + setOs(os) { + this.setParameter(DeviceInfo.KEY_OS, os); + return this; } /** * @return {String} */ - static get ZH_CN() { - return Language._MAP.ZH_CN; + getOs() { + return this.getParameter(DeviceInfo.KEY_OS); } /** - * @return {String} + * @param {String} version - Device OS version + * @return {DeviceInfo} */ - static get ZH_TW() { - return Language._MAP.ZH_TW; + setOsVersion(version) { + this.setParameter(DeviceInfo.KEY_OS_VERSION, version); + return this; } /** * @return {String} */ - static get JA_JP() { - return Language._MAP.JA_JP; + getOsVersion() { + return this.getParameter(DeviceInfo.KEY_OS_VERSION); } /** - * @return {String} + * @param {String} carrier - Device mobile carrier (if applicable) + * @return {DeviceInfo} */ - static get AR_SA() { - return Language._MAP.AR_SA; + setCarrier(carrier) { + this.setParameter(DeviceInfo.KEY_CARRIER, carrier); + return this; } /** * @return {String} */ - static get KO_KR() { - return Language._MAP.KO_KR; + getCarrier() { + return this.getParameter(DeviceInfo.KEY_CARRIER); } /** - * @return {String} + * @param {Number} ports - Omitted if connected not via BT. + * @return {DeviceInfo} */ - static get PT_BR() { - return Language._MAP.PT_BR; + setMaxNumberRFCOMMPorts(ports) { + this.setParameter(DeviceInfo.KEY_MAX_NUMBER_RFCOMM_PORTS, ports); + return this; } /** - * @return {String} + * @return {Number} */ - static get CS_CZ() { - return Language._MAP.CS_CZ; + getMaxNumberRFCOMMPorts() { + return this.getParameter(DeviceInfo.KEY_MAX_NUMBER_RFCOMM_PORTS); } - /** - * @return {String} - */ + } - static get DA_DK() { - return Language._MAP.DA_DK; - } - /** - * @return {String} - */ + DeviceInfo.KEY_HARDWARE = 'hardware'; + DeviceInfo.KEY_FIRMWARE_REV = 'firmwareRev'; + DeviceInfo.KEY_OS = 'os'; + DeviceInfo.KEY_OS_VERSION = 'osVersion'; + DeviceInfo.KEY_CARRIER = 'carrier'; + DeviceInfo.KEY_MAX_NUMBER_RFCOMM_PORTS = 'maxNumberRFCOMMPorts'; + /* eslint-disable camelcase */ + /** + * Establishes an interface with a mobile application. Before registerAppInterface no other commands will be + * accepted/executed. + */ - static get NO_NO() { - return Language._MAP.NO_NO; - } + class RegisterAppInterface extends RpcRequest { /** - * @return {String} + * @constructor */ - - - static get EN_IN() { - return Language._MAP.EN_IN; + constructor(store) { + super(store); + this.setFunctionName(FunctionID.RegisterAppInterface); } /** - * @return {String} + * @param {String} fullAppId + * @return {RegisterAppInterface} */ - static get TH_TH() { - return Language._MAP.TH_TH; - } - /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ - - - static valueForKey(key) { - return Language._valueForKey(key, Language._MAP); - } - /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ - - - static keyForValue(value) { - return Language._keyForValue(value, Language._MAP); - } - - } - - Language._MAP = Object.freeze({ - 'EN_SA': 'EN-SA', - 'HE_IL': 'HE-IL', - 'RO_RO': 'RO-RO', - 'UK_UA': 'UK-UA', - 'ID_ID': 'ID-ID', - 'VI_VN': 'VI-VN', - 'MS_MY': 'MS-MY', - 'HI_IN': 'HI-IN', - 'NL_BE': 'NL-BE', - 'EL_GR': 'EL-GR', - 'HU_HU': 'HU-HU', - 'FI_FI': 'FI-FI', - 'SK_SK': 'SK-SK', - 'EN_US': 'EN-US', - 'ES_MX': 'ES-MX', - 'FR_CA': 'FR-CA', - 'DE_DE': 'DE-DE', - 'ES_ES': 'ES-ES', - 'EN_GB': 'EN-GB', - 'RU_RU': 'RU-RU', - 'TR_TR': 'TR-TR', - 'PL_PL': 'PL-PL', - 'FR_FR': 'FR-FR', - 'IT_IT': 'IT-IT', - 'SV_SE': 'SV-SE', - 'PT_PT': 'PT-PT', - 'NL_NL': 'NL-NL', - 'EN_AU': 'EN-AU', - 'ZH_CN': 'ZH-CN', - 'ZH_TW': 'ZH-TW', - 'JA_JP': 'JA-JP', - 'AR_SA': 'AR-SA', - 'KO_KR': 'KO-KR', - 'PT_BR': 'PT-BR', - 'CS_CZ': 'CS-CZ', - 'DA_DK': 'DA-DK', - 'NO_NO': 'NO-NO', - 'EN_IN': 'EN-IN', - 'TH_TH': 'TH-TH' - }); - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - /** - * @typedef {Enum} AppHMIType - * @property {Object} _MAP - */ - - class AppHMIType extends Enum { - constructor() { - super(); - } - /** - * @return {String} - */ - - - static get DEFAULT() { - return AppHMIType._MAP.DEFAULT; - } - /** - * @return {String} - */ - - - static get COMMUNICATION() { - return AppHMIType._MAP.COMMUNICATION; - } - /** - * @return {String} - */ - - - static get MEDIA() { - return AppHMIType._MAP.MEDIA; - } - /** - * @return {String} - */ - - - static get MESSAGING() { - return AppHMIType._MAP.MESSAGING; - } - /** - * @return {String} - */ - - - static get NAVIGATION() { - return AppHMIType._MAP.NAVIGATION; - } - /** - * @return {String} - */ - - - static get INFORMATION() { - return AppHMIType._MAP.INFORMATION; - } - /** - * @return {String} - */ + setFullAppId(fullAppId) { + this.validateType(String, fullAppId); + if (fullAppId !== null) { + fullAppId = fullAppId.toLowerCase(); + this.setParameter(RegisterAppInterface.KEY_FULL_APP_ID, fullAppId); + let appID; - static get SOCIAL() { - return AppHMIType._MAP.SOCIAL; - } - /** - * @return {String} - */ + if (fullAppId.length <= RegisterAppInterface.APP_ID_MAX_LENGTH) { + appID = fullAppId; + } else { + appID = fullAppId.replace('-', '').substring(0, RegisterAppInterface.APP_ID_MAX_LENGTH); + } + this._setAppId(appID); + } else { + this.setParameter(RegisterAppInterface.KEY_FULL_APP_ID, null); + } - static get BACKGROUND_PROCESS() { - return AppHMIType._MAP.BACKGROUND_PROCESS; + return this; } /** - * @return {String} + * @return {String} the app id */ - static get TESTING() { - return AppHMIType._MAP.TESTING; + getFullAppId() { + return this.getParameter(RegisterAppInterface.KEY_FULL_APP_ID); } /** - * @return {String} + * @param {String} appId - This method should not be accessed directly by developers. Only set the full ID and this + * param will be set. + * @return {RegisterAppInterface} */ - static get SYSTEM() { - return AppHMIType._MAP.SYSTEM; + _setAppId(appId) { + this.validateType(String, appId); + this.setParameter(RegisterAppInterface.KEY_APP_ID, appId); + return this; } /** - * @return {String} + * @return {String} the app id */ - static get PROJECTION() { - return AppHMIType._MAP.PROJECTION; + getAppId() { + return this.getParameter(RegisterAppInterface.KEY_APP_ID); } /** - * @return {String} + * @param {SdlMsgVersion} version - See SyncMsgVersion + * @return {RegisterAppInterface} */ - static get REMOTE_CONTROL() { - return AppHMIType._MAP.REMOTE_CONTROL; - } - /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ - - - static valueForKey(key) { - return AppHMIType._valueForKey(key, AppHMIType._MAP); - } - /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ - - - static keyForValue(value) { - return AppHMIType._keyForValue(value, AppHMIType._MAP); - } - - } - - AppHMIType._MAP = Object.freeze({ - 'DEFAULT': 'DEFAULT', - 'COMMUNICATION': 'COMMUNICATION', - 'MEDIA': 'MEDIA', - 'MESSAGING': 'MESSAGING', - 'NAVIGATION': 'NAVIGATION', - 'INFORMATION': 'INFORMATION', - 'SOCIAL': 'SOCIAL', - 'BACKGROUND_PROCESS': 'BACKGROUND_PROCESS', - 'TESTING': 'TESTING', - 'SYSTEM': 'SYSTEM', - 'PROJECTION': 'PROJECTION', - 'REMOTE_CONTROL': 'REMOTE_CONTROL' - }); - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - class RegisterAppInterface extends RpcRequest { - constructor(store) { - super(store); - this.setFunctionName(FunctionID.RegisterAppInterface); - } - /** - * @param {SdlMsgVersion} The max RPC Spec version supported by this library - * @return {RegisterAppInterface} - */ - - - setSdlMsgVersion(sdlMsgVersion) { - this.validateType(SdlMsgVersion, sdlMsgVersion); - this.setParameter(RegisterAppInterface.KEY_SDL_MSG_VERSION, sdlMsgVersion); + setSdlMsgVersion(version) { + this.validateType(SdlMsgVersion, version); + this.setParameter(RegisterAppInterface.KEY_SDL_MSG_VERSION, version); return this; } /** - * @return {SdlMsgVersion} - */ + * @return {SdlMsgVersion} + */ getSdlMsgVersion() { return this.getObject(SdlMsgVersion, RegisterAppInterface.KEY_SDL_MSG_VERSION); } /** - * @param {String} appName the name of the app that is registering - * @return {RegisterAppInterface} - */ + * @param {String} name - The mobile application name, e.g. "My SDL App". Needs to be unique over all applications + * from the same device. May not be empty. May not start with a new line character. May not + * interfere with any name or synonym of previously registered applications from the same + * device and any predefined blacklist of words (global commands) Additional applications + * with the same name from the same device will be rejected. Only characters from char set + * @return {RegisterAppInterface} + */ - setAppName(appName) { - this.validateType(String, appName); - this.setParameter(RegisterAppInterface.KEY_APP_NAME, appName); + setAppName(name) { + this.setParameter(RegisterAppInterface.KEY_APP_NAME, name); return this; } /** - * @return {String} the app name - */ + * @return {String} + */ getAppName() { return this.getParameter(RegisterAppInterface.KEY_APP_NAME); } /** - * @param {Array} ttsNames TTS string for VR recognition of the mobile application name, e.g. "My S D L App". - * Meant to overcome any failing on speech engine in properly pronouncing / understanding - * app name. Needs to be unique over all applications from the same device. May not be - * empty. May not start with a new line character. Only characters from char set - * @return {RegisterAppInterface} - */ + * @param {TTSChunk[]} name - TTS string for VR recognition of the mobile application name, e.g. "My S D L App". + * Meant to overcome any failing on speech engine in properly pronouncing / understanding + * app name. Needs to be unique over all applications from the same device. May not be + * empty. May not start with a new line character. Only characters from char set + * @return {RegisterAppInterface} + */ - setTtsName(ttsNames) { - this.setParameter(RegisterAppInterface.KEY_TTS_NAME, ttsNames); + setTtsName(name) { + this.validateType(TTSChunk, name, true); + this.setParameter(RegisterAppInterface.KEY_TTS_NAME, name); return this; } /** - * @return {Array} - */ + * @return {TTSChunk[]} + */ getTtsName() { return this.getObject(TTSChunk, RegisterAppInterface.KEY_TTS_NAME); } /** - * @param {String} ngnppName Provides an abbreviated version of the app name (if needed), that will be displayed - * on the NGN media screen. If not provided, the appName is used instead (and - * will be truncated if too long)Only characters from char set. - * @return {RegisterAppInterface} - */ + * @param {String} name - Provides an abbreviated version of the app name (if needed), that will be displayed on the + * NGN media screen. If not provided, the appName is used instead (and will be truncated if + * too long) Only characters from char set + * @return {RegisterAppInterface} + */ - setNgnMediaScreenAppName(ngnppName) { - this.validateType(String, ngnppName); - this.setParameter(RegisterAppInterface.KEY_NGN_MEDIA_SCREEN_APP_NAME, ngnppName); + setNgnMediaScreenAppName(name) { + this.setParameter(RegisterAppInterface.KEY_NGN_MEDIA_SCREEN_APP_NAME, name); return this; } /** - * @return {String} an abbreviated version of the app name - */ + * @return {String} + */ getNgnMediaScreenAppName() { return this.getParameter(RegisterAppInterface.KEY_NGN_MEDIA_SCREEN_APP_NAME); } /** - * @param {Array} vrSynonyms Defines an additional voice recognition command. May not - * interfere with any app name of previously registered applications - * from the same device and any predefined blacklist of words (global - * commands)Only characters from char set - * @return {RegisterAppInterface} - */ + * @param {String[]} synonyms - Defines an additional voice recognition command. May not interfere with any app name + * of previously registered applications from the same device and any predefined + * blacklist of words (global commands) Only characters from char set + * @return {RegisterAppInterface} + */ - setVrSynonyms(vrSynonyms) { - this.setParameter(RegisterAppInterface.KEY_VR_SYNONYMS, vrSynonyms); + setVrSynonyms(synonyms) { + this.setParameter(RegisterAppInterface.KEY_VR_SYNONYMS, synonyms); return this; } /** - * @return {Array} - */ + * @return {String[]} + */ getVrSynonyms() { return this.getParameter(RegisterAppInterface.KEY_VR_SYNONYMS); } /** - * @param {Boolean} isMediaApplication Indicates if the application is a media or a non-media application. - * Only media applications will be able to stream audio to the module - * that is audible outside of the BT media source. - * @return {RegisterAppInterface} - */ + * @param {Boolean} application - Indicates if the application is a media or a non-media application. Only media + * applications will be able to stream audio to the module that is audible outside of + * the BT media source. + * @return {RegisterAppInterface} + */ - setIsMediaApplication(isMediaApplication) { - this.setParameter(RegisterAppInterface.KEY_IS_MEDIA_APPLICATION, isMediaApplication); + setIsMediaApplication(application) { + this.setParameter(RegisterAppInterface.KEY_IS_MEDIA_APPLICATION, application); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ getIsMediaApplication() { return this.getParameter(RegisterAppInterface.KEY_IS_MEDIA_APPLICATION); } /** - * @param {Language} languageDesired - * @return {RegisterAppInterface} - */ + * @param {Language} desired - See Language Current app's expected VR+TTS language If there is a mismatch with the + * module, the app will be able to change this registration with changeRegistration + * prior to app being brought into focus. + * @return {RegisterAppInterface} + */ - setLanguageDesired(languageDesired) { - this.validateType(Language, languageDesired); - this.setParameter(RegisterAppInterface.KEY_LANGUAGE_DESIRED, languageDesired); + setLanguageDesired(desired) { + this.validateType(Language, desired); + this.setParameter(RegisterAppInterface.KEY_LANGUAGE_DESIRED, desired); return this; } /** - * @return {Language} - */ + * @return {Language} + */ getLanguageDesired() { return this.getObject(Language, RegisterAppInterface.KEY_LANGUAGE_DESIRED); } /** - * @param {Language} hmiDisplayLanguageDesired - * @return {RegisterAppInterface} - */ + * @param {Language} desired - See Language Current app's expected display language If there is a mismatch with the + * module, the app will be able to change this registration with changeRegistration + * prior to app being brought into focus. + * @return {RegisterAppInterface} + */ - setHmiDisplayLanguageDesired(hmiDisplayLanguageDesired) { - this.validateType(Language, hmiDisplayLanguageDesired); - this.setParameter(RegisterAppInterface.KEY_HMI_DISPLAY_LANGUAGE_DESIRED, hmiDisplayLanguageDesired); + setHmiDisplayLanguageDesired(desired) { + this.validateType(Language, desired); + this.setParameter(RegisterAppInterface.KEY_HMI_DISPLAY_LANGUAGE_DESIRED, desired); return this; } /** - * @return {Language} - */ + * @return {Language} + */ getHmiDisplayLanguageDesired() { return this.getObject(Language, RegisterAppInterface.KEY_HMI_DISPLAY_LANGUAGE_DESIRED); } /** - * @param {Array} appHMIType - * @return {RegisterAppInterface} - */ + * @param {AppHMIType[]} type - See AppHMIType List of all applicable app HMI types stating which HMI + * classifications to be given to the app. + * @return {RegisterAppInterface} + */ - setAppHmiType(appHMIType) { - // TODO make validate type accept arrays - // this.validateType(AppHMIType, appHMIType); - this.setParameter(RegisterAppInterface.KEY_APP_HMI_TYPE, appHMIType); + setAppHMIType(type) { + this.validateType(AppHMIType, type, true); + this.setParameter(RegisterAppInterface.KEY_APP_HMI_TYPE, type); return this; } /** - * @return {Array} - */ + * @return {AppHMIType[]} + */ - getAppHmiType() { + getAppHMIType() { return this.getObject(AppHMIType, RegisterAppInterface.KEY_APP_HMI_TYPE); } /** - * @param {String} hashID the hash ID - * @return {RegisterAppInterface} - */ + * @param {String} id - ID used to uniquely identify current state of all app data that can persist through + * connection cycles (e.g. ignition cycles). This registered data (commands, submenus, choice + * sets, etc.) can be reestablished without needing to explicitly reregister each piece. If + * omitted, then the previous state of an app's commands, etc. will not be restored. When + * sending hashID, all RegisterAppInterface parameters should still be provided (e.g. ttsName, + * etc.). + * @return {RegisterAppInterface} + */ - setHashID(hashID) { - this.validateType(String, hashID); - this.setParameter(RegisterAppInterface.KEY_HASH_ID, hashID); + setHashID(id) { + this.setParameter(RegisterAppInterface.KEY_HASH_ID, id); return this; } /** - * @return {String} the hash ID - */ + * @return {String} + */ getHashID() { return this.getParameter(RegisterAppInterface.KEY_HASH_ID); } /** - * @param {DeviceInfo} deviceInfo + * @param {DeviceInfo} info - See DeviceInfo. * @return {RegisterAppInterface} */ - setDeviceInfo(deviceInfo) { - this.validateType(DeviceInfo, deviceInfo); - this.setParameter(RegisterAppInterface.KEY_DEVICE_INFO, deviceInfo); + setDeviceInfo(info) { + this.validateType(DeviceInfo, info); + this.setParameter(RegisterAppInterface.KEY_DEVICE_INFO, info); return this; } /** - * @return {DeviceInfo} - */ + * @return {DeviceInfo} + */ getDeviceInfo() { return this.getObject(DeviceInfo, RegisterAppInterface.KEY_DEVICE_INFO); } /** - * @param {String} appName This method should not be accessed directly by developers. Only set the full ID and this param will be set. - * @return {RegisterAppInterface} - */ - - - _setAppId(appId) { - this.validateType(String, appId); - this.setParameter(RegisterAppInterface.KEY_APP_ID, appId); - return this; - } - /** - * @return {String} the app id - */ - - - getAppId() { - return this.getParameter(RegisterAppInterface.KEY_APP_ID); - } - /** - * @param {String} fullAppId - * @return {RegisterAppInterface} - */ - - - setFullAppId(fullAppId) { - this.validateType(String, fullAppId); - - if (fullAppId !== null) { - fullAppId = fullAppId.toLowerCase(); - this.setParameter(RegisterAppInterface.KEY_FULL_APP_ID, fullAppId); - let appId; - - if (fullAppId.length <= RegisterAppInterface.APP_ID_MAX_LENGTH) { - appId = fullAppId; - } else { - appId = fullAppId.replace('-', '').substring(0, RegisterAppInterface.APP_ID_MAX_LENGTH); - } + * @param {String} id - ID used to validate app with policy table entries + * @return {RegisterAppInterface} + */ - this._setAppId(appId); - } else { - this.setParameter(RegisterAppInterface.KEY_FULL_APP_ID, null); - } + setFullAppID(id) { + this.setParameter(RegisterAppInterface.KEY_FULL_APP_ID, id); return this; } /** - * @return {String} the app id - */ + * @return {String} + */ - getFullAppId() { + getFullAppID() { return this.getParameter(RegisterAppInterface.KEY_FULL_APP_ID); } /** - * @param {AppInfo} appInfo + * @param {AppInfo} info - See AppInfo. * @return {RegisterAppInterface} */ - setAppInfo(appInfo) { - this.validateType(AppInfo, appInfo); - this.setParameter(RegisterAppInterface.KEY_APP_INFO, appInfo); + setAppInfo(info) { + this.validateType(AppInfo, info); + this.setParameter(RegisterAppInterface.KEY_APP_INFO, info); return this; } /** - * @return {AppInfo} - */ + * @return {AppInfo} + */ getAppInfo() { return this.getObject(AppInfo, RegisterAppInterface.KEY_APP_INFO); } /** - * @param {TemplateColorScheme} dayColorScheme + * @param {TemplateColorScheme} scheme - A color scheme for all display layout templates. * @return {RegisterAppInterface} */ - setDayColorScheme(dayColorScheme) { - this.validateType(TemplateColorScheme, dayColorScheme); - this.setParameter(RegisterAppInterface.KEY_DAY_COLOR_SCHEME, dayColorScheme); + setDayColorScheme(scheme) { + this.validateType(TemplateColorScheme, scheme); + this.setParameter(RegisterAppInterface.KEY_DAY_COLOR_SCHEME, scheme); return this; } /** - * @return {TemplateColorScheme} - */ + * @return {TemplateColorScheme} + */ getDayColorScheme() { return this.getObject(TemplateColorScheme, RegisterAppInterface.KEY_DAY_COLOR_SCHEME); } /** - * @param {TemplateColorScheme} nightColorScheme + * @param {TemplateColorScheme} scheme - A color scheme for all display layout templates. * @return {RegisterAppInterface} */ - setNightColorScheme(nightColorScheme) { - this.validateType(TemplateColorScheme, nightColorScheme); - this.setParameter(RegisterAppInterface.KEY_NIGHT_COLOR_SCHEME, nightColorScheme); + setNightColorScheme(scheme) { + this.validateType(TemplateColorScheme, scheme); + this.setParameter(RegisterAppInterface.KEY_NIGHT_COLOR_SCHEME, scheme); return this; } /** - * @return {TemplateColorScheme} - */ + * @return {TemplateColorScheme} + */ getNightColorScheme() { @@ -3587,7 +3421,6 @@ } - RegisterAppInterface.KEY_SYNC_MSG_VERSION = 'syncMsgVersion'; RegisterAppInterface.KEY_SDL_MSG_VERSION = 'syncMsgVersion'; RegisterAppInterface.KEY_APP_NAME = 'appName'; RegisterAppInterface.KEY_TTS_NAME = 'ttsName'; @@ -3606,37 +3439,7 @@ RegisterAppInterface.KEY_NIGHT_COLOR_SCHEME = 'nightColorScheme'; RegisterAppInterface.APP_ID_MAX_LENGTH = 10; - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ /** * @typedef {Enum} Result * @property {Object} _MAP @@ -3650,6 +3453,7 @@ super(); } /** + * The request succeeded * @return {String} */ @@ -3658,6 +3462,7 @@ return Result._MAP.SUCCESS; } /** + * The request is not supported by the headunit * @return {String} */ @@ -3666,14 +3471,16 @@ return Result._MAP.UNSUPPORTED_REQUEST; } /** + * A button that was requested for subscription is not supported under the current system. * @return {String} */ static get UNSUPPORTED_RESOURCE() { - return Result._MAP.UNSUPPORTED_REQUEST; + return Result._MAP.UNSUPPORTED_RESOURCE; } /** + * RPC is not authorized in local policy table. * @return {String} */ @@ -3682,6 +3489,9 @@ return Result._MAP.DISALLOWED; } /** + * The requested command was rejected, e.g. because mobile app is in background and cannot perform any HMI + * commands. Or an HMI command (e.g. Speak) is rejected because a higher priority HMI command (e.g. Alert) is + * playing. * @return {String} */ @@ -3690,6 +3500,8 @@ return Result._MAP.REJECTED; } /** + * A command was aborted, for example due to user interaction (e.g. user pressed button). Or an HMI command (e.g. + * Speak) is aborted because a higher priority HMI command (e.g. Alert) was requested. * @return {String} */ @@ -3698,6 +3510,9 @@ return Result._MAP.ABORTED; } /** + * A command was ignored, because the intended result is already in effect. For example, SetMediaClockTimer was + * used to pause the media clock although the clock is paused already. NOTE: potentially replaces + * SUBSCRIBED_ALREADY * @return {String} */ @@ -3706,6 +3521,8 @@ return Result._MAP.IGNORED; } /** + * The user interrupted the RPC (e.g. PerformAudioPassThru) and indicated to start over. Note, the app must issue + * the new RPC. * @return {String} */ @@ -3714,6 +3531,8 @@ return Result._MAP.RETRY; } /** + * The data may not be changed, because it is currently in use. For example when trying to delete a command set + * that is currently involved in an interaction. * @return {String} */ @@ -3722,6 +3541,7 @@ return Result._MAP.IN_USE; } /** + * The requested vehicle data is not available on this vehicle or is not published. * @return {String} */ @@ -3730,6 +3550,7 @@ return Result._MAP.VEHICLE_DATA_NOT_AVAILABLE; } /** + * Overlay reached the maximum timeout and closed. * @return {String} */ @@ -3738,6 +3559,8 @@ return Result._MAP.TIMED_OUT; } /** + * The data sent is invalid. For example: Invalid Json syntax Parameters out of bounds (number or enum range) + * Mandatory parameters not provided Parameter provided with wrong type Invalid characters Empty string * @return {String} */ @@ -3754,6 +3577,8 @@ return Result._MAP.CHAR_LIMIT_EXCEEDED; } /** + * One of the provided IDs is not valid. For example This applies to CorrelationID, SubscriptionID, CommandID, + * MenuID, etc. * @return {String} */ @@ -3762,6 +3587,7 @@ return Result._MAP.INVALID_ID; } /** + * There was a conflict with an registered name (application or menu item) or vr command * @return {String} */ @@ -3770,6 +3596,7 @@ return Result._MAP.DUPLICATE_NAME; } /** + * An command can not be executed because no application has been registered with RegisterApplication. * @return {String} */ @@ -3778,6 +3605,8 @@ return Result._MAP.APPLICATION_NOT_REGISTERED; } /** + * The requested language is currently not supported. Might be because of a mismatch of the currently active + * language on the headunit and the requested language * @return {String} */ @@ -3786,6 +3615,7 @@ return Result._MAP.WRONG_LANGUAGE; } /** + * The system could not process the request because the necessary memory couldn't be allocated * @return {String} */ @@ -3794,6 +3624,8 @@ return Result._MAP.OUT_OF_MEMORY; } /** + * There are too many requests pending (means, that the response has not been delivered, yet).There may be a + * maximum of 1000 pending requests at a time. * @return {String} */ @@ -3802,6 +3634,7 @@ return Result._MAP.TOO_MANY_PENDING_REQUESTS; } /** + * There are already too many registered applications * @return {String} */ @@ -3810,6 +3643,7 @@ return Result._MAP.TOO_MANY_APPLICATIONS; } /** + * RegisterApplication has been called again, after a RegisterApplication was successful before. * @return {String} */ @@ -3818,6 +3652,7 @@ return Result._MAP.APPLICATION_REGISTERED_ALREADY; } /** + * The RPC (e.g. SubscribeVehicleData) executed successfully but one or more items have a warning or failure. * @return {String} */ @@ -3826,6 +3661,7 @@ return Result._MAP.WARNINGS; } /** + * Provided data is valid but something went wrong in the lower layers. * @return {String} */ @@ -3834,6 +3670,7 @@ return Result._MAP.GENERIC_ERROR; } /** + * RPC is included in a functional group explicitly blocked by the user. * @return {String} */ @@ -3842,6 +3679,8 @@ return Result._MAP.USER_DISALLOWED; } /** + * The RPC (e.g. ReadDID) executed successfully but the data exceeded the platform maximum threshold and thus, + * only part of the data is available. * @return {String} */ @@ -3850,6 +3689,7 @@ return Result._MAP.TRUNCATED_DATA; } /** + * Sync doesn't support the protocol that is requested by the mobile application * @return {String} */ @@ -3858,6 +3698,7 @@ return Result._MAP.UNSUPPORTED_VERSION; } /** + * The user has turned off access to vehicle data, and it is globally unavailable to mobile applications. * @return {String} */ @@ -3866,6 +3707,7 @@ return Result._MAP.VEHICLE_DATA_NOT_ALLOWED; } /** + * A specified file could not be found on the headunit. * @return {String} */ @@ -3874,6 +3716,7 @@ return Result._MAP.FILE_NOT_FOUND; } /** + * User selected to Cancel Route. * @return {String} */ @@ -3882,6 +3725,7 @@ return Result._MAP.CANCEL_ROUTE; } /** + * The RPC (e.g. Slider) executed successfully and the user elected to save the current position / value. * @return {String} */ @@ -3890,6 +3734,7 @@ return Result._MAP.SAVED; } /** + * The certificate provided during authentication is invalid. * @return {String} */ @@ -3898,6 +3743,7 @@ return Result._MAP.INVALID_CERT; } /** + * The certificate provided during authentication is expired. * @return {String} */ @@ -3906,6 +3752,8 @@ return Result._MAP.EXPIRED_CERT; } /** + * The provided hash ID does not match the hash of the current set of registered data or the core could not resume + * the previous data. * @return {String} */ @@ -3914,6 +3762,8 @@ return Result._MAP.RESUME_FAILED; } /** + * The requested information is currently not available. This is different than UNSUPPORTED_RESOURCE because it + * implies the data is at some point available. * @return {String} */ @@ -3922,6 +3772,7 @@ return Result._MAP.DATA_NOT_AVAILABLE; } /** + * The value being set is read only * @return {String} */ @@ -3930,6 +3781,7 @@ return Result._MAP.READ_ONLY; } /** + * The data sent failed to pass CRC check in receiver end * @return {String} */ @@ -3938,20 +3790,29 @@ return Result._MAP.CORRUPTED_DATA; } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * SDL receives an un-encrypted RPC request that needs protection. + * @return {String} + */ + + + static get ENCRYPTION_NEEDED() { + return Result._MAP.ENCRYPTION_NEEDED; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ static valueForKey(key) { return Result._valueForKey(key, Result._MAP); } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ static keyForValue(value) { @@ -3996,7 +3857,8 @@ 'RESUME_FAILED': 'RESUME_FAILED', 'DATA_NOT_AVAILABLE': 'DATA_NOT_AVAILABLE', 'READ_ONLY': 'READ_ONLY', - 'CORRUPTED_DATA': 'CORRUPTED_DATA' + 'CORRUPTED_DATA': 'CORRUPTED_DATA', + 'ENCRYPTION_NEEDED': 'ENCRYPTION_NEEDED' }); /* @@ -17801,539 +17663,342 @@ } - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ /** - * @typedef {Enum} ImageType - * @property {Object} _MAP + * Contains information about a SoftButton's capabilities. */ - class ImageType extends Enum { + class SoftButtonCapabilities extends RpcStruct { /** - * @constructor - */ - constructor() { - super(); + * @constructor + */ + constructor(parameters) { + super(parameters); } /** - * @return {String} + * @param {Boolean} available - The button supports a short press. Whenever the button is pressed short, + * onButtonPressed( SHORT) will be invoked. + * @return {SoftButtonCapabilities} */ - static get STATIC() { - return ImageType._MAP.STATIC; + setShortPressAvailable(available) { + this.setParameter(SoftButtonCapabilities.KEY_SHORT_PRESS_AVAILABLE, available); + return this; } /** - * @return {String} + * @return {Boolean} */ - static get DYNAMIC() { - return ImageType._MAP.DYNAMIC; + getShortPressAvailable() { + return this.getParameter(SoftButtonCapabilities.KEY_SHORT_PRESS_AVAILABLE); } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * @param {Boolean} available - The button supports a LONG press. Whenever the button is pressed long, + * onButtonPressed( LONG) will be invoked. + * @return {SoftButtonCapabilities} + */ - static valueForKey(key) { - return ImageType._valueForKey(key, ImageType._MAP); + setLongPressAvailable(available) { + this.setParameter(SoftButtonCapabilities.KEY_LONG_PRESS_AVAILABLE, available); + return this; } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ - - - static keyForValue(value) { - return ImageType._keyForValue(value, ImageType._MAP); - } - - } - - ImageType._MAP = Object.freeze({ - 'STATIC': 'STATIC', - 'DYNAMIC': 'DYNAMIC' - }); + * @return {Boolean} + */ - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - class Image extends RpcStruct { - /** - * @constructor - */ - constructor(parameters) { - super(parameters); + getLongPressAvailable() { + return this.getParameter(SoftButtonCapabilities.KEY_LONG_PRESS_AVAILABLE); } /** - * @param {String} value - * @return {Image} - */ + * @param {Boolean} available - The button supports "button down" and "button up". Whenever the button is pressed, + * onButtonEvent( DOWN) will be invoked. Whenever the button is released, + * onButtonEvent( UP) will be invoked. + * @return {SoftButtonCapabilities} + */ - setValue(value) { - this.setParameter(Image.KEY_VALUE, value); + setUpDownAvailable(available) { + this.setParameter(SoftButtonCapabilities.KEY_UP_DOWN_AVAILABLE, available); return this; } /** - * @return {String} - */ + * @return {Boolean} + */ - getValue() { - return this.getParameter(Image.KEY_VALUE); + getUpDownAvailable() { + return this.getParameter(SoftButtonCapabilities.KEY_UP_DOWN_AVAILABLE); } /** - * @param {ImageType} type - * @return {Image} - */ + * @param {Boolean} supported - The button supports referencing a static or dynamic image. + * @return {SoftButtonCapabilities} + */ - setImageType(type) { - this.validateType(ImageType, type); - this.setParameter(Image.KEY_IMAGE_TYPE, type); + setImageSupported(supported) { + this.setParameter(SoftButtonCapabilities.KEY_IMAGE_SUPPORTED, supported); return this; } /** - * @return {ImageType} - */ + * @return {Boolean} + */ - getImageType() { - return this.getObject(ImageType, Image.KEY_IMAGE_TYPE); + getImageSupported() { + return this.getParameter(SoftButtonCapabilities.KEY_IMAGE_SUPPORTED); } /** - * @param {Boolean} isTemplate - * @return {Image} - */ + * @param {Boolean} supported - The button supports the use of text. If not included, the default value should be + * considered true that the button will support text. + * @return {SoftButtonCapabilities} + */ - setIsTemplate(isTemplate) { - this.setParameter(Image.KEY_IS_TEMPLATE, isTemplate); + setTextSupported(supported) { + this.setParameter(SoftButtonCapabilities.KEY_TEXT_SUPPORTED, supported); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ - getIsTemplate() { - return this.getParameter(Image.KEY_IS_TEMPLATE); + getTextSupported() { + return this.getParameter(SoftButtonCapabilities.KEY_TEXT_SUPPORTED); } } - Image.KEY_VALUE = 'value'; - Image.KEY_IMAGE_TYPE = 'imageType'; - Image.KEY_IS_TEMPLATE = 'isTemplate'; + SoftButtonCapabilities.KEY_SHORT_PRESS_AVAILABLE = 'shortPressAvailable'; + SoftButtonCapabilities.KEY_LONG_PRESS_AVAILABLE = 'longPressAvailable'; + SoftButtonCapabilities.KEY_UP_DOWN_AVAILABLE = 'upDownAvailable'; + SoftButtonCapabilities.KEY_IMAGE_SUPPORTED = 'imageSupported'; + SoftButtonCapabilities.KEY_TEXT_SUPPORTED = 'textSupported'; - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ + /** + * Contains a list of prerecorded speech items present on the platform. + * @typedef {Enum} PrerecordedSpeech + * @property {Object} _MAP + */ - class MenuParams extends RpcStruct { + class PrerecordedSpeech extends Enum { /** - * @constructor - */ - constructor(parameters) { - super(parameters); + * @constructor + */ + constructor() { + super(); } /** - * @param {Number} id - * @return {MenuParams} - */ + * @return {String} + */ - setParentID(id) { - this.setParameter(MenuParams.KEY_PARENT_ID, id); - return this; + static get HELP_JINGLE() { + return PrerecordedSpeech._MAP.HELP_JINGLE; } /** - * @return {Number} - */ + * @return {String} + */ - getParentID() { - return this.getParameter(MenuParams.KEY_PARENT_ID); + static get INITIAL_JINGLE() { + return PrerecordedSpeech._MAP.INITIAL_JINGLE; } /** - * @param {Number} position - * @return {MenuParams} - */ + * @return {String} + */ - setPosition(position) { - this.setParameter(MenuParams.KEY_POSITION, position); - return this; + static get LISTEN_JINGLE() { + return PrerecordedSpeech._MAP.LISTEN_JINGLE; } /** - * @return {Number} - */ + * @return {String} + */ - getPosition() { - return this.getParameter(MenuParams.KEY_POSITION); + static get POSITIVE_JINGLE() { + return PrerecordedSpeech._MAP.POSITIVE_JINGLE; } /** - * @param {String} menuName - * @return {MenuParams} - */ + * @return {String} + */ - setMenuName(menuName) { - this.setParameter(MenuParams.KEY_MENU_NAME, menuName); - return this; + static get NEGATIVE_JINGLE() { + return PrerecordedSpeech._MAP.NEGATIVE_JINGLE; } /** - * @param {String} - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ - getMenuName() { - return this.getParameter(MenuParams.KEY_MENU_NAME); + static valueForKey(key) { + return PrerecordedSpeech._valueForKey(key, PrerecordedSpeech._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return PrerecordedSpeech._keyForValue(value, PrerecordedSpeech._MAP); } } - MenuParams.KEY_PARENT_ID = 'parentID'; - MenuParams.KEY_POSITION = 'position'; - MenuParams.KEY_MENU_NAME = 'menuName'; + PrerecordedSpeech._MAP = Object.freeze({ + 'HELP_JINGLE': 'HELP_JINGLE', + 'INITIAL_JINGLE': 'INITIAL_JINGLE', + 'LISTEN_JINGLE': 'LISTEN_JINGLE', + 'POSITIVE_JINGLE': 'POSITIVE_JINGLE', + 'NEGATIVE_JINGLE': 'NEGATIVE_JINGLE' + }); - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ + /** + * Contains information about on-screen preset capabilities. + */ - class AddCommand extends RpcRequest { + class PresetBankCapabilities extends RpcStruct { /** - * @constructor - */ - constructor(store) { - super(store); - this.setFunctionName(FunctionID.AddCommand); + * @constructor + */ + constructor(parameters) { + super(parameters); } /** - * @param {Number} id - * @return {AddCommand} - */ + * @param {Boolean} available - Onscreen custom presets are available. + * @return {PresetBankCapabilities} + */ - setCmdID(id) { - this.setParameter(AddCommand.KEY_CMD_ID, id); + setOnScreenPresetsAvailable(available) { + this.setParameter(PresetBankCapabilities.KEY_ON_SCREEN_PRESETS_AVAILABLE, available); return this; } /** - * @return {Number} - */ + * @return {Boolean} + */ - getCmdID() { - return this.getParameter(AddCommand.KEY_CMD_ID); + getOnScreenPresetsAvailable() { + return this.getParameter(PresetBankCapabilities.KEY_ON_SCREEN_PRESETS_AVAILABLE); } + + } + + PresetBankCapabilities.KEY_ON_SCREEN_PRESETS_AVAILABLE = 'onScreenPresetsAvailable'; + + /* eslint-disable camelcase */ + + class VehicleType extends RpcStruct { /** - * @param {MenuParams} menuParams - * @return {AddCommand} - */ + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {String} make - Make of the vehicle, e.g. Ford + * @return {VehicleType} + */ - setMenuParams(menuParams) { - this.validateType(MenuParams, menuParams); - this.setParameter(AddCommand.KEY_MENU_PARAMS, menuParams); + setMake(make) { + this.setParameter(VehicleType.KEY_MAKE, make); return this; } /** - * @return {MenuParams} - */ + * @return {String} + */ - getMenuParams() { - return this.getObject(MenuParams, AddCommand.KEY_MENU_PARAMS); + getMake() { + return this.getParameter(VehicleType.KEY_MAKE); } /** - * @param {Array} vrCommands - * @return {AddCommand} - */ + * @param {String} model - Model of the vehicle, e.g. Fiesta + * @return {VehicleType} + */ - setVrCommands(vrCommands) { - this.setParameter(AddCommand.KEY_VR_COMMANDS, vrCommands); + setModel(model) { + this.setParameter(VehicleType.KEY_MODEL, model); return this; } /** - * @return {Array} - */ + * @return {String} + */ - getVrCommands() { - return this.getParameter(AddCommand.KEY_VR_COMMANDS); + getModel() { + return this.getParameter(VehicleType.KEY_MODEL); } /** - * @param {Image} icon - * @return {AddCommand} - */ + * @param {String} year - Model Year of the vehicle, e.g. 2013 + * @return {VehicleType} + */ - setCmdIcon(icon) { - this.validateType(Image, icon); - this.setParameter(AddCommand.KEY_CMD_ICON, icon); + setModelYear(year) { + this.setParameter(VehicleType.KEY_MODEL_YEAR, year); return this; } /** - * @return {Image} - */ + * @return {String} + */ - getCmdIcon() { - return this.getObject(Image, AddCommand.KEY_CMD_ICON); + getModelYear() { + return this.getParameter(VehicleType.KEY_MODEL_YEAR); } + /** + * @param {String} trim - Trim of the vehicle, e.g. SE + * @return {VehicleType} + */ - } - - AddCommand.KEY_CMD_ICON = 'cmdIcon'; - AddCommand.KEY_MENU_PARAMS = 'menuParams'; - AddCommand.KEY_CMD_ID = 'cmdID'; - AddCommand.KEY_VR_COMMANDS = 'vrCommands'; - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - class AddCommandResponse extends RpcResponse { - /** - * @constructor - */ - constructor(store) { - super(store); - this.setFunctionName(FunctionID.AddCommand); + setTrim(trim) { + this.setParameter(VehicleType.KEY_TRIM, trim); + return this; } + /** + * @return {String} + */ - } - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - class RpcNotification extends RpcMessage { - /** - * @constructor - */ - constructor(store) { - super(store); - this.setRPCType(RpcType.NOTIFICATION); + getTrim() { + return this.getParameter(VehicleType.KEY_TRIM); } } - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + VehicleType.KEY_MAKE = 'make'; + VehicleType.KEY_MODEL = 'model'; + VehicleType.KEY_MODEL_YEAR = 'modelYear'; + VehicleType.KEY_TRIM = 'trim'; + + /* eslint-disable camelcase */ /** - * @typedef {Enum} HMILevel + * Contains information about the HMI zone capabilities. For future use. + * @typedef {Enum} HmiZoneCapabilities * @property {Object} _MAP */ - class HMILevel extends Enum { + class HmiZoneCapabilities extends Enum { + /** + * @constructor + */ constructor() { super(); } @@ -18342,665 +18007,584 @@ */ - static get HMI_FULL() { - return HMILevel._MAP.HMI_FULL; + static get FRONT() { + return HmiZoneCapabilities._MAP.FRONT; } /** * @return {String} */ - static get HMI_LIMITED() { - return HMILevel._MAP.HMI_LIMITED; - } - /** - * @return {String} - */ - - - static get HMI_BACKGROUND() { - return HMILevel._MAP.HMI_BACKGROUND; + static get BACK() { + return HmiZoneCapabilities._MAP.BACK; } /** - * @return {String} + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found */ - static get HMI_NONE() { - return HMILevel._MAP.HMI_NONE; - } - /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ - - static valueForKey(key) { - return HMILevel._valueForKey(key, HMILevel._MAP); + return HmiZoneCapabilities._valueForKey(key, HmiZoneCapabilities._MAP); } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ static keyForValue(value) { - return HMILevel._keyForValue(value, HMILevel._MAP); + return HmiZoneCapabilities._keyForValue(value, HmiZoneCapabilities._MAP); } } - HMILevel._MAP = Object.freeze({ - 'HMI_FULL': 'FULL', - 'HMI_LIMITED': 'LIMITED', - 'HMI_BACKGROUND': 'BACKGROUND', - 'HMI_NONE': 'NONE' + HmiZoneCapabilities._MAP = Object.freeze({ + 'FRONT': 'FRONT', + 'BACK': 'BACK' }); - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ /** - * @typedef {Enum} AudioStreamingState + * @typedef {Enum} MediaClockFormat * @property {Object} _MAP */ - class AudioStreamingState extends Enum { + class MediaClockFormat extends Enum { + /** + * @constructor + */ constructor() { super(); } /** + * minutesFieldWidth = 2;minutesFieldMax = 19;secondsFieldWidth = 2;secondsFieldMax = 99;maxHours = 19;maxMinutes + * = 59;maxSeconds = 59; used for Type II and CID headunits * @return {String} */ - static get AUDIBLE() { - return AudioStreamingState._MAP.AUDIBLE; + static get CLOCK1() { + return MediaClockFormat._MAP.CLOCK1; } /** + * minutesFieldWidth = 3;minutesFieldMax = 199;secondsFieldWidth = 2;secondsFieldMax = 99;maxHours = 59;maxMinutes + * = 59;maxSeconds = 59; used for Type V headunit * @return {String} */ - static get ATTENUATED() { - return AudioStreamingState._MAP.ATTENUATED; + static get CLOCK2() { + return MediaClockFormat._MAP.CLOCK2; } /** + * minutesFieldWidth = 2;minutesFieldMax = 59;secondsFieldWidth = 2;secondsFieldMax = 59;maxHours = 9;maxMinutes = + * 59;maxSeconds = 59; used for GEN1.1 MFD3/4/5 headunits * @return {String} */ - static get NOT_AUDIBLE() { - return AudioStreamingState._MAP.NOT_AUDIBLE; + static get CLOCK3() { + return MediaClockFormat._MAP.CLOCK3; } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * 5 characters possible Format: 1|sp c :|sp c c 1|sp : digit "1" or space c : character out of following + * character set: sp|0-9|[letters, see TypeII column in XLS. See :|sp : colon or space used for Type II headunit + * @return {String} + */ - static valueForKey(key) { - return AudioStreamingState._valueForKey(key, AudioStreamingState._MAP); + static get CLOCKTEXT1() { + return MediaClockFormat._MAP.CLOCKTEXT1; } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ - - - static keyForValue(value) { - return AudioStreamingState._keyForValue(value, AudioStreamingState._MAP); - } - - } - - AudioStreamingState._MAP = Object.freeze({ - 'AUDIBLE': 'AUDIBLE', - 'ATTENUATED': 'ATTENUATED', - 'NOT_AUDIBLE': 'NOT_AUDIBLE' - }); + * 5 chars possible Format: 1|sp c :|sp c c 1|sp : digit "1" or space c : character out of following character + * set: sp|0-9|[letters, see CID column in XLS. See :|sp : colon or space used for CID headunit NOTE: difference + * between CLOCKTEXT1 and CLOCKTEXT2 is the supported character set + * @return {String} + */ - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - /** - * @typedef {Enum} VideoStreamingState - * @property {Object} _MAP - */ - class VideoStreamingState extends Enum { - constructor() { - super(); + static get CLOCKTEXT2() { + return MediaClockFormat._MAP.CLOCKTEXT2; } /** + * 6 chars possible Format: 1|sp c c :|sp c c 1|sp : digit "1" or space c : character out of following character + * set: sp|0-9|[letters, see Type 5 column in XLS]. See :|sp : colon or space used for Type V headunit * @return {String} */ - static get STREAMABLE() { - return VideoStreamingState._MAP.STREAMABLE; + static get CLOCKTEXT3() { + return MediaClockFormat._MAP.CLOCKTEXT3; } /** + * 6 chars possible Format: c :|sp c c : c c :|sp : colon or space c : character out of following character set: + * sp|0-9|[letters]. used for GEN1.1 MFD3/4/5 headunits * @return {String} */ - static get NOT_STREAMABLE() { - return VideoStreamingState._MAP.NOT_STREAMABLE; + static get CLOCKTEXT4() { + return MediaClockFormat._MAP.CLOCKTEXT4; } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ static valueForKey(key) { - return VideoStreamingState._valueForKey(key, VideoStreamingState._MAP); + return MediaClockFormat._valueForKey(key, MediaClockFormat._MAP); } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ static keyForValue(value) { - return VideoStreamingState._keyForValue(value, VideoStreamingState._MAP); + return MediaClockFormat._keyForValue(value, MediaClockFormat._MAP); } } - VideoStreamingState._MAP = Object.freeze({ - 'STREAMABLE': 'STREAMABLE', - 'NOT_STREAMABLE': 'NOT_STREAMABLE' + MediaClockFormat._MAP = Object.freeze({ + 'CLOCK1': 'CLOCK1', + 'CLOCK2': 'CLOCK2', + 'CLOCK3': 'CLOCK3', + 'CLOCKTEXT1': 'CLOCKTEXT1', + 'CLOCKTEXT2': 'CLOCKTEXT2', + 'CLOCKTEXT3': 'CLOCKTEXT3', + 'CLOCKTEXT4': 'CLOCKTEXT4' }); - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - /** - * @typedef {Enum} SystemContext - * @property {Object} _MAP - */ + /* eslint-disable camelcase */ - class SystemContext extends Enum { - constructor() { - super(); - } + class ImageResolution extends RpcStruct { /** - * @return {String} + * @constructor */ - - - static get SYSCTXT_MAIN() { - return SystemContext._MAP.SYSCTXT_MAIN; + constructor(parameters) { + super(parameters); } /** - * @return {String} + * @param {Number} width - The image resolution width. + * @return {ImageResolution} */ - static get SYSCTXT_VRSESSION() { - return SystemContext._MAP.SYSCTXT_VRSESSION; + setResolutionWidth(width) { + this.setParameter(ImageResolution.KEY_RESOLUTION_WIDTH, width); + return this; } /** - * @return {String} + * @return {Number} */ - static get SYSCTXT_MENU() { - return SystemContext._MAP.SYSCTXT_MENU; + getResolutionWidth() { + return this.getParameter(ImageResolution.KEY_RESOLUTION_WIDTH); } /** - * @return {String} + * @param {Number} height - The image resolution height. + * @return {ImageResolution} */ - static get SYSCTXT_HMI_OBSCURED() { - return SystemContext._MAP.SYSCTXT_HMI_OBSCURED; + setResolutionHeight(height) { + this.setParameter(ImageResolution.KEY_RESOLUTION_HEIGHT, height); + return this; } /** - * @return {String} + * @return {Number} */ - static get SYSCTXT_ALERT() { - return SystemContext._MAP.SYSCTXT_ALERT; - } - /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ - - - static valueForKey(key) { - return SystemContext._valueForKey(key, SystemContext._MAP); - } - /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ - - - static keyForValue(value) { - return SystemContext._keyForValue(value, SystemContext._MAP); + getResolutionHeight() { + return this.getParameter(ImageResolution.KEY_RESOLUTION_HEIGHT); } } - SystemContext._MAP = Object.freeze({ - 'SYSCTXT_MAIN': 'MAIN', - 'SYSCTXT_VRSESSION': 'VRSESSION', - 'SYSCTXT_MENU': 'MENU', - 'SYSCTXT_HMI_OBSCURED': 'HMI_OBSCURED', - 'SYSCTXT_ALERT': 'ALERT' - }); - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - class OnHmiStatus extends RpcNotification { - /** - * @constructor - */ - constructor(store) { - super(store); - this.setFunctionName(FunctionID.OnHMIStatus); - } - /** - * @param {HMILevel} hmiLevel - * @return {OnHmiStatus} - */ - - - setHMILevel(hmiLevel) { - this.validateType(HMILevel, hmiLevel); - this.setParameter(OnHmiStatus.KEY_HMI_LEVEL, hmiLevel); - return this; - } - /** - * @return {HMILevel} - */ - - - getHMILevel() { - return this.getObject(HMILevel, OnHmiStatus.KEY_HMI_LEVEL); - } - /** - * @param {AudioStreamingState} audioStreamingState - * @return {OnHmiStatus} - */ + ImageResolution.KEY_RESOLUTION_WIDTH = 'resolutionWidth'; + ImageResolution.KEY_RESOLUTION_HEIGHT = 'resolutionHeight'; + /* eslint-disable camelcase */ - setAudioStreamingState(audioStreamingState) { - this.validateType(AudioStreamingState, audioStreamingState); - this.setParameter(OnHmiStatus.KEY_AUDIO_STREAMING_STATE, audioStreamingState); - return this; - } + class TouchEventCapabilities extends RpcStruct { /** - * @return {AudioStreamingState} - */ - - - getAudioStreamingState() { - return this.getObject(AudioStreamingState, OnHmiStatus.KEY_AUDIO_STREAMING_STATE); + * @constructor + */ + constructor(parameters) { + super(parameters); } /** - * @param {SystemContext} systemContext - * @return {OnHmiStatus} - */ + * @param {Boolean} available + * @return {TouchEventCapabilities} + */ - setSystemContext(systemContext) { - this.validateType(SystemContext, systemContext); - this.setParameter(OnHmiStatus.KEY_SYSTEM_CONTEXT, systemContext); + setPressAvailable(available) { + this.setParameter(TouchEventCapabilities.KEY_PRESS_AVAILABLE, available); return this; } /** - * @return {SystemContext} - */ + * @return {Boolean} + */ - getSystemContext() { - return this.getObject(SystemContext, OnHmiStatus.KEY_SYSTEM_CONTEXT); + getPressAvailable() { + return this.getParameter(TouchEventCapabilities.KEY_PRESS_AVAILABLE); } /** - * @param {VideoStreamingState} videoStreamingState - * @return {OnHmiStatus} - */ + * @param {Boolean} available + * @return {TouchEventCapabilities} + */ - setVideoStreamingState(videoStreamingState) { - this.validateType(VideoStreamingState, videoStreamingState); - this.setParameter(OnHmiStatus.KEY_VIDEO_STREAMING_STATE, videoStreamingState); + setMultiTouchAvailable(available) { + this.setParameter(TouchEventCapabilities.KEY_MULTI_TOUCH_AVAILABLE, available); return this; } /** - * @return {VideoStreamingState} - */ + * @return {Boolean} + */ - getVideoStreamingState() { - return this.getObject(VideoStreamingState, OnHmiStatus.KEY_VIDEO_STREAMING_STATE); + getMultiTouchAvailable() { + return this.getParameter(TouchEventCapabilities.KEY_MULTI_TOUCH_AVAILABLE); } /** - * @param {Number} windowID - * @return {Show} - */ + * @param {Boolean} available + * @return {TouchEventCapabilities} + */ - setWindowID(windowID) { - this.setParameter(OnHmiStatus.KEY_WINDOW_ID, windowID); + setDoublePressAvailable(available) { + this.setParameter(TouchEventCapabilities.KEY_DOUBLE_PRESS_AVAILABLE, available); return this; } /** - * @return {Number} - */ + * @return {Boolean} + */ - getWindowID() { - return this.getParameter(OnHmiStatus.KEY_WINDOW_ID); + getDoublePressAvailable() { + return this.getParameter(TouchEventCapabilities.KEY_DOUBLE_PRESS_AVAILABLE); } } - OnHmiStatus.KEY_HMI_LEVEL = 'hmiLevel'; - OnHmiStatus.KEY_AUDIO_STREAMING_STATE = 'audioStreamingState'; - OnHmiStatus.KEY_SYSTEM_CONTEXT = 'systemContext'; - OnHmiStatus.KEY_VIDEO_STREAMING_STATE = 'videoStreamingState'; - OnHmiStatus.KEY_WINDOW_ID = 'windowID'; + TouchEventCapabilities.KEY_PRESS_AVAILABLE = 'pressAvailable'; + TouchEventCapabilities.KEY_MULTI_TOUCH_AVAILABLE = 'multiTouchAvailable'; + TouchEventCapabilities.KEY_DOUBLE_PRESS_AVAILABLE = 'doublePressAvailable'; - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ - class OnLanguageChange extends RpcNotification { + class ScreenParams extends RpcStruct { /** - * @constructor - */ - constructor(store) { - super(store); - this.setFunctionName(FunctionID.OnLanguageChange); + * @constructor + */ + constructor(parameters) { + super(parameters); } /** - * @param {Language} language - * @return {OnLanguageChange} - */ + * @param {ImageResolution} resolution - The resolution of the prescribed screen area. + * @return {ScreenParams} + */ - setLanguage(language) { - this.validateType(Language, language); - this.setParameter(OnLanguageChange.KEY_LANGUAGE, language); + setResolution(resolution) { + this.validateType(ImageResolution, resolution); + this.setParameter(ScreenParams.KEY_RESOLUTION, resolution); return this; } /** - * @return {Language} - */ + * @return {ImageResolution} + */ - getLanguage() { - return this.getObject(Language, OnLanguageChange.KEY_LANGUAGE); + getResolution() { + return this.getObject(ImageResolution, ScreenParams.KEY_RESOLUTION); } /** - * @param {Language} language - * @return {OnLanguageChange} - */ + * @param {TouchEventCapabilities} available - Types of screen touch events available in screen area. + * @return {ScreenParams} + */ - setHMIDisplayLanguage(language) { - this.validateType(Language, language); - this.setParameter(OnLanguageChange.KEY_HMI_DISPLAY_LANGUAGE, language); + setTouchEventAvailable(available) { + this.validateType(TouchEventCapabilities, available); + this.setParameter(ScreenParams.KEY_TOUCH_EVENT_AVAILABLE, available); return this; } /** - * @return {Language} - */ + * @return {TouchEventCapabilities} + */ - getHMIDisplayLanguage() { - return this.getObject(Language, OnLanguageChange.KEY_HMI_DISPLAY_LANGUAGE); + getTouchEventAvailable() { + return this.getObject(TouchEventCapabilities, ScreenParams.KEY_TOUCH_EVENT_AVAILABLE); } } - OnLanguageChange.KEY_LANGUAGE = 'language'; - OnLanguageChange.KEY_HMI_DISPLAY_LANGUAGE = 'hmiDisplayLanguage'; + ScreenParams.KEY_RESOLUTION = 'resolution'; + ScreenParams.KEY_TOUCH_EVENT_AVAILABLE = 'touchEventAvailable'; - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ /** - * @typedef {Enum} FileType + * @typedef {Enum} ImageFieldName * @property {Object} _MAP */ - class FileType extends Enum { + class ImageFieldName extends Enum { + /** + * @constructor + */ constructor() { super(); } /** + * The image field for SoftButton * @return {String} */ - static get GRAPHIC_BMP() { - return FileType._MAP.GRAPHIC_BMP; + static get softButtonImage() { + return ImageFieldName._MAP.softButtonImage; } /** + * The first image field for Choice * @return {String} */ - static get GRAPHIC_JPEG() { - return FileType._MAP.GRAPHIC_JPEG; + static get choiceImage() { + return ImageFieldName._MAP.choiceImage; } /** + * The secondary image field for Choice * @return {String} */ - static get GRAPHIC_PNG() { - return FileType._MAP.GRAPHIC_PNG; + static get choiceSecondaryImage() { + return ImageFieldName._MAP.choiceSecondaryImage; } /** + * The image field for vrHelpItem * @return {String} */ - static get AUDIO_WAVE() { - return FileType._MAP.AUDIO_WAVE; + static get vrHelpItem() { + return ImageFieldName._MAP.vrHelpItem; } /** + * The image field for Turn * @return {String} */ - static get AUDIO_AAC() { - return FileType._MAP.AUDIO_AAC; + static get turnIcon() { + return ImageFieldName._MAP.turnIcon; } /** + * The image field for the menu icon in SetGlobalProperties * @return {String} */ - static get BINARY() { - return FileType._MAP.BINARY; + static get menuIcon() { + return ImageFieldName._MAP.menuIcon; + } + /** + * The image field for AddCommand + * @return {String} + */ + + + static get cmdIcon() { + return ImageFieldName._MAP.cmdIcon; + } + /** + * The image field for the app icon (set by setAppIcon) + * @return {String} + */ + + + static get appIcon() { + return ImageFieldName._MAP.appIcon; + } + /** + * The primary image field for Show + * @return {String} + */ + + + static get graphic() { + return ImageFieldName._MAP.graphic; + } + /** + * The secondary image field for Show + * @return {String} + */ + + + static get secondaryGraphic() { + return ImageFieldName._MAP.secondaryGraphic; + } + /** + * The primary image field for ShowConstantTBT + * @return {String} + */ + + + static get showConstantTBTIcon() { + return ImageFieldName._MAP.showConstantTBTIcon; + } + /** + * The secondary image field for ShowConstantTBT + * @return {String} + */ + + + static get showConstantTBTNextTurnIcon() { + return ImageFieldName._MAP.showConstantTBTNextTurnIcon; + } + /** + * The optional image of a destination / location + * @return {String} + */ + + + static get locationImage() { + return ImageFieldName._MAP.locationImage; + } + /** + * The image field for Alert + * @return {String} + */ + + + static get alertIcon() { + return ImageFieldName._MAP.alertIcon; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return ImageFieldName._valueForKey(key, ImageFieldName._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return ImageFieldName._keyForValue(value, ImageFieldName._MAP); + } + + } + + ImageFieldName._MAP = Object.freeze({ + 'softButtonImage': 'softButtonImage', + 'choiceImage': 'choiceImage', + 'choiceSecondaryImage': 'choiceSecondaryImage', + 'vrHelpItem': 'vrHelpItem', + 'turnIcon': 'turnIcon', + 'menuIcon': 'menuIcon', + 'cmdIcon': 'cmdIcon', + 'appIcon': 'appIcon', + 'graphic': 'graphic', + 'secondaryGraphic': 'secondaryGraphic', + 'showConstantTBTIcon': 'showConstantTBTIcon', + 'showConstantTBTNextTurnIcon': 'showConstantTBTNextTurnIcon', + 'locationImage': 'locationImage', + 'alertIcon': 'alertIcon' + }); + + /* eslint-disable camelcase */ + /** + * Enumeration listing possible file types. + * @typedef {Enum} FileType + * @property {Object} _MAP + */ + + class FileType extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get GRAPHIC_BMP() { + return FileType._MAP.GRAPHIC_BMP; + } + /** + * @return {String} + */ + + + static get GRAPHIC_JPEG() { + return FileType._MAP.GRAPHIC_JPEG; + } + /** + * @return {String} + */ + + + static get GRAPHIC_PNG() { + return FileType._MAP.GRAPHIC_PNG; + } + /** + * @return {String} + */ + + + static get AUDIO_WAVE() { + return FileType._MAP.AUDIO_WAVE; + } + /** + * @return {String} + */ + + + static get AUDIO_MP3() { + return FileType._MAP.AUDIO_MP3; + } + /** + * @return {String} + */ + + + static get AUDIO_AAC() { + return FileType._MAP.AUDIO_AAC; + } + /** + * @return {String} + */ + + + static get BINARY() { + return FileType._MAP.BINARY; } /** * @return {String} @@ -19011,20 +18595,20 @@ return FileType._MAP.JSON; } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ static valueForKey(key) { return FileType._valueForKey(key, FileType._MAP); } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ static keyForValue(value) { @@ -19044,554 +18628,521 @@ 'JSON': 'JSON' }); - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ - class PutFile extends RpcRequest { + class ImageField extends RpcStruct { /** - * @constructor - */ - constructor(store) { - super(store); - this.setFunctionName(FunctionID.PutFile); - } // ------ Not part of the RPC spec itself ----- - + * @constructor + */ + constructor(parameters) { + super(parameters); + } /** - * @param {Uint8Array} fileData - * @return {PutFile} - */ + * @param {ImageFieldName} name - The name that identifies the field. See ImageFieldName. + * @return {ImageField} + */ - setFileData(fileData) { - this.setBulkData(fileData); + setName(name) { + this.validateType(ImageFieldName, name); + this.setParameter(ImageField.KEY_NAME, name); return this; } /** - * @return {Uint8Array} - */ - + * @return {ImageFieldName} + */ - getFileData() { - return this.getBulkData(); - } // ----------------- END ----------------------- + getName() { + return this.getObject(ImageFieldName, ImageField.KEY_NAME); + } /** - * @param {String} fileName - * @return {PutFile} - */ + * @param {FileType[]} supported - The image types that are supported in this field. See FileType. + * @return {ImageField} + */ - setFileName(fileName) { - this.setParameter(PutFile.KEY_FILE_NAME, fileName); + setImageTypeSupported(supported) { + this.validateType(FileType, supported, true); + this.setParameter(ImageField.KEY_IMAGE_TYPE_SUPPORTED, supported); return this; } /** - * @return {String} - */ + * @return {FileType[]} + */ - getFileName() { - return this.getParameter(PutFile.KEY_FILE_NAME); + getImageTypeSupported() { + return this.getObject(FileType, ImageField.KEY_IMAGE_TYPE_SUPPORTED); } /** - * @param {FileType} fileType - * @return {PutFile} - */ + * @param {ImageResolution} resolution - The image resolution of this field. + * @return {ImageField} + */ - setFileType(fileType) { - this.validateType(FileType, fileType); - this.setParameter(PutFile.KEY_FILE_TYPE, fileType); + setImageResolution(resolution) { + this.validateType(ImageResolution, resolution); + this.setParameter(ImageField.KEY_IMAGE_RESOLUTION, resolution); return this; } /** - * @return {FileType} - */ + * @return {ImageResolution} + */ - getFileType() { - return this.getObject(FileType, PutFile.KEY_MENU_PARAMS); + getImageResolution() { + return this.getObject(ImageResolution, ImageField.KEY_IMAGE_RESOLUTION); } - /** - * @param {Boolean} persistentFile - * @return {PutFile} - */ + } - setPersistentFile(persistentFile) { - this.setParameter(PutFile.KEY_PERSISTENT_FILE, persistentFile); - return this; + ImageField.KEY_NAME = 'name'; + ImageField.KEY_IMAGE_TYPE_SUPPORTED = 'imageTypeSupported'; + ImageField.KEY_IMAGE_RESOLUTION = 'imageResolution'; + + /* eslint-disable camelcase */ + /** + * See DAES for further infos regarding the displays + * @deprecated + * @typedef {Enum} DisplayType + * @property {Object} _MAP + */ + + class DisplayType extends Enum { + /** + * @deprecated + * @constructor + */ + constructor() { + super(); } /** - * @return {Boolean} - */ + * @deprecated + * @return {String} + */ - getPersistentFile() { - return this.getParameter(PutFile.KEY_PERSISTENT_FILE); + static get CID() { + return DisplayType._MAP.CID; } /** - * @param {Boolean} systemFile - * @return {PutFile} - */ + * @deprecated + * @return {String} + */ - setSystemFile(systemFile) { - this.setParameter(PutFile.KEY_SYSTEM_FILE, systemFile); - return this; + static get TYPE2() { + return DisplayType._MAP.TYPE2; } /** - * @return {Boolean} - */ + * @deprecated + * @return {String} + */ - getSystemFile() { - return this.getParameter(PutFile.KEY_SYSTEM_FILE); + static get TYPE5() { + return DisplayType._MAP.TYPE5; } /** - * @param {Number} offset - * @return {PutFile} - */ + * @deprecated + * @return {String} + */ - setOffset(offset) { - this.setParameter(PutFile.KEY_OFFSET, offset); - return this; + static get NGN() { + return DisplayType._MAP.NGN; } /** - * @return {Number} - */ + * @deprecated + * @return {String} + */ - getOffset() { - return this.getParameter(PutFile.KEY_OFFSET); + static get GEN2_8_DMA() { + return DisplayType._MAP.GEN2_8_DMA; } /** - * @param {Number} length - * @return {PutFile} - */ + * @deprecated + * @return {String} + */ - setLength(length) { - this.setParameter(PutFile.KEY_LENGTH, length); - return this; + static get GEN2_6_DMA() { + return DisplayType._MAP.GEN2_6_DMA; } /** - * @return {Number} - */ + * @deprecated + * @return {String} + */ - getLength() { - return this.getParameter(PutFile.KEY_LENGTH); + static get MFD3() { + return DisplayType._MAP.MFD3; } /** - * @param {Number} crc - * @return {PutFile} - */ + * @deprecated + * @return {String} + */ - setCRC(crc) { - this.setParameter(PutFile.KEY_CRC, crc); - return this; + static get MFD4() { + return DisplayType._MAP.MFD4; } /** - * @return {Number} - */ + * @deprecated + * @return {String} + */ - getCRC() { - return this.getParameter(PutFile.KEY_CRC); + static get MFD5() { + return DisplayType._MAP.MFD5; } + /** + * @deprecated + * @return {String} + */ - } - PutFile.KEY_FILE_NAME = 'syncFileName'; - PutFile.KEY_FILE_TYPE = 'fileType'; - PutFile.KEY_PERSISTENT_FILE = 'persistentFile'; - PutFile.KEY_SYSTEM_FILE = 'systemFile'; - PutFile.KEY_OFFSET = 'offset'; - PutFile.KEY_LENGTH = 'length'; - PutFile.KEY_CRC = 'crc'; + static get GEN3_8_INCH() { + return DisplayType._MAP.GEN3_8_INCH; + } + /** + * @deprecated + * @return {String} + */ - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - class PutFileResponse extends RpcResponse { - /** - * @constructor - */ - constructor(store) { - super(store); - this.setFunctionName(FunctionID.PutFile); + static get SDL_GENERIC() { + return DisplayType._MAP.SDL_GENERIC; } /** - * @param {Number} spaceAvailable - * @return {PutFileResponse} - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ - setSpaceAvailable(spaceAvailable) { - this.setParameter(PutFileResponse.KEY_SPACE_AVAILABLE, spaceAvailable); - return this; + static valueForKey(key) { + return DisplayType._valueForKey(key, DisplayType._MAP); } /** - * @return {Number} - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ - getSpaceAvailable() { - return this.getParameter(PutFileResponse.KEY_SPACE_AVAILABLE); + static keyForValue(value) { + return DisplayType._keyForValue(value, DisplayType._MAP); } } - PutFileResponse.KEY_SPACE_AVAILABLE = 'spaceAvailable'; + DisplayType._MAP = Object.freeze({ + 'CID': 'CID', + 'TYPE2': 'TYPE2', + 'TYPE5': 'TYPE5', + 'NGN': 'NGN', + 'GEN2_8_DMA': 'GEN2_8_DMA', + 'GEN2_6_DMA': 'GEN2_6_DMA', + 'MFD3': 'MFD3', + 'MFD4': 'MFD4', + 'MFD5': 'MFD5', + 'GEN3_8_INCH': 'GEN3_8-INCH', + 'SDL_GENERIC': 'SDL_GENERIC' + }); - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ /** * @typedef {Enum} TextFieldName * @property {Object} _MAP */ class TextFieldName extends Enum { + /** + * @constructor + */ constructor() { super(); } /** - * @return {String} - */ + * The first line of first set of main fields of the persistent display; applies to "Show" + * @return {String} + */ static get mainField1() { return TextFieldName._MAP.mainField1; } /** - * @return {String} - */ + * The second line of first set of main fields of the persistent display; applies to "Show" + * @return {String} + */ static get mainField2() { return TextFieldName._MAP.mainField2; } /** - * @return {String} - */ + * The first line of second set of main fields of persistent display; applies to "Show" + * @return {String} + */ static get mainField3() { return TextFieldName._MAP.mainField3; } /** - * @return {String} - */ + * The second line of second set of main fields of the persistent display; applies to "Show" + * @return {String} + */ static get mainField4() { return TextFieldName._MAP.mainField4; } /** - * @return {String} - */ + * The status bar on NGN; applies to "Show" + * @return {String} + */ static get statusBar() { return TextFieldName._MAP.statusBar; } /** - * @return {String} - */ + * Text value for MediaClock field; applies to "Show" + * @return {String} + */ static get mediaClock() { return TextFieldName._MAP.mediaClock; } /** - * @return {String} - */ + * The track field of NGN and GEN1.1 MFD displays. This field is only available for media applications; applies to + * "Show" + * @return {String} + */ static get mediaTrack() { return TextFieldName._MAP.mediaTrack; } /** - * @return {String} - */ + * The title of the new template that will be displayed; applies to "Show" + * @return {String} + */ static get templateTitle() { return TextFieldName._MAP.templateTitle; } /** - * @return {String} - */ + * The first line of the alert text field; applies to "Alert" + * @return {String} + */ static get alertText1() { return TextFieldName._MAP.alertText1; } /** - * @return {String} - */ + * The second line of the alert text field; applies to "Alert" + * @return {String} + */ static get alertText2() { return TextFieldName._MAP.alertText2; } /** - * @return {String} - */ + * The third line of the alert text field; applies to "Alert" + * @return {String} + */ static get alertText3() { return TextFieldName._MAP.alertText3; } /** - * @return {String} - */ + * Long form body of text that can include newlines and tabs; applies to "ScrollableMessage" + * @return {String} + */ static get scrollableMessageBody() { return TextFieldName._MAP.scrollableMessageBody; } /** - * @return {String} - */ + * First line suggestion for a user response (in the case of VR enabled interaction) + * @return {String} + */ static get initialInteractionText() { return TextFieldName._MAP.initialInteractionText; } /** - * @return {String} - */ + * First line of navigation text + * @return {String} + */ static get navigationText1() { return TextFieldName._MAP.navigationText1; } /** - * @return {String} - */ + * Second line of navigation text + * @return {String} + */ static get navigationText2() { return TextFieldName._MAP.navigationText2; } /** - * @return {String} - */ + * Estimated Time of Arrival time for navigation + * @return {String} + */ static get ETA() { return TextFieldName._MAP.ETA; } /** - * @return {String} - */ + * Total distance to destination for navigation + * @return {String} + */ static get totalDistance() { return TextFieldName._MAP.totalDistance; } /** - * @return {String} - */ + * First line of text for audio pass thru + * @return {String} + */ static get audioPassThruDisplayText1() { return TextFieldName._MAP.audioPassThruDisplayText1; } /** - * @return {String} - */ + * Second line of text for audio pass thru + * @return {String} + */ static get audioPassThruDisplayText2() { return TextFieldName._MAP.audioPassThruDisplayText2; } /** - * @return {String} - */ + * Header text for slider + * @return {String} + */ static get sliderHeader() { return TextFieldName._MAP.sliderHeader; } /** - * @return {String} - */ + * Footer text for slider + * @return {String} + */ static get sliderFooter() { return TextFieldName._MAP.sliderFooter; } /** - * @return {String} - */ + * Primary text for Choice + * @return {String} + */ static get menuName() { return TextFieldName._MAP.menuName; } /** - * @return {String} - */ + * Secondary text for Choice + * @return {String} + */ static get secondaryText() { return TextFieldName._MAP.secondaryText; } /** - * @return {String} - */ + * Tertiary text for Choice + * @return {String} + */ static get tertiaryText() { return TextFieldName._MAP.tertiaryText; } /** - * @return {String} - */ + * Optional text to label an app menu button (for certain touchscreen platforms). + * @return {String} + */ static get menuTitle() { return TextFieldName._MAP.menuTitle; } /** - * @return {String} - */ + * Optional name / title of intended location for SendLocation. + * @return {String} + */ static get locationName() { return TextFieldName._MAP.locationName; } /** - * @return {String} - */ + * Optional description of intended location / establishment (if applicable) for SendLocation. + * @return {String} + */ static get locationDescription() { return TextFieldName._MAP.locationDescription; } /** - * @return {String} - */ + * Optional location address (if applicable) for SendLocation. + * @return {String} + */ static get addressLines() { return TextFieldName._MAP.addressLines; } /** - * @return {String} - */ + * Optional hone number of intended location / establishment (if applicable) for SendLocation. + * @return {String} + */ static get phoneNumber() { return TextFieldName._MAP.phoneNumber; } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ static valueForKey(key) { return TextFieldName._valueForKey(key, TextFieldName._MAP); } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ static keyForValue(value) { @@ -19632,93 +19183,71 @@ 'phoneNumber': 'phoneNumber' }); - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ /** + * The list of potential character sets * @typedef {Enum} CharacterSet * @property {Object} _MAP */ class CharacterSet extends Enum { + /** + * @constructor + */ constructor() { super(); } /** - * @return {String} - */ + * See + * @return {String} + */ static get TYPE2SET() { return CharacterSet._MAP.TYPE2SET; } /** - * @return {String} - */ + * See + * @return {String} + */ static get TYPE5SET() { return CharacterSet._MAP.TYPE5SET; } /** - * @return {String} - */ + * See + * @return {String} + */ static get CID1SET() { return CharacterSet._MAP.CID1SET; } /** - * @return {String} - */ + * See + * @return {String} + */ static get CID2SET() { return CharacterSet._MAP.CID2SET; } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ static valueForKey(key) { return CharacterSet._valueForKey(key, CharacterSet._MAP); } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ static keyForValue(value) { @@ -19734,84 +19263,57 @@ 'CID2SET': 'CID2SET' }); - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ class TextField extends RpcStruct { + /** + * @constructor + */ constructor(parameters) { super(parameters); } /** - * @param {TextFieldName} textFieldName - * @return {TextField} - */ + * @param {TextFieldName} name - The name that identifies the field. See TextFieldName. + * @return {TextField} + */ - setTextFieldName(textFieldName) { - this.validateType(TextFieldName, textFieldName); - this.setParameter(TextField.KEY_NAME, textFieldName); + setName(name) { + this.validateType(TextFieldName, name); + this.setParameter(TextField.KEY_NAME, name); return this; } /** - * @return {TextFieldName} - */ + * @return {TextFieldName} + */ - getTextFieldName() { + getName() { return this.getObject(TextFieldName, TextField.KEY_NAME); } /** - * @param {CharacterSet} textFieldName - * @return {TextField} - */ + * @param {CharacterSet} set - The character set that is supported in this field. See CharacterSet. + * @return {TextField} + */ - setCharacterSet(characterSet) { - this.validateType(CharacterSet, characterSet); - this.setParameter(TextField.KEY_CHARACTER_SET, characterSet); + setCharacterSet(set) { + this.validateType(CharacterSet, set); + this.setParameter(TextField.KEY_CHARACTER_SET, set); return this; } /** - * @return {CharacterSet} - */ + * @return {CharacterSet} + */ getCharacterSet() { return this.getObject(CharacterSet, TextField.KEY_CHARACTER_SET); } /** - * @param {Number} width - * @return {TextField} - */ + * @param {Number} width - The number of characters in one row of this field. + * @return {TextField} + */ setWidth(width) { @@ -19819,17 +19321,17 @@ return this; } /** - * @return {Number} - */ + * @return {Number} + */ getWidth() { return this.getParameter(TextField.KEY_WIDTH); } /** - * @param {Number} rows - * @return {TextField} - */ + * @param {Number} rows - The number of rows of this field. + * @return {TextField} + */ setRows(rows) { @@ -19837,8 +19339,8 @@ return this; } /** - * @return {Number} - */ + * @return {Number} + */ getRows() { @@ -19852,756 +19354,548 @@ TextField.KEY_WIDTH = 'width'; TextField.KEY_ROWS = 'rows'; - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ + /** + * Contains information about the display capabilities. This struct is deprecated; please see the new SystemCapability + * DISPLAYS and corresponding struct DisplayCapability + * @deprecated + */ - class ImageResolution extends RpcStruct { + class DisplayCapabilities extends RpcStruct { + /** + * @deprecated + * @constructor + */ constructor(parameters) { super(parameters); } /** - * @param {Number} resolutionWidth - * @return {ImageResolution} - */ + * @deprecated + * @param {DisplayType} type - The type of the display. See DisplayType + * @return {DisplayCapabilities} + */ - setResolutionWidth(resolutionWidth) { - this.setParameter(ImageResolution.KEY_RESOLUTION_WIDTH, resolutionWidth); + setDisplayType(type) { + this.validateType(DisplayType, type); + this.setParameter(DisplayCapabilities.KEY_DISPLAY_TYPE, type); return this; } /** - * @return {Number} - */ + * @deprecated + * @return {DisplayType} + */ - getResolutionWidth() { - return this.getParameter(ImageResolution.KEY_RESOLUTION_WIDTH); + getDisplayType() { + return this.getObject(DisplayType, DisplayCapabilities.KEY_DISPLAY_TYPE); } /** - * @param {Number} resolutionHeight - * @return {ImageResolution} - */ + * @deprecated + * @param {String} name - The name of the display the app is connected to. + * @return {DisplayCapabilities} + */ - setResolutionHeight(resolutionHeight) { - this.setParameter(ImageResolution.KEY_RESOLUTION_HEIGHT, resolutionHeight); + setDisplayName(name) { + this.setParameter(DisplayCapabilities.KEY_DISPLAY_NAME, name); return this; } /** - * @return {Number} - */ - - - getResolutionHeight() { - return this.getParameter(ImageResolution.KEY_RESOLUTION_HEIGHT); - } - - } - - ImageResolution.KEY_RESOLUTION_WIDTH = 'resolutionWidth'; - ImageResolution.KEY_RESOLUTION_HEIGHT = 'resolutionHeight'; - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - /** - * @typedef {Enum} ImageFieldName - * @property {Object} _MAP - */ - - class ImageFieldName extends Enum { - constructor() { - super(); - } - /** - * @return {String} - */ - - - static get softButtonImage() { - return ImageFieldName._MAP.softButtonImage; - } - /** - * @return {String} - */ + * @deprecated + * @return {String} + */ - static get choiceImage() { - return ImageFieldName._MAP.choiceImage; + getDisplayName() { + return this.getParameter(DisplayCapabilities.KEY_DISPLAY_NAME); } /** - * @return {String} - */ + * @deprecated + * @param {TextField[]} fields - A set of all fields that support text data. See TextField + * @return {DisplayCapabilities} + */ - static get choiceSecondaryImage() { - return ImageFieldName._MAP.choiceSecondaryImage; + setTextFields(fields) { + this.validateType(TextField, fields, true); + this.setParameter(DisplayCapabilities.KEY_TEXT_FIELDS, fields); + return this; } /** - * @return {String} - */ + * @deprecated + * @return {TextField[]} + */ - static get vrHelpItem() { - return ImageFieldName._MAP.vrHelpItem; + getTextFields() { + return this.getObject(TextField, DisplayCapabilities.KEY_TEXT_FIELDS); } /** - * @return {String} - */ + * @deprecated + * @param {ImageField[]} fields - A set of all fields that support images. See ImageField + * @return {DisplayCapabilities} + */ - static get turnIcon() { - return ImageFieldName._MAP.turnIcon; + setImageFields(fields) { + this.validateType(ImageField, fields, true); + this.setParameter(DisplayCapabilities.KEY_IMAGE_FIELDS, fields); + return this; } /** - * @return {String} - */ + * @deprecated + * @return {ImageField[]} + */ - static get menuIcon() { - return ImageFieldName._MAP.menuIcon; + getImageFields() { + return this.getObject(ImageField, DisplayCapabilities.KEY_IMAGE_FIELDS); } /** - * @return {String} - */ + * @deprecated + * @param {MediaClockFormat[]} formats - A set of all supported formats of the media clock. See MediaClockFormat + * @return {DisplayCapabilities} + */ - static get cmdIcon() { - return ImageFieldName._MAP.cmdIcon; + setMediaClockFormats(formats) { + this.validateType(MediaClockFormat, formats, true); + this.setParameter(DisplayCapabilities.KEY_MEDIA_CLOCK_FORMATS, formats); + return this; } /** - * @return {String} - */ + * @deprecated + * @return {MediaClockFormat[]} + */ - static get appIcon() { - return ImageFieldName._MAP.appIcon; + getMediaClockFormats() { + return this.getObject(MediaClockFormat, DisplayCapabilities.KEY_MEDIA_CLOCK_FORMATS); } /** - * @return {String} - */ + * @deprecated + * @param {Boolean} supported - The display's persistent screen supports referencing a static or dynamic image. + * @return {DisplayCapabilities} + */ - static get graphic() { - return ImageFieldName._MAP.graphic; + setGraphicSupported(supported) { + this.setParameter(DisplayCapabilities.KEY_GRAPHIC_SUPPORTED, supported); + return this; } /** - * @return {String} - */ + * @deprecated + * @return {Boolean} + */ - static get secondaryGraphic() { - return ImageFieldName._MAP.secondaryGraphic; + getGraphicSupported() { + return this.getParameter(DisplayCapabilities.KEY_GRAPHIC_SUPPORTED); } /** - * @return {String} - */ + * @deprecated + * @param {String[]} available - A set of all predefined persistent display templates available on headunit. To be + * referenced in SetDisplayLayout. + * @return {DisplayCapabilities} + */ - static get showConstantTBTIcon() { - return ImageFieldName._MAP.showConstantTBTIcon; + setTemplatesAvailable(available) { + this.setParameter(DisplayCapabilities.KEY_TEMPLATES_AVAILABLE, available); + return this; } /** - * @return {String} - */ + * @deprecated + * @return {String[]} + */ - static get showConstantTBTNextTurnIcon() { - return ImageFieldName._MAP.showConstantTBTNextTurnIcon; + getTemplatesAvailable() { + return this.getParameter(DisplayCapabilities.KEY_TEMPLATES_AVAILABLE); } /** - * @return {String} - */ + * @deprecated + * @param {ScreenParams} params - A set of all parameters related to a prescribed screen area (e.g. for video / + * touch input). + * @return {DisplayCapabilities} + */ - static get locationImage() { - return ImageFieldName._MAP.locationImage; + setScreenParams(params) { + this.validateType(ScreenParams, params); + this.setParameter(DisplayCapabilities.KEY_SCREEN_PARAMS, params); + return this; } /** - * @return {String} - */ + * @deprecated + * @return {ScreenParams} + */ - static get alertIcon() { - return ImageFieldName._MAP.alertIcon; + getScreenParams() { + return this.getObject(ScreenParams, DisplayCapabilities.KEY_SCREEN_PARAMS); } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * @deprecated + * @param {Number} available - The number of on-screen custom presets available (if any); otherwise omitted. + * @return {DisplayCapabilities} + */ - static valueForKey(key) { - return ImageFieldName._valueForKey(key, ImageFieldName._MAP); + setNumCustomPresetsAvailable(available) { + this.setParameter(DisplayCapabilities.KEY_NUM_CUSTOM_PRESETS_AVAILABLE, available); + return this; } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * @deprecated + * @return {Number} + */ - static keyForValue(value) { - return ImageFieldName._keyForValue(value, ImageFieldName._MAP); + getNumCustomPresetsAvailable() { + return this.getParameter(DisplayCapabilities.KEY_NUM_CUSTOM_PRESETS_AVAILABLE); } } - ImageFieldName._MAP = Object.freeze({ - 'softButtonImage': 'softButtonImage', - 'choiceImage': 'choiceImage', - 'choiceSecondaryImage': 'choiceSecondaryImage', - 'vrHelpItem': 'vrHelpItem', - 'turnIcon': 'turnIcon', - 'menuIcon': 'menuIcon', - 'cmdIcon': 'cmdIcon', - 'appIcon': 'appIcon', - 'graphic': 'graphic', - 'secondaryGraphic': 'secondaryGraphic', - 'showConstantTBTIcon': 'showConstantTBTIcon', - 'showConstantTBTNextTurnIcon': 'showConstantTBTNextTurnIcon', - 'locationImage': 'locationImage', - 'alertIcon': 'alertIcon' - }); + DisplayCapabilities.KEY_DISPLAY_TYPE = 'displayType'; + DisplayCapabilities.KEY_DISPLAY_NAME = 'displayName'; + DisplayCapabilities.KEY_TEXT_FIELDS = 'textFields'; + DisplayCapabilities.KEY_IMAGE_FIELDS = 'imageFields'; + DisplayCapabilities.KEY_MEDIA_CLOCK_FORMATS = 'mediaClockFormats'; + DisplayCapabilities.KEY_GRAPHIC_SUPPORTED = 'graphicSupported'; + DisplayCapabilities.KEY_TEMPLATES_AVAILABLE = 'templatesAvailable'; + DisplayCapabilities.KEY_SCREEN_PARAMS = 'screenParams'; + DisplayCapabilities.KEY_NUM_CUSTOM_PRESETS_AVAILABLE = 'numCustomPresetsAvailable'; - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ + /** + * Describes different sampling options for PerformAudioPassThru. + * @typedef {Enum} SamplingRate + * @property {Object} _MAP + */ - class ImageField extends RpcStruct { - constructor(parameters) { - super(parameters); + class SamplingRate extends Enum { + /** + * @constructor + */ + constructor() { + super(); } /** - * @param {ImageFieldName} imageFieldName - * @return {ImageField} - */ + * Sampling rate of 8000 Hz. + * @return {String} + */ - setImageFieldName(imageFieldName) { - this.validateType(ImageFieldName, imageFieldName); - this.setParameter(ImageField.KEY_NAME, imageFieldName); - return this; + static get SamplingRate_8KHZ() { + return SamplingRate._MAP.SamplingRate_8KHZ; } /** - * @return {ImageFieldName} - */ + * Sampling rate of 16000 Hz. + * @return {String} + */ - getImageFieldName() { - return this.getObject(ImageFieldName, ImageField.KEY_NAME); + static get SamplingRate_16KHZ() { + return SamplingRate._MAP.SamplingRate_16KHZ; } /** - * @param {FileType[]} imageTypeSupported - * @return {ImageField} - */ + * Sampling rate of 22050 Hz. + * @return {String} + */ - setImageTypeSupported(imageTypeSupported) { - this.validateType(FileType, imageTypeSupported, true); - this.setParameter(ImageField.KEY_IMAGE_TYPE_SUPPORTED, imageTypeSupported); - return this; + static get SamplingRate_22KHZ() { + return SamplingRate._MAP.SamplingRate_22KHZ; } /** - * @return {FileType} - */ + * Sampling rate of 44100 Hz. + * @return {String} + */ - getImageTypeSupported() { - return this.getObject(FileType, ImageField.KEY_IMAGE_TYPE_SUPPORTED); + static get SamplingRate_44KHZ() { + return SamplingRate._MAP.SamplingRate_44KHZ; } /** - * @param {ImageResolution} imageResolution - * @return {ImageField} - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ - setImageResolution(imageResolution) { - this.validateType(ImageResolution, imageResolution); - this.setParameter(ImageField.KEY_IMAGE_RESOLUTION, imageResolution); - return this; + static valueForKey(key) { + return SamplingRate._valueForKey(key, SamplingRate._MAP); } /** - * @return {ImageResolution} - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ - getImageResolution() { - return this.getObject(ImageResolution, ImageField.KEY_IMAGE_RESOLUTION); + static keyForValue(value) { + return SamplingRate._keyForValue(value, SamplingRate._MAP); } } - ImageField.KEY_NAME = 'name'; - ImageField.KEY_IMAGE_TYPE_SUPPORTED = 'imageTypeSupported'; - ImageField.KEY_IMAGE_RESOLUTION = 'imageResolution'; - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - class TouchEventCapabilities extends RpcStruct { - constructor(parameters) { - super(parameters); - } - /** - * @param {Boolean} pressAvailable - * @return {TouchEventCapabilities} - */ + SamplingRate._MAP = Object.freeze({ + 'SamplingRate_8KHZ': '8KHZ', + 'SamplingRate_16KHZ': '16KHZ', + 'SamplingRate_22KHZ': '22KHZ', + 'SamplingRate_44KHZ': '44KHZ' + }); + /* eslint-disable camelcase */ + /** + * Describes different quality options for PerformAudioPassThru. + * @typedef {Enum} BitsPerSample + * @property {Object} _MAP + */ - setPressAvailable(pressAvailable) { - this.setParameter(TouchEventCapabilities.KEY_PRESS_AVAILABLE, pressAvailable); - return this; - } + class BitsPerSample extends Enum { /** - * @return {Boolean} - */ - - - getPressAvailable() { - return this.getParameter(TouchEventCapabilities.KEY_PRESS_AVAILABLE); + * @constructor + */ + constructor() { + super(); } /** - * @param {Boolean} multiTouchAvailable - * @return {TouchEventCapabilities} - */ + * Audio sample is 8 bits wide, unsigned. + * @return {String} + */ - setMultiTouchAvailable(multiTouchAvailable) { - this.setParameter(TouchEventCapabilities.KEY_MULTI_TOUCH_AVAILABLE, multiTouchAvailable); - return this; + static get BitsPerSample_8_BIT() { + return BitsPerSample._MAP.BitsPerSample_8_BIT; } /** - * @return {Boolean} - */ + * Audio sample is 16 bits wide, signed, and in little endian. + * @return {String} + */ - getMultiTouchAvailable() { - return this.getParameter(TouchEventCapabilities.KEY_MULTI_TOUCH_AVAILABLE); + static get BitsPerSample_16_BIT() { + return BitsPerSample._MAP.BitsPerSample_16_BIT; } /** - * @param {Boolean} doublePressAvailable - * @return {TouchEventCapabilities} - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ - setDoublePressAvailable(doublePressAvailable) { - this.setParameter(TouchEventCapabilities.KEY_DOUBLE_PRESS_AVAILABLE, doublePressAvailable); - return this; + static valueForKey(key) { + return BitsPerSample._valueForKey(key, BitsPerSample._MAP); } /** - * @return {Boolean} - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ - getDoublePressAvailable() { - return this.getParameter(TouchEventCapabilities.KEY_DOUBLE_PRESS_AVAILABLE); + static keyForValue(value) { + return BitsPerSample._keyForValue(value, BitsPerSample._MAP); } } - TouchEventCapabilities.KEY_PRESS_AVAILABLE = 'pressAvailable'; - TouchEventCapabilities.KEY_MULTI_TOUCH_AVAILABLE = 'multiTouchAvailable'; - TouchEventCapabilities.KEY_DOUBLE_PRESS_AVAILABLE = 'doublePressAvailable'; + BitsPerSample._MAP = Object.freeze({ + 'BitsPerSample_8_BIT': '8_BIT', + 'BitsPerSample_16_BIT': '16_BIT' + }); - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ + /** + * Describes different audio type options for PerformAudioPassThru. + * @typedef {Enum} AudioType + * @property {Object} _MAP + */ - class ScreenParams extends RpcStruct { - constructor(parameters) { - super(parameters); - } + class AudioType extends Enum { /** - * @param {ImageResolution} resolution - * @return {ScreenParams} - */ - - - setResolution(resolution) { - this.validateType(ImageResolution, resolution); - this.setParameter(ScreenParams.KEY_RESOLUTION, resolution); - return this; + * @constructor + */ + constructor() { + super(); } /** - * @return {ImageResolution} - */ + * Linear PCM. + * @return {String} + */ - getResolution() { - return this.getObject(ImageResolution, ScreenParams.KEY_RESOLUTION); + static get PCM() { + return AudioType._MAP.PCM; } /** - * @param {TouchEventCapabilities} touchEventCapabilities - * @return {ScreenParams} - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ - setTouchEventAvailable(touchEventCapabilities) { - this.validateType(TouchEventCapabilities, touchEventCapabilities); - this.setParameter(ScreenParams.KEY_TOUCH_EVENT_AVAILABLE, touchEventCapabilities); - return this; + static valueForKey(key) { + return AudioType._valueForKey(key, AudioType._MAP); } /** - * @return {TouchEventCapabilities} - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ - getTouchEventAvailable() { - return this.getObject(TouchEventCapabilities, ScreenParams.KEY_TOUCH_EVENT_AVAILABLE); + static keyForValue(value) { + return AudioType._keyForValue(value, AudioType._MAP); } } - ScreenParams.KEY_RESOLUTION = 'resolution'; - ScreenParams.KEY_TOUCH_EVENT_AVAILABLE = 'touchEventAvailable'; + AudioType._MAP = Object.freeze({ + 'PCM': 'PCM' + }); - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ /** - * @typedef {Enum} DisplayType - * @property {Object} _MAP + * Describes different audio type configurations for PerformAudioPassThru. e.g. {8kHz,8-bit,PCM} The audio is recorded + * in monaural. */ - class DisplayType extends Enum { - constructor() { - super(); - } + class AudioPassThruCapabilities extends RpcStruct { /** - * @return {String} + * @constructor */ - - - static get CID() { - return DisplayType._MAP.CID; + constructor(parameters) { + super(parameters); } /** - * @return {String} + * @param {SamplingRate} rate - Describes different sampling options for PerformAudioPassThru. + * @return {AudioPassThruCapabilities} */ - static get TYPE2() { - return DisplayType._MAP.TYPE2; + setSamplingRate(rate) { + this.validateType(SamplingRate, rate); + this.setParameter(AudioPassThruCapabilities.KEY_SAMPLING_RATE, rate); + return this; } /** - * @return {String} + * @return {SamplingRate} */ - static get TYPE5() { - return DisplayType._MAP.TYPE5; + getSamplingRate() { + return this.getObject(SamplingRate, AudioPassThruCapabilities.KEY_SAMPLING_RATE); } /** - * @return {String} + * @param {BitsPerSample} sample - Describes different quality options for PerformAudioPassThru. + * @return {AudioPassThruCapabilities} */ - static get NGN() { - return DisplayType._MAP.NGN; + setBitsPerSample(sample) { + this.validateType(BitsPerSample, sample); + this.setParameter(AudioPassThruCapabilities.KEY_BITS_PER_SAMPLE, sample); + return this; } /** - * @return {String} + * @return {BitsPerSample} */ - static get GEN2_8_DMA() { - return DisplayType._MAP.GEN2_8_DMA; + getBitsPerSample() { + return this.getObject(BitsPerSample, AudioPassThruCapabilities.KEY_BITS_PER_SAMPLE); } /** - * @return {String} + * @param {AudioType} type - Describes different audio type options for PerformAudioPassThru. + * @return {AudioPassThruCapabilities} */ - static get GEN2_6_DMA() { - return DisplayType._MAP.GEN2_6_DMA; + setAudioType(type) { + this.validateType(AudioType, type); + this.setParameter(AudioPassThruCapabilities.KEY_AUDIO_TYPE, type); + return this; } /** - * @return {String} + * @return {AudioType} */ - static get MFD3() { - return DisplayType._MAP.MFD3; + getAudioType() { + return this.getObject(AudioType, AudioPassThruCapabilities.KEY_AUDIO_TYPE); } - /** - * @return {String} - */ + } - static get MFD4() { - return DisplayType._MAP.MFD4; - } - /** - * @return {String} - */ + AudioPassThruCapabilities.KEY_SAMPLING_RATE = 'samplingRate'; + AudioPassThruCapabilities.KEY_BITS_PER_SAMPLE = 'bitsPerSample'; + AudioPassThruCapabilities.KEY_AUDIO_TYPE = 'audioType'; + /* eslint-disable camelcase */ + /** + * Contains information about the VR capabilities. + * @typedef {Enum} VrCapabilities + * @property {Object} _MAP + */ - static get MFD5() { - return DisplayType._MAP.MFD5; - } + class VrCapabilities extends Enum { /** - * @return {String} + * @constructor */ - - - static get GEN3_8_INCH() { - return DisplayType._MAP.GEN3_8_INCH; + constructor() { + super(); } /** * @return {String} */ - static get SDL_GENERIC() { - return DisplayType._MAP.SDL_GENERIC; + static get VR_TEXT() { + return VrCapabilities._MAP.VR_TEXT; } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ static valueForKey(key) { - return DisplayType._valueForKey(key, DisplayType._MAP); + return VrCapabilities._valueForKey(key, VrCapabilities._MAP); } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ static keyForValue(value) { - return DisplayType._keyForValue(value, DisplayType._MAP); + return VrCapabilities._keyForValue(value, VrCapabilities._MAP); } } - DisplayType._MAP = Object.freeze({ - 'CID': 'CID', - 'TYPE2': 'TYPE2', - 'TYPE5': 'TYPE5', - 'NGN': 'NGN', - 'GEN2_8_DMA': 'GEN2_8_DMA', - 'GEN2_6_DMA': 'GEN2_6_DMA', - 'MFD3': 'MFD3', - 'MFD4': 'MFD4', - 'TESTING': 'TESTING', - 'MFD5': 'MFD5', - 'GEN3_8_INCH': 'GEN3_8-INCH', - 'SDL_GENERIC': 'SDL_GENERIC' + VrCapabilities._MAP = Object.freeze({ + 'VR_TEXT': 'TEXT' }); - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ /** - * @typedef {Enum} MediaClockFormat + * Defines the hard (physical) and soft (touchscreen) buttons available from the module + * @typedef {Enum} ButtonName * @property {Object} _MAP */ - class MediaClockFormat extends Enum { + class ButtonName extends Enum { + /** + * @constructor + */ constructor() { super(); } @@ -20610,792 +19904,169 @@ */ - static get CLOCK1() { - return MediaClockFormat._MAP.CLOCK1; + static get OK() { + return ButtonName._MAP.OK; } /** + * The button name for the physical Play/Pause toggle that can be used by media apps. * @return {String} */ - static get CLOCK2() { - return MediaClockFormat._MAP.CLOCK2; + static get PLAY_PAUSE() { + return ButtonName._MAP.PLAY_PAUSE; } /** * @return {String} */ - static get CLOCK3() { - return MediaClockFormat._MAP.CLOCK3; + static get SEEKLEFT() { + return ButtonName._MAP.SEEKLEFT; } /** * @return {String} */ - static get CLOCKTEXT1() { - return MediaClockFormat._MAP.CLOCKTEXT1; + static get SEEKRIGHT() { + return ButtonName._MAP.SEEKRIGHT; } /** * @return {String} */ - static get CLOCKTEXT2() { - return MediaClockFormat._MAP.CLOCKTEXT2; + static get TUNEUP() { + return ButtonName._MAP.TUNEUP; } /** * @return {String} */ - static get CLOCKTEXT3() { - return MediaClockFormat._MAP.CLOCKTEXT3; + static get TUNEDOWN() { + return ButtonName._MAP.TUNEDOWN; } /** * @return {String} */ - static get CLOCKTEXT4() { - return MediaClockFormat._MAP.CLOCKTEXT4; + static get PRESET_0() { + return ButtonName._MAP.PRESET_0; } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * @return {String} + */ - static valueForKey(key) { - return MediaClockFormat._valueForKey(key, MediaClockFormat._MAP); + static get PRESET_1() { + return ButtonName._MAP.PRESET_1; } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * @return {String} + */ - static keyForValue(value) { - return MediaClockFormat._keyForValue(value, MediaClockFormat._MAP); + static get PRESET_2() { + return ButtonName._MAP.PRESET_2; } + /** + * @return {String} + */ - } - - MediaClockFormat._MAP = Object.freeze({ - 'CLOCK1': 'CLOCK1', - 'CLOCK2': 'CLOCK2', - 'CLOCK3': 'CLOCK3', - 'CLOCKTEXT1': 'CLOCKTEXT1', - 'CLOCKTEXT2': 'CLOCKTEXT2', - 'CLOCKTEXT3': 'CLOCKTEXT3', - 'CLOCKTEXT4': 'CLOCKTEXT4' - }); - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - class DisplayCapabilities extends RpcStruct { - constructor(parameters) { - super(parameters); + static get PRESET_3() { + return ButtonName._MAP.PRESET_3; } /** - * @param {DisplayType} displayType - * @return {DisplayCapabilities} - */ + * @return {String} + */ - setDisplayType(displayType) { - this.validateType(DisplayType, displayType); - this.setParameter(DisplayCapabilities.KEY_DISPLAY_TYPE, displayType); - return this; + static get PRESET_4() { + return ButtonName._MAP.PRESET_4; } /** - * @return {DisplayType} - */ + * @return {String} + */ - getDisplayType() { - return this.getObject(DisplayType, DisplayCapabilities.KEY_DISPLAY_TYPE); + static get PRESET_5() { + return ButtonName._MAP.PRESET_5; } /** - * @param {String} displayName - * @return {DisplayCapabilities} - */ + * @return {String} + */ - setDisplayName(displayName) { - this.setParameter(DisplayCapabilities.KEY_DISPLAY_NAME, displayName); - return this; + static get PRESET_6() { + return ButtonName._MAP.PRESET_6; } /** - * @return {String} - */ + * @return {String} + */ - getDisplayName() { - return this.getParameter(DisplayCapabilities.KEY_DISPLAY_NAME); + static get PRESET_7() { + return ButtonName._MAP.PRESET_7; } /** - * @param {Array} textFields - * @return {DisplayCapabilities} - */ + * @return {String} + */ - setTextFields(textFields) { - // TODO make work with arrays - // this.validateType(TextField, textFields); - this.setParameter(DisplayCapabilities.KEY_TEXT_FIELDS, textFields); - return this; + static get PRESET_8() { + return ButtonName._MAP.PRESET_8; } /** - * @return {Array} - */ + * @return {String} + */ - getTextFields() { - return this.getObject(TextField, DisplayCapabilities.KEY_TEXT_FIELDS); + static get PRESET_9() { + return ButtonName._MAP.PRESET_9; } /** - * @param {Array} imageFields - * @return {DisplayCapabilities} - */ + * @return {String} + */ - setImageFields(imageFields) { - // TODO make work with arrays - // this.validateType(ImageField, imageFields); - this.setParameter(DisplayCapabilities.KEY_IMAGE_FIELDS, imageFields); - return this; + static get CUSTOM_BUTTON() { + return ButtonName._MAP.CUSTOM_BUTTON; } /** - * @return {Array} - */ + * @return {String} + */ - getImageFields() { - return this.getObject(ImageField, DisplayCapabilities.KEY_IMAGE_FIELDS); + static get SEARCH() { + return ButtonName._MAP.SEARCH; } /** - * @param {Array} mediaClockFormats - * @return {DisplayCapabilities} - */ + * @return {String} + */ - setMediaClockFormats(mediaClockFormats) { - // TODO make work with arrays - // this.validateType(ImageField, mediaClockFormats); - this.setParameter(DisplayCapabilities.KEY_MEDIA_CLOCK_FORMATS, mediaClockFormats); - return this; + static get AC_MAX() { + return ButtonName._MAP.AC_MAX; } /** - * @return {Array} - */ + * @return {String} + */ - getMediaClockFormats() { - return this.getObject(MediaClockFormat, DisplayCapabilities.KEY_MEDIA_CLOCK_FORMATS); + static get AC() { + return ButtonName._MAP.AC; } /** - * @param {Boolean} graphicSupported - * @return {DisplayCapabilities} - */ + * @return {String} + */ - setGraphicsSupported(graphicSupported) { - this.setParameter(DisplayCapabilities.KEY_GRAPHICS_SUPPORTED, graphicSupported); - return this; - } - /** - * @return {Boolean} - */ - - - getGraphicsSupported() { - return this.getParameter(DisplayCapabilities.KEY_GRAPHICS_SUPPORTED); - } - /** - * @param {Array} templatesAvailable - * @return {DisplayCapabilities} - */ - - - setTemplatesAvailable(templatesAvailable) { - // TODO make work with arrays - // this.validateType(String, templatesAvailable); - this.setParameter(DisplayCapabilities.KEY_TEMPLATES_AVAILABLE, templatesAvailable); - return this; - } - /** - * @return {Array} - */ - - - getTemplatesAvailable() { - return this.getParameter(DisplayCapabilities.KEY_TEMPLATES_AVAILABLE); - } - /** - * @param {ScreenParams} screenParams - * @return {DisplayCapabilities} - */ - - - setScreenParams(screenParams) { - this.validateType(ScreenParams, screenParams); - this.setParameter(DisplayCapabilities.KEY_SCREEN_PARAMS, screenParams); - return this; - } - /** - * @return {ScreenParams} - */ - - - getScreenParams() { - return this.getObject(ScreenParams, DisplayCapabilities.KEY_SCREEN_PARAMS); - } - /** - * @param {Array} numCustomPresetsAvailable - * @return {DisplayCapabilities} - */ - - - setNumCustomPresetsAvailable(numCustomPresetsAvailable) { - // TODO make work with arrays - // this.validateType(Number, numCustomPresetsAvailable); - this.setParameter(DisplayCapabilities.KEY_NUM_CUSTOM_PRESETS_AVAILABLE, numCustomPresetsAvailable); - return this; - } - /** - * @return {Array} - */ - - - getNumCustomPresetsAvailable() { - return this.getParameter(DisplayCapabilities.KEY_NUM_CUSTOM_PRESETS_AVAILABLE); - } - - } - - DisplayCapabilities.KEY_DISPLAY_TYPE = 'displayType'; - DisplayCapabilities.KEY_DISPLAY_NAME = 'displayName'; - DisplayCapabilities.KEY_TEXT_FIELDS = 'textFields'; - DisplayCapabilities.KEY_IMAGE_FIELDS = 'imageFields'; - DisplayCapabilities.KEY_MEDIA_CLOCK_FORMATS = 'mediaClockFormats'; - DisplayCapabilities.KEY_GRAPHICS_SUPPORTED = 'graphicSupported'; - DisplayCapabilities.KEY_TEMPLATES_AVAILABLE = 'templatesAvailable'; - DisplayCapabilities.KEY_SCREEN_PARAMS = 'screenParams'; - DisplayCapabilities.KEY_NUM_CUSTOM_PRESETS_AVAILABLE = 'numCustomPresetsAvailable'; - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - class Grid extends RpcStruct { - constructor(parameters) { - super(parameters); - } - /** - * @param {Number} column - * @return {Grid} - */ - - - setColumn(column) { - this.setParameter(Grid.KEY_COLUMN, column); - return this; - } - /** - * @return {Number} - */ - - - getColumn() { - return this.getParameter(Grid.KEY_COLUMN); - } - /** - * @param {Number} row - * @return {Grid} - */ - - - setRow(row) { - this.setParameter(Grid.KEY_ROW, row); - return this; - } - /** - * @return {Number} - */ - - - getRow() { - return this.getParameter(Grid.KEY_ROW); - } - /** - * @param {Number} level - * @return {Grid} - */ - - - setLevel(level) { - this.setParameter(Grid.KEY_LEVEL, level); - return this; - } - /** - * @return {Number} - */ - - - getLevel() { - return this.getParameter(Grid.KEY_LEVEL); - } - /** - * @param {Number} columnSpan - * @return {Grid} - */ - - - setColumnSpan(columnSpan) { - this.setParameter(Grid.KEY_COLUMN_SPAN, columnSpan); - return this; - } - /** - * @return {Number} - */ - - - getColumnSpan() { - return this.getParameter(Grid.KEY_COLUMN_SPAN); - } - /** - * @param {Number} rowSpan - * @return {Grid} - */ - - - setRowSpan(rowSpan) { - this.setParameter(Grid.KEY_ROW_SPAN, rowSpan); - return this; - } - /** - * @return {Number} - */ - - - getRowSpan() { - return this.getParameter(Grid.KEY_ROW_SPAN); - } - /** - * @param {Number} levelSpan - * @return {Grid} - */ - - - setLevelSpan(levelSpan) { - this.setParameter(Grid.KEY_LEVEL_SPAN, levelSpan); - return this; - } - /** - * @return {Number} - */ - - - getLevelSpan() { - return this.getParameter(Grid.KEY_LEVEL_SPAN); - } - - } - - Grid.KEY_COLUMN = 'col'; - Grid.KEY_ROW = 'row'; - Grid.KEY_LEVEL = 'level'; - Grid.KEY_COLUMN_SPAN = 'colspan'; - Grid.KEY_ROW_SPAN = 'rowspan'; - Grid.KEY_LEVEL_SPAN = 'levelspan'; - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - class ModuleInfo extends RpcStruct { - constructor(parameters) { - super(parameters); - } - /** - * @param {String} moduleId - * @return {ModuleInfo} - */ - - - setModuleId(moduleId) { - this.setParameter(ModuleInfo.KEY_MODULE_ID, moduleId); - return this; - } - /** - * @return {String} - */ - - - getModuleId() { - return this.getParameter(ModuleInfo.KEY_MODULE_ID); - } - /** - * @param {Grid} location - * @return {ModuleInfo} - */ - - - setLocation(location) { - this.validateType(Grid, location); - this.setParameter(ModuleInfo.KEY_LOCATION, location); - return this; - } - /** - * @return {Grid} - */ - - - getLocation() { - return this.getObject(Grid, ModuleInfo.KEY_LOCATION); - } - /** - * @param {Grid} serviceArea - * @return {ModuleInfo} - */ - - - setServiceArea(serviceArea) { - this.validateType(Grid, serviceArea); - this.setParameter(ModuleInfo.KEY_SERVICE_AREA, serviceArea); - return this; - } - /** - * @return {Grid} - */ - - - getServiceArea() { - return this.getObject(Grid, ModuleInfo.KEY_SERVICE_AREA); - } - /** - * @param {Boolean} allowMultipleAccess - * @return {ModuleInfo} - */ - - - setAllowMultipleAccess(allowMultipleAccess) { - this.setParameter(ModuleInfo.KEY_ALLOW_MULTIPLE_ACCESS, allowMultipleAccess); - return this; - } - /** - * @return {Boolean} - */ - - - getAllowMultipleAccess() { - return this.getParameter(ModuleInfo.KEY_ALLOW_MULTIPLE_ACCESS); - } - - } - - ModuleInfo.KEY_MODULE_ID = 'moduleId'; - ModuleInfo.KEY_LOCATION = 'location'; - ModuleInfo.KEY_SERVICE_AREA = 'serviceArea'; - ModuleInfo.KEY_ALLOW_MULTIPLE_ACCESS = 'allowMultipleAccess'; - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - /** - * @typedef {Enum} ButtonName - * @property {Object} _MAP - */ - - class ButtonName extends Enum { - constructor() { - super(); - } - /** - * @return {String} - */ - - - static get OK() { - return ButtonName._MAP.OK; - } - /** - * @return {String} - */ - - - static get PLAY_PAUSE() { - return ButtonName._MAP.PLAY_PAUSE; - } - /** - * @return {String} - */ - - - static get SEEKLEFT() { - return ButtonName._MAP.SEEKLEFT; - } - /** - * @return {String} - */ - - - static get SEEKRIGHT() { - return ButtonName._MAP.SEEKRIGHT; - } - /** - * @return {String} - */ - - - static get TUNEUP() { - return ButtonName._MAP.TUNEUP; - } - /** - * @return {String} - */ - - - static get TUNEDOWN() { - return ButtonName._MAP.TUNEDOWN; - } - /** - * @return {String} - */ - - - static get PRESET_0() { - return ButtonName._MAP.PRESET_0; - } - /** - * @return {String} - */ - - - static get PRESET_1() { - return ButtonName._MAP.PRESET_1; - } - /** - * @return {String} - */ - - - static get PRESET_2() { - return ButtonName._MAP.PRESET_2; - } - /** - * @return {String} - */ - - - static get PRESET_3() { - return ButtonName._MAP.PRESET_3; - } - /** - * @return {String} - */ - - - static get PRESET_4() { - return ButtonName._MAP.PRESET_4; - } - /** - * @return {String} - */ - - - static get PRESET_5() { - return ButtonName._MAP.PRESET_5; - } - /** - * @return {String} - */ - - - static get PRESET_6() { - return ButtonName._MAP.PRESET_6; - } - /** - * @return {String} - */ - - - static get PRESET_7() { - return ButtonName._MAP.PRESET_7; - } - /** - * @return {String} - */ - - - static get PRESET_8() { - return ButtonName._MAP.PRESET_8; - } - /** - * @return {String} - */ - - - static get PRESET_9() { - return ButtonName._MAP.PRESET_9; - } - /** - * @return {String} - */ - - - static get CUSTOM_BUTTON() { - return ButtonName._MAP.CUSTOM_BUTTON; - } - /** - * @return {String} - */ - - - static get SEARCH() { - return ButtonName._MAP.SEARCH; - } - /** - * @return {String} - */ - - - static get AC_MAX() { - return ButtonName._MAP.AC_MAX; - } - /** - * @return {String} - */ - - - static get AC() { - return ButtonName._MAP.AC; - } - /** - * @return {String} - */ - - - static get RECIRCULATE() { - return ButtonName._MAP.RECIRCULATE; + static get RECIRCULATE() { + return ButtonName._MAP.RECIRCULATE; } /** * @return {String} @@ -21606,6 +20277,9 @@ return ButtonName._MAP.NAV_PAN_UP_LEFT; } /** + * If supported, this toggles between a top-down view and an angled/3D view. If your app supports different, but + * substantially similar options, then you may implement those. If you don't implement these or similar options, + * do not subscribe to this button. * @return {String} */ @@ -21630,6 +20304,9 @@ return ButtonName._MAP.NAV_ROTATE_COUNTERCLOCKWISE; } /** + * If supported, this toggles between locking the orientation to north or to the vehicle's heading. If your app + * supports different, but substantially similar options, then you may implement those. If you don't implement + * these or similar options, do not subscribe to this button. * @return {String} */ @@ -21638,20 +20315,20 @@ return ButtonName._MAP.NAV_HEADING_TOGGLE; } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ static valueForKey(key) { return ButtonName._valueForKey(key, ButtonName._MAP); } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ static keyForValue(value) { @@ -21714,1828 +20391,1427 @@ 'NAV_HEADING_TOGGLE': 'NAV_HEADING_TOGGLE' }); - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ + /** + * Describes a location (origin coordinates and span) of a vehicle component. + */ - class ButtonCapabilities extends RpcStruct { + class Grid extends RpcStruct { + /** + * @constructor + */ constructor(parameters) { super(parameters); } /** - * @param {ButtonName} name - * @return {ButtonCapabilities} - */ + * @param {Number} col + * @return {Grid} + */ - setName(name) { - this.validateType(ButtonName, name); - this.setParameter(ButtonCapabilities.KEY_NAME, name); + setColumn(col) { + this.setParameter(Grid.KEY_COLUMN, col); return this; } /** - * @return {ButtonName} - */ + * @return {Number} + */ - getName() { - return this.getObject(ButtonName, ButtonCapabilities.KEY_NAME); + getColumn() { + return this.getParameter(Grid.KEY_COLUMN); } /** - * @param {ModuleInfo} moduleInfo - * @return {ButtonCapabilities} - */ + * @param {Number} row + * @return {Grid} + */ - setModuleInfo(moduleInfo) { - this.validateType(ModuleInfo, moduleInfo); - this.setParameter(ButtonCapabilities.KEY_MODULE_INFO, moduleInfo); + setRow(row) { + this.setParameter(Grid.KEY_ROW, row); return this; } /** - * @return {ModuleInfo} - */ + * @return {Number} + */ - getModuleInfo() { - return this.getObject(ModuleInfo, ButtonCapabilities.KEY_MODULE_INFO); + getRow() { + return this.getParameter(Grid.KEY_ROW); } /** - * @param {Boolean} shortPressAvailable - * @return {ButtonCapabilities} - */ + * @param {Number} level + * @return {Grid} + */ - setShortPressAvailable(shortPressAvailable) { - this.setParameter(ButtonCapabilities.KEY_SHORT_PRESS_AVAILABLE, shortPressAvailable); + setLevel(level) { + this.setParameter(Grid.KEY_LEVEL, level); return this; } /** - * @return {Boolean} - */ + * @return {Number} + */ - getShortPressAvailable() { - return this.getParameter(ButtonCapabilities.KEY_SHORT_PRESS_AVAILABLE); + getLevel() { + return this.getParameter(Grid.KEY_LEVEL); } /** - * @param {Boolean} longPressAvailable - * @return {ButtonCapabilities} - */ + * @param {Number} colspan + * @return {Grid} + */ - setLongPressAvailable(longPressAvailable) { - this.setParameter(ButtonCapabilities.KEY_LONG_PRESS_AVAILABLE, longPressAvailable); + setColumnSpan(colspan) { + this.setParameter(Grid.KEY_COLUMN_SPAN, colspan); return this; } /** - * @return {Boolean} - */ + * @return {Number} + */ - getLongPressAvailable() { - return this.getParameter(ButtonCapabilities.KEY_LONG_PRESS_AVAILABLE); + getColumnSpan() { + return this.getParameter(Grid.KEY_COLUMN_SPAN); } /** - * @param {Boolean} upDownAvailable - * @return {ButtonCapabilities} - */ + * @param {Number} rowspan + * @return {Grid} + */ - setUpDownAvailable(upDownAvailable) { - this.setParameter(ButtonCapabilities.KEY_UP_DOWN_AVAILABLE, upDownAvailable); + setRowSpan(rowspan) { + this.setParameter(Grid.KEY_ROW_SPAN, rowspan); return this; } /** - * @return {Boolean} - */ + * @return {Number} + */ - getUpDownAvailable() { - return this.getParameter(ButtonCapabilities.KEY_UP_DOWN_AVAILABLE); + getRowSpan() { + return this.getParameter(Grid.KEY_ROW_SPAN); } + /** + * @param {Number} levelspan + * @return {Grid} + */ - } - - ButtonCapabilities.KEY_NAME = 'name'; - ButtonCapabilities.KEY_MODULE_INFO = 'moduleInfo'; - ButtonCapabilities.KEY_SHORT_PRESS_AVAILABLE = 'shortPressAvailable'; - ButtonCapabilities.KEY_LONG_PRESS_AVAILABLE = 'longPressAvailable'; - ButtonCapabilities.KEY_UP_DOWN_AVAILABLE = 'upDownAvailable'; - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - class SoftButtonCapabilities extends RpcStruct { - constructor(parameters) { - super(parameters); + setLevelSpan(levelspan) { + this.setParameter(Grid.KEY_LEVEL_SPAN, levelspan); + return this; } /** - * @param {Boolean} shortPressAvailable - * @return {SoftButtonCapabilities} - */ + * @return {Number} + */ - setShortPressAvailable(shortPressAvailable) { - this.setParameter(SoftButtonCapabilities.KEY_SHORT_PRESS_AVAILABLE, shortPressAvailable); - return this; + getLevelSpan() { + return this.getParameter(Grid.KEY_LEVEL_SPAN); } - /** - * @return {Boolean} - */ + } - getShortPressAvailable() { - return this.getParameter(SoftButtonCapabilities.KEY_SHORT_PRESS_AVAILABLE); + Grid.KEY_COLUMN = 'col'; + Grid.KEY_ROW = 'row'; + Grid.KEY_LEVEL = 'level'; + Grid.KEY_COLUMN_SPAN = 'colspan'; + Grid.KEY_ROW_SPAN = 'rowspan'; + Grid.KEY_LEVEL_SPAN = 'levelspan'; + + /* eslint-disable camelcase */ + /** + * Information about a RC module + */ + + class ModuleInfo extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); } /** - * @param {Boolean} longPressAvailable - * @return {SoftButtonCapabilities} - */ + * @param {String} id - uuid of a module. "moduleId + moduleType" uniquely identify a module. + * @return {ModuleInfo} + */ - setLongPressAvailable(longPressAvailable) { - this.setParameter(SoftButtonCapabilities.KEY_LONG_PRESS_AVAILABLE, longPressAvailable); + setModuleId(id) { + this.setParameter(ModuleInfo.KEY_MODULE_ID, id); return this; } /** - * @return {Boolean} - */ + * @return {String} + */ - getLongPressAvailable() { - return this.getParameter(SoftButtonCapabilities.KEY_LONG_PRESS_AVAILABLE); + getModuleId() { + return this.getParameter(ModuleInfo.KEY_MODULE_ID); } /** - * @param {Boolean} upDownAvailable - * @return {SoftButtonCapabilities} - */ + * @param {Grid} location - Location of a module. + * @return {ModuleInfo} + */ - setUpDownAvailable(upDownAvailable) { - this.setParameter(SoftButtonCapabilities.KEY_UP_DOWN_AVAILABLE, upDownAvailable); + setLocation(location) { + this.validateType(Grid, location); + this.setParameter(ModuleInfo.KEY_LOCATION, location); return this; } /** - * @return {Boolean} - */ + * @return {Grid} + */ - getUpDownAvailable() { - return this.getParameter(SoftButtonCapabilities.KEY_UP_DOWN_AVAILABLE); + getLocation() { + return this.getObject(Grid, ModuleInfo.KEY_LOCATION); } /** - * @param {Boolean} imageSupported - * @return {SoftButtonCapabilities} - */ + * @param {Grid} area - Service area of a module. + * @return {ModuleInfo} + */ - setImageSupported(imageSupported) { - this.setParameter(SoftButtonCapabilities.KEY_IMAGE_SUPPORTED, imageSupported); + setServiceArea(area) { + this.validateType(Grid, area); + this.setParameter(ModuleInfo.KEY_SERVICE_AREA, area); return this; } /** - * @return {Boolean} - */ + * @return {Grid} + */ - getImageSupported() { - return this.getParameter(SoftButtonCapabilities.KEY_IMAGE_SUPPORTED); + getServiceArea() { + return this.getObject(Grid, ModuleInfo.KEY_SERVICE_AREA); } /** - * @param {Boolean} textSupported - * @return {SoftButtonCapabilities} - */ + * @param {Boolean} access - allow multiple users/apps to access the module or not + * @return {ModuleInfo} + */ - setTextSupported(textSupported) { - this.setParameter(SoftButtonCapabilities.KEY_TEXT_SUPPORTED, textSupported); + setAllowMultipleAccess(access) { + this.setParameter(ModuleInfo.KEY_ALLOW_MULTIPLE_ACCESS, access); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ - getTextSupported() { - return this.getParameter(SoftButtonCapabilities.KEY_TEXT_SUPPORTED); + getAllowMultipleAccess() { + return this.getParameter(ModuleInfo.KEY_ALLOW_MULTIPLE_ACCESS); } } - SoftButtonCapabilities.KEY_SHORT_PRESS_AVAILABLE = 'shortPressAvailable'; - SoftButtonCapabilities.KEY_LONG_PRESS_AVAILABLE = 'longPressAvailable'; - SoftButtonCapabilities.KEY_UP_DOWN_AVAILABLE = 'upDownAvailable'; - SoftButtonCapabilities.KEY_IMAGE_SUPPORTED = 'imageSupported'; - SoftButtonCapabilities.KEY_TEXT_SUPPORTED = 'textSupported'; + ModuleInfo.KEY_MODULE_ID = 'moduleId'; + ModuleInfo.KEY_LOCATION = 'location'; + ModuleInfo.KEY_SERVICE_AREA = 'serviceArea'; + ModuleInfo.KEY_ALLOW_MULTIPLE_ACCESS = 'allowMultipleAccess'; - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ + /** + * Contains information about a button's capabilities. + */ - class PresetBankCapabilities extends RpcStruct { + class ButtonCapabilities extends RpcStruct { + /** + * @constructor + */ constructor(parameters) { super(parameters); } /** - * @param {Boolean} onScreenPresetsAvailable - * @return {PresetBankCapabilities} - */ + * @param {ButtonName} name - The name of the button. See ButtonName. + * @return {ButtonCapabilities} + */ - setOnScreenPresetsAvailable(onScreenPresetsAvailable) { - this.setParameter(PresetBankCapabilities.KEY_ON_SCREEN_PRESETS_AVAILABLE, onScreenPresetsAvailable); + setName(name) { + this.validateType(ButtonName, name); + this.setParameter(ButtonCapabilities.KEY_NAME, name); return this; } /** - * @return {Boolean} - */ - - - getOnScreenPresetsAvailable() { - return this.getParameter(PresetBankCapabilities.KEY_ON_SCREEN_PRESETS_AVAILABLE); - } - - } - - PresetBankCapabilities.KEY_ON_SCREEN_PRESETS_AVAILABLE = 'onScreenPresetsAvailable'; + * @return {ButtonName} + */ - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - class VehicleType extends RpcStruct { - constructor(parameters) { - super(parameters); + getName() { + return this.getObject(ButtonName, ButtonCapabilities.KEY_NAME); } /** - * @param {String} make - * @return {VehicleType} - */ + * @param {ModuleInfo} info - Information about a RC module, including its id. + * @return {ButtonCapabilities} + */ - setMake(make) { - this.setParameter(VehicleType.KEY_MAKE, make); + setModuleInfo(info) { + this.validateType(ModuleInfo, info); + this.setParameter(ButtonCapabilities.KEY_MODULE_INFO, info); return this; } /** - * @return {String} - */ + * @return {ModuleInfo} + */ - getMake() { - return this.getParameter(VehicleType.KEY_MAKE); + getModuleInfo() { + return this.getObject(ModuleInfo, ButtonCapabilities.KEY_MODULE_INFO); } /** - * @param {String} model - * @return {VehicleType} - */ + * @param {Boolean} available - The button supports a short press. Whenever the button is pressed short, + * onButtonPressed( SHORT) will be invoked. + * @return {ButtonCapabilities} + */ - setModel(model) { - this.setParameter(VehicleType.KEY_MODEL, model); + setShortPressAvailable(available) { + this.setParameter(ButtonCapabilities.KEY_SHORT_PRESS_AVAILABLE, available); return this; } /** - * @return {String} - */ + * @return {Boolean} + */ - getModel() { - return this.getParameter(VehicleType.KEY_MODEL); + getShortPressAvailable() { + return this.getParameter(ButtonCapabilities.KEY_SHORT_PRESS_AVAILABLE); } /** - * @param {String} modelYear - * @return {VehicleType} - */ + * @param {Boolean} available - The button supports a LONG press. Whenever the button is pressed long, + * onButtonPressed( LONG) will be invoked. + * @return {ButtonCapabilities} + */ - setModelYear(modelYear) { - this.setParameter(VehicleType.KEY_MODEL_YEAR, modelYear); + setLongPressAvailable(available) { + this.setParameter(ButtonCapabilities.KEY_LONG_PRESS_AVAILABLE, available); return this; } /** - * @return {String} - */ + * @return {Boolean} + */ - getModelYear() { - return this.getParameter(VehicleType.KEY_MODEL_YEAR); + getLongPressAvailable() { + return this.getParameter(ButtonCapabilities.KEY_LONG_PRESS_AVAILABLE); } /** - * @param {String} trim - * @return {VehicleType} - */ + * @param {Boolean} available - The button supports "button down" and "button up". Whenever the button is pressed, + * onButtonEvent( DOWN) will be invoked. Whenever the button is released, + * onButtonEvent( UP) will be invoked. + * @return {ButtonCapabilities} + */ - setTrim(trim) { - this.setParameter(VehicleType.KEY_TRIM, trim); + setUpDownAvailable(available) { + this.setParameter(ButtonCapabilities.KEY_UP_DOWN_AVAILABLE, available); return this; } /** - * @return {String} - */ + * @return {Boolean} + */ - getTrim() { - return this.getParameter(VehicleType.KEY_TRIM); + getUpDownAvailable() { + return this.getParameter(ButtonCapabilities.KEY_UP_DOWN_AVAILABLE); } } - VehicleType.KEY_MAKE = 'make'; - VehicleType.KEY_MODEL = 'model'; - VehicleType.KEY_MODEL_YEAR = 'modelYear'; - VehicleType.KEY_TRIM = 'trim'; + ButtonCapabilities.KEY_NAME = 'name'; + ButtonCapabilities.KEY_MODULE_INFO = 'moduleInfo'; + ButtonCapabilities.KEY_SHORT_PRESS_AVAILABLE = 'shortPressAvailable'; + ButtonCapabilities.KEY_LONG_PRESS_AVAILABLE = 'longPressAvailable'; + ButtonCapabilities.KEY_UP_DOWN_AVAILABLE = 'upDownAvailable'; - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - /** - * @typedef {Enum} FileType - * @property {Object} _MAP - */ + /* eslint-disable camelcase */ - class HmiZoneCapabilities extends Enum { - constructor() { - super(); + class HMICapabilities extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); } /** - * @return {String} + * @param {Boolean} navigation - Availability of build in Nav. True: Available, False: Not Available + * @return {HMICapabilities} */ - static get FRONT() { - return HmiZoneCapabilities._MAP.FRONT; + setNavigation(navigation) { + this.setParameter(HMICapabilities.KEY_NAVIGATION, navigation); + return this; } /** - * @return {String} + * @return {Boolean} */ - static get BACK() { - return HmiZoneCapabilities._MAP.BACK; + getNavigation() { + return this.getParameter(HMICapabilities.KEY_NAVIGATION); } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * @param {Boolean} call - Availability of build in phone. True: Available, False: Not Available + * @return {HMICapabilities} + */ - static valueForKey(key) { - return HmiZoneCapabilities._valueForKey(key, HmiZoneCapabilities._MAP); + setPhoneCall(call) { + this.setParameter(HMICapabilities.KEY_PHONE_CALL, call); + return this; } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * @return {Boolean} + */ - static keyForValue(value) { - return HmiZoneCapabilities._keyForValue(value, HmiZoneCapabilities._MAP); + getPhoneCall() { + return this.getParameter(HMICapabilities.KEY_PHONE_CALL); } + /** + * @param {Boolean} streaming - Availability of video streaming. + * @return {HMICapabilities} + */ - } - - HmiZoneCapabilities._MAP = Object.freeze({ - 'FRONT': 'FRONT', - 'BACK': 'BACK' - }); - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - /** - * @typedef {Enum} PrerecordedSpeech - * @property {Object} _MAP - */ - class PrerecordedSpeech extends Enum { - constructor() { - super(); + setVideoStreaming(streaming) { + this.setParameter(HMICapabilities.KEY_VIDEO_STREAMING, streaming); + return this; } /** - * @return {String} + * @return {Boolean} */ - static get HELP_JINGLE() { - return PrerecordedSpeech._MAP.HELP_JINGLE; + getVideoStreaming() { + return this.getParameter(HMICapabilities.KEY_VIDEO_STREAMING); } /** - * @return {String} + * @param {Boolean} control - Availability of remote control feature. True: Available, False: Not Available + * @return {HMICapabilities} */ - static get INITIAL_JINGLE() { - return PrerecordedSpeech._MAP.INITIAL_JINGLE; + setRemoteControl(control) { + this.setParameter(HMICapabilities.KEY_REMOTE_CONTROL, control); + return this; } /** - * @return {String} + * @return {Boolean} */ - static get LISTEN_JINGLE() { - return PrerecordedSpeech._MAP.LISTEN_JINGLE; + getRemoteControl() { + return this.getParameter(HMICapabilities.KEY_REMOTE_CONTROL); } /** - * @return {String} + * @param {Boolean} services - Availability of App Services functionality. True: Available, False: Not Available + * @return {HMICapabilities} */ - static get POSITIVE_JINGLE() { - return PrerecordedSpeech._MAP.POSITIVE_JINGLE; + setAppServices(services) { + this.setParameter(HMICapabilities.KEY_APP_SERVICES, services); + return this; } /** - * @return {String} + * @return {Boolean} */ - static get NEGATIVE_JINGLE() { - return PrerecordedSpeech._MAP.NEGATIVE_JINGLE; + getAppServices() { + return this.getParameter(HMICapabilities.KEY_APP_SERVICES); } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * @param {Boolean} displays - Availability of displays capability. True: Available, False: Not Available + * @return {HMICapabilities} + */ - static valueForKey(key) { - return PrerecordedSpeech._valueForKey(key, PrerecordedSpeech._MAP); + setDisplays(displays) { + this.setParameter(HMICapabilities.KEY_DISPLAYS, displays); + return this; } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * @return {Boolean} + */ - static keyForValue(value) { - return PrerecordedSpeech._keyForValue(value, PrerecordedSpeech._MAP); + getDisplays() { + return this.getParameter(HMICapabilities.KEY_DISPLAYS); + } + /** + * @param {Boolean} location - Availability of seat location feature. True: Available, False: Not Available + * @return {HMICapabilities} + */ + + + setSeatLocation(location) { + this.setParameter(HMICapabilities.KEY_SEAT_LOCATION, location); + return this; + } + /** + * @return {Boolean} + */ + + + getSeatLocation() { + return this.getParameter(HMICapabilities.KEY_SEAT_LOCATION); } } - PrerecordedSpeech._MAP = Object.freeze({ - 'HELP_JINGLE': 'HELP_JINGLE', - 'INITIAL_JINGLE': 'INITIAL_JINGLE', - 'LISTEN_JINGLE': 'LISTEN_JINGLE', - 'POSITIVE_JINGLE': 'POSITIVE_JINGLE', - 'NEGATIVE_JINGLE': 'NEGATIVE_JINGLE' - }); + HMICapabilities.KEY_NAVIGATION = 'navigation'; + HMICapabilities.KEY_PHONE_CALL = 'phoneCall'; + HMICapabilities.KEY_VIDEO_STREAMING = 'videoStreaming'; + HMICapabilities.KEY_REMOTE_CONTROL = 'remoteControl'; + HMICapabilities.KEY_APP_SERVICES = 'appServices'; + HMICapabilities.KEY_DISPLAYS = 'displays'; + HMICapabilities.KEY_SEAT_LOCATION = 'seatLocation'; - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ /** - * @typedef {Enum} SamplingRate - * @property {Object} _MAP + * The response to registerAppInterface */ - class SamplingRate extends Enum { - constructor() { - super(); + class RegisterAppInterfaceResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.RegisterAppInterface); } /** - * @return {String} + * @param {SdlMsgVersion} version - See SyncMsgVersion + * @return {RegisterAppInterfaceResponse} */ - static get SamplingRate_8KHZ() { - return SamplingRate._MAP.SamplingRate_8KHZ; + setSdlMsgVersion(version) { + this.validateType(SdlMsgVersion, version); + this.setParameter(RegisterAppInterfaceResponse.KEY_SDL_MSG_VERSION, version); + return this; } /** - * @return {String} + * @return {SdlMsgVersion} */ - static get SamplingRate_16KHZ() { - return SamplingRate._MAP.SamplingRate_16KHZ; + getSdlMsgVersion() { + return this.getObject(SdlMsgVersion, RegisterAppInterfaceResponse.KEY_SDL_MSG_VERSION); } /** - * @return {String} + * @param {Language} language - The currently active VR+TTS language on the module. See "Language" for options. + * @return {RegisterAppInterfaceResponse} */ - static get SamplingRate_22KHZ() { - return SamplingRate._MAP.SamplingRate_22KHZ; + setLanguage(language) { + this.validateType(Language, language); + this.setParameter(RegisterAppInterfaceResponse.KEY_LANGUAGE, language); + return this; } /** - * @return {String} + * @return {Language} */ - static get SamplingRate_44KHZ() { - return SamplingRate._MAP.SamplingRate_44KHZ; + getLanguage() { + return this.getObject(Language, RegisterAppInterfaceResponse.KEY_LANGUAGE); } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * @param {Language} language - The currently active display language on the module. See "Language" for options. + * @return {RegisterAppInterfaceResponse} + */ - static valueForKey(key) { - return SamplingRate._valueForKey(key, SamplingRate._MAP); + setHmiDisplayLanguage(language) { + this.validateType(Language, language); + this.setParameter(RegisterAppInterfaceResponse.KEY_HMI_DISPLAY_LANGUAGE, language); + return this; } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * @return {Language} + */ - static keyForValue(value) { - return SamplingRate._keyForValue(value, SamplingRate._MAP); + getHmiDisplayLanguage() { + return this.getObject(Language, RegisterAppInterfaceResponse.KEY_HMI_DISPLAY_LANGUAGE); } + /** + * @param {DisplayCapabilities} capabilities - See DisplayCapabilities. This parameter is deprecated and replaced by + * SystemCapability using DISPLAYS. + * @return {RegisterAppInterfaceResponse} + */ - } // We have to use SamplingRate_ prefix in the name because javascript will not - // allow the enum to start with a number - - - SamplingRate._MAP = Object.freeze({ - 'SamplingRate_8KHZ': '8KHZ', - 'SamplingRate_16KHZ': '16KHZ', - 'SamplingRate_22KHZ': '22KHZ', - 'SamplingRate_44KHZ': '44KHZ' - }); - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - /** - * @typedef {Enum} BitsPerSample - * @property {Object} _MAP - */ - class BitsPerSample extends Enum { - constructor() { - super(); + setDisplayCapabilities(capabilities) { + this.validateType(DisplayCapabilities, capabilities); + this.setParameter(RegisterAppInterfaceResponse.KEY_DISPLAY_CAPABILITIES, capabilities); + return this; } /** - * @return {String} + * @return {DisplayCapabilities} */ - static get BitsPerSample_8_BIT() { - return BitsPerSample._MAP.BitsPerSample_8_BIT; + getDisplayCapabilities() { + return this.getObject(DisplayCapabilities, RegisterAppInterfaceResponse.KEY_DISPLAY_CAPABILITIES); } /** - * @return {String} + * @param {ButtonCapabilities[]} capabilities - See ButtonCapabilities. This parameter is deprecated and replaced by + * SystemCapability using DISPLAYS. + * @return {RegisterAppInterfaceResponse} */ - static get BitsPerSample_16_BIT() { - return BitsPerSample._MAP.BitsPerSample_16_BIT; + setButtonCapabilities(capabilities) { + this.validateType(ButtonCapabilities, capabilities, true); + this.setParameter(RegisterAppInterfaceResponse.KEY_BUTTON_CAPABILITIES, capabilities); + return this; } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * @return {ButtonCapabilities[]} + */ - static valueForKey(key) { - return BitsPerSample._valueForKey(key, BitsPerSample._MAP); + getButtonCapabilities() { + return this.getObject(ButtonCapabilities, RegisterAppInterfaceResponse.KEY_BUTTON_CAPABILITIES); } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * @param {SoftButtonCapabilities[]} capabilities - If returned, the platform supports on-screen SoftButtons; see + * SoftButtonCapabilities. This parameter is deprecated and + * replaced by SystemCapability using DISPLAYS. + * @return {RegisterAppInterfaceResponse} + */ - static keyForValue(value) { - return BitsPerSample._keyForValue(value, BitsPerSample._MAP); + setSoftButtonCapabilities(capabilities) { + this.validateType(SoftButtonCapabilities, capabilities, true); + this.setParameter(RegisterAppInterfaceResponse.KEY_SOFT_BUTTON_CAPABILITIES, capabilities); + return this; } + /** + * @return {SoftButtonCapabilities[]} + */ - } // We have to use BitsPerSample_ prefix in the name because javascript will not - // allow the enum to start with a number - - - BitsPerSample._MAP = Object.freeze({ - 'BitsPerSample_8_BIT': '8_BIT', - 'BitsPerSample_16_BIT': '16_BIT' - }); - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - /** - * @typedef {Enum} AudioType - * @property {Object} _MAP - */ - class AudioType extends Enum { - constructor() { - super(); + getSoftButtonCapabilities() { + return this.getObject(SoftButtonCapabilities, RegisterAppInterfaceResponse.KEY_SOFT_BUTTON_CAPABILITIES); } /** - * @return {String} + * @param {PresetBankCapabilities} capabilities - If returned, the platform supports custom on-screen Presets; see + * PresetBankCapabilities. This parameter is deprecated and replaced + * by SystemCapability using DISPLAYS. + * @return {RegisterAppInterfaceResponse} */ - static get PCM() { - return AudioType._MAP.PCM; + setPresetBankCapabilities(capabilities) { + this.validateType(PresetBankCapabilities, capabilities); + this.setParameter(RegisterAppInterfaceResponse.KEY_PRESET_BANK_CAPABILITIES, capabilities); + return this; } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * @return {PresetBankCapabilities} + */ - static valueForKey(key) { - return AudioType._valueForKey(key, AudioType._MAP); + getPresetBankCapabilities() { + return this.getObject(PresetBankCapabilities, RegisterAppInterfaceResponse.KEY_PRESET_BANK_CAPABILITIES); } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * @param {HmiZoneCapabilities[]} capabilities - See HmiZoneCapabilities + * @return {RegisterAppInterfaceResponse} + */ - static keyForValue(value) { - return AudioType._keyForValue(value, AudioType._MAP); + setHmiZoneCapabilities(capabilities) { + this.validateType(HmiZoneCapabilities, capabilities, true); + this.setParameter(RegisterAppInterfaceResponse.KEY_HMI_ZONE_CAPABILITIES, capabilities); + return this; } + /** + * @return {HmiZoneCapabilities[]} + */ - } - - AudioType._MAP = Object.freeze({ - 'PCM': 'PCM' - }); - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - class AudioPassThruCapabilities extends RpcStruct { - constructor(parameters) { - super(parameters); + getHmiZoneCapabilities() { + return this.getObject(HmiZoneCapabilities, RegisterAppInterfaceResponse.KEY_HMI_ZONE_CAPABILITIES); } /** - * @param {SamplingRate} samplingRate - * @return {AudioPassThruCapabilities} - */ + * @param {SpeechCapabilities[]} capabilities - See SpeechCapabilities + * @return {RegisterAppInterfaceResponse} + */ - setSamplingRate(samplingRate) { - this.validateType(SamplingRate, samplingRate); - this.setParameter(AudioPassThruCapabilities.KEY_SAMPLING_RATE, samplingRate); + setSpeechCapabilities(capabilities) { + this.validateType(SpeechCapabilities, capabilities, true); + this.setParameter(RegisterAppInterfaceResponse.KEY_SPEECH_CAPABILITIES, capabilities); return this; } /** - * @return {SamplingRate} - */ + * @return {SpeechCapabilities[]} + */ - getSamplingRate() { - return this.getObject(SamplingRate, AudioPassThruCapabilities.KEY_SAMPLING_RATE); + getSpeechCapabilities() { + return this.getObject(SpeechCapabilities, RegisterAppInterfaceResponse.KEY_SPEECH_CAPABILITIES); } /** - * @param {BitsPerSample} bitsPerSample - * @return {AudioPassThruCapabilities} - */ + * @param {PrerecordedSpeech[]} speech - See PrerecordedSpeech + * @return {RegisterAppInterfaceResponse} + */ - setBitsPerSample(bitsPerSample) { - this.validateType(BitsPerSample, bitsPerSample); - this.setParameter(AudioPassThruCapabilities.KEY_BITS_PER_SAMPLE, bitsPerSample); + setPrerecordedSpeech(speech) { + this.validateType(PrerecordedSpeech, speech, true); + this.setParameter(RegisterAppInterfaceResponse.KEY_PRERECORDED_SPEECH, speech); return this; } /** - * @return {BitsPerSample} - */ + * @return {PrerecordedSpeech[]} + */ - getBitsPerSample() { - return this.getObject(BitsPerSample, AudioPassThruCapabilities.KEY_BITS_PER_SAMPLE); + getPrerecordedSpeech() { + return this.getObject(PrerecordedSpeech, RegisterAppInterfaceResponse.KEY_PRERECORDED_SPEECH); } /** - * @param {AudioType} bitsPerSample - * @return {AudioPassThruCapabilities} - */ + * @param {VrCapabilities[]} capabilities - See VrCapabilities + * @return {RegisterAppInterfaceResponse} + */ - setAudioType(audioType) { - this.validateType(AudioType, audioType); - this.setParameter(AudioPassThruCapabilities.KEY_AUDIO_TYPE, audioType); + setVrCapabilities(capabilities) { + this.validateType(VrCapabilities, capabilities, true); + this.setParameter(RegisterAppInterfaceResponse.KEY_VR_CAPABILITIES, capabilities); return this; } /** - * @return {AudioType} - */ + * @return {VrCapabilities[]} + */ - getAudioType() { - return this.getObject(AudioType, AudioPassThruCapabilities.KEY_AUDIO_TYPE); + getVrCapabilities() { + return this.getObject(VrCapabilities, RegisterAppInterfaceResponse.KEY_VR_CAPABILITIES); } + /** + * @param {AudioPassThruCapabilities[]} capabilities - See AudioPassThruCapability + * @return {RegisterAppInterfaceResponse} + */ - } - - AudioPassThruCapabilities.KEY_SAMPLING_RATE = 'samplingRate'; - AudioPassThruCapabilities.KEY_BITS_PER_SAMPLE = 'bitsPerSample'; - AudioPassThruCapabilities.KEY_AUDIO_TYPE = 'audioType'; - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - /** - * @typedef {Enum} VrCapabilities - * @property {Object} _MAP - */ - class VrCapabilities extends Enum { - constructor() { - super(); + setAudioPassThruCapabilities(capabilities) { + this.validateType(AudioPassThruCapabilities, capabilities, true); + this.setParameter(RegisterAppInterfaceResponse.KEY_AUDIO_PASS_THRU_CAPABILITIES, capabilities); + return this; } /** - * @return {String} + * @return {AudioPassThruCapabilities[]} */ - static get VR_TEXT() { - return VrCapabilities._MAP.VR_TEXT; + getAudioPassThruCapabilities() { + return this.getObject(AudioPassThruCapabilities, RegisterAppInterfaceResponse.KEY_AUDIO_PASS_THRU_CAPABILITIES); } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * @param {AudioPassThruCapabilities} capabilities - See AudioPassThruCapability + * @return {RegisterAppInterfaceResponse} + */ - static valueForKey(key) { - return VrCapabilities._valueForKey(key, VrCapabilities._MAP); + setPcmStreamCapabilities(capabilities) { + this.validateType(AudioPassThruCapabilities, capabilities); + this.setParameter(RegisterAppInterfaceResponse.KEY_PCM_STREAM_CAPABILITIES, capabilities); + return this; } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * @return {AudioPassThruCapabilities} + */ - static keyForValue(value) { - return VrCapabilities._keyForValue(value, VrCapabilities._MAP); + getPcmStreamCapabilities() { + return this.getObject(AudioPassThruCapabilities, RegisterAppInterfaceResponse.KEY_PCM_STREAM_CAPABILITIES); } + /** + * @param {VehicleType} type - Specifies the vehicle's type. See VehicleType. + * @return {RegisterAppInterfaceResponse} + */ - } - VrCapabilities._MAP = Object.freeze({ - 'VR_TEXT': 'TEXT' - }); + setVehicleType(type) { + this.validateType(VehicleType, type); + this.setParameter(RegisterAppInterfaceResponse.KEY_VEHICLE_TYPE, type); + return this; + } + /** + * @return {VehicleType} + */ - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - class HMICapabilities extends RpcStruct { - constructor(parameters) { - super(parameters); + getVehicleType() { + return this.getObject(VehicleType, RegisterAppInterfaceResponse.KEY_VEHICLE_TYPE); } /** - * @param {Boolean} navigation - * @return {HMICapabilities} - */ + * @param {Number[]} modes - Specifies the white-list of supported diagnostic modes (0x00-0xFF) capable for + * DiagnosticMessage requests. If a mode outside this list is requested, it will be + * rejected. + * @return {RegisterAppInterfaceResponse} + */ - setNavigation(navigation) { - this.setParameter(HMICapabilities.KEY_NAVIGATION, navigation); + setSupportedDiagModes(modes) { + this.setParameter(RegisterAppInterfaceResponse.KEY_SUPPORTED_DIAG_MODES, modes); return this; } /** - * @return {Boolean} - */ + * @return {Number[]} + */ - getNavigation() { - return this.getParameter(HMICapabilities.KEY_NAVIGATION); + getSupportedDiagModes() { + return this.getParameter(RegisterAppInterfaceResponse.KEY_SUPPORTED_DIAG_MODES); } /** - * @param {Boolean} phoneCall - * @return {HMICapabilities} - */ + * @param {HMICapabilities} capabilities - Specifies the HMI's capabilities. See HMICapabilities. + * @return {RegisterAppInterfaceResponse} + */ - setPhoneCall(phoneCall) { - this.setParameter(HMICapabilities.KEY_PHONE_CALL, phoneCall); + setHmiCapabilities(capabilities) { + this.validateType(HMICapabilities, capabilities); + this.setParameter(RegisterAppInterfaceResponse.KEY_HMI_CAPABILITIES, capabilities); return this; } /** - * @return {Boolean} - */ + * @return {HMICapabilities} + */ - getPhoneCall() { - return this.getParameter(HMICapabilities.KEY_PHONE_CALL); + getHmiCapabilities() { + return this.getObject(HMICapabilities, RegisterAppInterfaceResponse.KEY_HMI_CAPABILITIES); } /** - * @param {Boolean} videoStreaming - * @return {HMICapabilities} - */ + * @param {String} version - The SmartDeviceLink version. + * @return {RegisterAppInterfaceResponse} + */ - setVideoStreaming(videoStreaming) { - this.setParameter(HMICapabilities.KEY_VIDEO_STREAMING, videoStreaming); + setSdlVersion(version) { + this.setParameter(RegisterAppInterfaceResponse.KEY_SDL_VERSION, version); return this; } /** - * @return {Boolean} - */ + * @return {String} + */ - getVideoStreaming() { - return this.getParameter(HMICapabilities.KEY_VIDEO_STREAMING); + getSdlVersion() { + return this.getParameter(RegisterAppInterfaceResponse.KEY_SDL_VERSION); } /** - * @param {Boolean} remoteControl - * @return {HMICapabilities} - */ + * @param {String} version - The software version of the system that implements the SmartDeviceLink core. + * @return {RegisterAppInterfaceResponse} + */ - setRemoteControl(remoteControl) { - this.setParameter(HMICapabilities.KEY_REMOTE_CONTROL, remoteControl); + setSystemSoftwareVersion(version) { + this.setParameter(RegisterAppInterfaceResponse.KEY_SYSTEM_SOFTWARE_VERSION, version); return this; } /** - * @return {Boolean} - */ + * @return {String} + */ - getRemoteControl() { - return this.getParameter(HMICapabilities.KEY_REMOTE_CONTROL); + getSystemSoftwareVersion() { + return this.getParameter(RegisterAppInterfaceResponse.KEY_SYSTEM_SOFTWARE_VERSION); } /** - * @param {Boolean} appServices - * @return {HMICapabilities} - */ + * @param {Boolean} resumed - Existence of apps icon at system. If true, apps icon was resumed at system. If false, + * apps icon is not resumed at system + * @return {RegisterAppInterfaceResponse} + */ - setAppService(appServices) { - this.setParameter(HMICapabilities.KEY_APP_SERVICES, appServices); + setIconResumed(resumed) { + this.setParameter(RegisterAppInterfaceResponse.KEY_ICON_RESUMED, resumed); return this; } /** - * @return {Boolean} - */ + * @return {Boolean} + */ - getAppService() { - return this.getParameter(HMICapabilities.KEY_APP_SERVICES); + getIconResumed() { + return this.getParameter(RegisterAppInterfaceResponse.KEY_ICON_RESUMED); } + + } + + RegisterAppInterfaceResponse.KEY_SDL_MSG_VERSION = 'syncMsgVersion'; + RegisterAppInterfaceResponse.KEY_LANGUAGE = 'language'; + RegisterAppInterfaceResponse.KEY_HMI_DISPLAY_LANGUAGE = 'hmiDisplayLanguage'; + RegisterAppInterfaceResponse.KEY_DISPLAY_CAPABILITIES = 'displayCapabilities'; + RegisterAppInterfaceResponse.KEY_BUTTON_CAPABILITIES = 'buttonCapabilities'; + RegisterAppInterfaceResponse.KEY_SOFT_BUTTON_CAPABILITIES = 'softButtonCapabilities'; + RegisterAppInterfaceResponse.KEY_PRESET_BANK_CAPABILITIES = 'presetBankCapabilities'; + RegisterAppInterfaceResponse.KEY_HMI_ZONE_CAPABILITIES = 'hmiZoneCapabilities'; + RegisterAppInterfaceResponse.KEY_SPEECH_CAPABILITIES = 'speechCapabilities'; + RegisterAppInterfaceResponse.KEY_PRERECORDED_SPEECH = 'prerecordedSpeech'; + RegisterAppInterfaceResponse.KEY_VR_CAPABILITIES = 'vrCapabilities'; + RegisterAppInterfaceResponse.KEY_AUDIO_PASS_THRU_CAPABILITIES = 'audioPassThruCapabilities'; + RegisterAppInterfaceResponse.KEY_PCM_STREAM_CAPABILITIES = 'pcmStreamCapabilities'; + RegisterAppInterfaceResponse.KEY_VEHICLE_TYPE = 'vehicleType'; + RegisterAppInterfaceResponse.KEY_SUPPORTED_DIAG_MODES = 'supportedDiagModes'; + RegisterAppInterfaceResponse.KEY_HMI_CAPABILITIES = 'hmiCapabilities'; + RegisterAppInterfaceResponse.KEY_SDL_VERSION = 'sdlVersion'; + RegisterAppInterfaceResponse.KEY_SYSTEM_SOFTWARE_VERSION = 'systemSoftwareVersion'; + RegisterAppInterfaceResponse.KEY_ICON_RESUMED = 'iconResumed'; + + /* eslint-disable camelcase */ + /** + * Closes an interface from a mobile application. After unregisterAppInterface, no commands other than + * registerAppInterface will be accepted/executed. Will fail, if no registerAppInterface was completed successfully + * before. + */ + + class UnregisterAppInterface extends RpcRequest { /** - * @param {Boolean} displays - * @return {HMICapabilities} - */ + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.UnregisterAppInterface); + } + } - setDisplays(displays) { - this.setParameter(HMICapabilities.KEY_DISPLAYS, displays); - return this; + /* eslint-disable camelcase */ + + class UnregisterAppInterfaceResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.UnregisterAppInterface); } + + } + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} WindowType + * @property {Object} _MAP + */ + + class WindowType extends Enum { /** - * @return {Boolean} - */ + * @constructor + */ + constructor() { + super(); + } + /** + * This window type describes the main window on a display. + * @return {String} + */ - getDisplays() { - return this.getParameter(HMICapabilities.KEY_DISPLAYS); + static get MAIN() { + return WindowType._MAP.MAIN; } /** - * @param {Boolean} seatLocation - * @return {HMICapabilities} - */ + * A widget is a small window that the app can create to provide information and soft buttons for quick app + * control. + * @return {String} + */ - setSeatLocation(seatLocation) { - this.setParameter(HMICapabilities.KEY_SEAT_LOCATION, seatLocation); - return this; + static get WIDGET() { + return WindowType._MAP.WIDGET; } /** - * @return {Boolean} - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ - getSeatLocation() { - return this.getParameter(HMICapabilities.KEY_SEAT_LOCATION); + static valueForKey(key) { + return WindowType._valueForKey(key, WindowType._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return WindowType._keyForValue(value, WindowType._MAP); } } - HMICapabilities.KEY_NAVIGATION = 'navigation'; - HMICapabilities.KEY_PHONE_CALL = 'phoneCall'; - HMICapabilities.KEY_VIDEO_STREAMING = 'videoStreaming'; - HMICapabilities.KEY_REMOTE_CONTROL = 'remoteControl'; - HMICapabilities.KEY_APP_SERVICES = 'appServices'; - HMICapabilities.KEY_DISPLAYS = 'displays'; - HMICapabilities.KEY_SEAT_LOCATION = 'seatLocation'; + WindowType._MAP = Object.freeze({ + 'MAIN': 'MAIN', + 'WIDGET': 'WIDGET' + }); - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ + /** + * Create a new window on the display with the specified window type. + */ - class RegisterAppInterfaceResponse extends RpcResponse { + class CreateWindow extends RpcRequest { + /** + * @constructor + */ constructor(store) { super(store); - this.setFunctionName(FunctionID.RegisterAppInterface); + this.setFunctionName(FunctionID.CreateWindow); } /** - * @param {SdlMsgVersion} The max RPC Spec version supported by this library - * @return {RegisterAppInterfaceResponse} - */ + * @param {Number} id - A unique ID to identify the window. The value of '0' will always be the default main window + * on the main display and should not be used in this context as it will already be created for + * the app. See PredefinedWindows enum. Creating a window with an ID that is already in use + * will be rejected with `INVALID_ID`. + * @return {CreateWindow} + */ - setSdlMsgVersion(sdlMsgVersion) { - this.validateType(SdlMsgVersion, sdlMsgVersion); - this.setParameter(RegisterAppInterfaceResponse.KEY_SDL_MSG_VERSION, sdlMsgVersion); + setWindowID(id) { + this.setParameter(CreateWindow.KEY_WINDOW_ID, id); return this; } /** - * @return {SdlMsgVersion} - */ + * @return {Number} + */ - getSdlMsgVersion() { - return this.getObject(SdlMsgVersion, RegisterAppInterfaceResponse.KEY_SDL_MSG_VERSION); + getWindowID() { + return this.getParameter(CreateWindow.KEY_WINDOW_ID); } /** - * @param {Language} language - * @return {RegisterAppInterfaceResponse} - */ + * @param {String} name - The window name to be used by the HMI. The name of the pre-created default window will + * match the app name. Multiple apps can share the same window name except for the default + * main window. Creating a window with a name which is already in use by the app will result + * in `DUPLICATE_NAME`. + * @return {CreateWindow} + */ - setLanguage(language) { - this.validateType(Language, language); - this.setParameter(RegisterAppInterfaceResponse.KEY_LANGUAGE, language); + setWindowName(name) { + this.setParameter(CreateWindow.KEY_WINDOW_NAME, name); return this; } /** - * @return {Language} - */ + * @return {String} + */ - getLanguage() { - return this.getObject(Language, RegisterAppInterfaceResponse.KEY_LANGUAGE); + getWindowName() { + return this.getParameter(CreateWindow.KEY_WINDOW_NAME); } /** - * @param {Language} hmiDisplayLanguage - * @return {RegisterAppInterfaceResponse} - */ + * @param {WindowType} type - The type of the window to be created. Main window or widget. + * @return {CreateWindow} + */ - setHmiDisplayLanguage(hmiDisplayLanguage) { - this.validateType(Language, hmiDisplayLanguage); - this.setParameter(RegisterAppInterfaceResponse.KEY_HMI_DISPLAY_LANGUAGE, hmiDisplayLanguage); + setType(type) { + this.validateType(WindowType, type); + this.setParameter(CreateWindow.KEY_TYPE, type); return this; } /** - * @return {Language} - */ + * @return {WindowType} + */ - getHmiDisplayLanguage() { - return this.getObject(Language, RegisterAppInterfaceResponse.KEY_HMI_DISPLAY_LANGUAGE); + getType() { + return this.getObject(WindowType, CreateWindow.KEY_TYPE); } /** - * @param {DisplayCapabilities} displayCapabilities - * @return {RegisterAppInterfaceResponse} - */ + * @param {String} type - Allows an app to create a widget related to a specific service type. As an example if a + * `MEDIA` app becomes active, this app becomes audible and is allowed to play audio. Actions + * such as skip or play/pause will be directed to this active media app. In case of widgets, + * the system can provide a single "media" widget which will act as a placeholder for the + * active media app. It is only allowed to have one window per service type. This means that + * a media app can only have a single MEDIA widget. Still the app can create widgets omitting + * this parameter. Those widgets would be available as app specific widgets that are + * permanently included in the HMI. This parameter is related to widgets only. The default + * main window, which is pre-created during app registration, will be created based on the + * HMI types specified in the app registration request. + * @return {CreateWindow} + */ - setDisplayCapabilities(displayCapabilities) { - this.validateType(DisplayCapabilities, displayCapabilities); - this.setParameter(RegisterAppInterfaceResponse.KEY_DISPLAY_CAPABILITIES, displayCapabilities); + setAssociatedServiceType(type) { + this.setParameter(CreateWindow.KEY_ASSOCIATED_SERVICE_TYPE, type); return this; } /** - * @return {DisplayCapabilities} - */ + * @return {String} + */ - getDisplayCapabilities() { - return this.getObject(DisplayCapabilities, RegisterAppInterfaceResponse.KEY_DISPLAY_CAPABILITIES); + getAssociatedServiceType() { + return this.getParameter(CreateWindow.KEY_ASSOCIATED_SERVICE_TYPE); } /** - * @param {Array} buttonCapabilities - * @return {RegisterAppInterfaceResponse} - */ + * @param {Number} id - Optional parameter. Specify whether the content sent to an existing window should be + * duplicated to the created window. If there isn't a window with the ID, the request will be + * rejected with `INVALID_DATA`. + * @return {CreateWindow} + */ - setButtonCapabilities(buttonCapabilities) { - // TODO make this work with arrays - // this.validateType(Language, buttonCapabilities); - this.setParameter(RegisterAppInterfaceResponse.KEY_BUTTON_CAPABILITIES, buttonCapabilities); + setDuplicateUpdatesFromWindowID(id) { + this.setParameter(CreateWindow.KEY_DUPLICATE_UPDATES_FROM_WINDOW_ID, id); return this; } /** - * @return {Array} - */ + * @return {Number} + */ - getButtonCapabilities() { - return this.getObject(ButtonCapabilities, RegisterAppInterfaceResponse.KEY_BUTTON_CAPABILITIES); + getDuplicateUpdatesFromWindowID() { + return this.getParameter(CreateWindow.KEY_DUPLICATE_UPDATES_FROM_WINDOW_ID); } - /** - * @param {Array} softButtonCapabilities - * @return {RegisterAppInterfaceResponse} - */ + } - setSoftButtonCapabilities(softButtonCapabilities) { - // TODO make this work with arrays - // this.validateType(SoftButtonCapabilities, softButtonCapabilities); - this.setParameter(RegisterAppInterfaceResponse.KEY_SOFT_BUTTON_CAPABILITIES, softButtonCapabilities); - return this; - } - /** - * @return {Array} - */ + CreateWindow.KEY_WINDOW_ID = 'windowID'; + CreateWindow.KEY_WINDOW_NAME = 'windowName'; + CreateWindow.KEY_TYPE = 'type'; + CreateWindow.KEY_ASSOCIATED_SERVICE_TYPE = 'associatedServiceType'; + CreateWindow.KEY_DUPLICATE_UPDATES_FROM_WINDOW_ID = 'duplicateUpdatesFromWindowID'; + /* eslint-disable camelcase */ - getSoftButtonCapabilities() { - return this.getObject(SoftButtonCapabilities, RegisterAppInterfaceResponse.KEY_SOFT_BUTTON_CAPABILITIES); - } + class CreateWindowResponse extends RpcResponse { /** - * @param {PresetBankCapabilities} presetBankCapabilities - * @return {RegisterAppInterfaceResponse} - */ - - - setPresetBankCapabilities(presetBankCapabilities) { - this.validateType(PresetBankCapabilities, presetBankCapabilities); - this.setParameter(RegisterAppInterfaceResponse.KEY_PRESET_BANK_CAPABILITIES, presetBankCapabilities); - return this; + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.CreateWindow); } - /** - * @return {PresetBankCapabilities} - */ + } - getPresetBankCapabilities() { - return this.getObject(PresetBankCapabilities, RegisterAppInterfaceResponse.KEY_PRESET_BANK_CAPABILITIES); + /* eslint-disable camelcase */ + /** + * Deletes previously created window of the SDL application. + */ + + class DeleteWindow extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.DeleteWindow); } /** - * @param {Array} hmiZoneCapabilities - * @return {RegisterAppInterfaceResponse} - */ + * @param {Number} id - A unique ID to identify the window. The value of '0' will always be the default main window + * on the main display and cannot be deleted. See PredefinedWindows enum. + * @return {DeleteWindow} + */ - setHmiZoneCapabilities(hmiZoneCapabilities) { - // TODO make this work for arrays - // this.validateType(HmiZoneCapabilities, hmiZoneCapabilities); - this.setParameter(RegisterAppInterfaceResponse.KEY_HMI_ZONE_CAPABILITIES, hmiZoneCapabilities); + setWindowID(id) { + this.setParameter(DeleteWindow.KEY_WINDOW_ID, id); return this; } /** - * @return {Array} - */ + * @return {Number} + */ - getHmiZoneCapabilities() { - return this.getObject(HmiZoneCapabilities, RegisterAppInterfaceResponse.KEY_HMI_ZONE_CAPABILITIES); + getWindowID() { + return this.getParameter(DeleteWindow.KEY_WINDOW_ID); } - /** - * @param {Array} speechCapabilities - * @return {RegisterAppInterfaceResponse} - */ + } - setSpeechCapabilities(speechCapabilities) { - // TODO make this work for arrays - // this.validateType(SpeechCapabilities, speechCapabilities); - this.setParameter(RegisterAppInterfaceResponse.KEY_SPEECH_CAPABILITIES, speechCapabilities); - return this; - } - /** - * @return {Array} - */ + DeleteWindow.KEY_WINDOW_ID = 'windowID'; + /* eslint-disable camelcase */ - getSpeechCapabilities() { - return this.getObject(SpeechCapabilities, RegisterAppInterfaceResponse.KEY_SPEECH_CAPABILITIES); - } + class DeleteWindowResponse extends RpcResponse { /** - * @param {Array} speechCapabilities - * @return {RegisterAppInterfaceResponse} - */ + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.DeleteWindow); + } + } - setPrerecordedSpeech(speechCapabilities) { - // TODO make this work for arrays - // this.validateType(PrerecordedSpeech, speechCapabilities); - this.setParameter(RegisterAppInterfaceResponse.KEY_PRERECORDED_SPEECH, speechCapabilities); - return this; + /* eslint-disable camelcase */ + /** + * Contains information about the type of image. + * @typedef {Enum} ImageType + * @property {Object} _MAP + */ + + class ImageType extends Enum { + /** + * @constructor + */ + constructor() { + super(); } /** - * @return {Array} - */ + * @return {String} + */ - getPrerecordedSpeech() { - return this.getObject(PrerecordedSpeech, RegisterAppInterfaceResponse.KEY_PRERECORDED_SPEECH); + static get STATIC() { + return ImageType._MAP.STATIC; } /** - * @param {Array} vrCapabilities - * @return {RegisterAppInterfaceResponse} - */ + * @return {String} + */ - setVrCapabilities(vrCapabilities) { - // TODO make this work for arrays - // this.validateType(VrCapabilities, vrCapabilities); - this.setParameter(RegisterAppInterfaceResponse.KEY_VR_CAPABILITIES, vrCapabilities); - return this; + static get DYNAMIC() { + return ImageType._MAP.DYNAMIC; } /** - * @return {Array} - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ - getVrCapabilities() { - return this.getObject(VrCapabilities, RegisterAppInterfaceResponse.KEY_VR_CAPABILITIES); + static valueForKey(key) { + return ImageType._valueForKey(key, ImageType._MAP); } /** - * @param {Array} audioPassThruCapabilities - * @return {RegisterAppInterfaceResponse} - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ - setAudioPassThruCapabilities(audioPassThruCapabilities) { - // TODO make this work for arrays - // this.validateType(AudioPassThruCapabilities, audioPassThruCapabilities); - this.setParameter(RegisterAppInterfaceResponse.KEY_AUDIO_PASS_THRU_CAPABILITIES, audioPassThruCapabilities); - return this; + static keyForValue(value) { + return ImageType._keyForValue(value, ImageType._MAP); } - /** - * @return {Array} - */ + } - getAudioPassThruCapabilities() { - return this.getObject(AudioPassThruCapabilities, RegisterAppInterfaceResponse.KEY_AUDIO_PASS_THRU_CAPABILITIES); + ImageType._MAP = Object.freeze({ + 'STATIC': 'STATIC', + 'DYNAMIC': 'DYNAMIC' + }); + + /* eslint-disable camelcase */ + + class Image extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); } /** - * @param {AudioPassThruCapabilities} pcmStreamCapabilities - * @return {RegisterAppInterfaceResponse} - */ + * @param {String} value - Either the static hex icon value or the binary image file name identifier (sent by + * PutFile). + * @return {Image} + */ - setPcmStreamCapabilities(pcmStreamCapabilities) { - this.validateType(AudioPassThruCapabilities, pcmStreamCapabilities); - this.setParameter(RegisterAppInterfaceResponse.KEY_PCM_STREAM_CAPABILITIES, pcmStreamCapabilities); + setValue(value) { + this.setParameter(Image.KEY_VALUE, value); return this; } /** - * @return {AudioPassThruCapabilities} - */ + * @return {String} + */ - getPcmStreamCapabilities() { - return this.getObject(AudioPassThruCapabilities, RegisterAppInterfaceResponse.KEY_PCM_STREAM_CAPABILITIES); + getValue() { + return this.getParameter(Image.KEY_VALUE); } /** - * @param {VehicleType} vehicleType - * @return {RegisterAppInterfaceResponse} - */ + * @param {ImageType} type - Describes, whether it is a static or dynamic image. + * @return {Image} + */ - setVehicleType(vehicleType) { - this.validateType(VehicleType, vehicleType); - this.setParameter(RegisterAppInterfaceResponse.KEY_VEHICLE_TYPE, vehicleType); + setImageType(type) { + this.validateType(ImageType, type); + this.setParameter(Image.KEY_IMAGE_TYPE, type); return this; } /** - * @return {VehicleType} - */ + * @return {ImageType} + */ - getVehicleType() { - return this.getObject(VehicleType, RegisterAppInterfaceResponse.KEY_VEHICLE_TYPE); + getImageType() { + return this.getObject(ImageType, Image.KEY_IMAGE_TYPE); } /** - * @param {Number} supportedDiagModes - * @return {RegisterAppInterfaceResponse} - */ + * @param {Boolean} template - If true, the image is a template image and can be recolored by the HMI + * @return {Image} + */ - setSupportedDiagModes(supportedDiagModes) { - this.setParameter(RegisterAppInterfaceResponse.KEY_SUPPORTED_DIAG_MODE, supportedDiagModes); + setIsTemplate(template) { + this.setParameter(Image.KEY_IS_TEMPLATE, template); return this; } /** - * @return {Number} - */ + * @return {Boolean} + */ - getSupportedDiagModes() { - return this.getParameter(RegisterAppInterfaceResponse.KEY_SUPPORTED_DIAG_MODE); + getIsTemplate() { + return this.getParameter(Image.KEY_IS_TEMPLATE); } - /** - * @param {HMICapabilities} hmiCapabilities - * @return {RegisterAppInterfaceResponse} - */ + } - setHMICapabilities(hmiCapabilities) { - this.validateType(HMICapabilities, hmiCapabilities); - this.setParameter(RegisterAppInterfaceResponse.KEY_HMI_CAPABILITIES, hmiCapabilities); - return this; - } - /** - * @return {HMICapabilities} - */ + Image.KEY_VALUE = 'value'; + Image.KEY_IMAGE_TYPE = 'imageType'; + Image.KEY_IS_TEMPLATE = 'isTemplate'; + /* eslint-disable camelcase */ - getHMICapabilities() { - return this.getObject(HMICapabilities, RegisterAppInterfaceResponse.KEY_HMI_CAPABILITIES); + class VrHelpItem extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); } /** - * @param {String} sdlVersion - * @return {RegisterAppInterfaceResponse} - */ + * @param {String} text - Text to display for VR Help item + * @return {VrHelpItem} + */ - setSdlVersion(sdlVersion) { - this.setParameter(RegisterAppInterfaceResponse.KEY_SDL_VERSION, sdlVersion); + setText(text) { + this.setParameter(VrHelpItem.KEY_TEXT, text); return this; } /** - * @return {String} - */ + * @return {String} + */ - getSdlVersion() { - return this.getParameter(RegisterAppInterfaceResponse.KEY_SDL_VERSION); + getText() { + return this.getParameter(VrHelpItem.KEY_TEXT); } /** - * @param {String} systemSoftwareVersion - * @return {RegisterAppInterfaceResponse} - */ + * @param {Image} image - Image struct for VR Help item + * @return {VrHelpItem} + */ - setSystemSoftwareVersion(systemSoftwareVersion) { - this.setParameter(RegisterAppInterfaceResponse.KEY_SYSTEM_SOFTWARE_VERSION, systemSoftwareVersion); + setImage(image) { + this.validateType(Image, image); + this.setParameter(VrHelpItem.KEY_IMAGE, image); return this; } /** - * @return {String} - */ + * @return {Image} + */ - getSystemSoftwareVersion() { - return this.getParameter(RegisterAppInterfaceResponse.KEY_SYSTEM_SOFTWARE_VERSION); + getImage() { + return this.getObject(Image, VrHelpItem.KEY_IMAGE); } /** - * @param {Boolean} iconResumed - * @return {RegisterAppInterfaceResponse} - */ + * @param {Number} position - Position to display item in VR Help list + * @return {VrHelpItem} + */ - setIconResumed(iconResumed) { - this.setParameter(RegisterAppInterfaceResponse.KEY_ICON_RESUMED, iconResumed); + setPosition(position) { + this.setParameter(VrHelpItem.KEY_POSITION, position); return this; } /** - * @return {Boolean} - */ + * @return {Number} + */ - getIconResumed() { - return this.getParameter(RegisterAppInterfaceResponse.KEY_ICON_RESUMED); + getPosition() { + return this.getParameter(VrHelpItem.KEY_POSITION); } } - RegisterAppInterfaceResponse.KEY_SDL_MSG_VERSION = 'syncMsgVersion'; - RegisterAppInterfaceResponse.KEY_LANGUAGE = 'language'; - RegisterAppInterfaceResponse.KEY_HMI_DISPLAY_LANGUAGE = 'hmiDisplayLanguage'; - RegisterAppInterfaceResponse.KEY_DISPLAY_CAPABILITIES = 'displayCapabilities'; - RegisterAppInterfaceResponse.KEY_BUTTON_CAPABILITIES = 'buttonCapabilities'; - RegisterAppInterfaceResponse.KEY_SOFT_BUTTON_CAPABILITIES = 'softButtonCapabilities'; - RegisterAppInterfaceResponse.KEY_PRESET_BANK_CAPABILITIES = 'presetBankCapabilities'; - RegisterAppInterfaceResponse.KEY_HMI_ZONE_CAPABILITIES = 'hmiZoneCapabilities'; - RegisterAppInterfaceResponse.KEY_SPEECH_CAPABILITIES = 'speechCapabilities'; - RegisterAppInterfaceResponse.KEY_PRERECORDED_SPEECH = 'prerecordedSpeech'; - RegisterAppInterfaceResponse.KEY_VR_CAPABILITIES = 'vrCapabilities'; - RegisterAppInterfaceResponse.KEY_AUDIO_PASS_THRU_CAPABILITIES = 'audioPassThruCapabilities'; - RegisterAppInterfaceResponse.KEY_PCM_STREAM_CAPABILITIES = 'pcmStreamCapabilities'; - RegisterAppInterfaceResponse.KEY_VEHICLE_TYPE = 'vehicleType'; - RegisterAppInterfaceResponse.KEY_SUPPORTED_DIAG_MODE = 'supportedDiagModes'; - RegisterAppInterfaceResponse.KEY_HMI_CAPABILITIES = 'hmiCapabilities'; - RegisterAppInterfaceResponse.KEY_SDL_VERSION = 'sdlVersion'; - RegisterAppInterfaceResponse.KEY_SYSTEM_SOFTWARE_VERSION = 'systemSoftwareVersion'; - RegisterAppInterfaceResponse.KEY_ICON_RESUMED = 'iconResumed'; + VrHelpItem.KEY_TEXT = 'text'; + VrHelpItem.KEY_IMAGE = 'image'; + VrHelpItem.KEY_POSITION = 'position'; - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ + /** + * Describes the location of a seat. + */ - class SetAppIcon extends RpcRequest { + class SeatLocation extends RpcStruct { /** - * @constructor - */ - constructor(store) { - super(store); - this.setFunctionName(FunctionID.SetAppIcon); + * @constructor + */ + constructor(parameters) { + super(parameters); } /** - * @param {String} fileName - * @return {SetAppIcon} - */ + * @param {Grid} grid - Describes a location (origin coordinates and span) of a vehicle component. + * @return {SeatLocation} + */ - setFileName(fileName) { - this.setParameter(SetAppIcon.KEY_FILE_NAME, fileName); + setGrid(grid) { + this.validateType(Grid, grid); + this.setParameter(SeatLocation.KEY_GRID, grid); return this; } /** - * @return {String} - */ + * @return {Grid} + */ - getFileName() { - return this.getParameter(SetAppIcon.KEY_FILE_NAME); + getGrid() { + return this.getObject(Grid, SeatLocation.KEY_GRID); } } - SetAppIcon.KEY_FILE_NAME = 'syncFileName'; - - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - class SetAppIconResponse extends RpcResponse { - /** - * @constructor - */ - constructor(store) { - super(store); - this.setFunctionName(FunctionID.SetAppIcon); - } - - } + SeatLocation.KEY_GRID = 'grid'; - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ /** - * @typedef {Enum} SoftButtonType + * How the main menu or submenu is laid out on screen + * @typedef {Enum} MenuLayout * @property {Object} _MAP */ - class SoftButtonType extends Enum { + class MenuLayout extends Enum { + /** + * @constructor + */ constructor() { super(); } @@ -23544,1664 +21820,20305 @@ */ - static get SBT_TEXT() { - return SoftButtonType._MAP.SBT_TEXT; + static get LIST() { + return MenuLayout._MAP.LIST; } /** * @return {String} */ - static get SBT_IMAGE() { - return SoftButtonType._MAP.SBT_IMAGE; + static get TILES() { + return MenuLayout._MAP.TILES; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return MenuLayout._valueForKey(key, MenuLayout._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return MenuLayout._keyForValue(value, MenuLayout._MAP); + } + + } + + MenuLayout._MAP = Object.freeze({ + 'LIST': 'LIST', + 'TILES': 'TILES' + }); + + /* eslint-disable camelcase */ + /** + * Enumeration listing possible keyboard layouts. + * @typedef {Enum} KeyboardLayout + * @property {Object} _MAP + */ + + class KeyboardLayout extends Enum { + /** + * @constructor + */ + constructor() { + super(); } /** * @return {String} */ - static get SBT_BOTH() { - return SoftButtonType._MAP.SBT_BOTH; + static get QWERTY() { + return KeyboardLayout._MAP.QWERTY; } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * @return {String} + */ + + + static get QWERTZ() { + return KeyboardLayout._MAP.QWERTZ; + } + /** + * @return {String} + */ + + + static get AZERTY() { + return KeyboardLayout._MAP.AZERTY; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ static valueForKey(key) { - return SoftButtonType._valueForKey(key, SoftButtonType._MAP); + return KeyboardLayout._valueForKey(key, KeyboardLayout._MAP); } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ static keyForValue(value) { - return SoftButtonType._keyForValue(value, SoftButtonType._MAP); + return KeyboardLayout._keyForValue(value, KeyboardLayout._MAP); } } - SoftButtonType._MAP = Object.freeze({ - 'SBT_TEXT': 'TEXT', - 'SBT_IMAGE': 'IMAGE', - 'SBT_BOTH': 'BOTH' + KeyboardLayout._MAP = Object.freeze({ + 'QWERTY': 'QWERTY', + 'QWERTZ': 'QWERTZ', + 'AZERTY': 'AZERTY' }); - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ /** - * @typedef {Enum} SystemAction + * Enumeration listing possible keyboard events. + * @typedef {Enum} KeypressMode * @property {Object} _MAP */ - class SystemAction extends Enum { + class KeypressMode extends Enum { + /** + * @constructor + */ constructor() { super(); } /** + * Each keypress is individually sent as the user presses the keyboard keys. * @return {String} */ - static get DEFAULT_ACTION() { - return SystemAction._MAP.DEFAULT_ACTION; + static get SINGLE_KEYPRESS() { + return KeypressMode._MAP.SINGLE_KEYPRESS; } /** + * The keypresses are queued and a string is eventually sent once the user chooses to submit their entry. * @return {String} */ - static get STEAL_FOCUS() { - return SystemAction._MAP.STEAL_FOCUS; + static get QUEUE_KEYPRESSES() { + return KeypressMode._MAP.QUEUE_KEYPRESSES; } /** + * The keypresses are queue and a string is sent each time the user presses a keyboard key; the string contains + * the entire current entry. * @return {String} */ - static get KEEP_CONTEXT() { - return SystemAction._MAP.KEEP_CONTEXT; + static get RESEND_CURRENT_ENTRY() { + return KeypressMode._MAP.RESEND_CURRENT_ENTRY; } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ static valueForKey(key) { - return SystemAction._valueForKey(key, SystemAction._MAP); + return KeypressMode._valueForKey(key, KeypressMode._MAP); } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ static keyForValue(value) { - return SystemAction._keyForValue(value, SystemAction._MAP); + return KeypressMode._keyForValue(value, KeypressMode._MAP); } } - SystemAction._MAP = Object.freeze({ - 'DEFAULT_ACTION': 'DEFAULT_ACTION', - 'STEAL_FOCUS': 'STEAL_FOCUS', - 'KEEP_CONTEXT': 'KEEP_CONTEXT' + KeypressMode._MAP = Object.freeze({ + 'SINGLE_KEYPRESS': 'SINGLE_KEYPRESS', + 'QUEUE_KEYPRESSES': 'QUEUE_KEYPRESSES', + 'RESEND_CURRENT_ENTRY': 'RESEND_CURRENT_ENTRY' }); - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ + /** + * Configuration of on-screen keyboard (if available). + */ - class SoftButton extends RpcStruct { + class KeyboardProperties extends RpcStruct { + /** + * @constructor + */ constructor(parameters) { super(parameters); } /** - * @param {SoftButtonType} type - * @return {SoftButton} - */ + * @param {Language} language - The keyboard language. + * @return {KeyboardProperties} + */ - setType(type) { - this.validateType(SoftButtonType, type); - this.setParameter(SoftButton.KEY_TYPE, type); + setLanguage(language) { + this.validateType(Language, language); + this.setParameter(KeyboardProperties.KEY_LANGUAGE, language); return this; } /** - * @return {SoftButtonType} - */ + * @return {Language} + */ - getType() { - return this.getObject(SoftButtonType, SoftButton.KEY_TYPE); + getLanguage() { + return this.getObject(Language, KeyboardProperties.KEY_LANGUAGE); } /** - * @param {String} text - * @return {SoftButton} - */ + * @param {KeyboardLayout} layout - Desired keyboard layout. + * @return {KeyboardProperties} + */ - setText(text) { - this.setParameter(SoftButton.KEY_TEXT, text); + setKeyboardLayout(layout) { + this.validateType(KeyboardLayout, layout); + this.setParameter(KeyboardProperties.KEY_KEYBOARD_LAYOUT, layout); return this; } /** - * @return {String} - */ + * @return {KeyboardLayout} + */ - getText() { - return this.getParameter(SoftButton.KEY_TEXT); + getKeyboardLayout() { + return this.getObject(KeyboardLayout, KeyboardProperties.KEY_KEYBOARD_LAYOUT); } /** - * @param {Image} image - * @return {SoftButton} - */ + * @param {KeypressMode} mode - Desired keypress mode. If omitted, this value will be set to RESEND_CURRENT_ENTRY. + * @return {KeyboardProperties} + */ - setImage(image) { - this.validateType(Image, image); - this.setParameter(SoftButton.KEY_IMAGE, image); + setKeypressMode(mode) { + this.validateType(KeypressMode, mode); + this.setParameter(KeyboardProperties.KEY_KEYPRESS_MODE, mode); return this; } /** - * @return {Image} - */ + * @return {KeypressMode} + */ - getImage() { - return this.getObject(Image, SoftButton.KEY_IMAGE); + getKeypressMode() { + return this.getObject(KeypressMode, KeyboardProperties.KEY_KEYPRESS_MODE); } /** - * @param {Boolean} isHighlighted - * @return {SoftButton} - */ + * @param {String[]} list - Array of keyboard characters to enable. All omitted characters will be greyed out + * (disabled) on the keyboard. If omitted, the entire keyboard will be enabled. + * @return {KeyboardProperties} + */ - setIsHighlighted(isHighlighted) { - this.setParameter(SoftButton.KEY_IS_HIGHLIGHTED, isHighlighted); + setLimitedCharacterList(list) { + this.setParameter(KeyboardProperties.KEY_LIMITED_CHARACTER_LIST, list); return this; } /** - * @return {Boolean} - */ + * @return {String[]} + */ - getIsHighlighted() { - return this.getParameter(SoftButton.KEY_IS_HIGHLIGHTED); + getLimitedCharacterList() { + return this.getParameter(KeyboardProperties.KEY_LIMITED_CHARACTER_LIST); } /** - * @param {Number} softButtonID - * @return {SoftButton} - */ + * @param {String} text - Deprecated, use autoCompleteList instead. + * @return {KeyboardProperties} + */ - setSoftButtonID(softButtonID) { - this.setParameter(SoftButton.KEY_SOFT_BUTTON_ID, softButtonID); + setAutoCompleteText(text) { + this.setParameter(KeyboardProperties.KEY_AUTO_COMPLETE_TEXT, text); return this; } /** - * @return {Number} - */ + * @return {String} + */ - getSoftButtonID() { - return this.getParameter(SoftButton.KEY_SOFT_BUTTON_ID); + getAutoCompleteText() { + return this.getParameter(KeyboardProperties.KEY_AUTO_COMPLETE_TEXT); } /** - * @param {SystemAction} systemAction - * @return {SoftButton} - */ + * @param {String[]} list - Allows an app to prepopulate the text field with a list of suggested or completed + * entries as the user types. If empty, the auto-complete list will be removed from the + * screen. + * @return {KeyboardProperties} + */ - setSystemAction(systemAction) { - this.validateType(SystemAction, systemAction); - this.setParameter(SoftButton.KEY_SYSTEM_ACTION, systemAction); + setAutoCompleteList(list) { + this.setParameter(KeyboardProperties.KEY_AUTO_COMPLETE_LIST, list); return this; } /** - * @return {SystemAction} - */ + * @return {String[]} + */ - getSystemAction() { - return this.getObject(SystemAction, SoftButton.KEY_SYSTEM_ACTION); + getAutoCompleteList() { + return this.getParameter(KeyboardProperties.KEY_AUTO_COMPLETE_LIST); } } - SoftButton.KEY_TYPE = 'type'; - SoftButton.KEY_TEXT = 'text'; - SoftButton.KEY_IMAGE = 'image'; - SoftButton.KEY_IS_HIGHLIGHTED = 'isHighlighted'; - SoftButton.KEY_SOFT_BUTTON_ID = 'softButtonID'; - SoftButton.KEY_SYSTEM_ACTION = 'systemAction'; + KeyboardProperties.KEY_LANGUAGE = 'language'; + KeyboardProperties.KEY_KEYBOARD_LAYOUT = 'keyboardLayout'; + KeyboardProperties.KEY_KEYPRESS_MODE = 'keypressMode'; + KeyboardProperties.KEY_LIMITED_CHARACTER_LIST = 'limitedCharacterList'; + KeyboardProperties.KEY_AUTO_COMPLETE_TEXT = 'autoCompleteText'; + KeyboardProperties.KEY_AUTO_COMPLETE_LIST = 'autoCompleteList'; - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ /** - * @typedef {Enum} MetadataType - * @property {Object} _MAP + * Allows setting global properties. */ - class MetadataType extends Enum { - constructor() { - super(); + class SetGlobalProperties extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SetGlobalProperties); } /** - * @return {String} + * @param {SeatLocation} location - Location of the user's seat. Default is driver's seat location if it is not set + * yet. + * @return {SetGlobalProperties} */ - static get mediaTitle() { - return MetadataType._MAP.mediaTitle; + setUserLocation(location) { + this.validateType(SeatLocation, location); + this.setParameter(SetGlobalProperties.KEY_USER_LOCATION, location); + return this; } /** - * @return {String} + * @return {SeatLocation} */ - static get mediaArtist() { - return MetadataType._MAP.mediaArtist; + getUserLocation() { + return this.getObject(SeatLocation, SetGlobalProperties.KEY_USER_LOCATION); } /** - * @return {String} + * @param {TTSChunk[]} prompt - The help prompt. An array of text chunks of type TTSChunk. See TTSChunk. The array + * must have at least one item. + * @return {SetGlobalProperties} */ - static get mediaAlbum() { - return MetadataType._MAP.mediaAlbum; + setHelpPrompt(prompt) { + this.validateType(TTSChunk, prompt, true); + this.setParameter(SetGlobalProperties.KEY_HELP_PROMPT, prompt); + return this; } /** - * @return {String} + * @return {TTSChunk[]} */ - static get mediaYear() { - return MetadataType._MAP.mediaYear; + getHelpPrompt() { + return this.getObject(TTSChunk, SetGlobalProperties.KEY_HELP_PROMPT); } /** - * @return {String} + * @param {TTSChunk[]} prompt - Help text for a wait timeout. An array of text chunks of type TTSChunk. See + * TTSChunk. The array must have at least one item. + * @return {SetGlobalProperties} */ - static get mediaGenre() { - return MetadataType._MAP.mediaGenre; + setTimeoutPrompt(prompt) { + this.validateType(TTSChunk, prompt, true); + this.setParameter(SetGlobalProperties.KEY_TIMEOUT_PROMPT, prompt); + return this; } /** - * @return {String} + * @return {TTSChunk[]} */ - static get mediaStation() { - return MetadataType._MAP.mediaStation; + getTimeoutPrompt() { + return this.getObject(TTSChunk, SetGlobalProperties.KEY_TIMEOUT_PROMPT); } /** - * @return {String} + * @param {String} title - VR Help Title text. If omitted on supported displays, the default module help title shall + * be used. If omitted and one or more vrHelp items are provided, the request will be + * rejected. + * @return {SetGlobalProperties} */ - static get rating() { - return MetadataType._MAP.rating; + setVrHelpTitle(title) { + this.setParameter(SetGlobalProperties.KEY_VR_HELP_TITLE, title); + return this; } /** * @return {String} */ - static get currentTemperature() { - return MetadataType._MAP.currentTemperature; + getVrHelpTitle() { + return this.getParameter(SetGlobalProperties.KEY_VR_HELP_TITLE); } /** - * @return {String} + * @param {VrHelpItem[]} help - VR Help Items. If omitted on supported displays, the default SmartDeviceLink VR help + * / What Can I Say? screen shall be used. If the list of VR Help Items contains + * nonsequential positions (e.g. [1,2,4]), the RPC shall be rejected. If omitted and a + * vrHelpTitle is provided, the request will be rejected. + * @return {SetGlobalProperties} */ - static get maximumTemperature() { - return MetadataType._MAP.maximumTemperature; + setVrHelp(help) { + this.validateType(VrHelpItem, help, true); + this.setParameter(SetGlobalProperties.KEY_VR_HELP, help); + return this; } /** - * @return {String} + * @return {VrHelpItem[]} */ - static get minimumTemperature() { - return MetadataType._MAP.minimumTemperature; + getVrHelp() { + return this.getObject(VrHelpItem, SetGlobalProperties.KEY_VR_HELP); } /** - * @return {String} + * @param {String} title - Optional text to label an app menu button (for certain touchscreen platforms). + * @return {SetGlobalProperties} */ - static get weatherTerm() { - return MetadataType._MAP.weatherTerm; + setMenuTitle(title) { + this.setParameter(SetGlobalProperties.KEY_MENU_TITLE, title); + return this; } /** * @return {String} */ - static get humidity() { - return MetadataType._MAP.humidity; + getMenuTitle() { + return this.getParameter(SetGlobalProperties.KEY_MENU_TITLE); } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * @param {Image} icon - Optional icon to draw on an app menu button (for certain touchscreen platforms). + * @return {SetGlobalProperties} + */ - static valueForKey(key) { - return MetadataType._valueForKey(key, MetadataType._MAP); + setMenuIcon(icon) { + this.validateType(Image, icon); + this.setParameter(SetGlobalProperties.KEY_MENU_ICON, icon); + return this; } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ - - - static keyForValue(value) { - return MetadataType._keyForValue(value, MetadataType._MAP); - } - - } - - MetadataType._MAP = Object.freeze({ - 'mediaTitle': 'mediaTitle', - 'mediaArtist': 'mediaArtist', - 'mediaAlbum': 'mediaAlbum', - 'mediaYear': 'mediaYear', - 'mediaGenre': 'mediaGenre', - 'mediaStation': 'mediaStation', - 'rating': 'rating', - 'currentTemperature': 'currentTemperature', - 'maximumTemperature': 'maximumTemperature', - 'minimumTemperature': 'minimumTemperature', - 'weatherTerm': 'weatherTerm', - 'humidity': 'humidity' - }); + * @return {Image} + */ - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - class MetadataTags extends RpcStruct { - /** - * @constructor - */ - constructor(parameters) { - super(parameters); + getMenuIcon() { + return this.getObject(Image, SetGlobalProperties.KEY_MENU_ICON); } /** - * @param {Array} mainField1 - * @return {MetadataTags} - */ + * @param {KeyboardProperties} properties - On-screen keyboard configuration (if available). + * @return {SetGlobalProperties} + */ - setMainField1(mainField1) { - this.setParameter(MetadataTags.KEY_MAIN_FIELD_1, mainField1); + setKeyboardProperties(properties) { + this.validateType(KeyboardProperties, properties); + this.setParameter(SetGlobalProperties.KEY_KEYBOARD_PROPERTIES, properties); return this; } /** - * @return {Array} - */ + * @return {KeyboardProperties} + */ - getMainField1() { - return this.getObject(MetadataType, MetadataTags.KEY_MAIN_FIELD_1); + getKeyboardProperties() { + return this.getObject(KeyboardProperties, SetGlobalProperties.KEY_KEYBOARD_PROPERTIES); } /** - * @param {Array} mainField2 - * @return {MetadataTags} - */ + * @param {MenuLayout} layout - Sets the layout of the main menu screen. If this is sent while a menu is already on- + * screen, the head unit will change the display to the new layout type. + * @return {SetGlobalProperties} + */ - setMainField2(mainField2) { - this.setParameter(MetadataTags.KEY_MAIN_FIELD_2, mainField2); + setMenuLayout(layout) { + this.validateType(MenuLayout, layout); + this.setParameter(SetGlobalProperties.KEY_MENU_LAYOUT, layout); return this; } /** - * @return {Array} - */ + * @return {MenuLayout} + */ - getMainField2() { - return this.getObject(MetadataType, MetadataTags.KEY_MAIN_FIELD_2); + getMenuLayout() { + return this.getObject(MenuLayout, SetGlobalProperties.KEY_MENU_LAYOUT); } + + } + + SetGlobalProperties.KEY_USER_LOCATION = 'userLocation'; + SetGlobalProperties.KEY_HELP_PROMPT = 'helpPrompt'; + SetGlobalProperties.KEY_TIMEOUT_PROMPT = 'timeoutPrompt'; + SetGlobalProperties.KEY_VR_HELP_TITLE = 'vrHelpTitle'; + SetGlobalProperties.KEY_VR_HELP = 'vrHelp'; + SetGlobalProperties.KEY_MENU_TITLE = 'menuTitle'; + SetGlobalProperties.KEY_MENU_ICON = 'menuIcon'; + SetGlobalProperties.KEY_KEYBOARD_PROPERTIES = 'keyboardProperties'; + SetGlobalProperties.KEY_MENU_LAYOUT = 'menuLayout'; + + /* eslint-disable camelcase */ + + class SetGlobalPropertiesResponse extends RpcResponse { /** - * @param {Array} mainField3 - * @return {MetadataTags} - */ + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SetGlobalProperties); + } + } - setMainField3(mainField3) { - this.setParameter(MetadataTags.KEY_MAIN_FIELD_3, mainField3); - return this; + /* eslint-disable camelcase */ + /** + * The different global properties. + * @typedef {Enum} GlobalProperty + * @property {Object} _MAP + */ + + class GlobalProperty extends Enum { + /** + * @constructor + */ + constructor() { + super(); } /** - * @return {Array} - */ + * Location of the user's seat of setGlobalProperties + * @return {String} + */ - getMainField3() { - return this.getObject(MetadataType, MetadataTags.KEY_MAIN_FIELD_3); + static get USER_LOCATION() { + return GlobalProperty._MAP.USER_LOCATION; } /** - * @param {Array} mainField4 - * @return {MetadataTags} - */ + * The property helpPrompt of setGlobalProperties + * @return {String} + */ - setMainField4(mainField4) { - this.setParameter(MetadataTags.KEY_MAIN_FIELD_4, mainField4); - return this; + static get HELPPROMPT() { + return GlobalProperty._MAP.HELPPROMPT; } /** - * @return {Array} - */ + * The property timeoutPrompt of setGlobalProperties + * @return {String} + */ - getMainField4() { - return this.getObject(MetadataType, MetadataTags.KEY_MAIN_FIELD_4); + static get TIMEOUTPROMPT() { + return GlobalProperty._MAP.TIMEOUTPROMPT; } + /** + * The property vrHelpTitle of setGlobalProperties + * @return {String} + */ - } - MetadataTags.KEY_MAIN_FIELD_1 = 'mainField1'; - MetadataTags.KEY_MAIN_FIELD_2 = 'mainField2'; - MetadataTags.KEY_MAIN_FIELD_3 = 'mainField3'; - MetadataTags.KEY_MAIN_FIELD_4 = 'mainField4'; + static get VRHELPTITLE() { + return GlobalProperty._MAP.VRHELPTITLE; + } + /** + * The property array of vrHelp of setGlobalProperties + * @return {String} + */ - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - /** - * @typedef {Enum} TextAlignment - * @property {Object} _MAP - */ - class TextAlignment extends Enum { - constructor() { - super(); + static get VRHELPITEMS() { + return GlobalProperty._MAP.VRHELPITEMS; } /** - * @return {String} - */ + * The property in-app menu name of setGlobalProperties + * @return {String} + */ - static get LEFT_ALIGNED() { - return TextAlignment._MAP.LEFT_ALIGNED; + static get MENUNAME() { + return GlobalProperty._MAP.MENUNAME; } /** - * @return {String} - */ + * The property in-app menu icon of setGlobalProperties + * @return {String} + */ - static get RIGHT_ALIGNED() { - return TextAlignment._MAP.RIGHT_ALIGNED; + static get MENUICON() { + return GlobalProperty._MAP.MENUICON; } /** - * @return {String} - */ + * The on-screen keyboard configuration of setGlobalProperties + * @return {String} + */ - static get CENTERED() { - return TextAlignment._MAP.CENTERED; + static get KEYBOARDPROPERTIES() { + return GlobalProperty._MAP.KEYBOARDPROPERTIES; } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ static valueForKey(key) { - return TextAlignment._valueForKey(key, TextAlignment._MAP); + return GlobalProperty._valueForKey(key, GlobalProperty._MAP); } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ static keyForValue(value) { - return TextAlignment._keyForValue(value, TextAlignment._MAP); + return GlobalProperty._keyForValue(value, GlobalProperty._MAP); } } - TextAlignment._MAP = Object.freeze({ - 'LEFT_ALIGNED': 'LEFT_ALIGNED', - 'RIGHT_ALIGNED': 'RIGHT_ALIGNED', - 'CENTERED': 'CENTERED' + GlobalProperty._MAP = Object.freeze({ + 'USER_LOCATION': 'USER_LOCATION', + 'HELPPROMPT': 'HELPPROMPT', + 'TIMEOUTPROMPT': 'TIMEOUTPROMPT', + 'VRHELPTITLE': 'VRHELPTITLE', + 'VRHELPITEMS': 'VRHELPITEMS', + 'MENUNAME': 'MENUNAME', + 'MENUICON': 'MENUICON', + 'KEYBOARDPROPERTIES': 'KEYBOARDPROPERTIES' }); - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ + /** + * Allows resetting global properties. + */ - class Show extends RpcRequest { + class ResetGlobalProperties extends RpcRequest { /** - * @constructor - */ + * @constructor + */ constructor(store) { super(store); - this.setFunctionName(FunctionID.Show); + this.setFunctionName(FunctionID.ResetGlobalProperties); } /** - * @param {String} mainField1 - * @return {Show} - */ + * @param {GlobalProperty[]} properties - Contains the names of all global properties (like timeoutPrompt) that + * should be unset. Resetting means, that they have the same value as at + * start up (default) + * @return {ResetGlobalProperties} + */ - setMainField1(mainField1) { - this.setParameter(Show.KEY_MAIN_FIELD_1, mainField1); + setProperties(properties) { + this.validateType(GlobalProperty, properties, true); + this.setParameter(ResetGlobalProperties.KEY_PROPERTIES, properties); return this; } /** - * @return {String} - */ + * @return {GlobalProperty[]} + */ - getMainField1() { - return this.getParameter(Show.KEY_MAIN_FIELD_1); + getProperties() { + return this.getObject(GlobalProperty, ResetGlobalProperties.KEY_PROPERTIES); + } + + } + + ResetGlobalProperties.KEY_PROPERTIES = 'properties'; + + /* eslint-disable camelcase */ + + class ResetGlobalPropertiesResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.ResetGlobalProperties); } + + } + + /* eslint-disable camelcase */ + + class MenuParams extends RpcStruct { /** - * @param {String} mainField2 - * @return {Show} - */ + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Number} id - unique ID of the sub menu, the command will be added to. If not provided, it will be + * provided to the top level of the in application menu. + * @return {MenuParams} + */ - setMainField2(mainField2) { - this.setParameter(Show.KEY_MAIN_FIELD_2, mainField2); + setParentID(id) { + this.setParameter(MenuParams.KEY_PARENT_ID, id); return this; } /** - * @return {String} - */ + * @return {Number} + */ - getMainField2() { - return this.getParameter(Show.KEY_MAIN_FIELD_2); + getParentID() { + return this.getParameter(MenuParams.KEY_PARENT_ID); } /** - * @param {String} mainField3 - * @return {Show} - */ + * @param {Number} position - Position within the items that are are at top level of the in application menu. 0 will + * insert at the front. 1 will insert at the second position. if position is greater or + * equal than the number of items on top level, the sub menu will be appended to the end. + * If this param was omitted the entry will be added at the end. + * @return {MenuParams} + */ - setMainField3(mainField3) { - this.setParameter(Show.KEY_MAIN_FIELD_3, mainField3); + setPosition(position) { + this.setParameter(MenuParams.KEY_POSITION, position); return this; } /** - * @return {String} - */ + * @return {Number} + */ - getMainField3() { - return this.getParameter(Show.KEY_MAIN_FIELD_3); + getPosition() { + return this.getParameter(MenuParams.KEY_POSITION); } /** - * @param {String} mainField4 - * @return {Show} - */ + * @param {String} name - Text to show in the menu for this sub menu. + * @return {MenuParams} + */ - setMainField4(mainField4) { - this.setParameter(Show.KEY_MAIN_FIELD_4, mainField4); + setMenuName(name) { + this.setParameter(MenuParams.KEY_MENU_NAME, name); return this; } /** - * @return {String} - */ + * @return {String} + */ - getMainField4() { - return this.getParameter(Show.KEY_MAIN_FIELD_4); + getMenuName() { + return this.getParameter(MenuParams.KEY_MENU_NAME); + } + + } + + MenuParams.KEY_PARENT_ID = 'parentID'; + MenuParams.KEY_POSITION = 'position'; + MenuParams.KEY_MENU_NAME = 'menuName'; + + /* eslint-disable camelcase */ + /** + * Adds a command to the in application menu. Either menuParams or vrCommands must be provided. + */ + + class AddCommand extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.AddCommand); } /** - * @param {TextAlignment} menuParams - * @return {Show} - */ + * @param {Number} id - unique ID of the command to add. + * @return {AddCommand} + */ - setAlignment(alignment) { - this.validateType(TextAlignment, alignment); - this.setParameter(Show.KEY_ALIGNMENT, alignment); + setCmdID(id) { + this.setParameter(AddCommand.KEY_CMD_ID, id); return this; } /** - * @return {TextAlignment} - */ + * @return {Number} + */ - getAlignment() { - return this.getObject(TextAlignment, Show.KEY_ALIGNMENT); + getCmdID() { + return this.getParameter(AddCommand.KEY_CMD_ID); } /** - * @param {String} statusBar - * @return {Show} - */ + * @param {MenuParams} params - Optional sub value containing menu parameters + * @return {AddCommand} + */ - setStatusBar(statusBar) { - this.setParameter(Show.KEY_STATUS_BAR, statusBar); + setMenuParams(params) { + this.validateType(MenuParams, params); + this.setParameter(AddCommand.KEY_MENU_PARAMS, params); return this; } /** - * @return {String} - */ + * @return {MenuParams} + */ - getStatusBar() { - return this.getParameter(Show.KEY_STATUS_BAR); + getMenuParams() { + return this.getObject(MenuParams, AddCommand.KEY_MENU_PARAMS); } /** - * @param {String} mediaClock - * @return {Show} - */ + * @param {String[]} commands - An array of strings to be used as VR synonyms for this command. If this array is + * provided, it may not be empty. + * @return {AddCommand} + */ - setMediaClock(mediaClock) { - this.setParameter(Show.KEY_MEDIA_CLOCK, mediaClock); + setVrCommands(commands) { + this.setParameter(AddCommand.KEY_VR_COMMANDS, commands); return this; } /** - * @return {String} - */ + * @return {String[]} + */ - getMediaClock() { - return this.getParameter(Show.KEY_MEDIA_CLOCK); + getVrCommands() { + return this.getParameter(AddCommand.KEY_VR_COMMANDS); } /** - * @param {String} mediaTrack - * @return {Show} - */ + * @param {Image} icon - Image struct determining whether static or dynamic icon. If omitted on supported displays, + * no (or the default if applicable) icon shall be displayed. + * @return {AddCommand} + */ - setMediaTrack(mediaTrack) { - this.setParameter(Show.KEY_MEDIA_TRACK, mediaTrack); + setCmdIcon(icon) { + this.validateType(Image, icon); + this.setParameter(AddCommand.KEY_CMD_ICON, icon); return this; } /** - * @return {String} - */ + * @return {Image} + */ - getMediaTrack() { - return this.getParameter(Show.KEY_MEDIA_TRACK); + getCmdIcon() { + return this.getObject(Image, AddCommand.KEY_CMD_ICON); } + + } + + AddCommand.KEY_CMD_ID = 'cmdID'; + AddCommand.KEY_MENU_PARAMS = 'menuParams'; + AddCommand.KEY_VR_COMMANDS = 'vrCommands'; + AddCommand.KEY_CMD_ICON = 'cmdIcon'; + + /* eslint-disable camelcase */ + + class AddCommandResponse extends RpcResponse { /** - * @param {Image} graphic - * @return {Show} - */ + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.AddCommand); + } + } - setGraphic(graphic) { - this.validateType(Image, graphic); - this.setParameter(Show.KEY_GRAPHIC, graphic); - return this; + /* eslint-disable camelcase */ + /** + * Deletes all commands from the in-application menu with the specified command id. + */ + + class DeleteCommand extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.DeleteCommand); } /** - * @return {Image} - */ + * @param {Number} id - ID of the command(s) to delete. + * @return {DeleteCommand} + */ - getGraphic() { - return this.getObject(Image, Show.KEY_GRAPHIC); + setCmdID(id) { + this.setParameter(DeleteCommand.KEY_CMD_ID, id); + return this; } /** - * @param {Image} secondaryGraphic - * @return {Show} - */ + * @return {Number} + */ - setSecondaryGraphic(secondaryGraphic) { - this.validateType(Image, secondaryGraphic); - this.setParameter(Show.KEY_SECONDARY_GRAPHIC, secondaryGraphic); - return this; + getCmdID() { + return this.getParameter(DeleteCommand.KEY_CMD_ID); } + + } + + DeleteCommand.KEY_CMD_ID = 'cmdID'; + + /* eslint-disable camelcase */ + + class DeleteCommandResponse extends RpcResponse { /** - * @return {Image} - */ + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.DeleteCommand); + } + } - getSecondaryGraphic() { - return this.getObject(Image, Show.KEY_SECONDARY_GRAPHIC); + /* eslint-disable camelcase */ + /** + * Adds a sub menu to the in-application menu. + */ + + class AddSubMenu extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.AddSubMenu); } /** - * @param {Array} softButtons - * @return {Show} - */ + * @param {Number} id - unique ID of the sub menu to add. + * @return {AddSubMenu} + */ - setSoftButtons(softButtons) { - // TODO make this work for arrays - // this.validateType(SoftButton, softButtons); - this.setParameter(Show.KEY_SOFT_BUTTONS, softButtons); + setMenuID(id) { + this.setParameter(AddSubMenu.KEY_MENU_ID, id); return this; } /** - * @return {Array} - */ + * @return {Number} + */ - getSoftButtons() { - return this.getObject(SoftButton, Show.KEY_SOFT_BUTTONS); + getMenuID() { + return this.getParameter(AddSubMenu.KEY_MENU_ID); } /** - * @param {Array} customPresets - * @return {Show} - */ + * @param {Number} position - Position within the items that are are at top level of the in application menu. 0 will + * insert at the front. 1 will insert at the second position. If position is greater or + * equal than the number of items on top level, the sub menu will be appended to the end. + * Position of any submenu will always be located before the return and exit options If + * this param was omitted the entry will be added at the end. + * @return {AddSubMenu} + */ - setCustomPresets(customPresets) { - this.setParameter(Show.KEY_CUSTOM_PRESETS, customPresets); + setPosition(position) { + this.setParameter(AddSubMenu.KEY_POSITION, position); return this; } /** - * @return {Array} - */ + * @return {Number} + */ - getCustomPresets() { - return this.getParameter(Show.KEY_CUSTOM_PRESETS); + getPosition() { + return this.getParameter(AddSubMenu.KEY_POSITION); } /** - * @param {MetadataTags} metadataTags - * @return {Show} - */ + * @param {String} name - Text to show in the menu for this sub menu. + * @return {AddSubMenu} + */ - setMetadataTags(metadataTags) { - this.validateType(MetadataTags, metadataTags); - this.setParameter(Show.KEY_METADATA_TAGS, metadataTags); + setMenuName(name) { + this.setParameter(AddSubMenu.KEY_MENU_NAME, name); return this; } /** - * @return {MetadataTags} - */ + * @return {String} + */ - getMetadataTags() { - return this.getObject(MetadataTags, Show.KEY_METADATA_TAGS); + getMenuName() { + return this.getParameter(AddSubMenu.KEY_MENU_NAME); } /** - * @param {String} templateTitle - * @return {Show} - */ + * @param {Image} icon - The image field for AddSubMenu + * @return {AddSubMenu} + */ - setTemplateTitle(templateTitle) { - this.setParameter(Show.KEY_TEMPLATE_TITLE, templateTitle); + setMenuIcon(icon) { + this.validateType(Image, icon); + this.setParameter(AddSubMenu.KEY_MENU_ICON, icon); return this; } /** - * @return {String} - */ + * @return {Image} + */ - getTemplateTitle() { - return this.getParameter(Show.KEY_TEMPLATE_TITLE); + getMenuIcon() { + return this.getObject(Image, AddSubMenu.KEY_MENU_ICON); } /** - * @param {Number} windowID - * @return {Show} - */ + * @param {MenuLayout} layout - Sets the layout of the submenu screen. + * @return {AddSubMenu} + */ - setWindowID(windowID) { - this.setParameter(Show.KEY_WINDOW_ID, windowID); + setMenuLayout(layout) { + this.validateType(MenuLayout, layout); + this.setParameter(AddSubMenu.KEY_MENU_LAYOUT, layout); return this; } /** - * @return {Number} - */ + * @return {MenuLayout} + */ - getWindowID() { - return this.getParameter(Show.KEY_WINDOW_ID); + getMenuLayout() { + return this.getObject(MenuLayout, AddSubMenu.KEY_MENU_LAYOUT); } } - Show.KEY_MAIN_FIELD_1 = 'mainField1'; - Show.KEY_MAIN_FIELD_2 = 'mainField2'; - Show.KEY_MAIN_FIELD_3 = 'mainField3'; - Show.KEY_MAIN_FIELD_4 = 'mainField4'; - Show.KEY_ALIGNMENT = 'alignment'; - Show.KEY_STATUS_BAR = 'statusBar'; - Show.KEY_MEDIA_CLOCK = 'mediaClock'; - Show.KEY_MEDIA_TRACK = 'mediaTrack'; - Show.KEY_GRAPHIC = 'graphic'; - Show.KEY_SECONDARY_GRAPHIC = 'secondaryGraphic'; - Show.KEY_SOFT_BUTTONS = 'softButtons'; - Show.KEY_CUSTOM_PRESETS = 'customPresets'; - Show.KEY_METADATA_TAGS = 'metadataTags'; - Show.KEY_TEMPLATE_TITLE = 'templateTitle'; - Show.KEY_WINDOW_ID = 'windowID'; + AddSubMenu.KEY_MENU_ID = 'menuID'; + AddSubMenu.KEY_POSITION = 'position'; + AddSubMenu.KEY_MENU_NAME = 'menuName'; + AddSubMenu.KEY_MENU_ICON = 'menuIcon'; + AddSubMenu.KEY_MENU_LAYOUT = 'menuLayout'; - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ - class ShowResponse extends RpcResponse { + class AddSubMenuResponse extends RpcResponse { /** - * @constructor - */ + * @constructor + */ constructor(store) { super(store); - this.setFunctionName(FunctionID.Show); + this.setFunctionName(FunctionID.AddSubMenu); } } - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ + /** + * Deletes a submenu from the in-application menu. + */ - class UnregisterAppInterface extends RpcRequest { + class DeleteSubMenu extends RpcRequest { /** - * @constructor - */ + * @constructor + */ constructor(store) { super(store); - this.setFunctionName(FunctionID.UnregisterAppInterface); + this.setFunctionName(FunctionID.DeleteSubMenu); + } + /** + * @param {Number} id - The "menuID" of the submenu to delete. (See addSubMenu.menuID) + * @return {DeleteSubMenu} + */ + + + setMenuID(id) { + this.setParameter(DeleteSubMenu.KEY_MENU_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getMenuID() { + return this.getParameter(DeleteSubMenu.KEY_MENU_ID); } } - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + DeleteSubMenu.KEY_MENU_ID = 'menuID'; - class UnregisterAppInterfaceResponse extends RpcResponse { + /* eslint-disable camelcase */ + + class DeleteSubMenuResponse extends RpcResponse { /** - * @constructor - */ + * @constructor + */ constructor(store) { super(store); - this.setFunctionName(FunctionID.UnregisterAppInterface); + this.setFunctionName(FunctionID.DeleteSubMenu); } } - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ + /** + * Shows the built in menu view + */ - class RpcCreator { + class ShowAppMenu extends RpcRequest { /** - * Converts an SdlPacket to an RpcMessage - * @param {SdlPacket} sdlPacket - * @return {RpcMessage} + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.ShowAppMenu); + } + /** + * @param {Number} id - If omitted the HMI opens the app's menu. If set to a sub-menu ID the HMI opens the + * corresponding sub-menu previously added using `AddSubMenu`. + * @return {ShowAppMenu} */ - static construct(sdlPacket) { - const payload = sdlPacket.getPayload(); - const binaryFrameHeader = BinaryFrameHeader.fromBinaryHeader(payload); - let message; - const rpcType = binaryFrameHeader.getRpcType(); - const rpcName = RpcType.keyForValue(rpcType); - const correlationId = binaryFrameHeader.getCorrelationId(); - const functionId = binaryFrameHeader.getFunctionId(); - const functionName = FunctionID.keyForValue(functionId); - const bulkData = binaryFrameHeader.getBulkData(); - const jsonData = binaryFrameHeader.getJsonData(); - const params = { - parameters: JsonRpcMarshaller.unmarshall(jsonData) - }; - switch (functionId) { - case FunctionID.AddCommand: - if (rpcType === RpcType.REQUEST) { - message = new AddCommand(params); - } else if (rpcType === RpcType.RESPONSE) { - message = new AddCommandResponse(params); - } - break; + setMenuID(id) { + this.setParameter(ShowAppMenu.KEY_MENU_ID, id); + return this; + } + /** + * @return {Number} + */ - case FunctionID.OnHMIStatus: - // TODO: should OnHMIStatus be OnHmiStatus, or the class name change to OnHMIStatus? or is this fine as is? - if (rpcType === RpcType.NOTIFICATION) { - message = new OnHmiStatus(params); - } - break; + getMenuID() { + return this.getParameter(ShowAppMenu.KEY_MENU_ID); + } - case FunctionID.OnLanguageChange: - if (rpcType === RpcType.NOTIFICATION) { - message = new OnLanguageChange(params); - } + } - break; + ShowAppMenu.KEY_MENU_ID = 'menuID'; - case FunctionID.PutFile: - if (rpcType === RpcType.REQUEST) { - message = new PutFile(params); - } else if (rpcType === RpcType.RESPONSE) { - message = new PutFileResponse(params); - } + /* eslint-disable camelcase */ - break; + class ShowAppMenuResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.ShowAppMenu); + } - case FunctionID.RegisterAppInterface: - if (rpcType === RpcType.REQUEST) { - message = new RegisterAppInterface(params); - } else if (rpcType === RpcType.RESPONSE) { - message = new RegisterAppInterfaceResponse(params); - } + } - break; + /* eslint-disable camelcase */ + /** + * A choice is an option given to the user, which can be selected either by menu, or through voice recognition system. + */ - case FunctionID.SetAppIcon: - if (rpcType === RpcType.REQUEST) { - message = new SetAppIcon(params); - } else if (rpcType === RpcType.RESPONSE) { - message = new SetAppIconResponse(params); - } + class Choice extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Number} id + * @return {Choice} + */ - break; - case FunctionID.Show: - if (rpcType === RpcType.REQUEST) { - message = new Show(params); - } else if (rpcType === RpcType.RESPONSE) { - message = new ShowResponse(params); - } + setChoiceID(id) { + this.setParameter(Choice.KEY_CHOICE_ID, id); + return this; + } + /** + * @return {Number} + */ - break; - case FunctionID.UnregisterAppInterface: - if (rpcType === RpcType.REQUEST) { - message = new UnregisterAppInterface(params); - } else if (rpcType === RpcType.RESPONSE) { - message = new UnregisterAppInterfaceResponse(params); - } + getChoiceID() { + return this.getParameter(Choice.KEY_CHOICE_ID); + } + /** + * @param {String} name + * @return {Choice} + */ - break; - default: - message = null; - } + setMenuName(name) { + this.setParameter(Choice.KEY_MENU_NAME, name); + return this; + } + /** + * @return {String} + */ - if (message === null || message === undefined) { - // informs of missing classes - console.warn(`RpcCreator couldn't construct an RPC for the ${functionName} ${rpcName}`); - return null; - } - if (rpcType === RpcType.REQUEST || rpcType === RpcType.RESPONSE) { - message.setCorrelationId(correlationId); - } + getMenuName() { + return this.getParameter(Choice.KEY_MENU_NAME); + } + /** + * @param {String[]} commands + * @return {Choice} + */ - if (bulkData) { - message.setBulkData(bulkData); - } - return message; + setVrCommands(commands) { + this.setParameter(Choice.KEY_VR_COMMANDS, commands); + return this; + } + /** + * @return {String[]} + */ + + + getVrCommands() { + return this.getParameter(Choice.KEY_VR_COMMANDS); + } + /** + * @param {Image} image + * @return {Choice} + */ + + + setImage(image) { + this.validateType(Image, image); + this.setParameter(Choice.KEY_IMAGE, image); + return this; + } + /** + * @return {Image} + */ + + + getImage() { + return this.getObject(Image, Choice.KEY_IMAGE); + } + /** + * @param {String} text - Optional secondary text to display; e.g. address of POI in a search result entry + * @return {Choice} + */ + + + setSecondaryText(text) { + this.setParameter(Choice.KEY_SECONDARY_TEXT, text); + return this; + } + /** + * @return {String} + */ + + + getSecondaryText() { + return this.getParameter(Choice.KEY_SECONDARY_TEXT); + } + /** + * @param {String} text - Optional tertiary text to display; e.g. distance to POI for a search result entry + * @return {Choice} + */ + + + setTertiaryText(text) { + this.setParameter(Choice.KEY_TERTIARY_TEXT, text); + return this; + } + /** + * @return {String} + */ + + + getTertiaryText() { + return this.getParameter(Choice.KEY_TERTIARY_TEXT); + } + /** + * @param {Image} image - Optional secondary image struct for choice + * @return {Choice} + */ + + + setSecondaryImage(image) { + this.validateType(Image, image); + this.setParameter(Choice.KEY_SECONDARY_IMAGE, image); + return this; + } + /** + * @return {Image} + */ + + + getSecondaryImage() { + return this.getObject(Image, Choice.KEY_SECONDARY_IMAGE); } } - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + Choice.KEY_CHOICE_ID = 'choiceID'; + Choice.KEY_MENU_NAME = 'menuName'; + Choice.KEY_VR_COMMANDS = 'vrCommands'; + Choice.KEY_IMAGE = 'image'; + Choice.KEY_SECONDARY_TEXT = 'secondaryText'; + Choice.KEY_TERTIARY_TEXT = 'tertiaryText'; + Choice.KEY_SECONDARY_IMAGE = 'secondaryImage'; + + /* eslint-disable camelcase */ /** - * @typedef {Enum} VideoStreamingProtocol + * creates interaction choice set to be used later by performInteraction + */ + + class CreateInteractionChoiceSet extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.CreateInteractionChoiceSet); + } + /** + * @param {Number} id - Unique ID used for this interaction choice set. + * @return {CreateInteractionChoiceSet} + */ + + + setInteractionChoiceSetID(id) { + this.setParameter(CreateInteractionChoiceSet.KEY_INTERACTION_CHOICE_SET_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getInteractionChoiceSetID() { + return this.getParameter(CreateInteractionChoiceSet.KEY_INTERACTION_CHOICE_SET_ID); + } + /** + * @param {Choice[]} set - A choice is an option given to the user, which can be selected either by menu, or through + * voice recognition system. + * @return {CreateInteractionChoiceSet} + */ + + + setChoiceSet(set) { + this.validateType(Choice, set, true); + this.setParameter(CreateInteractionChoiceSet.KEY_CHOICE_SET, set); + return this; + } + /** + * @return {Choice[]} + */ + + + getChoiceSet() { + return this.getObject(Choice, CreateInteractionChoiceSet.KEY_CHOICE_SET); + } + + } + + CreateInteractionChoiceSet.KEY_INTERACTION_CHOICE_SET_ID = 'interactionChoiceSetID'; + CreateInteractionChoiceSet.KEY_CHOICE_SET = 'choiceSet'; + + /* eslint-disable camelcase */ + + class CreateInteractionChoiceSetResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.CreateInteractionChoiceSet); + } + + } + + /* eslint-disable camelcase */ + /** + * For touchscreen interactions, the mode of how the choices are presented. + * @typedef {Enum} LayoutMode * @property {Object} _MAP */ - class VideoStreamingProtocol extends Enum { + class LayoutMode extends Enum { /** - * @constructor - */ + * @constructor + */ constructor() { super(); } /** + * This mode causes the interaction to display the previous set of choices as icons. * @return {String} */ - static get RAW() { - return VideoStreamingProtocol._MAP.RAW; + static get ICON_ONLY() { + return LayoutMode._MAP.ICON_ONLY; } /** + * This mode causes the interaction to display the previous set of choices as icons along with a search field in + * the HMI. * @return {String} */ - static get RTP() { - return VideoStreamingProtocol._MAP.RTP; + static get ICON_WITH_SEARCH() { + return LayoutMode._MAP.ICON_WITH_SEARCH; } /** + * This mode causes the interaction to display the previous set of choices as a list. * @return {String} */ - static get RTSP() { - return VideoStreamingProtocol._MAP.RTSP; + static get LIST_ONLY() { + return LayoutMode._MAP.LIST_ONLY; } /** + * This mode causes the interaction to display the previous set of choices as a list along with a search field in + * the HMI. * @return {String} */ - static get RTMP() { - return VideoStreamingProtocol._MAP.RTMP; + static get LIST_WITH_SEARCH() { + return LayoutMode._MAP.LIST_WITH_SEARCH; } /** + * This mode causes the interaction to immediately display a keyboard entry through the HMI. * @return {String} */ - static get WEBM() { - return VideoStreamingProtocol._MAP.WEBM; + static get KEYBOARD() { + return LayoutMode._MAP.KEYBOARD; } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ static valueForKey(key) { - return VideoStreamingProtocol._valueForKey(key, VideoStreamingProtocol._MAP); + return LayoutMode._valueForKey(key, LayoutMode._MAP); } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ static keyForValue(value) { - return VideoStreamingProtocol._keyForValue(value, VideoStreamingProtocol._MAP); + return LayoutMode._keyForValue(value, LayoutMode._MAP); } } - VideoStreamingProtocol._MAP = Object.freeze({ + LayoutMode._MAP = Object.freeze({ + 'ICON_ONLY': 'ICON_ONLY', + 'ICON_WITH_SEARCH': 'ICON_WITH_SEARCH', + 'LIST_ONLY': 'LIST_ONLY', + 'LIST_WITH_SEARCH': 'LIST_WITH_SEARCH', + 'KEYBOARD': 'KEYBOARD' + }); + + /* eslint-disable camelcase */ + /** + * For application-requested interactions, this mode indicates the method in which the user is notified and uses the + * interaction. + * @typedef {Enum} InteractionMode + * @property {Object} _MAP + */ + + class InteractionMode extends Enum { /** - * Raw stream bytes that contains no timestamp data and is the lowest supported video streaming + * @constructor + */ + constructor() { + super(); + } + /** + * This mode causes the interaction to only occur on the display, meaning the choices are provided only via the + * display. No Voice Interaction. + * @return {String} */ - 'RAW': 'RAW', + + static get MANUAL_ONLY() { + return InteractionMode._MAP.MANUAL_ONLY; + } /** - * RTP facilitates the transfer of real-time data. Information provided by this protocol include - * timestamps (for synchronization), sequence numbers (for packet loss and reordering detection) - * and the payload format which indicates the encoded format of the data. + * This mode causes the interaction to only occur using the headunits VR system. Selections are made by saying the + * command. + * @return {String} */ - 'RTP': 'RTP', + + static get VR_ONLY() { + return InteractionMode._MAP.VR_ONLY; + } /** - * The transmission of streaming data itself is not a task of RTSP. Most RTSP servers use the - * Real-time Transport Protocol (RTP) in conjunction with Real-time Control Protocol (RTCP) for - * media stream delivery. However, some vendors implement proprietary transport protocols. + * This mode causes both a VR and display selection option for an interaction. The user will first be asked via + * Voice Interaction (if available). If this is unsuccessful, the system will switch to manual input. + * @return {String} */ - 'RTSP': 'RTSP', + + static get BOTH() { + return InteractionMode._MAP.BOTH; + } /** - * Real-Time Messaging Protocol (RTMP) was initially a proprietary protocol developed by - * Macromedia for streaming audio, video and data over the Internet, between a Flash player and - * a server. Macromedia is now owned by Adobe, which has released an incomplete version of the - * specification of the protocol for public use. + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found */ - 'RTMP': 'RTMP', + + static valueForKey(key) { + return InteractionMode._valueForKey(key, InteractionMode._MAP); + } /** - * The WebM container is based on a profile of Matroska. WebM initially supported VP8 video and - * Vorbis audio streams. In 2013 it was updated to accommodate VP9 video and Opus audio. + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found */ - 'WEBM': 'WEBM' + + + static keyForValue(value) { + return InteractionMode._keyForValue(value, InteractionMode._MAP); + } + + } + + InteractionMode._MAP = Object.freeze({ + 'MANUAL_ONLY': 'MANUAL_ONLY', + 'VR_ONLY': 'VR_ONLY', + 'BOTH': 'BOTH' }); - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ /** - * @typedef {Enum} VideoStreamingCodec - * @property {Object} _MAP + * Triggers an interaction (e.g. "Permit GPS?" - Yes, no, Always Allow). */ - class VideoStreamingCodec extends Enum { + class PerformInteraction extends RpcRequest { /** - * @constructor - */ - constructor() { - super(); + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.PerformInteraction); } /** - * @return {String} + * @param {String} text - Text to be displayed first. + * @return {PerformInteraction} */ - static get H264() { - return VideoStreamingCodec._MAP.H264; + setInitialText(text) { + this.setParameter(PerformInteraction.KEY_INITIAL_TEXT, text); + return this; } /** * @return {String} */ - static get H265() { - return VideoStreamingCodec._MAP.H265; + getInitialText() { + return this.getParameter(PerformInteraction.KEY_INITIAL_TEXT); + } + /** + * @param {TTSChunk[]} prompt - This is the initial prompt spoken to the user at the start of an interaction. An + * array of text chunks of type TTSChunk. See TTSChunk. The array must have at least + * one item. + * @return {PerformInteraction} + */ + + + setInitialPrompt(prompt) { + this.validateType(TTSChunk, prompt, true); + this.setParameter(PerformInteraction.KEY_INITIAL_PROMPT, prompt); + return this; + } + /** + * @return {TTSChunk[]} + */ + + + getInitialPrompt() { + return this.getObject(TTSChunk, PerformInteraction.KEY_INITIAL_PROMPT); + } + /** + * @param {InteractionMode} mode - See InteractionMode. + * @return {PerformInteraction} + */ + + + setInteractionMode(mode) { + this.validateType(InteractionMode, mode); + this.setParameter(PerformInteraction.KEY_INTERACTION_MODE, mode); + return this; + } + /** + * @return {InteractionMode} + */ + + + getInteractionMode() { + return this.getObject(InteractionMode, PerformInteraction.KEY_INTERACTION_MODE); + } + /** + * @param {Number[]} list - List of interaction choice set IDs to use with an interaction. + * @return {PerformInteraction} + */ + + + setInteractionChoiceSetIDList(list) { + this.setParameter(PerformInteraction.KEY_INTERACTION_CHOICE_SET_IDLIST, list); + return this; + } + /** + * @return {Number[]} + */ + + + getInteractionChoiceSetIDList() { + return this.getParameter(PerformInteraction.KEY_INTERACTION_CHOICE_SET_IDLIST); + } + /** + * @param {TTSChunk[]} prompt - Help text. This is the spoken string when a user speaks "help" when the interaction + * is occurring. An array of text chunks of type TTSChunk. See TTSChunk. The array must + * have at least one item. + * @return {PerformInteraction} + */ + + + setHelpPrompt(prompt) { + this.validateType(TTSChunk, prompt, true); + this.setParameter(PerformInteraction.KEY_HELP_PROMPT, prompt); + return this; + } + /** + * @return {TTSChunk[]} + */ + + + getHelpPrompt() { + return this.getObject(TTSChunk, PerformInteraction.KEY_HELP_PROMPT); + } + /** + * @param {TTSChunk[]} prompt - Timeout text. This text is spoken when a VR interaction times out. An array of text + * chunks of type TTSChunk. See TTSChunk. The array must have at least one item. + * @return {PerformInteraction} + */ + + + setTimeoutPrompt(prompt) { + this.validateType(TTSChunk, prompt, true); + this.setParameter(PerformInteraction.KEY_TIMEOUT_PROMPT, prompt); + return this; + } + /** + * @return {TTSChunk[]} + */ + + + getTimeoutPrompt() { + return this.getObject(TTSChunk, PerformInteraction.KEY_TIMEOUT_PROMPT); + } + /** + * @param {Number} timeout - Timeout in milliseconds. If omitted a standard value of 10000 milliseconds is used. + * Applies only to the menu portion of the interaction. The VR timeout will be handled by + * the platform. + * @return {PerformInteraction} + */ + + + setTimeout(timeout) { + this.setParameter(PerformInteraction.KEY_TIMEOUT, timeout); + return this; + } + /** + * @return {Number} + */ + + + getTimeout() { + return this.getParameter(PerformInteraction.KEY_TIMEOUT); + } + /** + * @param {VrHelpItem[]} help - Ability to send suggested VR Help Items to display on-screen during Perform + * Interaction. If omitted on supported displays, the default generated list of + * suggested choices shall be displayed. + * @return {PerformInteraction} + */ + + + setVrHelp(help) { + this.validateType(VrHelpItem, help, true); + this.setParameter(PerformInteraction.KEY_VR_HELP, help); + return this; + } + /** + * @return {VrHelpItem[]} + */ + + + getVrHelp() { + return this.getObject(VrHelpItem, PerformInteraction.KEY_VR_HELP); + } + /** + * @param {LayoutMode} layout - See LayoutMode. + * @return {PerformInteraction} + */ + + + setInteractionLayout(layout) { + this.validateType(LayoutMode, layout); + this.setParameter(PerformInteraction.KEY_INTERACTION_LAYOUT, layout); + return this; + } + /** + * @return {LayoutMode} + */ + + + getInteractionLayout() { + return this.getObject(LayoutMode, PerformInteraction.KEY_INTERACTION_LAYOUT); + } + /** + * @param {Number} id - An ID for this specific PerformInteraction to allow cancellation through the + * `CancelInteraction` RPC. + * @return {PerformInteraction} + */ + + + setCancelID(id) { + this.setParameter(PerformInteraction.KEY_CANCEL_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getCancelID() { + return this.getParameter(PerformInteraction.KEY_CANCEL_ID); + } + + } + + PerformInteraction.KEY_INITIAL_TEXT = 'initialText'; + PerformInteraction.KEY_INITIAL_PROMPT = 'initialPrompt'; + PerformInteraction.KEY_INTERACTION_MODE = 'interactionMode'; + PerformInteraction.KEY_INTERACTION_CHOICE_SET_IDLIST = 'interactionChoiceSetIDList'; + PerformInteraction.KEY_HELP_PROMPT = 'helpPrompt'; + PerformInteraction.KEY_TIMEOUT_PROMPT = 'timeoutPrompt'; + PerformInteraction.KEY_TIMEOUT = 'timeout'; + PerformInteraction.KEY_VR_HELP = 'vrHelp'; + PerformInteraction.KEY_INTERACTION_LAYOUT = 'interactionLayout'; + PerformInteraction.KEY_CANCEL_ID = 'cancelID'; + + /* eslint-disable camelcase */ + /** + * Indicates the source from where the command was triggered. + * @typedef {Enum} TriggerSource + * @property {Object} _MAP + */ + + class TriggerSource extends Enum { + /** + * @constructor + */ + constructor() { + super(); } /** * @return {String} */ - static get Theora() { - return VideoStreamingCodec._MAP.Theora; + static get TS_MENU() { + return TriggerSource._MAP.TS_MENU; } /** * @return {String} */ - static get VP8() { - return VideoStreamingCodec._MAP.VP8; + static get TS_VR() { + return TriggerSource._MAP.TS_VR; } /** * @return {String} */ - static get VP9() { - return VideoStreamingCodec._MAP.VP9; + static get TS_KEYBOARD() { + return TriggerSource._MAP.TS_KEYBOARD; } /** - * Get the value for the given enum key - * @param value - A key to find in the map of the subclass - * @return {*} - Returns a value if found, or null if not found - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ static valueForKey(key) { - return VideoStreamingCodec._valueForKey(key, VideoStreamingCodec._MAP); + return TriggerSource._valueForKey(key, TriggerSource._MAP); } /** - * Get the key for the given enum value - * @param value - A primitive value to find the matching key for in the map of the subclass - * @return {*} - Returns a key if found, or null if not found - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ static keyForValue(value) { - return VideoStreamingCodec._keyForValue(value, VideoStreamingCodec._MAP); + return TriggerSource._keyForValue(value, TriggerSource._MAP); } } - VideoStreamingCodec._MAP = Object.freeze({ + TriggerSource._MAP = Object.freeze({ + 'TS_MENU': 'MENU', + 'TS_VR': 'VR', + 'TS_KEYBOARD': 'KEYBOARD' + }); + + /* eslint-disable camelcase */ + + class PerformInteractionResponse extends RpcResponse { /** - * A block-oriented motion-compensation-based video compression standard. As of 2014 it is one - * of the most commonly used formats for the recording, compression, and distribution of video - * content. + * @constructor */ - 'H264': 'H264', - + constructor(store) { + super(store); + this.setFunctionName(FunctionID.PerformInteraction); + } /** - * High Efficiency Video Coding (HEVC), also known as H.265 and MPEG-H Part 2, is a video - * compression standard, one of several potential successors to the widely used AVC - * (H.264 or MPEG-4 Part 10). In comparison to AVC, HEVC offers about double the data - * compression ratio at the same level of video quality, or substantially improved video quality - * at the same bit rate. It supports resolutions up to 8192x4320, including 8K UHD. + * @param {Number} id - ID of the choice that was selected in response to PerformInteraction. Only is valid if + * general result is "success:true". + * @return {PerformInteractionResponse} */ - 'H265': 'H265', + + setChoiceID(id) { + this.setParameter(PerformInteractionResponse.KEY_CHOICE_ID, id); + return this; + } /** - * Theora is derived from the formerly proprietary VP3 codec, released into the public domain by - * On2 Technologies. It is broadly comparable in design and bitrate efficiency to MPEG-4 Part 2, - * early versions of Windows Media Video, and RealVideo while lacking some of the features - * present in some of these other codecs. It is comparable in open standards philosophy to the - * BBC's Dirac codec. + * @return {Number} */ - 'Theora': 'Theora', + + getChoiceID() { + return this.getParameter(PerformInteractionResponse.KEY_CHOICE_ID); + } /** - * VP8 can be multiplexed into the Matroska-based container format WebM along with Vorbis and - * Opus audio. The image format WebP is based on VP8's intra-frame coding. VP8's direct - * successor, VP9, and the emerging royalty-free internet video format AV1 from the Alliance - * for Open Media (AOMedia) are based on VP8. + * @param {String} entry - Manually entered text selection, e.g. through keyboard Can be returned in lieu of + * choiceID, depending on trigger source + * @return {PerformInteractionResponse} */ - 'VP8': 'VP8', + + setManualTextEntry(entry) { + this.setParameter(PerformInteractionResponse.KEY_MANUAL_TEXT_ENTRY, entry); + return this; + } /** - * Similar to VP8, but VP9 is customized for video resolutions beyond high-definition video - * (UHD) and also enables lossless compression. + * @return {String} */ - 'VP9': 'VP9' - }); - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - class VideoStreamingFormat extends RpcStruct { - /** - * @constructor - */ - constructor() { - super(); + getManualTextEntry() { + return this.getParameter(PerformInteractionResponse.KEY_MANUAL_TEXT_ENTRY); } /** - * @param {VideoStreamingProtocol} val - * @return {VideoStreamingFormat} - */ + * @param {TriggerSource} source - See TriggerSource Only is valid if resultCode is SUCCESS. + * @return {PerformInteractionResponse} + */ - setProtocol(val) { - this.validateType(VideoStreamingProtocol, val); - this.setParameter(VideoStreamingFormat.KEY_PROTOCOL, val); + setTriggerSource(source) { + this.validateType(TriggerSource, source); + this.setParameter(PerformInteractionResponse.KEY_TRIGGER_SOURCE, source); return this; } /** - * @return {VideoStreamingProtocol} - */ + * @return {TriggerSource} + */ - getProtocol() { - return this.getParameter(VideoStreamingFormat.KEY_PROTOCOL); + getTriggerSource() { + return this.getObject(TriggerSource, PerformInteractionResponse.KEY_TRIGGER_SOURCE); + } + + } + + PerformInteractionResponse.KEY_CHOICE_ID = 'choiceID'; + PerformInteractionResponse.KEY_MANUAL_TEXT_ENTRY = 'manualTextEntry'; + PerformInteractionResponse.KEY_TRIGGER_SOURCE = 'triggerSource'; + + /* eslint-disable camelcase */ + /** + * Deletes interaction choice set that has been created with "CreateInteractionChoiceSet". The interaction may only be + * deleted when not currently in use by a "performInteraction". + */ + + class DeleteInteractionChoiceSet extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.DeleteInteractionChoiceSet); } /** - * @param {VideoStreamingCodec} val - * @return {VideoStreamingFormat} - */ + * @param {Number} id - ID of the interaction choice set to delete. + * @return {DeleteInteractionChoiceSet} + */ - setCodec(val) { - this.validateType(VideoStreamingCodec, val); - this.setParameter(VideoStreamingFormat.KEY_CODEC, val); + setInteractionChoiceSetID(id) { + this.setParameter(DeleteInteractionChoiceSet.KEY_INTERACTION_CHOICE_SET_ID, id); return this; } /** - * @return {VideoStreamingCodec} - */ + * @return {Number} + */ - getCodec() { - return this.getParameter(VideoStreamingFormat.KEY_CODEC); + getInteractionChoiceSetID() { + return this.getParameter(DeleteInteractionChoiceSet.KEY_INTERACTION_CHOICE_SET_ID); + } + + } + + DeleteInteractionChoiceSet.KEY_INTERACTION_CHOICE_SET_ID = 'interactionChoiceSetID'; + + /* eslint-disable camelcase */ + + class DeleteInteractionChoiceSetResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.DeleteInteractionChoiceSet); + } + + } + + /* eslint-disable camelcase */ + /** + * Contains information about the SoftButton capabilities. + * @typedef {Enum} SoftButtonType + * @property {Object} _MAP + */ + + class SoftButtonType extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get SBT_TEXT() { + return SoftButtonType._MAP.SBT_TEXT; + } + /** + * @return {String} + */ + + + static get SBT_IMAGE() { + return SoftButtonType._MAP.SBT_IMAGE; + } + /** + * @return {String} + */ + + + static get SBT_BOTH() { + return SoftButtonType._MAP.SBT_BOTH; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return SoftButtonType._valueForKey(key, SoftButtonType._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return SoftButtonType._keyForValue(value, SoftButtonType._MAP); + } + + } + + SoftButtonType._MAP = Object.freeze({ + 'SBT_TEXT': 'TEXT', + 'SBT_IMAGE': 'IMAGE', + 'SBT_BOTH': 'BOTH' + }); + + /* eslint-disable camelcase */ + /** + * Enumeration that describes system actions that can be triggered. + * @typedef {Enum} SystemAction + * @property {Object} _MAP + */ + + class SystemAction extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * Default action occurs. Standard behavior (e.g. SoftButton clears overlay). + * @return {String} + */ + + + static get DEFAULT_ACTION() { + return SystemAction._MAP.DEFAULT_ACTION; + } + /** + * App is brought into HMI_FULL. + * @return {String} + */ + + + static get STEAL_FOCUS() { + return SystemAction._MAP.STEAL_FOCUS; + } + /** + * Current system context is maintained. An overlay is persisted even though a SoftButton has been pressed and the + * notification sent. + * @return {String} + */ + + + static get KEEP_CONTEXT() { + return SystemAction._MAP.KEEP_CONTEXT; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return SystemAction._valueForKey(key, SystemAction._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return SystemAction._keyForValue(value, SystemAction._MAP); + } + + } + + SystemAction._MAP = Object.freeze({ + 'DEFAULT_ACTION': 'DEFAULT_ACTION', + 'STEAL_FOCUS': 'STEAL_FOCUS', + 'KEEP_CONTEXT': 'KEEP_CONTEXT' + }); + + /* eslint-disable camelcase */ + + class SoftButton extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {SoftButtonType} type - Describes, whether it is text, highlighted text, icon, or dynamic image. See + * softButtonType + * @return {SoftButton} + */ + + + setType(type) { + this.validateType(SoftButtonType, type); + this.setParameter(SoftButton.KEY_TYPE, type); + return this; + } + /** + * @return {SoftButtonType} + */ + + + getType() { + return this.getObject(SoftButtonType, SoftButton.KEY_TYPE); + } + /** + * @param {String} text - Optional text to display (if defined as TEXT or BOTH) + * @return {SoftButton} + */ + + + setText(text) { + this.setParameter(SoftButton.KEY_TEXT, text); + return this; + } + /** + * @return {String} + */ + + + getText() { + return this.getParameter(SoftButton.KEY_TEXT); + } + /** + * @param {Image} image - Optional image struct for SoftButton (if defined as IMAGE or BOTH) + * @return {SoftButton} + */ + + + setImage(image) { + this.validateType(Image, image); + this.setParameter(SoftButton.KEY_IMAGE, image); + return this; + } + /** + * @return {Image} + */ + + + getImage() { + return this.getObject(Image, SoftButton.KEY_IMAGE); + } + /** + * @param {Boolean} highlighted - True, if highlighted False, if not highlighted + * @return {SoftButton} + */ + + + setIsHighlighted(highlighted) { + this.setParameter(SoftButton.KEY_IS_HIGHLIGHTED, highlighted); + return this; + } + /** + * @return {Boolean} + */ + + + getIsHighlighted() { + return this.getParameter(SoftButton.KEY_IS_HIGHLIGHTED); + } + /** + * @param {Number} id - Value which is returned via OnButtonPress / OnButtonEvent + * @return {SoftButton} + */ + + + setSoftButtonID(id) { + this.setParameter(SoftButton.KEY_SOFT_BUTTON_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getSoftButtonID() { + return this.getParameter(SoftButton.KEY_SOFT_BUTTON_ID); + } + /** + * @param {SystemAction} action - Parameter indicating whether selecting a SoftButton shall call a specific system + * action. This is intended to allow Notifications to bring the callee into full / + * focus; or in the case of persistent overlays, the overlay can persist when a + * SoftButton is pressed. + * @return {SoftButton} + */ + + + setSystemAction(action) { + this.validateType(SystemAction, action); + this.setParameter(SoftButton.KEY_SYSTEM_ACTION, action); + return this; + } + /** + * @return {SystemAction} + */ + + + getSystemAction() { + return this.getObject(SystemAction, SoftButton.KEY_SYSTEM_ACTION); + } + + } + + SoftButton.KEY_TYPE = 'type'; + SoftButton.KEY_TEXT = 'text'; + SoftButton.KEY_IMAGE = 'image'; + SoftButton.KEY_IS_HIGHLIGHTED = 'isHighlighted'; + SoftButton.KEY_SOFT_BUTTON_ID = 'softButtonID'; + SoftButton.KEY_SYSTEM_ACTION = 'systemAction'; + + /* eslint-disable camelcase */ + /** + * Shows an alert which typically consists of text-to-speech message and text on the display. At least either + * alertText1, alertText2 or TTSChunks need to be provided. + */ + + class Alert extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.Alert); + } + /** + * @param {String} text1 - The first line of the alert text field + * @return {Alert} + */ + + + setAlertText1(text1) { + this.setParameter(Alert.KEY_ALERT_TEXT_1, text1); + return this; + } + /** + * @return {String} + */ + + + getAlertText1() { + return this.getParameter(Alert.KEY_ALERT_TEXT_1); + } + /** + * @param {String} text2 - The second line of the alert text field + * @return {Alert} + */ + + + setAlertText2(text2) { + this.setParameter(Alert.KEY_ALERT_TEXT_2, text2); + return this; + } + /** + * @return {String} + */ + + + getAlertText2() { + return this.getParameter(Alert.KEY_ALERT_TEXT_2); + } + /** + * @param {String} text3 - The optional third line of the alert text field + * @return {Alert} + */ + + + setAlertText3(text3) { + this.setParameter(Alert.KEY_ALERT_TEXT_3, text3); + return this; + } + /** + * @return {String} + */ + + + getAlertText3() { + return this.getParameter(Alert.KEY_ALERT_TEXT_3); + } + /** + * @param {TTSChunk[]} chunks - An array of text chunks of type TTSChunk. See TTSChunk. The array must have at least + * one item. + * @return {Alert} + */ + + + setTtsChunks(chunks) { + this.validateType(TTSChunk, chunks, true); + this.setParameter(Alert.KEY_TTS_CHUNKS, chunks); + return this; + } + /** + * @return {TTSChunk[]} + */ + + + getTtsChunks() { + return this.getObject(TTSChunk, Alert.KEY_TTS_CHUNKS); + } + /** + * @param {Number} duration - Timeout in milliseconds. Typical timeouts are 3-5 seconds. If omitted, timeout is set + * to 5s. + * @return {Alert} + */ + + + setDuration(duration) { + this.setParameter(Alert.KEY_DURATION, duration); + return this; + } + /** + * @return {Number} + */ + + + getDuration() { + return this.getParameter(Alert.KEY_DURATION); + } + /** + * @param {Boolean} tone - Defines if tone should be played. Tone is played before TTS. If omitted, no tone is + * played. + * @return {Alert} + */ + + + setPlayTone(tone) { + this.setParameter(Alert.KEY_PLAY_TONE, tone); + return this; + } + /** + * @return {Boolean} + */ + + + getPlayTone() { + return this.getParameter(Alert.KEY_PLAY_TONE); + } + /** + * @param {Boolean} indicator - If supported on the given platform, the alert GUI will include some sort of + * animation indicating that loading of a feature is progressing. e.g. a spinning wheel + * or hourglass, etc. + * @return {Alert} + */ + + + setProgressIndicator(indicator) { + this.setParameter(Alert.KEY_PROGRESS_INDICATOR, indicator); + return this; + } + /** + * @return {Boolean} + */ + + + getProgressIndicator() { + return this.getParameter(Alert.KEY_PROGRESS_INDICATOR); + } + /** + * @param {SoftButton[]} buttons - App defined SoftButtons. If omitted on supported displays, the displayed alert + * shall not have any SoftButtons. + * @return {Alert} + */ + + + setSoftButtons(buttons) { + this.validateType(SoftButton, buttons, true); + this.setParameter(Alert.KEY_SOFT_BUTTONS, buttons); + return this; + } + /** + * @return {SoftButton[]} + */ + + + getSoftButtons() { + return this.getObject(SoftButton, Alert.KEY_SOFT_BUTTONS); + } + /** + * @param {Image} icon - Image struct determining whether static or dynamic icon. If omitted on supported displays, + * no (or the default if applicable) icon should be displayed. + * @return {Alert} + */ + + + setAlertIcon(icon) { + this.validateType(Image, icon); + this.setParameter(Alert.KEY_ALERT_ICON, icon); + return this; + } + /** + * @return {Image} + */ + + + getAlertIcon() { + return this.getObject(Image, Alert.KEY_ALERT_ICON); + } + /** + * @param {Number} id - An ID for this specific alert to allow cancellation through the `CancelInteraction` RPC. + * @return {Alert} + */ + + + setCancelID(id) { + this.setParameter(Alert.KEY_CANCEL_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getCancelID() { + return this.getParameter(Alert.KEY_CANCEL_ID); + } + + } + + Alert.KEY_ALERT_TEXT_1 = 'alertText1'; + Alert.KEY_ALERT_TEXT_2 = 'alertText2'; + Alert.KEY_ALERT_TEXT_3 = 'alertText3'; + Alert.KEY_TTS_CHUNKS = 'ttsChunks'; + Alert.KEY_DURATION = 'duration'; + Alert.KEY_PLAY_TONE = 'playTone'; + Alert.KEY_PROGRESS_INDICATOR = 'progressIndicator'; + Alert.KEY_SOFT_BUTTONS = 'softButtons'; + Alert.KEY_ALERT_ICON = 'alertIcon'; + Alert.KEY_CANCEL_ID = 'cancelID'; + + /* eslint-disable camelcase */ + + class AlertResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.Alert); + } + /** + * @param {Number} time - Amount of time (in seconds) that an app must wait before resending an alert. If provided, + * another system event or overlay currently has a higher priority than this alert. An app + * must not send an alert without waiting at least the amount of time dictated. + * @return {AlertResponse} + */ + + + setTryAgainTime(time) { + this.setParameter(AlertResponse.KEY_TRY_AGAIN_TIME, time); + return this; + } + /** + * @return {Number} + */ + + + getTryAgainTime() { + return this.getParameter(AlertResponse.KEY_TRY_AGAIN_TIME); + } + + } + + AlertResponse.KEY_TRY_AGAIN_TIME = 'tryAgainTime'; + + /* eslint-disable camelcase */ + /** + * The list of possible alignments, left, right, or centered + * @typedef {Enum} TextAlignment + * @property {Object} _MAP + */ + + class TextAlignment extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get LEFT_ALIGNED() { + return TextAlignment._MAP.LEFT_ALIGNED; + } + /** + * @return {String} + */ + + + static get RIGHT_ALIGNED() { + return TextAlignment._MAP.RIGHT_ALIGNED; + } + /** + * @return {String} + */ + + + static get CENTERED() { + return TextAlignment._MAP.CENTERED; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return TextAlignment._valueForKey(key, TextAlignment._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return TextAlignment._keyForValue(value, TextAlignment._MAP); + } + + } + + TextAlignment._MAP = Object.freeze({ + 'LEFT_ALIGNED': 'LEFT_ALIGNED', + 'RIGHT_ALIGNED': 'RIGHT_ALIGNED', + 'CENTERED': 'CENTERED' + }); + + /* eslint-disable camelcase */ + + class TemplateConfiguration extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {String} template - Predefined or dynamically created window template. Currently only predefined window + * template layouts are defined. + * @return {TemplateConfiguration} + */ + + + setTemplate(template) { + this.setParameter(TemplateConfiguration.KEY_TEMPLATE, template); + return this; + } + /** + * @return {String} + */ + + + getTemplate() { + return this.getParameter(TemplateConfiguration.KEY_TEMPLATE); + } + /** + * @param {TemplateColorScheme} scheme - A color scheme for all display layout templates. + * @return {TemplateConfiguration} + */ + + + setDayColorScheme(scheme) { + this.validateType(TemplateColorScheme, scheme); + this.setParameter(TemplateConfiguration.KEY_DAY_COLOR_SCHEME, scheme); + return this; + } + /** + * @return {TemplateColorScheme} + */ + + + getDayColorScheme() { + return this.getObject(TemplateColorScheme, TemplateConfiguration.KEY_DAY_COLOR_SCHEME); + } + /** + * @param {TemplateColorScheme} scheme - A color scheme for all display layout templates. + * @return {TemplateConfiguration} + */ + + + setNightColorScheme(scheme) { + this.validateType(TemplateColorScheme, scheme); + this.setParameter(TemplateConfiguration.KEY_NIGHT_COLOR_SCHEME, scheme); + return this; + } + /** + * @return {TemplateColorScheme} + */ + + + getNightColorScheme() { + return this.getObject(TemplateColorScheme, TemplateConfiguration.KEY_NIGHT_COLOR_SCHEME); + } + + } + + TemplateConfiguration.KEY_TEMPLATE = 'template'; + TemplateConfiguration.KEY_DAY_COLOR_SCHEME = 'dayColorScheme'; + TemplateConfiguration.KEY_NIGHT_COLOR_SCHEME = 'nightColorScheme'; + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} MetadataType + * @property {Object} _MAP + */ + + class MetadataType extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * The data in this field contains the title of the currently playing audio track. + * @return {String} + */ + + + static get mediaTitle() { + return MetadataType._MAP.mediaTitle; + } + /** + * The data in this field contains the artist or creator of the currently playing audio track. + * @return {String} + */ + + + static get mediaArtist() { + return MetadataType._MAP.mediaArtist; + } + /** + * The data in this field contains the album title of the currently playing audio track. + * @return {String} + */ + + + static get mediaAlbum() { + return MetadataType._MAP.mediaAlbum; + } + /** + * The data in this field contains the creation year of the currently playing audio track. + * @return {String} + */ + + + static get mediaYear() { + return MetadataType._MAP.mediaYear; + } + /** + * The data in this field contains the genre of the currently playing audio track. + * @return {String} + */ + + + static get mediaGenre() { + return MetadataType._MAP.mediaGenre; + } + /** + * The data in this field contains the name of the current source for the media. + * @return {String} + */ + + + static get mediaStation() { + return MetadataType._MAP.mediaStation; + } + /** + * The data in this field is a rating. + * @return {String} + */ + + + static get rating() { + return MetadataType._MAP.rating; + } + /** + * The data in this field is the current temperature. + * @return {String} + */ + + + static get currentTemperature() { + return MetadataType._MAP.currentTemperature; + } + /** + * The data in this field is the maximum temperature for the day. + * @return {String} + */ + + + static get maximumTemperature() { + return MetadataType._MAP.maximumTemperature; + } + /** + * The data in this field is the minimum temperature for the day. + * @return {String} + */ + + + static get minimumTemperature() { + return MetadataType._MAP.minimumTemperature; + } + /** + * The data in this field describes the current weather (ex. cloudy, clear, etc.). + * @return {String} + */ + + + static get weatherTerm() { + return MetadataType._MAP.weatherTerm; + } + /** + * The data in this field describes the current humidity value. + * @return {String} + */ + + + static get humidity() { + return MetadataType._MAP.humidity; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return MetadataType._valueForKey(key, MetadataType._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return MetadataType._keyForValue(value, MetadataType._MAP); + } + + } + + MetadataType._MAP = Object.freeze({ + 'mediaTitle': 'mediaTitle', + 'mediaArtist': 'mediaArtist', + 'mediaAlbum': 'mediaAlbum', + 'mediaYear': 'mediaYear', + 'mediaGenre': 'mediaGenre', + 'mediaStation': 'mediaStation', + 'rating': 'rating', + 'currentTemperature': 'currentTemperature', + 'maximumTemperature': 'maximumTemperature', + 'minimumTemperature': 'minimumTemperature', + 'weatherTerm': 'weatherTerm', + 'humidity': 'humidity' + }); + + /* eslint-disable camelcase */ + + class MetadataTags extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {MetadataType[]} field1 - The type of data contained in the "mainField1" text field. + * @return {MetadataTags} + */ + + + setMainField1(field1) { + this.validateType(MetadataType, field1, true); + this.setParameter(MetadataTags.KEY_MAIN_FIELD_1, field1); + return this; + } + /** + * @return {MetadataType[]} + */ + + + getMainField1() { + return this.getObject(MetadataType, MetadataTags.KEY_MAIN_FIELD_1); + } + /** + * @param {MetadataType[]} field2 - The type of data contained in the "mainField2" text field. + * @return {MetadataTags} + */ + + + setMainField2(field2) { + this.validateType(MetadataType, field2, true); + this.setParameter(MetadataTags.KEY_MAIN_FIELD_2, field2); + return this; + } + /** + * @return {MetadataType[]} + */ + + + getMainField2() { + return this.getObject(MetadataType, MetadataTags.KEY_MAIN_FIELD_2); + } + /** + * @param {MetadataType[]} field3 - The type of data contained in the "mainField3" text field. + * @return {MetadataTags} + */ + + + setMainField3(field3) { + this.validateType(MetadataType, field3, true); + this.setParameter(MetadataTags.KEY_MAIN_FIELD_3, field3); + return this; + } + /** + * @return {MetadataType[]} + */ + + + getMainField3() { + return this.getObject(MetadataType, MetadataTags.KEY_MAIN_FIELD_3); + } + /** + * @param {MetadataType[]} field4 - The type of data contained in the "mainField4" text field. + * @return {MetadataTags} + */ + + + setMainField4(field4) { + this.validateType(MetadataType, field4, true); + this.setParameter(MetadataTags.KEY_MAIN_FIELD_4, field4); + return this; + } + /** + * @return {MetadataType[]} + */ + + + getMainField4() { + return this.getObject(MetadataType, MetadataTags.KEY_MAIN_FIELD_4); + } + + } + + MetadataTags.KEY_MAIN_FIELD_1 = 'mainField1'; + MetadataTags.KEY_MAIN_FIELD_2 = 'mainField2'; + MetadataTags.KEY_MAIN_FIELD_3 = 'mainField3'; + MetadataTags.KEY_MAIN_FIELD_4 = 'mainField4'; + + /* eslint-disable camelcase */ + /** + * Updates the persistent display. Supported fields depend on display capabilities. + */ + + class Show extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.Show); + } + /** + * @param {String} field1 - The text that should be displayed in a single or upper display line. If this text is not + * set, the text of mainField1 stays unchanged. If this text is empty "", the field will be + * cleared. + * @return {Show} + */ + + + setMainField1(field1) { + this.setParameter(Show.KEY_MAIN_FIELD_1, field1); + return this; + } + /** + * @return {String} + */ + + + getMainField1() { + return this.getParameter(Show.KEY_MAIN_FIELD_1); + } + /** + * @param {String} field2 - The text that should be displayed on the second display line. If this text is not set, + * the text of mainField2 stays unchanged. If this text is empty "", the field will be + * cleared. + * @return {Show} + */ + + + setMainField2(field2) { + this.setParameter(Show.KEY_MAIN_FIELD_2, field2); + return this; + } + /** + * @return {String} + */ + + + getMainField2() { + return this.getParameter(Show.KEY_MAIN_FIELD_2); + } + /** + * @param {String} field3 - The text that should be displayed on the second "page" first display line. If this text + * is not set, the text of mainField3 stays unchanged. If this text is empty "", the field + * will be cleared. + * @return {Show} + */ + + + setMainField3(field3) { + this.setParameter(Show.KEY_MAIN_FIELD_3, field3); + return this; + } + /** + * @return {String} + */ + + + getMainField3() { + return this.getParameter(Show.KEY_MAIN_FIELD_3); + } + /** + * @param {String} field4 - The text that should be displayed on the second "page" second display line. If this text + * is not set, the text of mainField4 stays unchanged. If this text is empty "", the field + * will be cleared. + * @return {Show} + */ + + + setMainField4(field4) { + this.setParameter(Show.KEY_MAIN_FIELD_4, field4); + return this; + } + /** + * @return {String} + */ + + + getMainField4() { + return this.getParameter(Show.KEY_MAIN_FIELD_4); + } + /** + * @param {TextAlignment} alignment - Specifies how mainField1 and mainField2 texts should be aligned on display. If + * omitted, texts will be centered. + * @return {Show} + */ + + + setAlignment(alignment) { + this.validateType(TextAlignment, alignment); + this.setParameter(Show.KEY_ALIGNMENT, alignment); + return this; + } + /** + * @return {TextAlignment} + */ + + + getAlignment() { + return this.getObject(TextAlignment, Show.KEY_ALIGNMENT); + } + /** + * @param {String} bar - Requires investigation regarding the nav display capabilities. Potentially lower + * lowerStatusBar, upperStatusBar, titleBar, etc. + * @return {Show} + */ + + + setStatusBar(bar) { + this.setParameter(Show.KEY_STATUS_BAR, bar); + return this; + } + /** + * @return {String} + */ + + + getStatusBar() { + return this.getParameter(Show.KEY_STATUS_BAR); + } + /** + * @param {String} clock - Text value for MediaClock field. Has to be properly formatted by Mobile App according to + * the module's capabilities. If this text is set, any automatic media clock updates + * previously set with SetMediaClockTimer will be stopped. + * @return {Show} + */ + + + setMediaClock(clock) { + this.setParameter(Show.KEY_MEDIA_CLOCK, clock); + return this; + } + /** + * @return {String} + */ + + + getMediaClock() { + return this.getParameter(Show.KEY_MEDIA_CLOCK); + } + /** + * @param {String} track - The text that should be displayed in the track field. If this text is not set, the text + * of mediaTrack stays unchanged. If this text is empty "", the field will be cleared. + * @return {Show} + */ + + + setMediaTrack(track) { + this.setParameter(Show.KEY_MEDIA_TRACK, track); + return this; + } + /** + * @return {String} + */ + + + getMediaTrack() { + return this.getParameter(Show.KEY_MEDIA_TRACK); + } + /** + * @param {Image} graphic - Image struct determining whether static or dynamic image to display in app. If omitted + * on supported displays, the displayed graphic shall not change. + * @return {Show} + */ + + + setGraphic(graphic) { + this.validateType(Image, graphic); + this.setParameter(Show.KEY_GRAPHIC, graphic); + return this; + } + /** + * @return {Image} + */ + + + getGraphic() { + return this.getObject(Image, Show.KEY_GRAPHIC); + } + /** + * @param {Image} graphic - Image struct determining whether static or dynamic secondary image to display in app. If + * omitted on supported displays, the displayed secondary graphic shall not change. + * @return {Show} + */ + + + setSecondaryGraphic(graphic) { + this.validateType(Image, graphic); + this.setParameter(Show.KEY_SECONDARY_GRAPHIC, graphic); + return this; + } + /** + * @return {Image} + */ + + + getSecondaryGraphic() { + return this.getObject(Image, Show.KEY_SECONDARY_GRAPHIC); + } + /** + * @param {SoftButton[]} buttons - App defined SoftButtons. If omitted on supported displays, the currently + * displayed SoftButton values will not change. + * @return {Show} + */ + + + setSoftButtons(buttons) { + this.validateType(SoftButton, buttons, true); + this.setParameter(Show.KEY_SOFT_BUTTONS, buttons); + return this; + } + /** + * @return {SoftButton[]} + */ + + + getSoftButtons() { + return this.getObject(SoftButton, Show.KEY_SOFT_BUTTONS); + } + /** + * @param {String[]} presets - App labeled on-screen presets (i.e. on-screen media presets or dynamic search + * suggestions). If omitted on supported displays, the presets will be shown as not + * defined. + * @return {Show} + */ + + + setCustomPresets(presets) { + this.setParameter(Show.KEY_CUSTOM_PRESETS, presets); + return this; + } + /** + * @return {String[]} + */ + + + getCustomPresets() { + return this.getParameter(Show.KEY_CUSTOM_PRESETS); + } + /** + * @param {MetadataTags} tags - App defined metadata information. See MetadataStruct. Uses mainField1, mainField2, + * mainField3, mainField4. If omitted on supported displays, the currently set metadata + * tags will not change. If any text field contains no tags or the none tag, the + * metadata tag for that textfield should be removed. + * @return {Show} + */ + + + setMetadataTags(tags) { + this.validateType(MetadataTags, tags); + this.setParameter(Show.KEY_METADATA_TAGS, tags); + return this; + } + /** + * @return {MetadataTags} + */ + + + getMetadataTags() { + return this.getObject(MetadataTags, Show.KEY_METADATA_TAGS); + } + /** + * @param {String} title - The title of the new template that will be displayed. How this will be displayed is + * dependent on the OEM design and implementation of the template. + * @return {Show} + */ + + + setTemplateTitle(title) { + this.setParameter(Show.KEY_TEMPLATE_TITLE, title); + return this; + } + /** + * @return {String} + */ + + + getTemplateTitle() { + return this.getParameter(Show.KEY_TEMPLATE_TITLE); + } + /** + * @param {Number} id - This is the unique ID assigned to the window that this RPC is intended. If this param is not + * included, it will be assumed that this request is specifically for the main window on the + * main display. See PredefinedWindows enum. + * @return {Show} + */ + + + setWindowID(id) { + this.setParameter(Show.KEY_WINDOW_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getWindowID() { + return this.getParameter(Show.KEY_WINDOW_ID); + } + /** + * @param {TemplateConfiguration} configuration - Used to set an alternate template layout to a window. + * @return {Show} + */ + + + setTemplateConfiguration(configuration) { + this.validateType(TemplateConfiguration, configuration); + this.setParameter(Show.KEY_TEMPLATE_CONFIGURATION, configuration); + return this; + } + /** + * @return {TemplateConfiguration} + */ + + + getTemplateConfiguration() { + return this.getObject(TemplateConfiguration, Show.KEY_TEMPLATE_CONFIGURATION); + } + + } + + Show.KEY_MAIN_FIELD_1 = 'mainField1'; + Show.KEY_MAIN_FIELD_2 = 'mainField2'; + Show.KEY_MAIN_FIELD_3 = 'mainField3'; + Show.KEY_MAIN_FIELD_4 = 'mainField4'; + Show.KEY_ALIGNMENT = 'alignment'; + Show.KEY_STATUS_BAR = 'statusBar'; + Show.KEY_MEDIA_CLOCK = 'mediaClock'; + Show.KEY_MEDIA_TRACK = 'mediaTrack'; + Show.KEY_GRAPHIC = 'graphic'; + Show.KEY_SECONDARY_GRAPHIC = 'secondaryGraphic'; + Show.KEY_SOFT_BUTTONS = 'softButtons'; + Show.KEY_CUSTOM_PRESETS = 'customPresets'; + Show.KEY_METADATA_TAGS = 'metadataTags'; + Show.KEY_TEMPLATE_TITLE = 'templateTitle'; + Show.KEY_WINDOW_ID = 'windowID'; + Show.KEY_TEMPLATE_CONFIGURATION = 'templateConfiguration'; + + /* eslint-disable camelcase */ + + class ShowResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.Show); + } + + } + + /* eslint-disable camelcase */ + /** + * Speaks a text. + */ + + class Speak extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.Speak); + } + /** + * @param {TTSChunk[]} chunks - An array of text chunks of type TTSChunk. See TTSChunk. The array must have at least + * one item. + * @return {Speak} + */ + + + setTtsChunks(chunks) { + this.validateType(TTSChunk, chunks, true); + this.setParameter(Speak.KEY_TTS_CHUNKS, chunks); + return this; + } + /** + * @return {TTSChunk[]} + */ + + + getTtsChunks() { + return this.getObject(TTSChunk, Speak.KEY_TTS_CHUNKS); + } + + } + + Speak.KEY_TTS_CHUNKS = 'ttsChunks'; + + /* eslint-disable camelcase */ + + class SpeakResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.Speak); + } + + } + + /* eslint-disable camelcase */ + + class StartTime extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Number} hours - The hour of the media clock. Some radios only support a max of 19 hours. If out of range, + * it will be rejected. + * @return {StartTime} + */ + + + setHours(hours) { + this.setParameter(StartTime.KEY_HOURS, hours); + return this; + } + /** + * @return {Number} + */ + + + getHours() { + return this.getParameter(StartTime.KEY_HOURS); + } + /** + * @param {Number} minutes + * @return {StartTime} + */ + + + setMinutes(minutes) { + this.setParameter(StartTime.KEY_MINUTES, minutes); + return this; + } + /** + * @return {Number} + */ + + + getMinutes() { + return this.getParameter(StartTime.KEY_MINUTES); + } + /** + * @param {Number} seconds + * @return {StartTime} + */ + + + setSeconds(seconds) { + this.setParameter(StartTime.KEY_SECONDS, seconds); + return this; + } + /** + * @return {Number} + */ + + + getSeconds() { + return this.getParameter(StartTime.KEY_SECONDS); + } + + } + + StartTime.KEY_HOURS = 'hours'; + StartTime.KEY_MINUTES = 'minutes'; + StartTime.KEY_SECONDS = 'seconds'; + + /* eslint-disable camelcase */ + /** + * Describes how the media clock timer should behave on the platform + * @typedef {Enum} UpdateMode + * @property {Object} _MAP + */ + + class UpdateMode extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * Starts the media clock timer counting upwards, as in time elapsed. + * @return {String} + */ + + + static get COUNTUP() { + return UpdateMode._MAP.COUNTUP; + } + /** + * Starts the media clock timer counting downwards, as in time remaining. + * @return {String} + */ + + + static get COUNTDOWN() { + return UpdateMode._MAP.COUNTDOWN; + } + /** + * Pauses the media clock timer + * @return {String} + */ + + + static get PAUSE() { + return UpdateMode._MAP.PAUSE; + } + /** + * Resume the media clock timer + * @return {String} + */ + + + static get RESUME() { + return UpdateMode._MAP.RESUME; + } + /** + * Clears the media clock timer (previously done through Show->mediaClock) + * @return {String} + */ + + + static get CLEAR() { + return UpdateMode._MAP.CLEAR; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return UpdateMode._valueForKey(key, UpdateMode._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return UpdateMode._keyForValue(value, UpdateMode._MAP); + } + + } + + UpdateMode._MAP = Object.freeze({ + 'COUNTUP': 'COUNTUP', + 'COUNTDOWN': 'COUNTDOWN', + 'PAUSE': 'PAUSE', + 'RESUME': 'RESUME', + 'CLEAR': 'CLEAR' + }); + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} AudioStreamingIndicator + * @property {Object} _MAP + */ + + class AudioStreamingIndicator extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * Default playback indicator. By default the playback indicator should be PLAY_PAUSE when: - the media app is + * newly registered on the head unit (after RegisterAppInterface) - the media app was closed by the user (App + * enters HMI_NONE) - the app sends SetMediaClockTimer with audioStreamingIndicator not set to any value + * @return {String} + */ + + + static get PLAY_PAUSE() { + return AudioStreamingIndicator._MAP.PLAY_PAUSE; + } + /** + * Indicates that a button press of the Play/Pause button starts the audio playback. + * @return {String} + */ + + + static get PLAY() { + return AudioStreamingIndicator._MAP.PLAY; + } + /** + * Indicates that a button press of the Play/Pause button pauses the current audio playback. + * @return {String} + */ + + + static get PAUSE() { + return AudioStreamingIndicator._MAP.PAUSE; + } + /** + * Indicates that a button press of the Play/Pause button stops the current audio playback. + * @return {String} + */ + + + static get STOP() { + return AudioStreamingIndicator._MAP.STOP; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return AudioStreamingIndicator._valueForKey(key, AudioStreamingIndicator._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return AudioStreamingIndicator._keyForValue(value, AudioStreamingIndicator._MAP); + } + + } + + AudioStreamingIndicator._MAP = Object.freeze({ + 'PLAY_PAUSE': 'PLAY_PAUSE', + 'PLAY': 'PLAY', + 'PAUSE': 'PAUSE', + 'STOP': 'STOP' + }); + + /* eslint-disable camelcase */ + /** + * Sets the initial media clock value and automatic update method. + */ + + class SetMediaClockTimer extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SetMediaClockTimer); + } + /** + * @param {StartTime} time - See StartTime. startTime must be provided for "COUNTUP" and "COUNTDOWN". startTime will + * be ignored for "RESUME", and "CLEAR" startTime can be sent for "PAUSE", in which case + * it will update the paused startTime + * @return {SetMediaClockTimer} + */ + + + setStartTime(time) { + this.validateType(StartTime, time); + this.setParameter(SetMediaClockTimer.KEY_START_TIME, time); + return this; + } + /** + * @return {StartTime} + */ + + + getStartTime() { + return this.getObject(StartTime, SetMediaClockTimer.KEY_START_TIME); + } + /** + * @param {StartTime} time - See StartTime. endTime can be provided for "COUNTUP" and "COUNTDOWN"; to be used to + * calculate any visual progress bar (if not provided, this feature is ignored) If endTime + * is greater then startTime for COUNTDOWN or less than startTime for COUNTUP, then the + * request will return an INVALID_DATA. endTime will be ignored for "RESUME", and "CLEAR" + * endTime can be sent for "PAUSE", in which case it will update the paused endTime + * @return {SetMediaClockTimer} + */ + + + setEndTime(time) { + this.validateType(StartTime, time); + this.setParameter(SetMediaClockTimer.KEY_END_TIME, time); + return this; + } + /** + * @return {StartTime} + */ + + + getEndTime() { + return this.getObject(StartTime, SetMediaClockTimer.KEY_END_TIME); + } + /** + * @param {UpdateMode} mode - Enumeration to control the media clock. In case of pause, resume, or clear, the start + * time value is ignored and shall be left out. For resume, the time continues with the + * same value as it was when paused. + * @return {SetMediaClockTimer} + */ + + + setUpdateMode(mode) { + this.validateType(UpdateMode, mode); + this.setParameter(SetMediaClockTimer.KEY_UPDATE_MODE, mode); + return this; + } + /** + * @return {UpdateMode} + */ + + + getUpdateMode() { + return this.getObject(UpdateMode, SetMediaClockTimer.KEY_UPDATE_MODE); + } + /** + * @param {AudioStreamingIndicator} indicator - Enumeration for the indicator icon on a play/pause button. see + * AudioStreamingIndicator. + * @return {SetMediaClockTimer} + */ + + + setAudioStreamingIndicator(indicator) { + this.validateType(AudioStreamingIndicator, indicator); + this.setParameter(SetMediaClockTimer.KEY_AUDIO_STREAMING_INDICATOR, indicator); + return this; + } + /** + * @return {AudioStreamingIndicator} + */ + + + getAudioStreamingIndicator() { + return this.getObject(AudioStreamingIndicator, SetMediaClockTimer.KEY_AUDIO_STREAMING_INDICATOR); + } + + } + + SetMediaClockTimer.KEY_START_TIME = 'startTime'; + SetMediaClockTimer.KEY_END_TIME = 'endTime'; + SetMediaClockTimer.KEY_UPDATE_MODE = 'updateMode'; + SetMediaClockTimer.KEY_AUDIO_STREAMING_INDICATOR = 'audioStreamingIndicator'; + + /* eslint-disable camelcase */ + + class SetMediaClockTimerResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SetMediaClockTimer); + } + + } + + /* eslint-disable camelcase */ + /** + * Starts audio pass thru session + */ + + class PerformAudioPassThru extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.PerformAudioPassThru); + } + /** + * @param {TTSChunk[]} prompt - The module will speak this prompt before opening the audio pass thru session. An + * array of text chunks of type TTSChunk. See TTSChunk. The array must have at least + * one item. If omitted, then no initial prompt is spoken. + * @return {PerformAudioPassThru} + */ + + + setInitialPrompt(prompt) { + this.validateType(TTSChunk, prompt, true); + this.setParameter(PerformAudioPassThru.KEY_INITIAL_PROMPT, prompt); + return this; + } + /** + * @return {TTSChunk[]} + */ + + + getInitialPrompt() { + return this.getObject(TTSChunk, PerformAudioPassThru.KEY_INITIAL_PROMPT); + } + /** + * @param {String} text1 - First line of text displayed during audio capture. + * @return {PerformAudioPassThru} + */ + + + setAudioPassThruDisplayText1(text1) { + this.setParameter(PerformAudioPassThru.KEY_AUDIO_PASS_THRU_DISPLAY_TEXT_1, text1); + return this; + } + /** + * @return {String} + */ + + + getAudioPassThruDisplayText1() { + return this.getParameter(PerformAudioPassThru.KEY_AUDIO_PASS_THRU_DISPLAY_TEXT_1); + } + /** + * @param {String} text2 - Second line of text displayed during audio capture. + * @return {PerformAudioPassThru} + */ + + + setAudioPassThruDisplayText2(text2) { + this.setParameter(PerformAudioPassThru.KEY_AUDIO_PASS_THRU_DISPLAY_TEXT_2, text2); + return this; + } + /** + * @return {String} + */ + + + getAudioPassThruDisplayText2() { + return this.getParameter(PerformAudioPassThru.KEY_AUDIO_PASS_THRU_DISPLAY_TEXT_2); + } + /** + * @param {SamplingRate} rate - This value shall be allowed at 8 kHz or 16 or 22 or 44 kHz. + * @return {PerformAudioPassThru} + */ + + + setSamplingRate(rate) { + this.validateType(SamplingRate, rate); + this.setParameter(PerformAudioPassThru.KEY_SAMPLING_RATE, rate); + return this; + } + /** + * @return {SamplingRate} + */ + + + getSamplingRate() { + return this.getObject(SamplingRate, PerformAudioPassThru.KEY_SAMPLING_RATE); + } + /** + * @param {Number} duration - The maximum duration of audio recording in milliseconds. + * @return {PerformAudioPassThru} + */ + + + setMaxDuration(duration) { + this.setParameter(PerformAudioPassThru.KEY_MAX_DURATION, duration); + return this; + } + /** + * @return {Number} + */ + + + getMaxDuration() { + return this.getParameter(PerformAudioPassThru.KEY_MAX_DURATION); + } + /** + * @param {BitsPerSample} sample - Specifies the quality the audio is recorded. Currently 8 bit or 16 bit. + * @return {PerformAudioPassThru} + */ + + + setBitsPerSample(sample) { + this.validateType(BitsPerSample, sample); + this.setParameter(PerformAudioPassThru.KEY_BITS_PER_SAMPLE, sample); + return this; + } + /** + * @return {BitsPerSample} + */ + + + getBitsPerSample() { + return this.getObject(BitsPerSample, PerformAudioPassThru.KEY_BITS_PER_SAMPLE); + } + /** + * @param {AudioType} type - Specifies the type of audio data being requested. + * @return {PerformAudioPassThru} + */ + + + setAudioType(type) { + this.validateType(AudioType, type); + this.setParameter(PerformAudioPassThru.KEY_AUDIO_TYPE, type); + return this; + } + /** + * @return {AudioType} + */ + + + getAudioType() { + return this.getObject(AudioType, PerformAudioPassThru.KEY_AUDIO_TYPE); + } + /** + * @param {Boolean} audio - Defines if the current audio source should be muted during the APT session. If not, the + * audio source will play without interruption. If omitted, the value is set to true. + * @return {PerformAudioPassThru} + */ + + + setMuteAudio(audio) { + this.setParameter(PerformAudioPassThru.KEY_MUTE_AUDIO, audio); + return this; + } + /** + * @return {Boolean} + */ + + + getMuteAudio() { + return this.getParameter(PerformAudioPassThru.KEY_MUTE_AUDIO); + } + + } + + PerformAudioPassThru.KEY_INITIAL_PROMPT = 'initialPrompt'; + PerformAudioPassThru.KEY_AUDIO_PASS_THRU_DISPLAY_TEXT_1 = 'audioPassThruDisplayText1'; + PerformAudioPassThru.KEY_AUDIO_PASS_THRU_DISPLAY_TEXT_2 = 'audioPassThruDisplayText2'; + PerformAudioPassThru.KEY_SAMPLING_RATE = 'samplingRate'; + PerformAudioPassThru.KEY_MAX_DURATION = 'maxDuration'; + PerformAudioPassThru.KEY_BITS_PER_SAMPLE = 'bitsPerSample'; + PerformAudioPassThru.KEY_AUDIO_TYPE = 'audioType'; + PerformAudioPassThru.KEY_MUTE_AUDIO = 'muteAudio'; + + /* eslint-disable camelcase */ + + class PerformAudioPassThruResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.PerformAudioPassThru); + } + + } + + /* eslint-disable camelcase */ + /** + * When this request is invoked, the audio capture stops. + */ + + class EndAudioPassThru extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.EndAudioPassThru); + } + + } + + /* eslint-disable camelcase */ + + class EndAudioPassThruResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.EndAudioPassThru); + } + + } + + /* eslint-disable camelcase */ + /** + * Subscribes to built-in HMI buttons. The application will be notified by the OnButtonEvent and OnButtonPress. To + * unsubscribe the notifications, use unsubscribeButton. + */ + + class SubscribeButton extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SubscribeButton); + } + /** + * @param {ButtonName} name - Name of the button to subscribe. + * @return {SubscribeButton} + */ + + + setButtonName(name) { + this.validateType(ButtonName, name); + this.setParameter(SubscribeButton.KEY_BUTTON_NAME, name); + return this; + } + /** + * @return {ButtonName} + */ + + + getButtonName() { + return this.getObject(ButtonName, SubscribeButton.KEY_BUTTON_NAME); + } + + } + + SubscribeButton.KEY_BUTTON_NAME = 'buttonName'; + + /* eslint-disable camelcase */ + + class SubscribeButtonResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SubscribeButton); + } + + } + + /* eslint-disable camelcase */ + /** + * Unsubscribes from built-in HMI buttons. + */ + + class UnsubscribeButton extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.UnsubscribeButton); + } + /** + * @param {ButtonName} name - Name of the button to unsubscribe. + * @return {UnsubscribeButton} + */ + + + setButtonName(name) { + this.validateType(ButtonName, name); + this.setParameter(UnsubscribeButton.KEY_BUTTON_NAME, name); + return this; + } + /** + * @return {ButtonName} + */ + + + getButtonName() { + return this.getObject(ButtonName, UnsubscribeButton.KEY_BUTTON_NAME); + } + + } + + UnsubscribeButton.KEY_BUTTON_NAME = 'buttonName'; + + /* eslint-disable camelcase */ + + class UnsubscribeButtonResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.UnsubscribeButton); + } + + } + + /* eslint-disable camelcase */ + /** + * Subscribes for specific published data items. The data will be only sent if it has changed. The application will be + * notified by the onVehicleData notification whenever new data is available. To unsubscribe the notifications, use + * unsubscribe with the same subscriptionType. + */ + + class SubscribeVehicleData extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SubscribeVehicleData); + } + /** + * @param {Boolean} gps - See GPSData + * @return {SubscribeVehicleData} + */ + + + setGps(gps) { + this.setParameter(SubscribeVehicleData.KEY_GPS, gps); + return this; + } + /** + * @return {Boolean} + */ + + + getGps() { + return this.getParameter(SubscribeVehicleData.KEY_GPS); + } + /** + * @param {Boolean} speed - The vehicle speed in kilometers per hour + * @return {SubscribeVehicleData} + */ + + + setSpeed(speed) { + this.setParameter(SubscribeVehicleData.KEY_SPEED, speed); + return this; + } + /** + * @return {Boolean} + */ + + + getSpeed() { + return this.getParameter(SubscribeVehicleData.KEY_SPEED); + } + /** + * @param {Boolean} rpm - The number of revolutions per minute of the engine + * @return {SubscribeVehicleData} + */ + + + setRpm(rpm) { + this.setParameter(SubscribeVehicleData.KEY_RPM, rpm); + return this; + } + /** + * @return {Boolean} + */ + + + getRpm() { + return this.getParameter(SubscribeVehicleData.KEY_RPM); + } + /** + * @param {Boolean} level - The fuel level in the tank (percentage) + * @return {SubscribeVehicleData} + */ + + + setFuelLevel(level) { + this.setParameter(SubscribeVehicleData.KEY_FUEL_LEVEL, level); + return this; + } + /** + * @return {Boolean} + */ + + + getFuelLevel() { + return this.getParameter(SubscribeVehicleData.KEY_FUEL_LEVEL); + } + /** + * @param {Boolean} level_state - The fuel level state + * @return {SubscribeVehicleData} + */ + + + setFuelLevel_State(level_state) { + this.setParameter(SubscribeVehicleData.KEY_FUEL_LEVEL_STATE, level_state); + return this; + } + /** + * @return {Boolean} + */ + + + getFuelLevel_State() { + return this.getParameter(SubscribeVehicleData.KEY_FUEL_LEVEL_STATE); + } + /** + * @param {Boolean} consumption - The instantaneous fuel consumption in microlitres + * @return {SubscribeVehicleData} + */ + + + setInstantFuelConsumption(consumption) { + this.setParameter(SubscribeVehicleData.KEY_INSTANT_FUEL_CONSUMPTION, consumption); + return this; + } + /** + * @return {Boolean} + */ + + + getInstantFuelConsumption() { + return this.getParameter(SubscribeVehicleData.KEY_INSTANT_FUEL_CONSUMPTION); + } + /** + * @param {Boolean} range - The estimate range in KM the vehicle can travel based on fuel level and consumption + * @return {SubscribeVehicleData} + */ + + + setFuelRange(range) { + this.setParameter(SubscribeVehicleData.KEY_FUEL_RANGE, range); + return this; + } + /** + * @return {Boolean} + */ + + + getFuelRange() { + return this.getParameter(SubscribeVehicleData.KEY_FUEL_RANGE); + } + /** + * @param {Boolean} temperature - The external temperature in degrees celsius + * @return {SubscribeVehicleData} + */ + + + setExternalTemperature(temperature) { + this.setParameter(SubscribeVehicleData.KEY_EXTERNAL_TEMPERATURE, temperature); + return this; + } + /** + * @return {Boolean} + */ + + + getExternalTemperature() { + return this.getParameter(SubscribeVehicleData.KEY_EXTERNAL_TEMPERATURE); + } + /** + * @param {Boolean} signal - See TurnSignal + * @return {SubscribeVehicleData} + */ + + + setTurnSignal(signal) { + this.setParameter(SubscribeVehicleData.KEY_TURN_SIGNAL, signal); + return this; + } + /** + * @return {Boolean} + */ + + + getTurnSignal() { + return this.getParameter(SubscribeVehicleData.KEY_TURN_SIGNAL); + } + /** + * @param {Boolean} prndl - See PRNDL + * @return {SubscribeVehicleData} + */ + + + setPrndl(prndl) { + this.setParameter(SubscribeVehicleData.KEY_PRNDL, prndl); + return this; + } + /** + * @return {Boolean} + */ + + + getPrndl() { + return this.getParameter(SubscribeVehicleData.KEY_PRNDL); + } + /** + * @param {Boolean} pressure - See TireStatus + * @return {SubscribeVehicleData} + */ + + + setTirePressure(pressure) { + this.setParameter(SubscribeVehicleData.KEY_TIRE_PRESSURE, pressure); + return this; + } + /** + * @return {Boolean} + */ + + + getTirePressure() { + return this.getParameter(SubscribeVehicleData.KEY_TIRE_PRESSURE); + } + /** + * @param {Boolean} odometer - Odometer in km + * @return {SubscribeVehicleData} + */ + + + setOdometer(odometer) { + this.setParameter(SubscribeVehicleData.KEY_ODOMETER, odometer); + return this; + } + /** + * @return {Boolean} + */ + + + getOdometer() { + return this.getParameter(SubscribeVehicleData.KEY_ODOMETER); + } + /** + * @param {Boolean} status - The status of the seat belts + * @return {SubscribeVehicleData} + */ + + + setBeltStatus(status) { + this.setParameter(SubscribeVehicleData.KEY_BELT_STATUS, status); + return this; + } + /** + * @return {Boolean} + */ + + + getBeltStatus() { + return this.getParameter(SubscribeVehicleData.KEY_BELT_STATUS); + } + /** + * @param {Boolean} information - The body information including power modes + * @return {SubscribeVehicleData} + */ + + + setBodyInformation(information) { + this.setParameter(SubscribeVehicleData.KEY_BODY_INFORMATION, information); + return this; + } + /** + * @return {Boolean} + */ + + + getBodyInformation() { + return this.getParameter(SubscribeVehicleData.KEY_BODY_INFORMATION); + } + /** + * @param {Boolean} status - The device status including signal and battery strength + * @return {SubscribeVehicleData} + */ + + + setDeviceStatus(status) { + this.setParameter(SubscribeVehicleData.KEY_DEVICE_STATUS, status); + return this; + } + /** + * @return {Boolean} + */ + + + getDeviceStatus() { + return this.getParameter(SubscribeVehicleData.KEY_DEVICE_STATUS); + } + /** + * @param {Boolean} braking - The status of the brake pedal + * @return {SubscribeVehicleData} + */ + + + setDriverBraking(braking) { + this.setParameter(SubscribeVehicleData.KEY_DRIVER_BRAKING, braking); + return this; + } + /** + * @return {Boolean} + */ + + + getDriverBraking() { + return this.getParameter(SubscribeVehicleData.KEY_DRIVER_BRAKING); + } + /** + * @param {Boolean} status - The status of the wipers + * @return {SubscribeVehicleData} + */ + + + setWiperStatus(status) { + this.setParameter(SubscribeVehicleData.KEY_WIPER_STATUS, status); + return this; + } + /** + * @return {Boolean} + */ + + + getWiperStatus() { + return this.getParameter(SubscribeVehicleData.KEY_WIPER_STATUS); + } + /** + * @param {Boolean} status - Status of the head lamps + * @return {SubscribeVehicleData} + */ + + + setHeadLampStatus(status) { + this.setParameter(SubscribeVehicleData.KEY_HEAD_LAMP_STATUS, status); + return this; + } + /** + * @return {Boolean} + */ + + + getHeadLampStatus() { + return this.getParameter(SubscribeVehicleData.KEY_HEAD_LAMP_STATUS); + } + /** + * @param {Boolean} torque - Torque value for engine (in Nm) on non-diesel variants + * @return {SubscribeVehicleData} + */ + + + setEngineTorque(torque) { + this.setParameter(SubscribeVehicleData.KEY_ENGINE_TORQUE, torque); + return this; + } + /** + * @return {Boolean} + */ + + + getEngineTorque() { + return this.getParameter(SubscribeVehicleData.KEY_ENGINE_TORQUE); + } + /** + * @param {Boolean} position - Accelerator pedal position (percentage depressed) + * @return {SubscribeVehicleData} + */ + + + setAccPedalPosition(position) { + this.setParameter(SubscribeVehicleData.KEY_ACC_PEDAL_POSITION, position); + return this; + } + /** + * @return {Boolean} + */ + + + getAccPedalPosition() { + return this.getParameter(SubscribeVehicleData.KEY_ACC_PEDAL_POSITION); + } + /** + * @param {Boolean} angle - Current angle of the steering wheel (in deg) + * @return {SubscribeVehicleData} + */ + + + setSteeringWheelAngle(angle) { + this.setParameter(SubscribeVehicleData.KEY_STEERING_WHEEL_ANGLE, angle); + return this; + } + /** + * @return {Boolean} + */ + + + getSteeringWheelAngle() { + return this.getParameter(SubscribeVehicleData.KEY_STEERING_WHEEL_ANGLE); + } + /** + * @param {Boolean} life - The estimated percentage of remaining oil life of the engine. + * @return {SubscribeVehicleData} + */ + + + setEngineOilLife(life) { + this.setParameter(SubscribeVehicleData.KEY_ENGINE_OIL_LIFE, life); + return this; + } + /** + * @return {Boolean} + */ + + + getEngineOilLife() { + return this.getParameter(SubscribeVehicleData.KEY_ENGINE_OIL_LIFE); + } + /** + * @param {Boolean} status - The status of the park brake as provided by Electric Park Brake (EPB) system. + * @return {SubscribeVehicleData} + */ + + + setElectronicParkBrakeStatus(status) { + this.setParameter(SubscribeVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS, status); + return this; + } + /** + * @return {Boolean} + */ + + + getElectronicParkBrakeStatus() { + return this.getParameter(SubscribeVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS); + } + /** + * @param {Boolean} id - Parameter used by cloud apps to identify a head unit + * @return {SubscribeVehicleData} + */ + + + setCloudAppVehicleID(id) { + this.setParameter(SubscribeVehicleData.KEY_CLOUD_APP_VEHICLE_ID, id); + return this; + } + /** + * @return {Boolean} + */ + + + getCloudAppVehicleID() { + return this.getParameter(SubscribeVehicleData.KEY_CLOUD_APP_VEHICLE_ID); + } + /** + * @param {Boolean} info - Emergency Call notification and confirmation data + * @return {SubscribeVehicleData} + */ + + + setECallInfo(info) { + this.setParameter(SubscribeVehicleData.KEY_E_CALL_INFO, info); + return this; + } + /** + * @return {Boolean} + */ + + + getECallInfo() { + return this.getParameter(SubscribeVehicleData.KEY_E_CALL_INFO); + } + /** + * @param {Boolean} status - The status of the air bags + * @return {SubscribeVehicleData} + */ + + + setAirbagStatus(status) { + this.setParameter(SubscribeVehicleData.KEY_AIRBAG_STATUS, status); + return this; + } + /** + * @return {Boolean} + */ + + + getAirbagStatus() { + return this.getParameter(SubscribeVehicleData.KEY_AIRBAG_STATUS); + } + /** + * @param {Boolean} event - Information related to an emergency event (and if it occurred) + * @return {SubscribeVehicleData} + */ + + + setEmergencyEvent(event) { + this.setParameter(SubscribeVehicleData.KEY_EMERGENCY_EVENT, event); + return this; + } + /** + * @return {Boolean} + */ + + + getEmergencyEvent() { + return this.getParameter(SubscribeVehicleData.KEY_EMERGENCY_EVENT); + } + /** + * @param {Boolean} status - The status modes of the cluster + * @return {SubscribeVehicleData} + */ + + + setClusterModeStatus(status) { + this.setParameter(SubscribeVehicleData.KEY_CLUSTER_MODE_STATUS, status); + return this; + } + /** + * @return {Boolean} + */ + + + getClusterModeStatus() { + return this.getParameter(SubscribeVehicleData.KEY_CLUSTER_MODE_STATUS); + } + /** + * @param {Boolean} key - Information related to the MyKey feature + * @return {SubscribeVehicleData} + */ + + + setMyKey(key) { + this.setParameter(SubscribeVehicleData.KEY_MY_KEY, key); + return this; + } + /** + * @return {Boolean} + */ + + + getMyKey() { + return this.getParameter(SubscribeVehicleData.KEY_MY_KEY); + } + + } + + SubscribeVehicleData.KEY_GPS = 'gps'; + SubscribeVehicleData.KEY_SPEED = 'speed'; + SubscribeVehicleData.KEY_RPM = 'rpm'; + SubscribeVehicleData.KEY_FUEL_LEVEL = 'fuelLevel'; + SubscribeVehicleData.KEY_FUEL_LEVEL_STATE = 'fuelLevel_State'; + SubscribeVehicleData.KEY_INSTANT_FUEL_CONSUMPTION = 'instantFuelConsumption'; + SubscribeVehicleData.KEY_FUEL_RANGE = 'fuelRange'; + SubscribeVehicleData.KEY_EXTERNAL_TEMPERATURE = 'externalTemperature'; + SubscribeVehicleData.KEY_TURN_SIGNAL = 'turnSignal'; + SubscribeVehicleData.KEY_PRNDL = 'prndl'; + SubscribeVehicleData.KEY_TIRE_PRESSURE = 'tirePressure'; + SubscribeVehicleData.KEY_ODOMETER = 'odometer'; + SubscribeVehicleData.KEY_BELT_STATUS = 'beltStatus'; + SubscribeVehicleData.KEY_BODY_INFORMATION = 'bodyInformation'; + SubscribeVehicleData.KEY_DEVICE_STATUS = 'deviceStatus'; + SubscribeVehicleData.KEY_DRIVER_BRAKING = 'driverBraking'; + SubscribeVehicleData.KEY_WIPER_STATUS = 'wiperStatus'; + SubscribeVehicleData.KEY_HEAD_LAMP_STATUS = 'headLampStatus'; + SubscribeVehicleData.KEY_ENGINE_TORQUE = 'engineTorque'; + SubscribeVehicleData.KEY_ACC_PEDAL_POSITION = 'accPedalPosition'; + SubscribeVehicleData.KEY_STEERING_WHEEL_ANGLE = 'steeringWheelAngle'; + SubscribeVehicleData.KEY_ENGINE_OIL_LIFE = 'engineOilLife'; + SubscribeVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS = 'electronicParkBrakeStatus'; + SubscribeVehicleData.KEY_CLOUD_APP_VEHICLE_ID = 'cloudAppVehicleID'; + SubscribeVehicleData.KEY_E_CALL_INFO = 'eCallInfo'; + SubscribeVehicleData.KEY_AIRBAG_STATUS = 'airbagStatus'; + SubscribeVehicleData.KEY_EMERGENCY_EVENT = 'emergencyEvent'; + SubscribeVehicleData.KEY_CLUSTER_MODE_STATUS = 'clusterModeStatus'; + SubscribeVehicleData.KEY_MY_KEY = 'myKey'; + + /* eslint-disable camelcase */ + /** + * Enumeration that describes possible result codes of a vehicle data entry request. + * @typedef {Enum} VehicleDataResultCode + * @property {Object} _MAP + */ + + class VehicleDataResultCode extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * Individual vehicle data item / DTC / DID request or subscription successful + * @return {String} + */ + + + static get VDRC_SUCCESS() { + return VehicleDataResultCode._MAP.VDRC_SUCCESS; + } + /** + * DTC / DID request successful, however, not all active DTCs or full contents of DID location available + * @return {String} + */ + + + static get VDRC_TRUNCATED_DATA() { + return VehicleDataResultCode._MAP.VDRC_TRUNCATED_DATA; + } + /** + * This vehicle data item is not allowed for this app by the OEM/Manufactorer of the connected module. + * @return {String} + */ + + + static get VDRC_DISALLOWED() { + return VehicleDataResultCode._MAP.VDRC_DISALLOWED; + } + /** + * The user has not granted access to this type of vehicle data item at this time. + * @return {String} + */ + + + static get VDRC_USER_DISALLOWED() { + return VehicleDataResultCode._MAP.VDRC_USER_DISALLOWED; + } + /** + * The ECU ID referenced is not a valid ID on the bus / system. + * @return {String} + */ + + + static get VDRC_INVALID_ID() { + return VehicleDataResultCode._MAP.VDRC_INVALID_ID; + } + /** + * The requested vehicle data item / DTC / DID is not currently available or responding on the bus / system. + * @return {String} + */ + + + static get VDRC_DATA_NOT_AVAILABLE() { + return VehicleDataResultCode._MAP.VDRC_DATA_NOT_AVAILABLE; + } + /** + * The vehicle data item is already subscribed. + * @return {String} + */ + + + static get VDRC_DATA_ALREADY_SUBSCRIBED() { + return VehicleDataResultCode._MAP.VDRC_DATA_ALREADY_SUBSCRIBED; + } + /** + * The vehicle data item cannot be unsubscribed because it is not currently subscribed. + * @return {String} + */ + + + static get VDRC_DATA_NOT_SUBSCRIBED() { + return VehicleDataResultCode._MAP.VDRC_DATA_NOT_SUBSCRIBED; + } + /** + * The request for this item is ignored because it is already in progress. + * @return {String} + */ + + + static get VDRC_IGNORED() { + return VehicleDataResultCode._MAP.VDRC_IGNORED; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return VehicleDataResultCode._valueForKey(key, VehicleDataResultCode._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return VehicleDataResultCode._keyForValue(value, VehicleDataResultCode._MAP); + } + + } + + VehicleDataResultCode._MAP = Object.freeze({ + 'VDRC_SUCCESS': 'SUCCESS', + 'VDRC_TRUNCATED_DATA': 'TRUNCATED_DATA', + 'VDRC_DISALLOWED': 'DISALLOWED', + 'VDRC_USER_DISALLOWED': 'USER_DISALLOWED', + 'VDRC_INVALID_ID': 'INVALID_ID', + 'VDRC_DATA_NOT_AVAILABLE': 'VEHICLE_DATA_NOT_AVAILABLE', + 'VDRC_DATA_ALREADY_SUBSCRIBED': 'DATA_ALREADY_SUBSCRIBED', + 'VDRC_DATA_NOT_SUBSCRIBED': 'DATA_NOT_SUBSCRIBED', + 'VDRC_IGNORED': 'IGNORED' + }); + + /* eslint-disable camelcase */ + /** + * Defines the data types that can be published and subscribed to. + * @typedef {Enum} VehicleDataType + * @property {Object} _MAP + */ + + class VehicleDataType extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * Notifies GPSData may be subscribed + * @return {String} + */ + + + static get VEHICLEDATA_GPS() { + return VehicleDataType._MAP.VEHICLEDATA_GPS; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_SPEED() { + return VehicleDataType._MAP.VEHICLEDATA_SPEED; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_RPM() { + return VehicleDataType._MAP.VEHICLEDATA_RPM; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_FUELLEVEL() { + return VehicleDataType._MAP.VEHICLEDATA_FUELLEVEL; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_FUELLEVEL_STATE() { + return VehicleDataType._MAP.VEHICLEDATA_FUELLEVEL_STATE; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_FUELCONSUMPTION() { + return VehicleDataType._MAP.VEHICLEDATA_FUELCONSUMPTION; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_EXTERNTEMP() { + return VehicleDataType._MAP.VEHICLEDATA_EXTERNTEMP; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_VIN() { + return VehicleDataType._MAP.VEHICLEDATA_VIN; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_PRNDL() { + return VehicleDataType._MAP.VEHICLEDATA_PRNDL; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_TIREPRESSURE() { + return VehicleDataType._MAP.VEHICLEDATA_TIREPRESSURE; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_ODOMETER() { + return VehicleDataType._MAP.VEHICLEDATA_ODOMETER; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_BELTSTATUS() { + return VehicleDataType._MAP.VEHICLEDATA_BELTSTATUS; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_BODYINFO() { + return VehicleDataType._MAP.VEHICLEDATA_BODYINFO; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_DEVICESTATUS() { + return VehicleDataType._MAP.VEHICLEDATA_DEVICESTATUS; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_ECALLINFO() { + return VehicleDataType._MAP.VEHICLEDATA_ECALLINFO; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_AIRBAGSTATUS() { + return VehicleDataType._MAP.VEHICLEDATA_AIRBAGSTATUS; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_EMERGENCYEVENT() { + return VehicleDataType._MAP.VEHICLEDATA_EMERGENCYEVENT; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_CLUSTERMODESTATUS() { + return VehicleDataType._MAP.VEHICLEDATA_CLUSTERMODESTATUS; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_MYKEY() { + return VehicleDataType._MAP.VEHICLEDATA_MYKEY; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_BRAKING() { + return VehicleDataType._MAP.VEHICLEDATA_BRAKING; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_WIPERSTATUS() { + return VehicleDataType._MAP.VEHICLEDATA_WIPERSTATUS; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_HEADLAMPSTATUS() { + return VehicleDataType._MAP.VEHICLEDATA_HEADLAMPSTATUS; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_BATTVOLTAGE() { + return VehicleDataType._MAP.VEHICLEDATA_BATTVOLTAGE; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_ENGINETORQUE() { + return VehicleDataType._MAP.VEHICLEDATA_ENGINETORQUE; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_ACCPEDAL() { + return VehicleDataType._MAP.VEHICLEDATA_ACCPEDAL; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_STEERINGWHEEL() { + return VehicleDataType._MAP.VEHICLEDATA_STEERINGWHEEL; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_TURNSIGNAL() { + return VehicleDataType._MAP.VEHICLEDATA_TURNSIGNAL; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_FUELRANGE() { + return VehicleDataType._MAP.VEHICLEDATA_FUELRANGE; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_ENGINEOILLIFE() { + return VehicleDataType._MAP.VEHICLEDATA_ENGINEOILLIFE; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_ELECTRONICPARKBRAKESTATUS() { + return VehicleDataType._MAP.VEHICLEDATA_ELECTRONICPARKBRAKESTATUS; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_CLOUDAPPVEHICLEID() { + return VehicleDataType._MAP.VEHICLEDATA_CLOUDAPPVEHICLEID; + } + /** + * @return {String} + */ + + + static get VEHICLEDATA_OEM_CUSTOM_DATA() { + return VehicleDataType._MAP.VEHICLEDATA_OEM_CUSTOM_DATA; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return VehicleDataType._valueForKey(key, VehicleDataType._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return VehicleDataType._keyForValue(value, VehicleDataType._MAP); + } + + } + + VehicleDataType._MAP = Object.freeze({ + 'VEHICLEDATA_GPS': 'VEHICLEDATA_GPS', + 'VEHICLEDATA_SPEED': 'VEHICLEDATA_SPEED', + 'VEHICLEDATA_RPM': 'VEHICLEDATA_RPM', + 'VEHICLEDATA_FUELLEVEL': 'VEHICLEDATA_FUELLEVEL', + 'VEHICLEDATA_FUELLEVEL_STATE': 'VEHICLEDATA_FUELLEVEL_STATE', + 'VEHICLEDATA_FUELCONSUMPTION': 'VEHICLEDATA_FUELCONSUMPTION', + 'VEHICLEDATA_EXTERNTEMP': 'VEHICLEDATA_EXTERNTEMP', + 'VEHICLEDATA_VIN': 'VEHICLEDATA_VIN', + 'VEHICLEDATA_PRNDL': 'VEHICLEDATA_PRNDL', + 'VEHICLEDATA_TIREPRESSURE': 'VEHICLEDATA_TIREPRESSURE', + 'VEHICLEDATA_ODOMETER': 'VEHICLEDATA_ODOMETER', + 'VEHICLEDATA_BELTSTATUS': 'VEHICLEDATA_BELTSTATUS', + 'VEHICLEDATA_BODYINFO': 'VEHICLEDATA_BODYINFO', + 'VEHICLEDATA_DEVICESTATUS': 'VEHICLEDATA_DEVICESTATUS', + 'VEHICLEDATA_ECALLINFO': 'VEHICLEDATA_ECALLINFO', + 'VEHICLEDATA_AIRBAGSTATUS': 'VEHICLEDATA_AIRBAGSTATUS', + 'VEHICLEDATA_EMERGENCYEVENT': 'VEHICLEDATA_EMERGENCYEVENT', + 'VEHICLEDATA_CLUSTERMODESTATUS': 'VEHICLEDATA_CLUSTERMODESTATUS', + 'VEHICLEDATA_MYKEY': 'VEHICLEDATA_MYKEY', + 'VEHICLEDATA_BRAKING': 'VEHICLEDATA_BRAKING', + 'VEHICLEDATA_WIPERSTATUS': 'VEHICLEDATA_WIPERSTATUS', + 'VEHICLEDATA_HEADLAMPSTATUS': 'VEHICLEDATA_HEADLAMPSTATUS', + 'VEHICLEDATA_BATTVOLTAGE': 'VEHICLEDATA_BATTVOLTAGE', + 'VEHICLEDATA_ENGINETORQUE': 'VEHICLEDATA_ENGINETORQUE', + 'VEHICLEDATA_ACCPEDAL': 'VEHICLEDATA_ACCPEDAL', + 'VEHICLEDATA_STEERINGWHEEL': 'VEHICLEDATA_STEERINGWHEEL', + 'VEHICLEDATA_TURNSIGNAL': 'VEHICLEDATA_TURNSIGNAL', + 'VEHICLEDATA_FUELRANGE': 'VEHICLEDATA_FUELRANGE', + 'VEHICLEDATA_ENGINEOILLIFE': 'VEHICLEDATA_ENGINEOILLIFE', + 'VEHICLEDATA_ELECTRONICPARKBRAKESTATUS': 'VEHICLEDATA_ELECTRONICPARKBRAKESTATUS', + 'VEHICLEDATA_CLOUDAPPVEHICLEID': 'VEHICLEDATA_CLOUDAPPVEHICLEID', + 'VEHICLEDATA_OEM_CUSTOM_DATA': 'VEHICLEDATA_OEM_CUSTOM_DATA' + }); + + /* eslint-disable camelcase */ + /** + * Individual published data request result + */ + + class VehicleDataResult extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {VehicleDataType} type - Defined published data element type. + * @return {VehicleDataResult} + */ + + + setDataType(type) { + this.validateType(VehicleDataType, type); + this.setParameter(VehicleDataResult.KEY_DATA_TYPE, type); + return this; + } + /** + * @return {VehicleDataType} + */ + + + getDataType() { + return this.getObject(VehicleDataType, VehicleDataResult.KEY_DATA_TYPE); + } + /** + * @param {VehicleDataResultCode} code - Published data result code. + * @return {VehicleDataResult} + */ + + + setResultCode(code) { + this.validateType(VehicleDataResultCode, code); + this.setParameter(VehicleDataResult.KEY_RESULT_CODE, code); + return this; + } + /** + * @return {VehicleDataResultCode} + */ + + + getResultCode() { + return this.getObject(VehicleDataResultCode, VehicleDataResult.KEY_RESULT_CODE); + } + /** + * @param {String} type - Type of requested oem specific parameter + * @return {VehicleDataResult} + */ + + + setOemCustomDataType(type) { + this.setParameter(VehicleDataResult.KEY_OEM_CUSTOM_DATA_TYPE, type); + return this; + } + /** + * @return {String} + */ + + + getOemCustomDataType() { + return this.getParameter(VehicleDataResult.KEY_OEM_CUSTOM_DATA_TYPE); + } + + } + + VehicleDataResult.KEY_DATA_TYPE = 'dataType'; + VehicleDataResult.KEY_RESULT_CODE = 'resultCode'; + VehicleDataResult.KEY_OEM_CUSTOM_DATA_TYPE = 'oemCustomDataType'; + + /* eslint-disable camelcase */ + + class SubscribeVehicleDataResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SubscribeVehicleData); + } + /** + * @param {VehicleDataResult} gps - See GPSData + * @return {SubscribeVehicleDataResponse} + */ + + + setGps(gps) { + this.validateType(VehicleDataResult, gps); + this.setParameter(SubscribeVehicleDataResponse.KEY_GPS, gps); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getGps() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_GPS); + } + /** + * @param {VehicleDataResult} speed - The vehicle speed in kilometers per hour + * @return {SubscribeVehicleDataResponse} + */ + + + setSpeed(speed) { + this.validateType(VehicleDataResult, speed); + this.setParameter(SubscribeVehicleDataResponse.KEY_SPEED, speed); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getSpeed() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_SPEED); + } + /** + * @param {VehicleDataResult} rpm - The number of revolutions per minute of the engine + * @return {SubscribeVehicleDataResponse} + */ + + + setRpm(rpm) { + this.validateType(VehicleDataResult, rpm); + this.setParameter(SubscribeVehicleDataResponse.KEY_RPM, rpm); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getRpm() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_RPM); + } + /** + * @param {VehicleDataResult} level - The fuel level in the tank (percentage) + * @return {SubscribeVehicleDataResponse} + */ + + + setFuelLevel(level) { + this.validateType(VehicleDataResult, level); + this.setParameter(SubscribeVehicleDataResponse.KEY_FUEL_LEVEL, level); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getFuelLevel() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_FUEL_LEVEL); + } + /** + * @param {VehicleDataResult} level_state - The fuel level state + * @return {SubscribeVehicleDataResponse} + */ + + + setFuelLevel_State(level_state) { + this.validateType(VehicleDataResult, level_state); + this.setParameter(SubscribeVehicleDataResponse.KEY_FUEL_LEVEL_STATE, level_state); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getFuelLevel_State() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_FUEL_LEVEL_STATE); + } + /** + * @param {VehicleDataResult} consumption - The instantaneous fuel consumption in microlitres + * @return {SubscribeVehicleDataResponse} + */ + + + setInstantFuelConsumption(consumption) { + this.validateType(VehicleDataResult, consumption); + this.setParameter(SubscribeVehicleDataResponse.KEY_INSTANT_FUEL_CONSUMPTION, consumption); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getInstantFuelConsumption() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_INSTANT_FUEL_CONSUMPTION); + } + /** + * @param {VehicleDataResult} range - The estimate range in KM the vehicle can travel based on fuel level and + * consumption + * @return {SubscribeVehicleDataResponse} + */ + + + setFuelRange(range) { + this.validateType(VehicleDataResult, range); + this.setParameter(SubscribeVehicleDataResponse.KEY_FUEL_RANGE, range); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getFuelRange() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_FUEL_RANGE); + } + /** + * @param {VehicleDataResult} temperature - The external temperature in degrees celsius. + * @return {SubscribeVehicleDataResponse} + */ + + + setExternalTemperature(temperature) { + this.validateType(VehicleDataResult, temperature); + this.setParameter(SubscribeVehicleDataResponse.KEY_EXTERNAL_TEMPERATURE, temperature); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getExternalTemperature() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_EXTERNAL_TEMPERATURE); + } + /** + * @param {VehicleDataResult} signal - See TurnSignal + * @return {SubscribeVehicleDataResponse} + */ + + + setTurnSignal(signal) { + this.validateType(VehicleDataResult, signal); + this.setParameter(SubscribeVehicleDataResponse.KEY_TURN_SIGNAL, signal); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getTurnSignal() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_TURN_SIGNAL); + } + /** + * @param {VehicleDataResult} prndl - See PRNDL + * @return {SubscribeVehicleDataResponse} + */ + + + setPrndl(prndl) { + this.validateType(VehicleDataResult, prndl); + this.setParameter(SubscribeVehicleDataResponse.KEY_PRNDL, prndl); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getPrndl() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_PRNDL); + } + /** + * @param {VehicleDataResult} pressure - See TireStatus + * @return {SubscribeVehicleDataResponse} + */ + + + setTirePressure(pressure) { + this.validateType(VehicleDataResult, pressure); + this.setParameter(SubscribeVehicleDataResponse.KEY_TIRE_PRESSURE, pressure); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getTirePressure() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_TIRE_PRESSURE); + } + /** + * @param {VehicleDataResult} odometer - Odometer in km + * @return {SubscribeVehicleDataResponse} + */ + + + setOdometer(odometer) { + this.validateType(VehicleDataResult, odometer); + this.setParameter(SubscribeVehicleDataResponse.KEY_ODOMETER, odometer); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getOdometer() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_ODOMETER); + } + /** + * @param {VehicleDataResult} status - The status of the seat belts + * @return {SubscribeVehicleDataResponse} + */ + + + setBeltStatus(status) { + this.validateType(VehicleDataResult, status); + this.setParameter(SubscribeVehicleDataResponse.KEY_BELT_STATUS, status); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getBeltStatus() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_BELT_STATUS); + } + /** + * @param {VehicleDataResult} information - The body information including power modes + * @return {SubscribeVehicleDataResponse} + */ + + + setBodyInformation(information) { + this.validateType(VehicleDataResult, information); + this.setParameter(SubscribeVehicleDataResponse.KEY_BODY_INFORMATION, information); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getBodyInformation() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_BODY_INFORMATION); + } + /** + * @param {VehicleDataResult} status - The device status including signal and battery strength + * @return {SubscribeVehicleDataResponse} + */ + + + setDeviceStatus(status) { + this.validateType(VehicleDataResult, status); + this.setParameter(SubscribeVehicleDataResponse.KEY_DEVICE_STATUS, status); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getDeviceStatus() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_DEVICE_STATUS); + } + /** + * @param {VehicleDataResult} braking - The status of the brake pedal + * @return {SubscribeVehicleDataResponse} + */ + + + setDriverBraking(braking) { + this.validateType(VehicleDataResult, braking); + this.setParameter(SubscribeVehicleDataResponse.KEY_DRIVER_BRAKING, braking); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getDriverBraking() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_DRIVER_BRAKING); + } + /** + * @param {VehicleDataResult} status - The status of the wipers + * @return {SubscribeVehicleDataResponse} + */ + + + setWiperStatus(status) { + this.validateType(VehicleDataResult, status); + this.setParameter(SubscribeVehicleDataResponse.KEY_WIPER_STATUS, status); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getWiperStatus() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_WIPER_STATUS); + } + /** + * @param {VehicleDataResult} status - Status of the head lamps + * @return {SubscribeVehicleDataResponse} + */ + + + setHeadLampStatus(status) { + this.validateType(VehicleDataResult, status); + this.setParameter(SubscribeVehicleDataResponse.KEY_HEAD_LAMP_STATUS, status); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getHeadLampStatus() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_HEAD_LAMP_STATUS); + } + /** + * @param {VehicleDataResult} torque - Torque value for engine (in Nm) on non-diesel variants + * @return {SubscribeVehicleDataResponse} + */ + + + setEngineTorque(torque) { + this.validateType(VehicleDataResult, torque); + this.setParameter(SubscribeVehicleDataResponse.KEY_ENGINE_TORQUE, torque); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getEngineTorque() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_ENGINE_TORQUE); + } + /** + * @param {VehicleDataResult} position - Accelerator pedal position (percentage depressed) + * @return {SubscribeVehicleDataResponse} + */ + + + setAccPedalPosition(position) { + this.validateType(VehicleDataResult, position); + this.setParameter(SubscribeVehicleDataResponse.KEY_ACC_PEDAL_POSITION, position); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getAccPedalPosition() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_ACC_PEDAL_POSITION); + } + /** + * @param {VehicleDataResult} angle - Current angle of the steering wheel (in deg) + * @return {SubscribeVehicleDataResponse} + */ + + + setSteeringWheelAngle(angle) { + this.validateType(VehicleDataResult, angle); + this.setParameter(SubscribeVehicleDataResponse.KEY_STEERING_WHEEL_ANGLE, angle); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getSteeringWheelAngle() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_STEERING_WHEEL_ANGLE); + } + /** + * @param {VehicleDataResult} life - The estimated percentage of remaining oil life of the engine. + * @return {SubscribeVehicleDataResponse} + */ + + + setEngineOilLife(life) { + this.validateType(VehicleDataResult, life); + this.setParameter(SubscribeVehicleDataResponse.KEY_ENGINE_OIL_LIFE, life); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getEngineOilLife() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_ENGINE_OIL_LIFE); + } + /** + * @param {VehicleDataResult} status - The status of the park brake as provided by Electric Park Brake (EPB) system. + * @return {SubscribeVehicleDataResponse} + */ + + + setElectronicParkBrakeStatus(status) { + this.validateType(VehicleDataResult, status); + this.setParameter(SubscribeVehicleDataResponse.KEY_ELECTRONIC_PARK_BRAKE_STATUS, status); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getElectronicParkBrakeStatus() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_ELECTRONIC_PARK_BRAKE_STATUS); + } + /** + * @param {VehicleDataResult} id - Parameter used by cloud apps to identify a head unit + * @return {SubscribeVehicleDataResponse} + */ + + + setCloudAppVehicleID(id) { + this.validateType(VehicleDataResult, id); + this.setParameter(SubscribeVehicleDataResponse.KEY_CLOUD_APP_VEHICLE_ID, id); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getCloudAppVehicleID() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_CLOUD_APP_VEHICLE_ID); + } + /** + * @param {VehicleDataResult} info - Emergency Call notification and confirmation data + * @return {SubscribeVehicleDataResponse} + */ + + + setECallInfo(info) { + this.validateType(VehicleDataResult, info); + this.setParameter(SubscribeVehicleDataResponse.KEY_E_CALL_INFO, info); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getECallInfo() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_E_CALL_INFO); + } + /** + * @param {VehicleDataResult} status - The status of the air bags + * @return {SubscribeVehicleDataResponse} + */ + + + setAirbagStatus(status) { + this.validateType(VehicleDataResult, status); + this.setParameter(SubscribeVehicleDataResponse.KEY_AIRBAG_STATUS, status); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getAirbagStatus() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_AIRBAG_STATUS); + } + /** + * @param {VehicleDataResult} event - Information related to an emergency event (and if it occurred) + * @return {SubscribeVehicleDataResponse} + */ + + + setEmergencyEvent(event) { + this.validateType(VehicleDataResult, event); + this.setParameter(SubscribeVehicleDataResponse.KEY_EMERGENCY_EVENT, event); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getEmergencyEvent() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_EMERGENCY_EVENT); + } + /** + * @param {VehicleDataResult} modes - The status modes of the cluster + * @return {SubscribeVehicleDataResponse} + */ + + + setClusterModes(modes) { + this.validateType(VehicleDataResult, modes); + this.setParameter(SubscribeVehicleDataResponse.KEY_CLUSTER_MODES, modes); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getClusterModes() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_CLUSTER_MODES); + } + /** + * @param {VehicleDataResult} key - Information related to the MyKey feature + * @return {SubscribeVehicleDataResponse} + */ + + + setMyKey(key) { + this.validateType(VehicleDataResult, key); + this.setParameter(SubscribeVehicleDataResponse.KEY_MY_KEY, key); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getMyKey() { + return this.getObject(VehicleDataResult, SubscribeVehicleDataResponse.KEY_MY_KEY); + } + + } + + SubscribeVehicleDataResponse.KEY_GPS = 'gps'; + SubscribeVehicleDataResponse.KEY_SPEED = 'speed'; + SubscribeVehicleDataResponse.KEY_RPM = 'rpm'; + SubscribeVehicleDataResponse.KEY_FUEL_LEVEL = 'fuelLevel'; + SubscribeVehicleDataResponse.KEY_FUEL_LEVEL_STATE = 'fuelLevel_State'; + SubscribeVehicleDataResponse.KEY_INSTANT_FUEL_CONSUMPTION = 'instantFuelConsumption'; + SubscribeVehicleDataResponse.KEY_FUEL_RANGE = 'fuelRange'; + SubscribeVehicleDataResponse.KEY_EXTERNAL_TEMPERATURE = 'externalTemperature'; + SubscribeVehicleDataResponse.KEY_TURN_SIGNAL = 'turnSignal'; + SubscribeVehicleDataResponse.KEY_PRNDL = 'prndl'; + SubscribeVehicleDataResponse.KEY_TIRE_PRESSURE = 'tirePressure'; + SubscribeVehicleDataResponse.KEY_ODOMETER = 'odometer'; + SubscribeVehicleDataResponse.KEY_BELT_STATUS = 'beltStatus'; + SubscribeVehicleDataResponse.KEY_BODY_INFORMATION = 'bodyInformation'; + SubscribeVehicleDataResponse.KEY_DEVICE_STATUS = 'deviceStatus'; + SubscribeVehicleDataResponse.KEY_DRIVER_BRAKING = 'driverBraking'; + SubscribeVehicleDataResponse.KEY_WIPER_STATUS = 'wiperStatus'; + SubscribeVehicleDataResponse.KEY_HEAD_LAMP_STATUS = 'headLampStatus'; + SubscribeVehicleDataResponse.KEY_ENGINE_TORQUE = 'engineTorque'; + SubscribeVehicleDataResponse.KEY_ACC_PEDAL_POSITION = 'accPedalPosition'; + SubscribeVehicleDataResponse.KEY_STEERING_WHEEL_ANGLE = 'steeringWheelAngle'; + SubscribeVehicleDataResponse.KEY_ENGINE_OIL_LIFE = 'engineOilLife'; + SubscribeVehicleDataResponse.KEY_ELECTRONIC_PARK_BRAKE_STATUS = 'electronicParkBrakeStatus'; + SubscribeVehicleDataResponse.KEY_CLOUD_APP_VEHICLE_ID = 'cloudAppVehicleID'; + SubscribeVehicleDataResponse.KEY_E_CALL_INFO = 'eCallInfo'; + SubscribeVehicleDataResponse.KEY_AIRBAG_STATUS = 'airbagStatus'; + SubscribeVehicleDataResponse.KEY_EMERGENCY_EVENT = 'emergencyEvent'; + SubscribeVehicleDataResponse.KEY_CLUSTER_MODES = 'clusterModes'; + SubscribeVehicleDataResponse.KEY_MY_KEY = 'myKey'; + + /* eslint-disable camelcase */ + /** + * This function is used to unsubscribe the notifications from the subscribeVehicleData function. + */ + + class UnsubscribeVehicleData extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.UnsubscribeVehicleData); + } + /** + * @param {Boolean} gps - See GPSData + * @return {UnsubscribeVehicleData} + */ + + + setGps(gps) { + this.setParameter(UnsubscribeVehicleData.KEY_GPS, gps); + return this; + } + /** + * @return {Boolean} + */ + + + getGps() { + return this.getParameter(UnsubscribeVehicleData.KEY_GPS); + } + /** + * @param {Boolean} speed - The vehicle speed in kilometers per hour + * @return {UnsubscribeVehicleData} + */ + + + setSpeed(speed) { + this.setParameter(UnsubscribeVehicleData.KEY_SPEED, speed); + return this; + } + /** + * @return {Boolean} + */ + + + getSpeed() { + return this.getParameter(UnsubscribeVehicleData.KEY_SPEED); + } + /** + * @param {Boolean} rpm - The number of revolutions per minute of the engine + * @return {UnsubscribeVehicleData} + */ + + + setRpm(rpm) { + this.setParameter(UnsubscribeVehicleData.KEY_RPM, rpm); + return this; + } + /** + * @return {Boolean} + */ + + + getRpm() { + return this.getParameter(UnsubscribeVehicleData.KEY_RPM); + } + /** + * @param {Boolean} level - The fuel level in the tank (percentage) + * @return {UnsubscribeVehicleData} + */ + + + setFuelLevel(level) { + this.setParameter(UnsubscribeVehicleData.KEY_FUEL_LEVEL, level); + return this; + } + /** + * @return {Boolean} + */ + + + getFuelLevel() { + return this.getParameter(UnsubscribeVehicleData.KEY_FUEL_LEVEL); + } + /** + * @param {Boolean} level_state - The fuel level state + * @return {UnsubscribeVehicleData} + */ + + + setFuelLevel_State(level_state) { + this.setParameter(UnsubscribeVehicleData.KEY_FUEL_LEVEL_STATE, level_state); + return this; + } + /** + * @return {Boolean} + */ + + + getFuelLevel_State() { + return this.getParameter(UnsubscribeVehicleData.KEY_FUEL_LEVEL_STATE); + } + /** + * @param {Boolean} consumption - The instantaneous fuel consumption in microlitres + * @return {UnsubscribeVehicleData} + */ + + + setInstantFuelConsumption(consumption) { + this.setParameter(UnsubscribeVehicleData.KEY_INSTANT_FUEL_CONSUMPTION, consumption); + return this; + } + /** + * @return {Boolean} + */ + + + getInstantFuelConsumption() { + return this.getParameter(UnsubscribeVehicleData.KEY_INSTANT_FUEL_CONSUMPTION); + } + /** + * @param {Boolean} range - The estimate range in KM the vehicle can travel based on fuel level and consumption + * @return {UnsubscribeVehicleData} + */ + + + setFuelRange(range) { + this.setParameter(UnsubscribeVehicleData.KEY_FUEL_RANGE, range); + return this; + } + /** + * @return {Boolean} + */ + + + getFuelRange() { + return this.getParameter(UnsubscribeVehicleData.KEY_FUEL_RANGE); + } + /** + * @param {Boolean} temperature - The external temperature in degrees celsius. + * @return {UnsubscribeVehicleData} + */ + + + setExternalTemperature(temperature) { + this.setParameter(UnsubscribeVehicleData.KEY_EXTERNAL_TEMPERATURE, temperature); + return this; + } + /** + * @return {Boolean} + */ + + + getExternalTemperature() { + return this.getParameter(UnsubscribeVehicleData.KEY_EXTERNAL_TEMPERATURE); + } + /** + * @param {Boolean} signal - See TurnSignal + * @return {UnsubscribeVehicleData} + */ + + + setTurnSignal(signal) { + this.setParameter(UnsubscribeVehicleData.KEY_TURN_SIGNAL, signal); + return this; + } + /** + * @return {Boolean} + */ + + + getTurnSignal() { + return this.getParameter(UnsubscribeVehicleData.KEY_TURN_SIGNAL); + } + /** + * @param {Boolean} prndl - See PRNDL + * @return {UnsubscribeVehicleData} + */ + + + setPrndl(prndl) { + this.setParameter(UnsubscribeVehicleData.KEY_PRNDL, prndl); + return this; + } + /** + * @return {Boolean} + */ + + + getPrndl() { + return this.getParameter(UnsubscribeVehicleData.KEY_PRNDL); + } + /** + * @param {Boolean} pressure - See TireStatus + * @return {UnsubscribeVehicleData} + */ + + + setTirePressure(pressure) { + this.setParameter(UnsubscribeVehicleData.KEY_TIRE_PRESSURE, pressure); + return this; + } + /** + * @return {Boolean} + */ + + + getTirePressure() { + return this.getParameter(UnsubscribeVehicleData.KEY_TIRE_PRESSURE); + } + /** + * @param {Boolean} odometer - Odometer in km + * @return {UnsubscribeVehicleData} + */ + + + setOdometer(odometer) { + this.setParameter(UnsubscribeVehicleData.KEY_ODOMETER, odometer); + return this; + } + /** + * @return {Boolean} + */ + + + getOdometer() { + return this.getParameter(UnsubscribeVehicleData.KEY_ODOMETER); + } + /** + * @param {Boolean} status - The status of the seat belts + * @return {UnsubscribeVehicleData} + */ + + + setBeltStatus(status) { + this.setParameter(UnsubscribeVehicleData.KEY_BELT_STATUS, status); + return this; + } + /** + * @return {Boolean} + */ + + + getBeltStatus() { + return this.getParameter(UnsubscribeVehicleData.KEY_BELT_STATUS); + } + /** + * @param {Boolean} information - The body information including power modes + * @return {UnsubscribeVehicleData} + */ + + + setBodyInformation(information) { + this.setParameter(UnsubscribeVehicleData.KEY_BODY_INFORMATION, information); + return this; + } + /** + * @return {Boolean} + */ + + + getBodyInformation() { + return this.getParameter(UnsubscribeVehicleData.KEY_BODY_INFORMATION); + } + /** + * @param {Boolean} status - The device status including signal and battery strength + * @return {UnsubscribeVehicleData} + */ + + + setDeviceStatus(status) { + this.setParameter(UnsubscribeVehicleData.KEY_DEVICE_STATUS, status); + return this; + } + /** + * @return {Boolean} + */ + + + getDeviceStatus() { + return this.getParameter(UnsubscribeVehicleData.KEY_DEVICE_STATUS); + } + /** + * @param {Boolean} braking - The status of the brake pedal + * @return {UnsubscribeVehicleData} + */ + + + setDriverBraking(braking) { + this.setParameter(UnsubscribeVehicleData.KEY_DRIVER_BRAKING, braking); + return this; + } + /** + * @return {Boolean} + */ + + + getDriverBraking() { + return this.getParameter(UnsubscribeVehicleData.KEY_DRIVER_BRAKING); + } + /** + * @param {Boolean} status - The status of the wipers + * @return {UnsubscribeVehicleData} + */ + + + setWiperStatus(status) { + this.setParameter(UnsubscribeVehicleData.KEY_WIPER_STATUS, status); + return this; + } + /** + * @return {Boolean} + */ + + + getWiperStatus() { + return this.getParameter(UnsubscribeVehicleData.KEY_WIPER_STATUS); + } + /** + * @param {Boolean} status - Status of the head lamps + * @return {UnsubscribeVehicleData} + */ + + + setHeadLampStatus(status) { + this.setParameter(UnsubscribeVehicleData.KEY_HEAD_LAMP_STATUS, status); + return this; + } + /** + * @return {Boolean} + */ + + + getHeadLampStatus() { + return this.getParameter(UnsubscribeVehicleData.KEY_HEAD_LAMP_STATUS); + } + /** + * @param {Boolean} torque - Torque value for engine (in Nm) on non-diesel variants + * @return {UnsubscribeVehicleData} + */ + + + setEngineTorque(torque) { + this.setParameter(UnsubscribeVehicleData.KEY_ENGINE_TORQUE, torque); + return this; + } + /** + * @return {Boolean} + */ + + + getEngineTorque() { + return this.getParameter(UnsubscribeVehicleData.KEY_ENGINE_TORQUE); + } + /** + * @param {Boolean} position - Accelerator pedal position (percentage depressed) + * @return {UnsubscribeVehicleData} + */ + + + setAccPedalPosition(position) { + this.setParameter(UnsubscribeVehicleData.KEY_ACC_PEDAL_POSITION, position); + return this; + } + /** + * @return {Boolean} + */ + + + getAccPedalPosition() { + return this.getParameter(UnsubscribeVehicleData.KEY_ACC_PEDAL_POSITION); + } + /** + * @param {Boolean} angle - Current angle of the steering wheel (in deg) + * @return {UnsubscribeVehicleData} + */ + + + setSteeringWheelAngle(angle) { + this.setParameter(UnsubscribeVehicleData.KEY_STEERING_WHEEL_ANGLE, angle); + return this; + } + /** + * @return {Boolean} + */ + + + getSteeringWheelAngle() { + return this.getParameter(UnsubscribeVehicleData.KEY_STEERING_WHEEL_ANGLE); + } + /** + * @param {Boolean} life - The estimated percentage of remaining oil life of the engine. + * @return {UnsubscribeVehicleData} + */ + + + setEngineOilLife(life) { + this.setParameter(UnsubscribeVehicleData.KEY_ENGINE_OIL_LIFE, life); + return this; + } + /** + * @return {Boolean} + */ + + + getEngineOilLife() { + return this.getParameter(UnsubscribeVehicleData.KEY_ENGINE_OIL_LIFE); + } + /** + * @param {Boolean} status - The status of the park brake as provided by Electric Park Brake (EPB) system. + * @return {UnsubscribeVehicleData} + */ + + + setElectronicParkBrakeStatus(status) { + this.setParameter(UnsubscribeVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS, status); + return this; + } + /** + * @return {Boolean} + */ + + + getElectronicParkBrakeStatus() { + return this.getParameter(UnsubscribeVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS); + } + /** + * @param {Boolean} id - Parameter used by cloud apps to identify a head unit + * @return {UnsubscribeVehicleData} + */ + + + setCloudAppVehicleID(id) { + this.setParameter(UnsubscribeVehicleData.KEY_CLOUD_APP_VEHICLE_ID, id); + return this; + } + /** + * @return {Boolean} + */ + + + getCloudAppVehicleID() { + return this.getParameter(UnsubscribeVehicleData.KEY_CLOUD_APP_VEHICLE_ID); + } + /** + * @param {Boolean} info - Emergency Call notification and confirmation data + * @return {UnsubscribeVehicleData} + */ + + + setECallInfo(info) { + this.setParameter(UnsubscribeVehicleData.KEY_E_CALL_INFO, info); + return this; + } + /** + * @return {Boolean} + */ + + + getECallInfo() { + return this.getParameter(UnsubscribeVehicleData.KEY_E_CALL_INFO); + } + /** + * @param {Boolean} status - The status of the air bags + * @return {UnsubscribeVehicleData} + */ + + + setAirbagStatus(status) { + this.setParameter(UnsubscribeVehicleData.KEY_AIRBAG_STATUS, status); + return this; + } + /** + * @return {Boolean} + */ + + + getAirbagStatus() { + return this.getParameter(UnsubscribeVehicleData.KEY_AIRBAG_STATUS); + } + /** + * @param {Boolean} event - Information related to an emergency event (and if it occurred) + * @return {UnsubscribeVehicleData} + */ + + + setEmergencyEvent(event) { + this.setParameter(UnsubscribeVehicleData.KEY_EMERGENCY_EVENT, event); + return this; + } + /** + * @return {Boolean} + */ + + + getEmergencyEvent() { + return this.getParameter(UnsubscribeVehicleData.KEY_EMERGENCY_EVENT); + } + /** + * @param {Boolean} status - The status modes of the cluster + * @return {UnsubscribeVehicleData} + */ + + + setClusterModeStatus(status) { + this.setParameter(UnsubscribeVehicleData.KEY_CLUSTER_MODE_STATUS, status); + return this; + } + /** + * @return {Boolean} + */ + + + getClusterModeStatus() { + return this.getParameter(UnsubscribeVehicleData.KEY_CLUSTER_MODE_STATUS); + } + /** + * @param {Boolean} key - Information related to the MyKey feature + * @return {UnsubscribeVehicleData} + */ + + + setMyKey(key) { + this.setParameter(UnsubscribeVehicleData.KEY_MY_KEY, key); + return this; + } + /** + * @return {Boolean} + */ + + + getMyKey() { + return this.getParameter(UnsubscribeVehicleData.KEY_MY_KEY); + } + + } + + UnsubscribeVehicleData.KEY_GPS = 'gps'; + UnsubscribeVehicleData.KEY_SPEED = 'speed'; + UnsubscribeVehicleData.KEY_RPM = 'rpm'; + UnsubscribeVehicleData.KEY_FUEL_LEVEL = 'fuelLevel'; + UnsubscribeVehicleData.KEY_FUEL_LEVEL_STATE = 'fuelLevel_State'; + UnsubscribeVehicleData.KEY_INSTANT_FUEL_CONSUMPTION = 'instantFuelConsumption'; + UnsubscribeVehicleData.KEY_FUEL_RANGE = 'fuelRange'; + UnsubscribeVehicleData.KEY_EXTERNAL_TEMPERATURE = 'externalTemperature'; + UnsubscribeVehicleData.KEY_TURN_SIGNAL = 'turnSignal'; + UnsubscribeVehicleData.KEY_PRNDL = 'prndl'; + UnsubscribeVehicleData.KEY_TIRE_PRESSURE = 'tirePressure'; + UnsubscribeVehicleData.KEY_ODOMETER = 'odometer'; + UnsubscribeVehicleData.KEY_BELT_STATUS = 'beltStatus'; + UnsubscribeVehicleData.KEY_BODY_INFORMATION = 'bodyInformation'; + UnsubscribeVehicleData.KEY_DEVICE_STATUS = 'deviceStatus'; + UnsubscribeVehicleData.KEY_DRIVER_BRAKING = 'driverBraking'; + UnsubscribeVehicleData.KEY_WIPER_STATUS = 'wiperStatus'; + UnsubscribeVehicleData.KEY_HEAD_LAMP_STATUS = 'headLampStatus'; + UnsubscribeVehicleData.KEY_ENGINE_TORQUE = 'engineTorque'; + UnsubscribeVehicleData.KEY_ACC_PEDAL_POSITION = 'accPedalPosition'; + UnsubscribeVehicleData.KEY_STEERING_WHEEL_ANGLE = 'steeringWheelAngle'; + UnsubscribeVehicleData.KEY_ENGINE_OIL_LIFE = 'engineOilLife'; + UnsubscribeVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS = 'electronicParkBrakeStatus'; + UnsubscribeVehicleData.KEY_CLOUD_APP_VEHICLE_ID = 'cloudAppVehicleID'; + UnsubscribeVehicleData.KEY_E_CALL_INFO = 'eCallInfo'; + UnsubscribeVehicleData.KEY_AIRBAG_STATUS = 'airbagStatus'; + UnsubscribeVehicleData.KEY_EMERGENCY_EVENT = 'emergencyEvent'; + UnsubscribeVehicleData.KEY_CLUSTER_MODE_STATUS = 'clusterModeStatus'; + UnsubscribeVehicleData.KEY_MY_KEY = 'myKey'; + + /* eslint-disable camelcase */ + + class UnsubscribeVehicleDataResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.UnsubscribeVehicleData); + } + /** + * @param {VehicleDataResult} gps - See GPSData + * @return {UnsubscribeVehicleDataResponse} + */ + + + setGps(gps) { + this.validateType(VehicleDataResult, gps); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_GPS, gps); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getGps() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_GPS); + } + /** + * @param {VehicleDataResult} speed - The vehicle speed in kilometers per hour + * @return {UnsubscribeVehicleDataResponse} + */ + + + setSpeed(speed) { + this.validateType(VehicleDataResult, speed); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_SPEED, speed); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getSpeed() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_SPEED); + } + /** + * @param {VehicleDataResult} rpm - The number of revolutions per minute of the engine + * @return {UnsubscribeVehicleDataResponse} + */ + + + setRpm(rpm) { + this.validateType(VehicleDataResult, rpm); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_RPM, rpm); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getRpm() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_RPM); + } + /** + * @param {VehicleDataResult} level - The fuel level in the tank (percentage) + * @return {UnsubscribeVehicleDataResponse} + */ + + + setFuelLevel(level) { + this.validateType(VehicleDataResult, level); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_FUEL_LEVEL, level); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getFuelLevel() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_FUEL_LEVEL); + } + /** + * @param {VehicleDataResult} level_state - The fuel level state + * @return {UnsubscribeVehicleDataResponse} + */ + + + setFuelLevel_State(level_state) { + this.validateType(VehicleDataResult, level_state); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_FUEL_LEVEL_STATE, level_state); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getFuelLevel_State() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_FUEL_LEVEL_STATE); + } + /** + * @param {VehicleDataResult} consumption - The instantaneous fuel consumption in microlitres + * @return {UnsubscribeVehicleDataResponse} + */ + + + setInstantFuelConsumption(consumption) { + this.validateType(VehicleDataResult, consumption); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_INSTANT_FUEL_CONSUMPTION, consumption); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getInstantFuelConsumption() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_INSTANT_FUEL_CONSUMPTION); + } + /** + * @param {VehicleDataResult} range - The estimate range in KM the vehicle can travel based on fuel level and + * consumption + * @return {UnsubscribeVehicleDataResponse} + */ + + + setFuelRange(range) { + this.validateType(VehicleDataResult, range); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_FUEL_RANGE, range); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getFuelRange() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_FUEL_RANGE); + } + /** + * @param {VehicleDataResult} temperature - The external temperature in degrees celsius + * @return {UnsubscribeVehicleDataResponse} + */ + + + setExternalTemperature(temperature) { + this.validateType(VehicleDataResult, temperature); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_EXTERNAL_TEMPERATURE, temperature); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getExternalTemperature() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_EXTERNAL_TEMPERATURE); + } + /** + * @param {VehicleDataResult} signal - See TurnSignal + * @return {UnsubscribeVehicleDataResponse} + */ + + + setTurnSignal(signal) { + this.validateType(VehicleDataResult, signal); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_TURN_SIGNAL, signal); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getTurnSignal() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_TURN_SIGNAL); + } + /** + * @param {VehicleDataResult} prndl - See PRNDL + * @return {UnsubscribeVehicleDataResponse} + */ + + + setPrndl(prndl) { + this.validateType(VehicleDataResult, prndl); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_PRNDL, prndl); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getPrndl() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_PRNDL); + } + /** + * @param {VehicleDataResult} pressure - See TireStatus + * @return {UnsubscribeVehicleDataResponse} + */ + + + setTirePressure(pressure) { + this.validateType(VehicleDataResult, pressure); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_TIRE_PRESSURE, pressure); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getTirePressure() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_TIRE_PRESSURE); + } + /** + * @param {VehicleDataResult} odometer - Odometer in km + * @return {UnsubscribeVehicleDataResponse} + */ + + + setOdometer(odometer) { + this.validateType(VehicleDataResult, odometer); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_ODOMETER, odometer); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getOdometer() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_ODOMETER); + } + /** + * @param {VehicleDataResult} status - The status of the seat belts + * @return {UnsubscribeVehicleDataResponse} + */ + + + setBeltStatus(status) { + this.validateType(VehicleDataResult, status); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_BELT_STATUS, status); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getBeltStatus() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_BELT_STATUS); + } + /** + * @param {VehicleDataResult} information - The body information including power modes + * @return {UnsubscribeVehicleDataResponse} + */ + + + setBodyInformation(information) { + this.validateType(VehicleDataResult, information); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_BODY_INFORMATION, information); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getBodyInformation() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_BODY_INFORMATION); + } + /** + * @param {VehicleDataResult} status - The device status including signal and battery strength + * @return {UnsubscribeVehicleDataResponse} + */ + + + setDeviceStatus(status) { + this.validateType(VehicleDataResult, status); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_DEVICE_STATUS, status); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getDeviceStatus() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_DEVICE_STATUS); + } + /** + * @param {VehicleDataResult} braking - The status of the brake pedal + * @return {UnsubscribeVehicleDataResponse} + */ + + + setDriverBraking(braking) { + this.validateType(VehicleDataResult, braking); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_DRIVER_BRAKING, braking); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getDriverBraking() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_DRIVER_BRAKING); + } + /** + * @param {VehicleDataResult} status - The status of the wipers + * @return {UnsubscribeVehicleDataResponse} + */ + + + setWiperStatus(status) { + this.validateType(VehicleDataResult, status); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_WIPER_STATUS, status); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getWiperStatus() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_WIPER_STATUS); + } + /** + * @param {VehicleDataResult} status - Status of the head lamps + * @return {UnsubscribeVehicleDataResponse} + */ + + + setHeadLampStatus(status) { + this.validateType(VehicleDataResult, status); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_HEAD_LAMP_STATUS, status); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getHeadLampStatus() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_HEAD_LAMP_STATUS); + } + /** + * @param {VehicleDataResult} torque - Torque value for engine (in Nm) on non-diesel variants + * @return {UnsubscribeVehicleDataResponse} + */ + + + setEngineTorque(torque) { + this.validateType(VehicleDataResult, torque); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_ENGINE_TORQUE, torque); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getEngineTorque() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_ENGINE_TORQUE); + } + /** + * @param {VehicleDataResult} position - Accelerator pedal position (percentage depressed) + * @return {UnsubscribeVehicleDataResponse} + */ + + + setAccPedalPosition(position) { + this.validateType(VehicleDataResult, position); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_ACC_PEDAL_POSITION, position); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getAccPedalPosition() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_ACC_PEDAL_POSITION); + } + /** + * @param {VehicleDataResult} angle - Current angle of the steering wheel (in deg) + * @return {UnsubscribeVehicleDataResponse} + */ + + + setSteeringWheelAngle(angle) { + this.validateType(VehicleDataResult, angle); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_STEERING_WHEEL_ANGLE, angle); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getSteeringWheelAngle() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_STEERING_WHEEL_ANGLE); + } + /** + * @param {VehicleDataResult} life - The estimated percentage of remaining oil life of the engine. + * @return {UnsubscribeVehicleDataResponse} + */ + + + setEngineOilLife(life) { + this.validateType(VehicleDataResult, life); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_ENGINE_OIL_LIFE, life); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getEngineOilLife() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_ENGINE_OIL_LIFE); + } + /** + * @param {VehicleDataResult} status - The status of the park brake as provided by Electric Park Brake (EPB) system. + * @return {UnsubscribeVehicleDataResponse} + */ + + + setElectronicParkBrakeStatus(status) { + this.validateType(VehicleDataResult, status); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_ELECTRONIC_PARK_BRAKE_STATUS, status); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getElectronicParkBrakeStatus() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_ELECTRONIC_PARK_BRAKE_STATUS); + } + /** + * @param {VehicleDataResult} id - Parameter used by cloud apps to identify a head unit + * @return {UnsubscribeVehicleDataResponse} + */ + + + setCloudAppVehicleID(id) { + this.validateType(VehicleDataResult, id); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_CLOUD_APP_VEHICLE_ID, id); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getCloudAppVehicleID() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_CLOUD_APP_VEHICLE_ID); + } + /** + * @param {VehicleDataResult} info - Emergency Call notification and confirmation data + * @return {UnsubscribeVehicleDataResponse} + */ + + + setECallInfo(info) { + this.validateType(VehicleDataResult, info); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_E_CALL_INFO, info); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getECallInfo() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_E_CALL_INFO); + } + /** + * @param {VehicleDataResult} status - The status of the air bags + * @return {UnsubscribeVehicleDataResponse} + */ + + + setAirbagStatus(status) { + this.validateType(VehicleDataResult, status); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_AIRBAG_STATUS, status); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getAirbagStatus() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_AIRBAG_STATUS); + } + /** + * @param {VehicleDataResult} event - Information related to an emergency event (and if it occurred) + * @return {UnsubscribeVehicleDataResponse} + */ + + + setEmergencyEvent(event) { + this.validateType(VehicleDataResult, event); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_EMERGENCY_EVENT, event); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getEmergencyEvent() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_EMERGENCY_EVENT); + } + /** + * @param {VehicleDataResult} modes - The status modes of the cluster + * @return {UnsubscribeVehicleDataResponse} + */ + + + setClusterModes(modes) { + this.validateType(VehicleDataResult, modes); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_CLUSTER_MODES, modes); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getClusterModes() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_CLUSTER_MODES); + } + /** + * @param {VehicleDataResult} key - Information related to the MyKey feature + * @return {UnsubscribeVehicleDataResponse} + */ + + + setMyKey(key) { + this.validateType(VehicleDataResult, key); + this.setParameter(UnsubscribeVehicleDataResponse.KEY_MY_KEY, key); + return this; + } + /** + * @return {VehicleDataResult} + */ + + + getMyKey() { + return this.getObject(VehicleDataResult, UnsubscribeVehicleDataResponse.KEY_MY_KEY); + } + + } + + UnsubscribeVehicleDataResponse.KEY_GPS = 'gps'; + UnsubscribeVehicleDataResponse.KEY_SPEED = 'speed'; + UnsubscribeVehicleDataResponse.KEY_RPM = 'rpm'; + UnsubscribeVehicleDataResponse.KEY_FUEL_LEVEL = 'fuelLevel'; + UnsubscribeVehicleDataResponse.KEY_FUEL_LEVEL_STATE = 'fuelLevel_State'; + UnsubscribeVehicleDataResponse.KEY_INSTANT_FUEL_CONSUMPTION = 'instantFuelConsumption'; + UnsubscribeVehicleDataResponse.KEY_FUEL_RANGE = 'fuelRange'; + UnsubscribeVehicleDataResponse.KEY_EXTERNAL_TEMPERATURE = 'externalTemperature'; + UnsubscribeVehicleDataResponse.KEY_TURN_SIGNAL = 'turnSignal'; + UnsubscribeVehicleDataResponse.KEY_PRNDL = 'prndl'; + UnsubscribeVehicleDataResponse.KEY_TIRE_PRESSURE = 'tirePressure'; + UnsubscribeVehicleDataResponse.KEY_ODOMETER = 'odometer'; + UnsubscribeVehicleDataResponse.KEY_BELT_STATUS = 'beltStatus'; + UnsubscribeVehicleDataResponse.KEY_BODY_INFORMATION = 'bodyInformation'; + UnsubscribeVehicleDataResponse.KEY_DEVICE_STATUS = 'deviceStatus'; + UnsubscribeVehicleDataResponse.KEY_DRIVER_BRAKING = 'driverBraking'; + UnsubscribeVehicleDataResponse.KEY_WIPER_STATUS = 'wiperStatus'; + UnsubscribeVehicleDataResponse.KEY_HEAD_LAMP_STATUS = 'headLampStatus'; + UnsubscribeVehicleDataResponse.KEY_ENGINE_TORQUE = 'engineTorque'; + UnsubscribeVehicleDataResponse.KEY_ACC_PEDAL_POSITION = 'accPedalPosition'; + UnsubscribeVehicleDataResponse.KEY_STEERING_WHEEL_ANGLE = 'steeringWheelAngle'; + UnsubscribeVehicleDataResponse.KEY_ENGINE_OIL_LIFE = 'engineOilLife'; + UnsubscribeVehicleDataResponse.KEY_ELECTRONIC_PARK_BRAKE_STATUS = 'electronicParkBrakeStatus'; + UnsubscribeVehicleDataResponse.KEY_CLOUD_APP_VEHICLE_ID = 'cloudAppVehicleID'; + UnsubscribeVehicleDataResponse.KEY_E_CALL_INFO = 'eCallInfo'; + UnsubscribeVehicleDataResponse.KEY_AIRBAG_STATUS = 'airbagStatus'; + UnsubscribeVehicleDataResponse.KEY_EMERGENCY_EVENT = 'emergencyEvent'; + UnsubscribeVehicleDataResponse.KEY_CLUSTER_MODES = 'clusterModes'; + UnsubscribeVehicleDataResponse.KEY_MY_KEY = 'myKey'; + + /* eslint-disable camelcase */ + /** + * Non periodic vehicle data read request. + */ + + class GetVehicleData extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.GetVehicleData); + } + /** + * @param {Boolean} gps - See GPSData + * @return {GetVehicleData} + */ + + + setGps(gps) { + this.setParameter(GetVehicleData.KEY_GPS, gps); + return this; + } + /** + * @return {Boolean} + */ + + + getGps() { + return this.getParameter(GetVehicleData.KEY_GPS); + } + /** + * @param {Boolean} speed - The vehicle speed in kilometers per hour + * @return {GetVehicleData} + */ + + + setSpeed(speed) { + this.setParameter(GetVehicleData.KEY_SPEED, speed); + return this; + } + /** + * @return {Boolean} + */ + + + getSpeed() { + return this.getParameter(GetVehicleData.KEY_SPEED); + } + /** + * @param {Boolean} rpm - The number of revolutions per minute of the engine + * @return {GetVehicleData} + */ + + + setRpm(rpm) { + this.setParameter(GetVehicleData.KEY_RPM, rpm); + return this; + } + /** + * @return {Boolean} + */ + + + getRpm() { + return this.getParameter(GetVehicleData.KEY_RPM); + } + /** + * @param {Boolean} level - The fuel level in the tank (percentage) + * @return {GetVehicleData} + */ + + + setFuelLevel(level) { + this.setParameter(GetVehicleData.KEY_FUEL_LEVEL, level); + return this; + } + /** + * @return {Boolean} + */ + + + getFuelLevel() { + return this.getParameter(GetVehicleData.KEY_FUEL_LEVEL); + } + /** + * @param {Boolean} level_state - The fuel level state + * @return {GetVehicleData} + */ + + + setFuelLevel_State(level_state) { + this.setParameter(GetVehicleData.KEY_FUEL_LEVEL_STATE, level_state); + return this; + } + /** + * @return {Boolean} + */ + + + getFuelLevel_State() { + return this.getParameter(GetVehicleData.KEY_FUEL_LEVEL_STATE); + } + /** + * @param {Boolean} consumption - The instantaneous fuel consumption in microlitres + * @return {GetVehicleData} + */ + + + setInstantFuelConsumption(consumption) { + this.setParameter(GetVehicleData.KEY_INSTANT_FUEL_CONSUMPTION, consumption); + return this; + } + /** + * @return {Boolean} + */ + + + getInstantFuelConsumption() { + return this.getParameter(GetVehicleData.KEY_INSTANT_FUEL_CONSUMPTION); + } + /** + * @param {Boolean} range - The estimate range in KM the vehicle can travel based on fuel level and consumption + * @return {GetVehicleData} + */ + + + setFuelRange(range) { + this.setParameter(GetVehicleData.KEY_FUEL_RANGE, range); + return this; + } + /** + * @return {Boolean} + */ + + + getFuelRange() { + return this.getParameter(GetVehicleData.KEY_FUEL_RANGE); + } + /** + * @param {Boolean} temperature - The external temperature in degrees celsius + * @return {GetVehicleData} + */ + + + setExternalTemperature(temperature) { + this.setParameter(GetVehicleData.KEY_EXTERNAL_TEMPERATURE, temperature); + return this; + } + /** + * @return {Boolean} + */ + + + getExternalTemperature() { + return this.getParameter(GetVehicleData.KEY_EXTERNAL_TEMPERATURE); + } + /** + * @param {Boolean} signal - See TurnSignal + * @return {GetVehicleData} + */ + + + setTurnSignal(signal) { + this.setParameter(GetVehicleData.KEY_TURN_SIGNAL, signal); + return this; + } + /** + * @return {Boolean} + */ + + + getTurnSignal() { + return this.getParameter(GetVehicleData.KEY_TURN_SIGNAL); + } + /** + * @param {Boolean} vin - Vehicle identification number + * @return {GetVehicleData} + */ + + + setVin(vin) { + this.setParameter(GetVehicleData.KEY_VIN, vin); + return this; + } + /** + * @return {Boolean} + */ + + + getVin() { + return this.getParameter(GetVehicleData.KEY_VIN); + } + /** + * @param {Boolean} prndl - See PRNDL + * @return {GetVehicleData} + */ + + + setPrndl(prndl) { + this.setParameter(GetVehicleData.KEY_PRNDL, prndl); + return this; + } + /** + * @return {Boolean} + */ + + + getPrndl() { + return this.getParameter(GetVehicleData.KEY_PRNDL); + } + /** + * @param {Boolean} pressure - See TireStatus + * @return {GetVehicleData} + */ + + + setTirePressure(pressure) { + this.setParameter(GetVehicleData.KEY_TIRE_PRESSURE, pressure); + return this; + } + /** + * @return {Boolean} + */ + + + getTirePressure() { + return this.getParameter(GetVehicleData.KEY_TIRE_PRESSURE); + } + /** + * @param {Boolean} odometer - Odometer in km + * @return {GetVehicleData} + */ + + + setOdometer(odometer) { + this.setParameter(GetVehicleData.KEY_ODOMETER, odometer); + return this; + } + /** + * @return {Boolean} + */ + + + getOdometer() { + return this.getParameter(GetVehicleData.KEY_ODOMETER); + } + /** + * @param {Boolean} status - The status of the seat belts + * @return {GetVehicleData} + */ + + + setBeltStatus(status) { + this.setParameter(GetVehicleData.KEY_BELT_STATUS, status); + return this; + } + /** + * @return {Boolean} + */ + + + getBeltStatus() { + return this.getParameter(GetVehicleData.KEY_BELT_STATUS); + } + /** + * @param {Boolean} information - The body information including ignition status and internal temp + * @return {GetVehicleData} + */ + + + setBodyInformation(information) { + this.setParameter(GetVehicleData.KEY_BODY_INFORMATION, information); + return this; + } + /** + * @return {Boolean} + */ + + + getBodyInformation() { + return this.getParameter(GetVehicleData.KEY_BODY_INFORMATION); + } + /** + * @param {Boolean} status - The device status including signal and battery strength + * @return {GetVehicleData} + */ + + + setDeviceStatus(status) { + this.setParameter(GetVehicleData.KEY_DEVICE_STATUS, status); + return this; + } + /** + * @return {Boolean} + */ + + + getDeviceStatus() { + return this.getParameter(GetVehicleData.KEY_DEVICE_STATUS); + } + /** + * @param {Boolean} braking - The status of the brake pedal + * @return {GetVehicleData} + */ + + + setDriverBraking(braking) { + this.setParameter(GetVehicleData.KEY_DRIVER_BRAKING, braking); + return this; + } + /** + * @return {Boolean} + */ + + + getDriverBraking() { + return this.getParameter(GetVehicleData.KEY_DRIVER_BRAKING); + } + /** + * @param {Boolean} status - The status of the wipers + * @return {GetVehicleData} + */ + + + setWiperStatus(status) { + this.setParameter(GetVehicleData.KEY_WIPER_STATUS, status); + return this; + } + /** + * @return {Boolean} + */ + + + getWiperStatus() { + return this.getParameter(GetVehicleData.KEY_WIPER_STATUS); + } + /** + * @param {Boolean} status - Status of the head lamps + * @return {GetVehicleData} + */ + + + setHeadLampStatus(status) { + this.setParameter(GetVehicleData.KEY_HEAD_LAMP_STATUS, status); + return this; + } + /** + * @return {Boolean} + */ + + + getHeadLampStatus() { + return this.getParameter(GetVehicleData.KEY_HEAD_LAMP_STATUS); + } + /** + * @param {Boolean} torque - Torque value for engine (in Nm) on non-diesel variants + * @return {GetVehicleData} + */ + + + setEngineTorque(torque) { + this.setParameter(GetVehicleData.KEY_ENGINE_TORQUE, torque); + return this; + } + /** + * @return {Boolean} + */ + + + getEngineTorque() { + return this.getParameter(GetVehicleData.KEY_ENGINE_TORQUE); + } + /** + * @param {Boolean} position - Accelerator pedal position (percentage depressed) + * @return {GetVehicleData} + */ + + + setAccPedalPosition(position) { + this.setParameter(GetVehicleData.KEY_ACC_PEDAL_POSITION, position); + return this; + } + /** + * @return {Boolean} + */ + + + getAccPedalPosition() { + return this.getParameter(GetVehicleData.KEY_ACC_PEDAL_POSITION); + } + /** + * @param {Boolean} angle - Current angle of the steering wheel (in deg) + * @return {GetVehicleData} + */ + + + setSteeringWheelAngle(angle) { + this.setParameter(GetVehicleData.KEY_STEERING_WHEEL_ANGLE, angle); + return this; + } + /** + * @return {Boolean} + */ + + + getSteeringWheelAngle() { + return this.getParameter(GetVehicleData.KEY_STEERING_WHEEL_ANGLE); + } + /** + * @param {Boolean} life - The estimated percentage of remaining oil life of the engine. + * @return {GetVehicleData} + */ + + + setEngineOilLife(life) { + this.setParameter(GetVehicleData.KEY_ENGINE_OIL_LIFE, life); + return this; + } + /** + * @return {Boolean} + */ + + + getEngineOilLife() { + return this.getParameter(GetVehicleData.KEY_ENGINE_OIL_LIFE); + } + /** + * @param {Boolean} status - The status of the park brake as provided by Electric Park Brake (EPB) system. + * @return {GetVehicleData} + */ + + + setElectronicParkBrakeStatus(status) { + this.setParameter(GetVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS, status); + return this; + } + /** + * @return {Boolean} + */ + + + getElectronicParkBrakeStatus() { + return this.getParameter(GetVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS); + } + /** + * @param {Boolean} id - Parameter used by cloud apps to identify a head unit + * @return {GetVehicleData} + */ + + + setCloudAppVehicleID(id) { + this.setParameter(GetVehicleData.KEY_CLOUD_APP_VEHICLE_ID, id); + return this; + } + /** + * @return {Boolean} + */ + + + getCloudAppVehicleID() { + return this.getParameter(GetVehicleData.KEY_CLOUD_APP_VEHICLE_ID); + } + /** + * @param {Boolean} info - Emergency Call notification and confirmation data + * @return {GetVehicleData} + */ + + + setECallInfo(info) { + this.setParameter(GetVehicleData.KEY_E_CALL_INFO, info); + return this; + } + /** + * @return {Boolean} + */ + + + getECallInfo() { + return this.getParameter(GetVehicleData.KEY_E_CALL_INFO); + } + /** + * @param {Boolean} status - The status of the air bags + * @return {GetVehicleData} + */ + + + setAirbagStatus(status) { + this.setParameter(GetVehicleData.KEY_AIRBAG_STATUS, status); + return this; + } + /** + * @return {Boolean} + */ + + + getAirbagStatus() { + return this.getParameter(GetVehicleData.KEY_AIRBAG_STATUS); + } + /** + * @param {Boolean} event - Information related to an emergency event (and if it occurred) + * @return {GetVehicleData} + */ + + + setEmergencyEvent(event) { + this.setParameter(GetVehicleData.KEY_EMERGENCY_EVENT, event); + return this; + } + /** + * @return {Boolean} + */ + + + getEmergencyEvent() { + return this.getParameter(GetVehicleData.KEY_EMERGENCY_EVENT); + } + /** + * @param {Boolean} status - The status modes of the cluster + * @return {GetVehicleData} + */ + + + setClusterModeStatus(status) { + this.setParameter(GetVehicleData.KEY_CLUSTER_MODE_STATUS, status); + return this; + } + /** + * @return {Boolean} + */ + + + getClusterModeStatus() { + return this.getParameter(GetVehicleData.KEY_CLUSTER_MODE_STATUS); + } + /** + * @param {Boolean} key - Information related to the MyKey feature + * @return {GetVehicleData} + */ + + + setMyKey(key) { + this.setParameter(GetVehicleData.KEY_MY_KEY, key); + return this; + } + /** + * @return {Boolean} + */ + + + getMyKey() { + return this.getParameter(GetVehicleData.KEY_MY_KEY); + } + + } + + GetVehicleData.KEY_GPS = 'gps'; + GetVehicleData.KEY_SPEED = 'speed'; + GetVehicleData.KEY_RPM = 'rpm'; + GetVehicleData.KEY_FUEL_LEVEL = 'fuelLevel'; + GetVehicleData.KEY_FUEL_LEVEL_STATE = 'fuelLevel_State'; + GetVehicleData.KEY_INSTANT_FUEL_CONSUMPTION = 'instantFuelConsumption'; + GetVehicleData.KEY_FUEL_RANGE = 'fuelRange'; + GetVehicleData.KEY_EXTERNAL_TEMPERATURE = 'externalTemperature'; + GetVehicleData.KEY_TURN_SIGNAL = 'turnSignal'; + GetVehicleData.KEY_VIN = 'vin'; + GetVehicleData.KEY_PRNDL = 'prndl'; + GetVehicleData.KEY_TIRE_PRESSURE = 'tirePressure'; + GetVehicleData.KEY_ODOMETER = 'odometer'; + GetVehicleData.KEY_BELT_STATUS = 'beltStatus'; + GetVehicleData.KEY_BODY_INFORMATION = 'bodyInformation'; + GetVehicleData.KEY_DEVICE_STATUS = 'deviceStatus'; + GetVehicleData.KEY_DRIVER_BRAKING = 'driverBraking'; + GetVehicleData.KEY_WIPER_STATUS = 'wiperStatus'; + GetVehicleData.KEY_HEAD_LAMP_STATUS = 'headLampStatus'; + GetVehicleData.KEY_ENGINE_TORQUE = 'engineTorque'; + GetVehicleData.KEY_ACC_PEDAL_POSITION = 'accPedalPosition'; + GetVehicleData.KEY_STEERING_WHEEL_ANGLE = 'steeringWheelAngle'; + GetVehicleData.KEY_ENGINE_OIL_LIFE = 'engineOilLife'; + GetVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS = 'electronicParkBrakeStatus'; + GetVehicleData.KEY_CLOUD_APP_VEHICLE_ID = 'cloudAppVehicleID'; + GetVehicleData.KEY_E_CALL_INFO = 'eCallInfo'; + GetVehicleData.KEY_AIRBAG_STATUS = 'airbagStatus'; + GetVehicleData.KEY_EMERGENCY_EVENT = 'emergencyEvent'; + GetVehicleData.KEY_CLUSTER_MODE_STATUS = 'clusterModeStatus'; + GetVehicleData.KEY_MY_KEY = 'myKey'; + + /* eslint-disable camelcase */ + /** + * Reflects the status of a vehicle data event; e.g. a seat belt event status. + * @typedef {Enum} VehicleDataEventStatus + * @property {Object} _MAP + */ + + class VehicleDataEventStatus extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get VDES_NO_EVENT() { + return VehicleDataEventStatus._MAP.VDES_NO_EVENT; + } + /** + * @return {String} + */ + + + static get VDES_NO() { + return VehicleDataEventStatus._MAP.VDES_NO; + } + /** + * @return {String} + */ + + + static get VDES_YES() { + return VehicleDataEventStatus._MAP.VDES_YES; + } + /** + * @return {String} + */ + + + static get VDES_NOT_SUPPORTED() { + return VehicleDataEventStatus._MAP.VDES_NOT_SUPPORTED; + } + /** + * @return {String} + */ + + + static get VDES_FAULT() { + return VehicleDataEventStatus._MAP.VDES_FAULT; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return VehicleDataEventStatus._valueForKey(key, VehicleDataEventStatus._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return VehicleDataEventStatus._keyForValue(value, VehicleDataEventStatus._MAP); + } + + } + + VehicleDataEventStatus._MAP = Object.freeze({ + 'VDES_NO_EVENT': 'NO_EVENT', + 'VDES_NO': 'NO', + 'VDES_YES': 'YES', + 'VDES_NOT_SUPPORTED': 'NOT_SUPPORTED', + 'VDES_FAULT': 'FAULT' + }); + + /* eslint-disable camelcase */ + + class AirbagStatus extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsDrvBag_D_Ltchd". See VehicleDataEventStatus. + * @return {AirbagStatus} + */ + + + setDriverAirbagDeployed(deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(AirbagStatus.KEY_DRIVER_AIRBAG_DEPLOYED, deployed); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getDriverAirbagDeployed() { + return this.getObject(VehicleDataEventStatus, AirbagStatus.KEY_DRIVER_AIRBAG_DEPLOYED); + } + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsDrvSideBag_D_Ltchd". See + * VehicleDataEventStatus. + * @return {AirbagStatus} + */ + + + setDriverSideAirbagDeployed(deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(AirbagStatus.KEY_DRIVER_SIDE_AIRBAG_DEPLOYED, deployed); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getDriverSideAirbagDeployed() { + return this.getObject(VehicleDataEventStatus, AirbagStatus.KEY_DRIVER_SIDE_AIRBAG_DEPLOYED); + } + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsDrvCrtnBag_D_Ltchd". See + * VehicleDataEventStatus. + * @return {AirbagStatus} + */ + + + setDriverCurtainAirbagDeployed(deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(AirbagStatus.KEY_DRIVER_CURTAIN_AIRBAG_DEPLOYED, deployed); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getDriverCurtainAirbagDeployed() { + return this.getObject(VehicleDataEventStatus, AirbagStatus.KEY_DRIVER_CURTAIN_AIRBAG_DEPLOYED); + } + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsPasBag_D_Ltchd". See VehicleDataEventStatus. + * @return {AirbagStatus} + */ + + + setPassengerAirbagDeployed(deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(AirbagStatus.KEY_PASSENGER_AIRBAG_DEPLOYED, deployed); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getPassengerAirbagDeployed() { + return this.getObject(VehicleDataEventStatus, AirbagStatus.KEY_PASSENGER_AIRBAG_DEPLOYED); + } + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsPasCrtnBag_D_Ltchd". See + * VehicleDataEventStatus. + * @return {AirbagStatus} + */ + + + setPassengerCurtainAirbagDeployed(deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(AirbagStatus.KEY_PASSENGER_CURTAIN_AIRBAG_DEPLOYED, deployed); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getPassengerCurtainAirbagDeployed() { + return this.getObject(VehicleDataEventStatus, AirbagStatus.KEY_PASSENGER_CURTAIN_AIRBAG_DEPLOYED); + } + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsKneeDrvBag_D_Ltchd". See + * VehicleDataEventStatus. + * @return {AirbagStatus} + */ + + + setDriverKneeAirbagDeployed(deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(AirbagStatus.KEY_DRIVER_KNEE_AIRBAG_DEPLOYED, deployed); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getDriverKneeAirbagDeployed() { + return this.getObject(VehicleDataEventStatus, AirbagStatus.KEY_DRIVER_KNEE_AIRBAG_DEPLOYED); + } + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsPasSideBag_D_Ltchd". See + * VehicleDataEventStatus. + * @return {AirbagStatus} + */ + + + setPassengerSideAirbagDeployed(deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(AirbagStatus.KEY_PASSENGER_SIDE_AIRBAG_DEPLOYED, deployed); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getPassengerSideAirbagDeployed() { + return this.getObject(VehicleDataEventStatus, AirbagStatus.KEY_PASSENGER_SIDE_AIRBAG_DEPLOYED); + } + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsKneePasBag_D_Ltchd". See + * VehicleDataEventStatus. + * @return {AirbagStatus} + */ + + + setPassengerKneeAirbagDeployed(deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(AirbagStatus.KEY_PASSENGER_KNEE_AIRBAG_DEPLOYED, deployed); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getPassengerKneeAirbagDeployed() { + return this.getObject(VehicleDataEventStatus, AirbagStatus.KEY_PASSENGER_KNEE_AIRBAG_DEPLOYED); + } + + } + + AirbagStatus.KEY_DRIVER_AIRBAG_DEPLOYED = 'driverAirbagDeployed'; + AirbagStatus.KEY_DRIVER_SIDE_AIRBAG_DEPLOYED = 'driverSideAirbagDeployed'; + AirbagStatus.KEY_DRIVER_CURTAIN_AIRBAG_DEPLOYED = 'driverCurtainAirbagDeployed'; + AirbagStatus.KEY_PASSENGER_AIRBAG_DEPLOYED = 'passengerAirbagDeployed'; + AirbagStatus.KEY_PASSENGER_CURTAIN_AIRBAG_DEPLOYED = 'passengerCurtainAirbagDeployed'; + AirbagStatus.KEY_DRIVER_KNEE_AIRBAG_DEPLOYED = 'driverKneeAirbagDeployed'; + AirbagStatus.KEY_PASSENGER_SIDE_AIRBAG_DEPLOYED = 'passengerSideAirbagDeployed'; + AirbagStatus.KEY_PASSENGER_KNEE_AIRBAG_DEPLOYED = 'passengerKneeAirbagDeployed'; + + /* eslint-disable camelcase */ + /** + * Reflects the status of the current power mode. + * @typedef {Enum} PowerModeStatus + * @property {Object} _MAP + */ + + class PowerModeStatus extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get KEY_OUT() { + return PowerModeStatus._MAP.KEY_OUT; + } + /** + * @return {String} + */ + + + static get KEY_RECENTLY_OUT() { + return PowerModeStatus._MAP.KEY_RECENTLY_OUT; + } + /** + * @return {String} + */ + + + static get KEY_APPROVED_0() { + return PowerModeStatus._MAP.KEY_APPROVED_0; + } + /** + * @return {String} + */ + + + static get POST_ACCESORY_0() { + return PowerModeStatus._MAP.POST_ACCESORY_0; + } + /** + * @return {String} + */ + + + static get ACCESORY_1() { + return PowerModeStatus._MAP.ACCESORY_1; + } + /** + * @return {String} + */ + + + static get POST_IGNITION_1() { + return PowerModeStatus._MAP.POST_IGNITION_1; + } + /** + * @return {String} + */ + + + static get IGNITION_ON_2() { + return PowerModeStatus._MAP.IGNITION_ON_2; + } + /** + * @return {String} + */ + + + static get RUNNING_2() { + return PowerModeStatus._MAP.RUNNING_2; + } + /** + * @return {String} + */ + + + static get CRANK_3() { + return PowerModeStatus._MAP.CRANK_3; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return PowerModeStatus._valueForKey(key, PowerModeStatus._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return PowerModeStatus._keyForValue(value, PowerModeStatus._MAP); + } + + } + + PowerModeStatus._MAP = Object.freeze({ + 'KEY_OUT': 'KEY_OUT', + 'KEY_RECENTLY_OUT': 'KEY_RECENTLY_OUT', + 'KEY_APPROVED_0': 'KEY_APPROVED_0', + 'POST_ACCESORY_0': 'POST_ACCESORY_0', + 'ACCESORY_1': 'ACCESORY_1', + 'POST_IGNITION_1': 'POST_IGNITION_1', + 'IGNITION_ON_2': 'IGNITION_ON_2', + 'RUNNING_2': 'RUNNING_2', + 'CRANK_3': 'CRANK_3' + }); + + /* eslint-disable camelcase */ + /** + * Reflects the status of the current car mode. + * @typedef {Enum} CarModeStatus + * @property {Object} _MAP + */ + + class CarModeStatus extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get CMS_NORMAL() { + return CarModeStatus._MAP.CMS_NORMAL; + } + /** + * @return {String} + */ + + + static get CMS_FACTORY() { + return CarModeStatus._MAP.CMS_FACTORY; + } + /** + * @return {String} + */ + + + static get CMS_TRANSPORT() { + return CarModeStatus._MAP.CMS_TRANSPORT; + } + /** + * @return {String} + */ + + + static get CMS_CRASH() { + return CarModeStatus._MAP.CMS_CRASH; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return CarModeStatus._valueForKey(key, CarModeStatus._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return CarModeStatus._keyForValue(value, CarModeStatus._MAP); + } + + } + + CarModeStatus._MAP = Object.freeze({ + 'CMS_NORMAL': 'NORMAL', + 'CMS_FACTORY': 'FACTORY', + 'CMS_TRANSPORT': 'TRANSPORT', + 'CMS_CRASH': 'CRASH' + }); + + /* eslint-disable camelcase */ + /** + * Reflects the status of the current power mode qualification. + * @typedef {Enum} PowerModeQualificationStatus + * @property {Object} _MAP + */ + + class PowerModeQualificationStatus extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get POWER_MODE_UNDEFINED() { + return PowerModeQualificationStatus._MAP.POWER_MODE_UNDEFINED; + } + /** + * @return {String} + */ + + + static get POWER_MODE_EVALUATION_IN_PROGRESS() { + return PowerModeQualificationStatus._MAP.POWER_MODE_EVALUATION_IN_PROGRESS; + } + /** + * @return {String} + */ + + + static get NOT_DEFINED() { + return PowerModeQualificationStatus._MAP.NOT_DEFINED; + } + /** + * @return {String} + */ + + + static get POWER_MODE_OK() { + return PowerModeQualificationStatus._MAP.POWER_MODE_OK; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return PowerModeQualificationStatus._valueForKey(key, PowerModeQualificationStatus._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return PowerModeQualificationStatus._keyForValue(value, PowerModeQualificationStatus._MAP); + } + + } + + PowerModeQualificationStatus._MAP = Object.freeze({ + 'POWER_MODE_UNDEFINED': 'POWER_MODE_UNDEFINED', + 'POWER_MODE_EVALUATION_IN_PROGRESS': 'POWER_MODE_EVALUATION_IN_PROGRESS', + 'NOT_DEFINED': 'NOT_DEFINED', + 'POWER_MODE_OK': 'POWER_MODE_OK' + }); + + /* eslint-disable camelcase */ + + class ClusterModeStatus extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Boolean} active - References signal "PowerMode_UB". + * @return {ClusterModeStatus} + */ + + + setPowerModeActive(active) { + this.setParameter(ClusterModeStatus.KEY_POWER_MODE_ACTIVE, active); + return this; + } + /** + * @return {Boolean} + */ + + + getPowerModeActive() { + return this.getParameter(ClusterModeStatus.KEY_POWER_MODE_ACTIVE); + } + /** + * @param {PowerModeQualificationStatus} status - References signal "PowerModeQF". See PowerModeQualificationStatus. + * @return {ClusterModeStatus} + */ + + + setPowerModeQualificationStatus(status) { + this.validateType(PowerModeQualificationStatus, status); + this.setParameter(ClusterModeStatus.KEY_POWER_MODE_QUALIFICATION_STATUS, status); + return this; + } + /** + * @return {PowerModeQualificationStatus} + */ + + + getPowerModeQualificationStatus() { + return this.getObject(PowerModeQualificationStatus, ClusterModeStatus.KEY_POWER_MODE_QUALIFICATION_STATUS); + } + /** + * @param {CarModeStatus} status - References signal "CarMode". See CarMode. + * @return {ClusterModeStatus} + */ + + + setCarModeStatus(status) { + this.validateType(CarModeStatus, status); + this.setParameter(ClusterModeStatus.KEY_CAR_MODE_STATUS, status); + return this; + } + /** + * @return {CarModeStatus} + */ + + + getCarModeStatus() { + return this.getObject(CarModeStatus, ClusterModeStatus.KEY_CAR_MODE_STATUS); + } + /** + * @param {PowerModeStatus} status - References signal "PowerMode". See PowerMode. + * @return {ClusterModeStatus} + */ + + + setPowerModeStatus(status) { + this.validateType(PowerModeStatus, status); + this.setParameter(ClusterModeStatus.KEY_POWER_MODE_STATUS, status); + return this; + } + /** + * @return {PowerModeStatus} + */ + + + getPowerModeStatus() { + return this.getObject(PowerModeStatus, ClusterModeStatus.KEY_POWER_MODE_STATUS); + } + + } + + ClusterModeStatus.KEY_POWER_MODE_ACTIVE = 'powerModeActive'; + ClusterModeStatus.KEY_POWER_MODE_QUALIFICATION_STATUS = 'powerModeQualificationStatus'; + ClusterModeStatus.KEY_CAR_MODE_STATUS = 'carModeStatus'; + ClusterModeStatus.KEY_POWER_MODE_STATUS = 'powerModeStatus'; + + /* eslint-disable camelcase */ + /** + * Reflects the status of the RCM fuel cutoff. + * @typedef {Enum} FuelCutoffStatus + * @property {Object} _MAP + */ + + class FuelCutoffStatus extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get FCS_TERMINATE_FUEL() { + return FuelCutoffStatus._MAP.FCS_TERMINATE_FUEL; + } + /** + * @return {String} + */ + + + static get FCS_NORMAL_OPERATION() { + return FuelCutoffStatus._MAP.FCS_NORMAL_OPERATION; + } + /** + * @return {String} + */ + + + static get FCS_FAULT() { + return FuelCutoffStatus._MAP.FCS_FAULT; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return FuelCutoffStatus._valueForKey(key, FuelCutoffStatus._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return FuelCutoffStatus._keyForValue(value, FuelCutoffStatus._MAP); + } + + } + + FuelCutoffStatus._MAP = Object.freeze({ + 'FCS_TERMINATE_FUEL': 'TERMINATE_FUEL', + 'FCS_NORMAL_OPERATION': 'NORMAL_OPERATION', + 'FCS_FAULT': 'FAULT' + }); + + /* eslint-disable camelcase */ + /** + * Reflects the emergency event status of the vehicle. + * @typedef {Enum} EmergencyEventType + * @property {Object} _MAP + */ + + class EmergencyEventType extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get EET_NO_EVENT() { + return EmergencyEventType._MAP.EET_NO_EVENT; + } + /** + * @return {String} + */ + + + static get EET_FRONTAL() { + return EmergencyEventType._MAP.EET_FRONTAL; + } + /** + * @return {String} + */ + + + static get EET_SIDE() { + return EmergencyEventType._MAP.EET_SIDE; + } + /** + * @return {String} + */ + + + static get EET_REAR() { + return EmergencyEventType._MAP.EET_REAR; + } + /** + * @return {String} + */ + + + static get EET_ROLLOVER() { + return EmergencyEventType._MAP.EET_ROLLOVER; + } + /** + * @return {String} + */ + + + static get EET_NOT_SUPPORTED() { + return EmergencyEventType._MAP.EET_NOT_SUPPORTED; + } + /** + * @return {String} + */ + + + static get EET_FAULT() { + return EmergencyEventType._MAP.EET_FAULT; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return EmergencyEventType._valueForKey(key, EmergencyEventType._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return EmergencyEventType._keyForValue(value, EmergencyEventType._MAP); + } + + } + + EmergencyEventType._MAP = Object.freeze({ + 'EET_NO_EVENT': 'NO_EVENT', + 'EET_FRONTAL': 'FRONTAL', + 'EET_SIDE': 'SIDE', + 'EET_REAR': 'REAR', + 'EET_ROLLOVER': 'ROLLOVER', + 'EET_NOT_SUPPORTED': 'NOT_SUPPORTED', + 'EET_FAULT': 'FAULT' + }); + + /* eslint-disable camelcase */ + + class EmergencyEvent extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {EmergencyEventType} type - References signal "VedsEvntType_D_Ltchd". See EmergencyEventType. + * @return {EmergencyEvent} + */ + + + setEmergencyEventType(type) { + this.validateType(EmergencyEventType, type); + this.setParameter(EmergencyEvent.KEY_EMERGENCY_EVENT_TYPE, type); + return this; + } + /** + * @return {EmergencyEventType} + */ + + + getEmergencyEventType() { + return this.getObject(EmergencyEventType, EmergencyEvent.KEY_EMERGENCY_EVENT_TYPE); + } + /** + * @param {FuelCutoffStatus} status - References signal "RCM_FuelCutoff". See FuelCutoffStatus. + * @return {EmergencyEvent} + */ + + + setFuelCutoffStatus(status) { + this.validateType(FuelCutoffStatus, status); + this.setParameter(EmergencyEvent.KEY_FUEL_CUTOFF_STATUS, status); + return this; + } + /** + * @return {FuelCutoffStatus} + */ + + + getFuelCutoffStatus() { + return this.getObject(FuelCutoffStatus, EmergencyEvent.KEY_FUEL_CUTOFF_STATUS); + } + /** + * @param {VehicleDataEventStatus} event - References signal "VedsEvntRoll_D_Ltchd". See VehicleDataEventStatus. + * @return {EmergencyEvent} + */ + + + setRolloverEvent(event) { + this.validateType(VehicleDataEventStatus, event); + this.setParameter(EmergencyEvent.KEY_ROLLOVER_EVENT, event); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getRolloverEvent() { + return this.getObject(VehicleDataEventStatus, EmergencyEvent.KEY_ROLLOVER_EVENT); + } + /** + * @param {Number} velocity - References signal "VedsMaxDeltaV_D_Ltchd". Change in velocity in KPH. Additional + * reserved values: 0x00 No event 0xFE Not supported 0xFF Fault + * @return {EmergencyEvent} + */ + + + setMaximumChangeVelocity(velocity) { + this.setParameter(EmergencyEvent.KEY_MAXIMUM_CHANGE_VELOCITY, velocity); + return this; + } + /** + * @return {Number} + */ + + + getMaximumChangeVelocity() { + return this.getParameter(EmergencyEvent.KEY_MAXIMUM_CHANGE_VELOCITY); + } + /** + * @param {VehicleDataEventStatus} events - References signal "VedsMultiEvnt_D_Ltchd". See VehicleDataEventStatus. + * @return {EmergencyEvent} + */ + + + setMultipleEvents(events) { + this.validateType(VehicleDataEventStatus, events); + this.setParameter(EmergencyEvent.KEY_MULTIPLE_EVENTS, events); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getMultipleEvents() { + return this.getObject(VehicleDataEventStatus, EmergencyEvent.KEY_MULTIPLE_EVENTS); + } + + } + + EmergencyEvent.KEY_EMERGENCY_EVENT_TYPE = 'emergencyEventType'; + EmergencyEvent.KEY_FUEL_CUTOFF_STATUS = 'fuelCutoffStatus'; + EmergencyEvent.KEY_ROLLOVER_EVENT = 'rolloverEvent'; + EmergencyEvent.KEY_MAXIMUM_CHANGE_VELOCITY = 'maximumChangeVelocity'; + EmergencyEvent.KEY_MULTIPLE_EVENTS = 'multipleEvents'; + + /* eslint-disable camelcase */ + /** + * Enumeration that describes the status of the turn light indicator. + * @typedef {Enum} TurnSignal + * @property {Object} _MAP + */ + + class TurnSignal extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * Turn signal is OFF + * @return {String} + */ + + + static get OFF() { + return TurnSignal._MAP.OFF; + } + /** + * Left turn signal is on + * @return {String} + */ + + + static get LEFT() { + return TurnSignal._MAP.LEFT; + } + /** + * Right turn signal is on + * @return {String} + */ + + + static get RIGHT() { + return TurnSignal._MAP.RIGHT; + } + /** + * Both signals (left and right) are on. + * @return {String} + */ + + + static get BOTH() { + return TurnSignal._MAP.BOTH; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return TurnSignal._valueForKey(key, TurnSignal._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return TurnSignal._keyForValue(value, TurnSignal._MAP); + } + + } + + TurnSignal._MAP = Object.freeze({ + 'OFF': 'OFF', + 'LEFT': 'LEFT', + 'RIGHT': 'RIGHT', + 'BOTH': 'BOTH' + }); + + /* eslint-disable camelcase */ + /** + * Reflects the status of the ambient light sensor. + * @typedef {Enum} AmbientLightStatus + * @property {Object} _MAP + */ + + class AmbientLightStatus extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get NIGHT() { + return AmbientLightStatus._MAP.NIGHT; + } + /** + * @return {String} + */ + + + static get TWILIGHT_1() { + return AmbientLightStatus._MAP.TWILIGHT_1; + } + /** + * @return {String} + */ + + + static get TWILIGHT_2() { + return AmbientLightStatus._MAP.TWILIGHT_2; + } + /** + * @return {String} + */ + + + static get TWILIGHT_3() { + return AmbientLightStatus._MAP.TWILIGHT_3; + } + /** + * @return {String} + */ + + + static get TWILIGHT_4() { + return AmbientLightStatus._MAP.TWILIGHT_4; + } + /** + * @return {String} + */ + + + static get DAY() { + return AmbientLightStatus._MAP.DAY; + } + /** + * @return {String} + */ + + + static get ALS_UNKNOWN() { + return AmbientLightStatus._MAP.ALS_UNKNOWN; + } + /** + * @return {String} + */ + + + static get INVALID() { + return AmbientLightStatus._MAP.INVALID; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return AmbientLightStatus._valueForKey(key, AmbientLightStatus._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return AmbientLightStatus._keyForValue(value, AmbientLightStatus._MAP); + } + + } + + AmbientLightStatus._MAP = Object.freeze({ + 'NIGHT': 'NIGHT', + 'TWILIGHT_1': 'TWILIGHT_1', + 'TWILIGHT_2': 'TWILIGHT_2', + 'TWILIGHT_3': 'TWILIGHT_3', + 'TWILIGHT_4': 'TWILIGHT_4', + 'DAY': 'DAY', + 'ALS_UNKNOWN': 'UNKNOWN', + 'INVALID': 'INVALID' + }); + + /* eslint-disable camelcase */ + + class HeadLampStatus extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Boolean} on - Status of the low beam lamps. References signal "HeadLampLoActv_B_Stat". + * @return {HeadLampStatus} + */ + + + setLowBeamsOn(on) { + this.setParameter(HeadLampStatus.KEY_LOW_BEAMS_ON, on); + return this; + } + /** + * @return {Boolean} + */ + + + getLowBeamsOn() { + return this.getParameter(HeadLampStatus.KEY_LOW_BEAMS_ON); + } + /** + * @param {Boolean} on - Status of the high beam lamps. References signal "HeadLghtHiOn_B_Stat". + * @return {HeadLampStatus} + */ + + + setHighBeamsOn(on) { + this.setParameter(HeadLampStatus.KEY_HIGH_BEAMS_ON, on); + return this; + } + /** + * @return {Boolean} + */ + + + getHighBeamsOn() { + return this.getParameter(HeadLampStatus.KEY_HIGH_BEAMS_ON); + } + /** + * @param {AmbientLightStatus} status - Status of the ambient light sensor. + * @return {HeadLampStatus} + */ + + + setAmbientLightSensorStatus(status) { + this.validateType(AmbientLightStatus, status); + this.setParameter(HeadLampStatus.KEY_AMBIENT_LIGHT_SENSOR_STATUS, status); + return this; + } + /** + * @return {AmbientLightStatus} + */ + + + getAmbientLightSensorStatus() { + return this.getObject(AmbientLightStatus, HeadLampStatus.KEY_AMBIENT_LIGHT_SENSOR_STATUS); + } + + } + + HeadLampStatus.KEY_LOW_BEAMS_ON = 'lowBeamsOn'; + HeadLampStatus.KEY_HIGH_BEAMS_ON = 'highBeamsOn'; + HeadLampStatus.KEY_AMBIENT_LIGHT_SENSOR_STATUS = 'ambientLightSensorStatus'; + + /* eslint-disable camelcase */ + /** + * Reflects the current primary audio source (if selected). + * @typedef {Enum} PrimaryAudioSource + * @property {Object} _MAP + */ + + class PrimaryAudioSource extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get NO_SOURCE_SELECTED() { + return PrimaryAudioSource._MAP.NO_SOURCE_SELECTED; + } + /** + * @return {String} + */ + + + static get CD() { + return PrimaryAudioSource._MAP.CD; + } + /** + * @return {String} + */ + + + static get USB() { + return PrimaryAudioSource._MAP.USB; + } + /** + * @return {String} + */ + + + static get USB2() { + return PrimaryAudioSource._MAP.USB2; + } + /** + * @return {String} + */ + + + static get BLUETOOTH_STEREO_BTST() { + return PrimaryAudioSource._MAP.BLUETOOTH_STEREO_BTST; + } + /** + * @return {String} + */ + + + static get LINE_IN() { + return PrimaryAudioSource._MAP.LINE_IN; + } + /** + * @return {String} + */ + + + static get IPOD() { + return PrimaryAudioSource._MAP.IPOD; + } + /** + * @return {String} + */ + + + static get MOBILE_APP() { + return PrimaryAudioSource._MAP.MOBILE_APP; + } + /** + * @return {String} + */ + + + static get AM() { + return PrimaryAudioSource._MAP.AM; + } + /** + * @return {String} + */ + + + static get FM() { + return PrimaryAudioSource._MAP.FM; + } + /** + * @return {String} + */ + + + static get XM() { + return PrimaryAudioSource._MAP.XM; + } + /** + * @return {String} + */ + + + static get DAB() { + return PrimaryAudioSource._MAP.DAB; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return PrimaryAudioSource._valueForKey(key, PrimaryAudioSource._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return PrimaryAudioSource._keyForValue(value, PrimaryAudioSource._MAP); + } + + } + + PrimaryAudioSource._MAP = Object.freeze({ + 'NO_SOURCE_SELECTED': 'NO_SOURCE_SELECTED', + 'CD': 'CD', + 'USB': 'USB', + 'USB2': 'USB2', + 'BLUETOOTH_STEREO_BTST': 'BLUETOOTH_STEREO_BTST', + 'LINE_IN': 'LINE_IN', + 'IPOD': 'IPOD', + 'MOBILE_APP': 'MOBILE_APP', + 'AM': 'AM', + 'FM': 'FM', + 'XM': 'XM', + 'DAB': 'DAB' + }); + + /* eslint-disable camelcase */ + /** + * Reflects the reported battery status of the connected device, if reported. + * @typedef {Enum} DeviceLevelStatus + * @property {Object} _MAP + */ + + class DeviceLevelStatus extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get ZERO_LEVEL_BARS() { + return DeviceLevelStatus._MAP.ZERO_LEVEL_BARS; + } + /** + * @return {String} + */ + + + static get ONE_LEVEL_BARS() { + return DeviceLevelStatus._MAP.ONE_LEVEL_BARS; + } + /** + * @return {String} + */ + + + static get TWO_LEVEL_BARS() { + return DeviceLevelStatus._MAP.TWO_LEVEL_BARS; + } + /** + * @return {String} + */ + + + static get THREE_LEVEL_BARS() { + return DeviceLevelStatus._MAP.THREE_LEVEL_BARS; + } + /** + * @return {String} + */ + + + static get FOUR_LEVEL_BARS() { + return DeviceLevelStatus._MAP.FOUR_LEVEL_BARS; + } + /** + * @return {String} + */ + + + static get NOT_PROVIDED() { + return DeviceLevelStatus._MAP.NOT_PROVIDED; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return DeviceLevelStatus._valueForKey(key, DeviceLevelStatus._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return DeviceLevelStatus._keyForValue(value, DeviceLevelStatus._MAP); + } + + } + + DeviceLevelStatus._MAP = Object.freeze({ + 'ZERO_LEVEL_BARS': 'ZERO_LEVEL_BARS', + 'ONE_LEVEL_BARS': 'ONE_LEVEL_BARS', + 'TWO_LEVEL_BARS': 'TWO_LEVEL_BARS', + 'THREE_LEVEL_BARS': 'THREE_LEVEL_BARS', + 'FOUR_LEVEL_BARS': 'FOUR_LEVEL_BARS', + 'NOT_PROVIDED': 'NOT_PROVIDED' + }); + + /* eslint-disable camelcase */ + + class DeviceStatus extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Boolean} on - References signal "CPM_VoiceRec_STAT". + * @return {DeviceStatus} + */ + + + setVoiceRecOn(on) { + this.setParameter(DeviceStatus.KEY_VOICE_REC_ON, on); + return this; + } + /** + * @return {Boolean} + */ + + + getVoiceRecOn() { + return this.getParameter(DeviceStatus.KEY_VOICE_REC_ON); + } + /** + * @param {Boolean} on - References signal "BT_ICON". + * @return {DeviceStatus} + */ + + + setBtIconOn(on) { + this.setParameter(DeviceStatus.KEY_BT_ICON_ON, on); + return this; + } + /** + * @return {Boolean} + */ + + + getBtIconOn() { + return this.getParameter(DeviceStatus.KEY_BT_ICON_ON); + } + /** + * @param {Boolean} active - References signal "CPM_Call_Active_STAT". + * @return {DeviceStatus} + */ + + + setCallActive(active) { + this.setParameter(DeviceStatus.KEY_CALL_ACTIVE, active); + return this; + } + /** + * @return {Boolean} + */ + + + getCallActive() { + return this.getParameter(DeviceStatus.KEY_CALL_ACTIVE); + } + /** + * @param {Boolean} roaming - References signal "CPM_Phone_Roaming_STAT". + * @return {DeviceStatus} + */ + + + setPhoneRoaming(roaming) { + this.setParameter(DeviceStatus.KEY_PHONE_ROAMING, roaming); + return this; + } + /** + * @return {Boolean} + */ + + + getPhoneRoaming() { + return this.getParameter(DeviceStatus.KEY_PHONE_ROAMING); + } + /** + * @param {Boolean} available - References signal "CPM_TextMsg_AVAL". + * @return {DeviceStatus} + */ + + + setTextMsgAvailable(available) { + this.setParameter(DeviceStatus.KEY_TEXT_MSG_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getTextMsgAvailable() { + return this.getParameter(DeviceStatus.KEY_TEXT_MSG_AVAILABLE); + } + /** + * @param {DeviceLevelStatus} status - Device battery level status. References signal "CPM_Batt_Level_STAT". See + * DeviceLevelStatus. + * @return {DeviceStatus} + */ + + + setBattLevelStatus(status) { + this.validateType(DeviceLevelStatus, status); + this.setParameter(DeviceStatus.KEY_BATT_LEVEL_STATUS, status); + return this; + } + /** + * @return {DeviceLevelStatus} + */ + + + getBattLevelStatus() { + return this.getObject(DeviceLevelStatus, DeviceStatus.KEY_BATT_LEVEL_STATUS); + } + /** + * @param {Boolean} muted - References signal "CPM_Stereo_Audio_Output". + * @return {DeviceStatus} + */ + + + setStereoAudioOutputMuted(muted) { + this.setParameter(DeviceStatus.KEY_STEREO_AUDIO_OUTPUT_MUTED, muted); + return this; + } + /** + * @return {Boolean} + */ + + + getStereoAudioOutputMuted() { + return this.getParameter(DeviceStatus.KEY_STEREO_AUDIO_OUTPUT_MUTED); + } + /** + * @param {Boolean} muted - References signal "CPM_Mono_Audio_Output". + * @return {DeviceStatus} + */ + + + setMonoAudioOutputMuted(muted) { + this.setParameter(DeviceStatus.KEY_MONO_AUDIO_OUTPUT_MUTED, muted); + return this; + } + /** + * @return {Boolean} + */ + + + getMonoAudioOutputMuted() { + return this.getParameter(DeviceStatus.KEY_MONO_AUDIO_OUTPUT_MUTED); + } + /** + * @param {DeviceLevelStatus} status - Device signal level status. References signal "CPM_Signal_Strength_STAT". See + * DeviceLevelStatus. + * @return {DeviceStatus} + */ + + + setSignalLevelStatus(status) { + this.validateType(DeviceLevelStatus, status); + this.setParameter(DeviceStatus.KEY_SIGNAL_LEVEL_STATUS, status); + return this; + } + /** + * @return {DeviceLevelStatus} + */ + + + getSignalLevelStatus() { + return this.getObject(DeviceLevelStatus, DeviceStatus.KEY_SIGNAL_LEVEL_STATUS); + } + /** + * @param {PrimaryAudioSource} source - References signal "CPM_Stereo_PAS_Source". See PrimaryAudioSource. + * @return {DeviceStatus} + */ + + + setPrimaryAudioSource(source) { + this.validateType(PrimaryAudioSource, source); + this.setParameter(DeviceStatus.KEY_PRIMARY_AUDIO_SOURCE, source); + return this; + } + /** + * @return {PrimaryAudioSource} + */ + + + getPrimaryAudioSource() { + return this.getObject(PrimaryAudioSource, DeviceStatus.KEY_PRIMARY_AUDIO_SOURCE); + } + /** + * @param {Boolean} active - References signal "eCall_Event". + * @return {DeviceStatus} + */ + + + setECallEventActive(active) { + this.setParameter(DeviceStatus.KEY_E_CALL_EVENT_ACTIVE, active); + return this; + } + /** + * @return {Boolean} + */ + + + getECallEventActive() { + return this.getParameter(DeviceStatus.KEY_E_CALL_EVENT_ACTIVE); + } + + } + + DeviceStatus.KEY_VOICE_REC_ON = 'voiceRecOn'; + DeviceStatus.KEY_BT_ICON_ON = 'btIconOn'; + DeviceStatus.KEY_CALL_ACTIVE = 'callActive'; + DeviceStatus.KEY_PHONE_ROAMING = 'phoneRoaming'; + DeviceStatus.KEY_TEXT_MSG_AVAILABLE = 'textMsgAvailable'; + DeviceStatus.KEY_BATT_LEVEL_STATUS = 'battLevelStatus'; + DeviceStatus.KEY_STEREO_AUDIO_OUTPUT_MUTED = 'stereoAudioOutputMuted'; + DeviceStatus.KEY_MONO_AUDIO_OUTPUT_MUTED = 'monoAudioOutputMuted'; + DeviceStatus.KEY_SIGNAL_LEVEL_STATUS = 'signalLevelStatus'; + DeviceStatus.KEY_PRIMARY_AUDIO_SOURCE = 'primaryAudioSource'; + DeviceStatus.KEY_E_CALL_EVENT_ACTIVE = 'eCallEventActive'; + + /* eslint-disable camelcase */ + /** + * Reflects the status of the wipers. + * @typedef {Enum} WiperStatus + * @property {Object} _MAP + */ + + class WiperStatus extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get OFF() { + return WiperStatus._MAP.OFF; + } + /** + * @return {String} + */ + + + static get AUTO_OFF() { + return WiperStatus._MAP.AUTO_OFF; + } + /** + * @return {String} + */ + + + static get OFF_MOVING() { + return WiperStatus._MAP.OFF_MOVING; + } + /** + * @return {String} + */ + + + static get MAN_INT_OFF() { + return WiperStatus._MAP.MAN_INT_OFF; + } + /** + * @return {String} + */ + + + static get MAN_INT_ON() { + return WiperStatus._MAP.MAN_INT_ON; + } + /** + * @return {String} + */ + + + static get MAN_LOW() { + return WiperStatus._MAP.MAN_LOW; + } + /** + * @return {String} + */ + + + static get MAN_HIGH() { + return WiperStatus._MAP.MAN_HIGH; + } + /** + * @return {String} + */ + + + static get MAN_FLICK() { + return WiperStatus._MAP.MAN_FLICK; + } + /** + * @return {String} + */ + + + static get WASH() { + return WiperStatus._MAP.WASH; + } + /** + * @return {String} + */ + + + static get AUTO_LOW() { + return WiperStatus._MAP.AUTO_LOW; + } + /** + * @return {String} + */ + + + static get AUTO_HIGH() { + return WiperStatus._MAP.AUTO_HIGH; + } + /** + * @return {String} + */ + + + static get COURTESYWIPE() { + return WiperStatus._MAP.COURTESYWIPE; + } + /** + * @return {String} + */ + + + static get AUTO_ADJUST() { + return WiperStatus._MAP.AUTO_ADJUST; + } + /** + * @return {String} + */ + + + static get STALLED() { + return WiperStatus._MAP.STALLED; + } + /** + * @return {String} + */ + + + static get NO_DATA_EXISTS() { + return WiperStatus._MAP.NO_DATA_EXISTS; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return WiperStatus._valueForKey(key, WiperStatus._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return WiperStatus._keyForValue(value, WiperStatus._MAP); + } + + } + + WiperStatus._MAP = Object.freeze({ + 'OFF': 'OFF', + 'AUTO_OFF': 'AUTO_OFF', + 'OFF_MOVING': 'OFF_MOVING', + 'MAN_INT_OFF': 'MAN_INT_OFF', + 'MAN_INT_ON': 'MAN_INT_ON', + 'MAN_LOW': 'MAN_LOW', + 'MAN_HIGH': 'MAN_HIGH', + 'MAN_FLICK': 'MAN_FLICK', + 'WASH': 'WASH', + 'AUTO_LOW': 'AUTO_LOW', + 'AUTO_HIGH': 'AUTO_HIGH', + 'COURTESYWIPE': 'COURTESYWIPE', + 'AUTO_ADJUST': 'AUTO_ADJUST', + 'STALLED': 'STALLED', + 'NO_DATA_EXISTS': 'NO_DATA_EXISTS' + }); + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} ElectronicParkBrakeStatus + * @property {Object} _MAP + */ + + class ElectronicParkBrakeStatus extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * Park brake actuators have been fully applied. + * @return {String} + */ + + + static get CLOSED() { + return ElectronicParkBrakeStatus._MAP.CLOSED; + } + /** + * Park brake actuators are transitioning to either Apply/Closed or Release/Open state. + * @return {String} + */ + + + static get TRANSITION() { + return ElectronicParkBrakeStatus._MAP.TRANSITION; + } + /** + * Park brake actuators are released. + * @return {String} + */ + + + static get OPEN() { + return ElectronicParkBrakeStatus._MAP.OPEN; + } + /** + * When driver pulls the Electronic Park Brake switch while driving "at speed". + * @return {String} + */ + + + static get DRIVE_ACTIVE() { + return ElectronicParkBrakeStatus._MAP.DRIVE_ACTIVE; + } + /** + * When system has a fault or is under maintenance. + * @return {String} + */ + + + static get FAULT() { + return ElectronicParkBrakeStatus._MAP.FAULT; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return ElectronicParkBrakeStatus._valueForKey(key, ElectronicParkBrakeStatus._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return ElectronicParkBrakeStatus._keyForValue(value, ElectronicParkBrakeStatus._MAP); + } + + } + + ElectronicParkBrakeStatus._MAP = Object.freeze({ + 'CLOSED': 'CLOSED', + 'TRANSITION': 'TRANSITION', + 'OPEN': 'OPEN', + 'DRIVE_ACTIVE': 'DRIVE_ACTIVE', + 'FAULT': 'FAULT' + }); + + /* eslint-disable camelcase */ + /** + * Reflects the status of a binary vehicle data item. + * @typedef {Enum} VehicleDataStatus + * @property {Object} _MAP + */ + + class VehicleDataStatus extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get VDS_NO_DATA_EXISTS() { + return VehicleDataStatus._MAP.VDS_NO_DATA_EXISTS; + } + /** + * @return {String} + */ + + + static get VDS_OFF() { + return VehicleDataStatus._MAP.VDS_OFF; + } + /** + * @return {String} + */ + + + static get VDS_ON() { + return VehicleDataStatus._MAP.VDS_ON; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return VehicleDataStatus._valueForKey(key, VehicleDataStatus._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return VehicleDataStatus._keyForValue(value, VehicleDataStatus._MAP); + } + + } + + VehicleDataStatus._MAP = Object.freeze({ + 'VDS_NO_DATA_EXISTS': 'NO_DATA_EXISTS', + 'VDS_OFF': 'OFF', + 'VDS_ON': 'ON' + }); + + /* eslint-disable camelcase */ + + class MyKey extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {VehicleDataStatus} e911override - Indicates whether e911 override is on. References signal + * "MyKey_e911Override_St". See VehicleDataStatus. + * @return {MyKey} + */ + + + setE911Override(e911override) { + this.validateType(VehicleDataStatus, e911override); + this.setParameter(MyKey.KEY_E911OVERRIDE, e911override); + return this; + } + /** + * @return {VehicleDataStatus} + */ + + + getE911Override() { + return this.getObject(VehicleDataStatus, MyKey.KEY_E911OVERRIDE); + } + + } + + MyKey.KEY_E911OVERRIDE = 'e911Override'; + + /* eslint-disable camelcase */ + /** + * The list of potential compass directions + * @typedef {Enum} CompassDirection + * @property {Object} _MAP + */ + + class CompassDirection extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get NORTH() { + return CompassDirection._MAP.NORTH; + } + /** + * @return {String} + */ + + + static get NORTHWEST() { + return CompassDirection._MAP.NORTHWEST; + } + /** + * @return {String} + */ + + + static get WEST() { + return CompassDirection._MAP.WEST; + } + /** + * @return {String} + */ + + + static get SOUTHWEST() { + return CompassDirection._MAP.SOUTHWEST; + } + /** + * @return {String} + */ + + + static get SOUTH() { + return CompassDirection._MAP.SOUTH; + } + /** + * @return {String} + */ + + + static get SOUTHEAST() { + return CompassDirection._MAP.SOUTHEAST; + } + /** + * @return {String} + */ + + + static get EAST() { + return CompassDirection._MAP.EAST; + } + /** + * @return {String} + */ + + + static get NORTHEAST() { + return CompassDirection._MAP.NORTHEAST; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return CompassDirection._valueForKey(key, CompassDirection._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return CompassDirection._keyForValue(value, CompassDirection._MAP); + } + + } + + CompassDirection._MAP = Object.freeze({ + 'NORTH': 'NORTH', + 'NORTHWEST': 'NORTHWEST', + 'WEST': 'WEST', + 'SOUTHWEST': 'SOUTHWEST', + 'SOUTH': 'SOUTH', + 'SOUTHEAST': 'SOUTHEAST', + 'EAST': 'EAST', + 'NORTHEAST': 'NORTHEAST' + }); + + /* eslint-disable camelcase */ + /** + * The supported dimensions of the GPS + * @typedef {Enum} Dimension + * @property {Object} _MAP + */ + + class Dimension extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * No GPS at all + * @return {String} + */ + + + static get Dimension_NO_FIX() { + return Dimension._MAP.Dimension_NO_FIX; + } + /** + * Longitude and latitude + * @return {String} + */ + + + static get Dimension_2D() { + return Dimension._MAP.Dimension_2D; + } + /** + * Longitude and latitude and altitude + * @return {String} + */ + + + static get Dimension_3D() { + return Dimension._MAP.Dimension_3D; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return Dimension._valueForKey(key, Dimension._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return Dimension._keyForValue(value, Dimension._MAP); + } + + } + + Dimension._MAP = Object.freeze({ + 'Dimension_NO_FIX': 'NO_FIX', + 'Dimension_2D': '2D', + 'Dimension_3D': '3D' + }); + + /* eslint-disable camelcase */ + /** + * Struct with the GPS data. + */ + + class GPSData extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Number} degrees + * @return {GPSData} + */ + + + setLongitudeDegrees(degrees) { + this.setParameter(GPSData.KEY_LONGITUDE_DEGREES, degrees); + return this; + } + /** + * @return {Number} + */ + + + getLongitudeDegrees() { + return this.getParameter(GPSData.KEY_LONGITUDE_DEGREES); + } + /** + * @param {Number} degrees + * @return {GPSData} + */ + + + setLatitudeDegrees(degrees) { + this.setParameter(GPSData.KEY_LATITUDE_DEGREES, degrees); + return this; + } + /** + * @return {Number} + */ + + + getLatitudeDegrees() { + return this.getParameter(GPSData.KEY_LATITUDE_DEGREES); + } + /** + * @param {Number} year - The current UTC year. + * @return {GPSData} + */ + + + setUtcYear(year) { + this.setParameter(GPSData.KEY_UTC_YEAR, year); + return this; + } + /** + * @return {Number} + */ + + + getUtcYear() { + return this.getParameter(GPSData.KEY_UTC_YEAR); + } + /** + * @param {Number} month - The current UTC month. + * @return {GPSData} + */ + + + setUtcMonth(month) { + this.setParameter(GPSData.KEY_UTC_MONTH, month); + return this; + } + /** + * @return {Number} + */ + + + getUtcMonth() { + return this.getParameter(GPSData.KEY_UTC_MONTH); + } + /** + * @param {Number} day - The current UTC day. + * @return {GPSData} + */ + + + setUtcDay(day) { + this.setParameter(GPSData.KEY_UTC_DAY, day); + return this; + } + /** + * @return {Number} + */ + + + getUtcDay() { + return this.getParameter(GPSData.KEY_UTC_DAY); + } + /** + * @param {Number} hours - The current UTC hour. + * @return {GPSData} + */ + + + setUtcHours(hours) { + this.setParameter(GPSData.KEY_UTC_HOURS, hours); + return this; + } + /** + * @return {Number} + */ + + + getUtcHours() { + return this.getParameter(GPSData.KEY_UTC_HOURS); + } + /** + * @param {Number} minutes - The current UTC minute. + * @return {GPSData} + */ + + + setUtcMinutes(minutes) { + this.setParameter(GPSData.KEY_UTC_MINUTES, minutes); + return this; + } + /** + * @return {Number} + */ + + + getUtcMinutes() { + return this.getParameter(GPSData.KEY_UTC_MINUTES); + } + /** + * @param {Number} seconds - The current UTC second. + * @return {GPSData} + */ + + + setUtcSeconds(seconds) { + this.setParameter(GPSData.KEY_UTC_SECONDS, seconds); + return this; + } + /** + * @return {Number} + */ + + + getUtcSeconds() { + return this.getParameter(GPSData.KEY_UTC_SECONDS); + } + /** + * @param {CompassDirection} direction - See CompassDirection. + * @return {GPSData} + */ + + + setCompassDirection(direction) { + this.validateType(CompassDirection, direction); + this.setParameter(GPSData.KEY_COMPASS_DIRECTION, direction); + return this; + } + /** + * @return {CompassDirection} + */ + + + getCompassDirection() { + return this.getObject(CompassDirection, GPSData.KEY_COMPASS_DIRECTION); + } + /** + * @param {Number} pdop - PDOP. If undefined or unavailable, then value shall be set to 0. + * @return {GPSData} + */ + + + setPdop(pdop) { + this.setParameter(GPSData.KEY_PDOP, pdop); + return this; + } + /** + * @return {Number} + */ + + + getPdop() { + return this.getParameter(GPSData.KEY_PDOP); + } + /** + * @param {Number} hdop - HDOP. If value is unknown, value shall be set to 0. + * @return {GPSData} + */ + + + setHdop(hdop) { + this.setParameter(GPSData.KEY_HDOP, hdop); + return this; + } + /** + * @return {Number} + */ + + + getHdop() { + return this.getParameter(GPSData.KEY_HDOP); + } + /** + * @param {Number} vdop - VDOP. If value is unknown, value shall be set to 0. + * @return {GPSData} + */ + + + setVdop(vdop) { + this.setParameter(GPSData.KEY_VDOP, vdop); + return this; + } + /** + * @return {Number} + */ + + + getVdop() { + return this.getParameter(GPSData.KEY_VDOP); + } + /** + * @param {Boolean} actual - True, if actual. False, if inferred. + * @return {GPSData} + */ + + + setActual(actual) { + this.setParameter(GPSData.KEY_ACTUAL, actual); + return this; + } + /** + * @return {Boolean} + */ + + + getActual() { + return this.getParameter(GPSData.KEY_ACTUAL); + } + /** + * @param {Number} satellites - Number of satellites in view + * @return {GPSData} + */ + + + setSatellites(satellites) { + this.setParameter(GPSData.KEY_SATELLITES, satellites); + return this; + } + /** + * @return {Number} + */ + + + getSatellites() { + return this.getParameter(GPSData.KEY_SATELLITES); + } + /** + * @param {Dimension} dimension - See Dimension + * @return {GPSData} + */ + + + setDimension(dimension) { + this.validateType(Dimension, dimension); + this.setParameter(GPSData.KEY_DIMENSION, dimension); + return this; + } + /** + * @return {Dimension} + */ + + + getDimension() { + return this.getObject(Dimension, GPSData.KEY_DIMENSION); + } + /** + * @param {Number} altitude - Altitude in meters + * @return {GPSData} + */ + + + setAltitude(altitude) { + this.setParameter(GPSData.KEY_ALTITUDE, altitude); + return this; + } + /** + * @return {Number} + */ + + + getAltitude() { + return this.getParameter(GPSData.KEY_ALTITUDE); + } + /** + * @param {Number} heading - The heading. North is 0. Resolution is 0.01 + * @return {GPSData} + */ + + + setHeading(heading) { + this.setParameter(GPSData.KEY_HEADING, heading); + return this; + } + /** + * @return {Number} + */ + + + getHeading() { + return this.getParameter(GPSData.KEY_HEADING); + } + /** + * @param {Number} speed - The speed in KPH + * @return {GPSData} + */ + + + setSpeed(speed) { + this.setParameter(GPSData.KEY_SPEED, speed); + return this; + } + /** + * @return {Number} + */ + + + getSpeed() { + return this.getParameter(GPSData.KEY_SPEED); + } + /** + * @param {Boolean} shifted - True, if GPS lat/long, time, and altitude have been purposefully shifted (requires a + * proprietary algorithm to unshift). False, if the GPS data is raw and un-shifted. If + * not provided, then value is assumed False. + * @return {GPSData} + */ + + + setShifted(shifted) { + this.setParameter(GPSData.KEY_SHIFTED, shifted); + return this; + } + /** + * @return {Boolean} + */ + + + getShifted() { + return this.getParameter(GPSData.KEY_SHIFTED); + } + + } + + GPSData.KEY_LONGITUDE_DEGREES = 'longitudeDegrees'; + GPSData.KEY_LATITUDE_DEGREES = 'latitudeDegrees'; + GPSData.KEY_UTC_YEAR = 'utcYear'; + GPSData.KEY_UTC_MONTH = 'utcMonth'; + GPSData.KEY_UTC_DAY = 'utcDay'; + GPSData.KEY_UTC_HOURS = 'utcHours'; + GPSData.KEY_UTC_MINUTES = 'utcMinutes'; + GPSData.KEY_UTC_SECONDS = 'utcSeconds'; + GPSData.KEY_COMPASS_DIRECTION = 'compassDirection'; + GPSData.KEY_PDOP = 'pdop'; + GPSData.KEY_HDOP = 'hdop'; + GPSData.KEY_VDOP = 'vdop'; + GPSData.KEY_ACTUAL = 'actual'; + GPSData.KEY_SATELLITES = 'satellites'; + GPSData.KEY_DIMENSION = 'dimension'; + GPSData.KEY_ALTITUDE = 'altitude'; + GPSData.KEY_HEADING = 'heading'; + GPSData.KEY_SPEED = 'speed'; + GPSData.KEY_SHIFTED = 'shifted'; + + /* eslint-disable camelcase */ + /** + * The selected gear. + * @typedef {Enum} PRNDL + * @property {Object} _MAP + */ + + class PRNDL extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * Parking + * @return {String} + */ + + + static get PARK() { + return PRNDL._MAP.PARK; + } + /** + * Reverse gear + * @return {String} + */ + + + static get REVERSE() { + return PRNDL._MAP.REVERSE; + } + /** + * No gear + * @return {String} + */ + + + static get NEUTRAL() { + return PRNDL._MAP.NEUTRAL; + } + /** + * @return {String} + */ + + + static get DRIVE() { + return PRNDL._MAP.DRIVE; + } + /** + * Drive Sport mode + * @return {String} + */ + + + static get SPORT() { + return PRNDL._MAP.SPORT; + } + /** + * 1st gear hold + * @return {String} + */ + + + static get LOWGEAR() { + return PRNDL._MAP.LOWGEAR; + } + /** + * @return {String} + */ + + + static get FIRST() { + return PRNDL._MAP.FIRST; + } + /** + * @return {String} + */ + + + static get SECOND() { + return PRNDL._MAP.SECOND; + } + /** + * @return {String} + */ + + + static get THIRD() { + return PRNDL._MAP.THIRD; + } + /** + * @return {String} + */ + + + static get FOURTH() { + return PRNDL._MAP.FOURTH; + } + /** + * @return {String} + */ + + + static get FIFTH() { + return PRNDL._MAP.FIFTH; + } + /** + * @return {String} + */ + + + static get SIXTH() { + return PRNDL._MAP.SIXTH; + } + /** + * @return {String} + */ + + + static get SEVENTH() { + return PRNDL._MAP.SEVENTH; + } + /** + * @return {String} + */ + + + static get EIGHTH() { + return PRNDL._MAP.EIGHTH; + } + /** + * @return {String} + */ + + + static get UNKNOWN() { + return PRNDL._MAP.UNKNOWN; + } + /** + * @return {String} + */ + + + static get FAULT() { + return PRNDL._MAP.FAULT; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return PRNDL._valueForKey(key, PRNDL._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return PRNDL._keyForValue(value, PRNDL._MAP); + } + + } + + PRNDL._MAP = Object.freeze({ + 'PARK': 'PARK', + 'REVERSE': 'REVERSE', + 'NEUTRAL': 'NEUTRAL', + 'DRIVE': 'DRIVE', + 'SPORT': 'SPORT', + 'LOWGEAR': 'LOWGEAR', + 'FIRST': 'FIRST', + 'SECOND': 'SECOND', + 'THIRD': 'THIRD', + 'FOURTH': 'FOURTH', + 'FIFTH': 'FIFTH', + 'SIXTH': 'SIXTH', + 'SEVENTH': 'SEVENTH', + 'EIGHTH': 'EIGHTH', + 'UNKNOWN': 'UNKNOWN', + 'FAULT': 'FAULT' + }); + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} FuelType + * @property {Object} _MAP + */ + + class FuelType extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get GASOLINE() { + return FuelType._MAP.GASOLINE; + } + /** + * @return {String} + */ + + + static get DIESEL() { + return FuelType._MAP.DIESEL; + } + /** + * For vehicles using compressed natural gas. + * @return {String} + */ + + + static get CNG() { + return FuelType._MAP.CNG; + } + /** + * For vehicles using liquefied petroleum gas. + * @return {String} + */ + + + static get LPG() { + return FuelType._MAP.LPG; + } + /** + * For FCEV (fuel cell electric vehicle). + * @return {String} + */ + + + static get HYDROGEN() { + return FuelType._MAP.HYDROGEN; + } + /** + * For BEV (Battery Electric Vehicle), PHEV (Plug-in Hybrid Electric Vehicle), solar vehicles and other vehicles + * which run on a battery. + * @return {String} + */ + + + static get BATTERY() { + return FuelType._MAP.BATTERY; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return FuelType._valueForKey(key, FuelType._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return FuelType._keyForValue(value, FuelType._MAP); + } + + } + + FuelType._MAP = Object.freeze({ + 'GASOLINE': 'GASOLINE', + 'DIESEL': 'DIESEL', + 'CNG': 'CNG', + 'LPG': 'LPG', + 'HYDROGEN': 'HYDROGEN', + 'BATTERY': 'BATTERY' + }); + + /* eslint-disable camelcase */ + + class FuelRange extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {FuelType} type + * @return {FuelRange} + */ + + + setType(type) { + this.validateType(FuelType, type); + this.setParameter(FuelRange.KEY_TYPE, type); + return this; + } + /** + * @return {FuelType} + */ + + + getType() { + return this.getObject(FuelType, FuelRange.KEY_TYPE); + } + /** + * @param {Number} range - The estimate range in KM the vehicle can travel based on fuel level and consumption. + * @return {FuelRange} + */ + + + setRange(range) { + this.setParameter(FuelRange.KEY_RANGE, range); + return this; + } + /** + * @return {Number} + */ + + + getRange() { + return this.getParameter(FuelRange.KEY_RANGE); + } + + } + + FuelRange.KEY_TYPE = 'type'; + FuelRange.KEY_RANGE = 'range'; + + /* eslint-disable camelcase */ + /** + * Reflects the status of a vehicle data notification. + * @typedef {Enum} VehicleDataNotificationStatus + * @property {Object} _MAP + */ + + class VehicleDataNotificationStatus extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get VDNS_NOT_SUPPORTED() { + return VehicleDataNotificationStatus._MAP.VDNS_NOT_SUPPORTED; + } + /** + * @return {String} + */ + + + static get VDNS_NORMAL() { + return VehicleDataNotificationStatus._MAP.VDNS_NORMAL; + } + /** + * @return {String} + */ + + + static get VDNS_ACTIVE() { + return VehicleDataNotificationStatus._MAP.VDNS_ACTIVE; + } + /** + * @return {String} + */ + + + static get VDNS_NOT_USED() { + return VehicleDataNotificationStatus._MAP.VDNS_NOT_USED; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return VehicleDataNotificationStatus._valueForKey(key, VehicleDataNotificationStatus._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return VehicleDataNotificationStatus._keyForValue(value, VehicleDataNotificationStatus._MAP); + } + + } + + VehicleDataNotificationStatus._MAP = Object.freeze({ + 'VDNS_NOT_SUPPORTED': 'NOT_SUPPORTED', + 'VDNS_NORMAL': 'NORMAL', + 'VDNS_ACTIVE': 'ACTIVE', + 'VDNS_NOT_USED': 'NOT_USED' + }); + + /* eslint-disable camelcase */ + /** + * Reflects the status of the eCall Notification. + * @typedef {Enum} ECallConfirmationStatus + * @property {Object} _MAP + */ + + class ECallConfirmationStatus extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get ECCS_NORMAL() { + return ECallConfirmationStatus._MAP.ECCS_NORMAL; + } + /** + * @return {String} + */ + + + static get ECCS_CALL_IN_PROGRESS() { + return ECallConfirmationStatus._MAP.ECCS_CALL_IN_PROGRESS; + } + /** + * @return {String} + */ + + + static get ECCS_CALL_CANCELLED() { + return ECallConfirmationStatus._MAP.ECCS_CALL_CANCELLED; + } + /** + * @return {String} + */ + + + static get CALL_COMPLETED() { + return ECallConfirmationStatus._MAP.CALL_COMPLETED; + } + /** + * @return {String} + */ + + + static get ECCS_CALL_UNSUCCESSFUL() { + return ECallConfirmationStatus._MAP.ECCS_CALL_UNSUCCESSFUL; + } + /** + * @return {String} + */ + + + static get ECCS_ECALL_CONFIGURED_OFF() { + return ECallConfirmationStatus._MAP.ECCS_ECALL_CONFIGURED_OFF; + } + /** + * @return {String} + */ + + + static get ECCS_CALL_COMPLETE_DTMF_TIMEOUT() { + return ECallConfirmationStatus._MAP.ECCS_CALL_COMPLETE_DTMF_TIMEOUT; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return ECallConfirmationStatus._valueForKey(key, ECallConfirmationStatus._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return ECallConfirmationStatus._keyForValue(value, ECallConfirmationStatus._MAP); + } + + } + + ECallConfirmationStatus._MAP = Object.freeze({ + 'ECCS_NORMAL': 'NORMAL', + 'ECCS_CALL_IN_PROGRESS': 'CALL_IN_PROGRESS', + 'ECCS_CALL_CANCELLED': 'CALL_CANCELLED', + 'CALL_COMPLETED': 'CALL_COMPLETED', + 'ECCS_CALL_UNSUCCESSFUL': 'CALL_UNSUCCESSFUL', + 'ECCS_ECALL_CONFIGURED_OFF': 'ECALL_CONFIGURED_OFF', + 'ECCS_CALL_COMPLETE_DTMF_TIMEOUT': 'CALL_COMPLETE_DTMF_TIMEOUT' + }); + + /* eslint-disable camelcase */ + + class ECallInfo extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {VehicleDataNotificationStatus} status - References signal "eCallNotification_4A". See + * VehicleDataNotificationStatus. + * @return {ECallInfo} + */ + + + setECallNotificationStatus(status) { + this.validateType(VehicleDataNotificationStatus, status); + this.setParameter(ECallInfo.KEY_E_CALL_NOTIFICATION_STATUS, status); + return this; + } + /** + * @return {VehicleDataNotificationStatus} + */ + + + getECallNotificationStatus() { + return this.getObject(VehicleDataNotificationStatus, ECallInfo.KEY_E_CALL_NOTIFICATION_STATUS); + } + /** + * @param {VehicleDataNotificationStatus} status - References signal "eCallNotification". See + * VehicleDataNotificationStatus. + * @return {ECallInfo} + */ + + + setAuxECallNotificationStatus(status) { + this.validateType(VehicleDataNotificationStatus, status); + this.setParameter(ECallInfo.KEY_AUX_ECALL_NOTIFICATION_STATUS, status); + return this; + } + /** + * @return {VehicleDataNotificationStatus} + */ + + + getAuxECallNotificationStatus() { + return this.getObject(VehicleDataNotificationStatus, ECallInfo.KEY_AUX_ECALL_NOTIFICATION_STATUS); + } + /** + * @param {ECallConfirmationStatus} status - References signal "eCallConfirmation". See ECallConfirmationStatus. + * @return {ECallInfo} + */ + + + setECallConfirmationStatus(status) { + this.validateType(ECallConfirmationStatus, status); + this.setParameter(ECallInfo.KEY_E_CALL_CONFIRMATION_STATUS, status); + return this; + } + /** + * @return {ECallConfirmationStatus} + */ + + + getECallConfirmationStatus() { + return this.getObject(ECallConfirmationStatus, ECallInfo.KEY_E_CALL_CONFIRMATION_STATUS); + } + + } + + ECallInfo.KEY_E_CALL_NOTIFICATION_STATUS = 'eCallNotificationStatus'; + ECallInfo.KEY_AUX_ECALL_NOTIFICATION_STATUS = 'auxECallNotificationStatus'; + ECallInfo.KEY_E_CALL_CONFIRMATION_STATUS = 'eCallConfirmationStatus'; + + /* eslint-disable camelcase */ + + class BeltStatus extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsDrvBelt_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + + + setDriverBeltDeployed(deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(BeltStatus.KEY_DRIVER_BELT_DEPLOYED, deployed); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getDriverBeltDeployed() { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_DRIVER_BELT_DEPLOYED); + } + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsPasBelt_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + + + setPassengerBeltDeployed(deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(BeltStatus.KEY_PASSENGER_BELT_DEPLOYED, deployed); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getPassengerBeltDeployed() { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_PASSENGER_BELT_DEPLOYED); + } + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw1PasBckl_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + + + setPassengerBuckleBelted(belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_PASSENGER_BUCKLE_BELTED, belted); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getPassengerBuckleBelted() { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_PASSENGER_BUCKLE_BELTED); + } + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw1DrvBckl_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + + + setDriverBuckleBelted(belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_DRIVER_BUCKLE_BELTED, belted); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getDriverBuckleBelted() { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_DRIVER_BUCKLE_BELTED); + } + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw2lBckl_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + + + setLeftRow2BuckleBelted(belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_LEFT_ROW2BUCKLE_BELTED, belted); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getLeftRow2BuckleBelted() { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_LEFT_ROW2BUCKLE_BELTED); + } + /** + * @param {VehicleDataEventStatus} detected - References signal "VedsRw1PasChld_D_Ltchd". See + * VehicleDataEventStatus. + * @return {BeltStatus} + */ + + + setPassengerChildDetected(detected) { + this.validateType(VehicleDataEventStatus, detected); + this.setParameter(BeltStatus.KEY_PASSENGER_CHILD_DETECTED, detected); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getPassengerChildDetected() { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_PASSENGER_CHILD_DETECTED); + } + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw2rBckl_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + + + setRightRow2BuckleBelted(belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_RIGHT_ROW2BUCKLE_BELTED, belted); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getRightRow2BuckleBelted() { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_RIGHT_ROW2BUCKLE_BELTED); + } + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw2mBckl_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + + + setMiddleRow2BuckleBelted(belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_MIDDLE_ROW2BUCKLE_BELTED, belted); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getMiddleRow2BuckleBelted() { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_MIDDLE_ROW2BUCKLE_BELTED); + } + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw3mBckl_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + + + setMiddleRow3BuckleBelted(belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_MIDDLE_ROW3BUCKLE_BELTED, belted); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getMiddleRow3BuckleBelted() { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_MIDDLE_ROW3BUCKLE_BELTED); + } + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw3lBckl_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + + + setLeftRow3BuckleBelted(belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_LEFT_ROW3BUCKLE_BELTED, belted); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getLeftRow3BuckleBelted() { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_LEFT_ROW3BUCKLE_BELTED); + } + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw3rBckl_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + + + setRightRow3BuckleBelted(belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_RIGHT_ROW3BUCKLE_BELTED, belted); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getRightRow3BuckleBelted() { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_RIGHT_ROW3BUCKLE_BELTED); + } + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw2lRib_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + + + setLeftRearInflatableBelted(belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_LEFT_REAR_INFLATABLE_BELTED, belted); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getLeftRearInflatableBelted() { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_LEFT_REAR_INFLATABLE_BELTED); + } + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw2rRib_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + + + setRightRearInflatableBelted(belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_RIGHT_REAR_INFLATABLE_BELTED, belted); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getRightRearInflatableBelted() { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_RIGHT_REAR_INFLATABLE_BELTED); + } + /** + * @param {VehicleDataEventStatus} deployed - References signal "VedsRw1mBelt_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + + + setMiddleRow1BeltDeployed(deployed) { + this.validateType(VehicleDataEventStatus, deployed); + this.setParameter(BeltStatus.KEY_MIDDLE_ROW1BELT_DEPLOYED, deployed); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getMiddleRow1BeltDeployed() { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_MIDDLE_ROW1BELT_DEPLOYED); + } + /** + * @param {VehicleDataEventStatus} belted - References signal "VedsRw1mBckl_D_Ltchd". See VehicleDataEventStatus. + * @return {BeltStatus} + */ + + + setMiddleRow1BuckleBelted(belted) { + this.validateType(VehicleDataEventStatus, belted); + this.setParameter(BeltStatus.KEY_MIDDLE_ROW1BUCKLE_BELTED, belted); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getMiddleRow1BuckleBelted() { + return this.getObject(VehicleDataEventStatus, BeltStatus.KEY_MIDDLE_ROW1BUCKLE_BELTED); + } + + } + + BeltStatus.KEY_DRIVER_BELT_DEPLOYED = 'driverBeltDeployed'; + BeltStatus.KEY_PASSENGER_BELT_DEPLOYED = 'passengerBeltDeployed'; + BeltStatus.KEY_PASSENGER_BUCKLE_BELTED = 'passengerBuckleBelted'; + BeltStatus.KEY_DRIVER_BUCKLE_BELTED = 'driverBuckleBelted'; + BeltStatus.KEY_LEFT_ROW2BUCKLE_BELTED = 'leftRow2BuckleBelted'; + BeltStatus.KEY_PASSENGER_CHILD_DETECTED = 'passengerChildDetected'; + BeltStatus.KEY_RIGHT_ROW2BUCKLE_BELTED = 'rightRow2BuckleBelted'; + BeltStatus.KEY_MIDDLE_ROW2BUCKLE_BELTED = 'middleRow2BuckleBelted'; + BeltStatus.KEY_MIDDLE_ROW3BUCKLE_BELTED = 'middleRow3BuckleBelted'; + BeltStatus.KEY_LEFT_ROW3BUCKLE_BELTED = 'leftRow3BuckleBelted'; + BeltStatus.KEY_RIGHT_ROW3BUCKLE_BELTED = 'rightRow3BuckleBelted'; + BeltStatus.KEY_LEFT_REAR_INFLATABLE_BELTED = 'leftRearInflatableBelted'; + BeltStatus.KEY_RIGHT_REAR_INFLATABLE_BELTED = 'rightRearInflatableBelted'; + BeltStatus.KEY_MIDDLE_ROW1BELT_DEPLOYED = 'middleRow1BeltDeployed'; + BeltStatus.KEY_MIDDLE_ROW1BUCKLE_BELTED = 'middleRow1BuckleBelted'; + + /* eslint-disable camelcase */ + /** + * The volume status of a vehicle component. + * @typedef {Enum} ComponentVolumeStatus + * @property {Object} _MAP + */ + + class ComponentVolumeStatus extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get CVS_UNKNOWN() { + return ComponentVolumeStatus._MAP.CVS_UNKNOWN; + } + /** + * @return {String} + */ + + + static get CVS_NORMAL() { + return ComponentVolumeStatus._MAP.CVS_NORMAL; + } + /** + * @return {String} + */ + + + static get CVS_LOW() { + return ComponentVolumeStatus._MAP.CVS_LOW; + } + /** + * @return {String} + */ + + + static get CVS_FAULT() { + return ComponentVolumeStatus._MAP.CVS_FAULT; + } + /** + * @return {String} + */ + + + static get CVS_ALERT() { + return ComponentVolumeStatus._MAP.CVS_ALERT; + } + /** + * @return {String} + */ + + + static get CVS_NOT_SUPPORTED() { + return ComponentVolumeStatus._MAP.CVS_NOT_SUPPORTED; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return ComponentVolumeStatus._valueForKey(key, ComponentVolumeStatus._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return ComponentVolumeStatus._keyForValue(value, ComponentVolumeStatus._MAP); + } + + } + + ComponentVolumeStatus._MAP = Object.freeze({ + 'CVS_UNKNOWN': 'UNKNOWN', + 'CVS_NORMAL': 'NORMAL', + 'CVS_LOW': 'LOW', + 'CVS_FAULT': 'FAULT', + 'CVS_ALERT': 'ALERT', + 'CVS_NOT_SUPPORTED': 'NOT_SUPPORTED' + }); + + /* eslint-disable camelcase */ + /** + * Reflects the status of ignition. + * @typedef {Enum} IgnitionStatus + * @property {Object} _MAP + */ + + class IgnitionStatus extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get IS_UNKNOWN() { + return IgnitionStatus._MAP.IS_UNKNOWN; + } + /** + * @return {String} + */ + + + static get IS_OFF() { + return IgnitionStatus._MAP.IS_OFF; + } + /** + * @return {String} + */ + + + static get IS_ACCESSORY() { + return IgnitionStatus._MAP.IS_ACCESSORY; + } + /** + * @return {String} + */ + + + static get IS_RUN() { + return IgnitionStatus._MAP.IS_RUN; + } + /** + * @return {String} + */ + + + static get IS_START() { + return IgnitionStatus._MAP.IS_START; + } + /** + * @return {String} + */ + + + static get IS_INVALID() { + return IgnitionStatus._MAP.IS_INVALID; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return IgnitionStatus._valueForKey(key, IgnitionStatus._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return IgnitionStatus._keyForValue(value, IgnitionStatus._MAP); + } + + } + + IgnitionStatus._MAP = Object.freeze({ + 'IS_UNKNOWN': 'UNKNOWN', + 'IS_OFF': 'OFF', + 'IS_ACCESSORY': 'ACCESSORY', + 'IS_RUN': 'RUN', + 'IS_START': 'START', + 'IS_INVALID': 'INVALID' + }); + + /* eslint-disable camelcase */ + /** + * Reflects the ignition switch stability. + * @typedef {Enum} IgnitionStableStatus + * @property {Object} _MAP + */ + + class IgnitionStableStatus extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get IGNITION_SWITCH_NOT_STABLE() { + return IgnitionStableStatus._MAP.IGNITION_SWITCH_NOT_STABLE; + } + /** + * @return {String} + */ + + + static get IGNITION_SWITCH_STABLE() { + return IgnitionStableStatus._MAP.IGNITION_SWITCH_STABLE; + } + /** + * @return {String} + */ + + + static get MISSING_FROM_TRANSMITTER() { + return IgnitionStableStatus._MAP.MISSING_FROM_TRANSMITTER; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return IgnitionStableStatus._valueForKey(key, IgnitionStableStatus._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return IgnitionStableStatus._keyForValue(value, IgnitionStableStatus._MAP); + } + + } + + IgnitionStableStatus._MAP = Object.freeze({ + 'IGNITION_SWITCH_NOT_STABLE': 'IGNITION_SWITCH_NOT_STABLE', + 'IGNITION_SWITCH_STABLE': 'IGNITION_SWITCH_STABLE', + 'MISSING_FROM_TRANSMITTER': 'MISSING_FROM_TRANSMITTER' + }); + + /* eslint-disable camelcase */ + + class BodyInformation extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Boolean} active - References signal "PrkBrkActv_B_Actl". + * @return {BodyInformation} + */ + + + setParkBrakeActive(active) { + this.setParameter(BodyInformation.KEY_PARK_BRAKE_ACTIVE, active); + return this; + } + /** + * @return {Boolean} + */ + + + getParkBrakeActive() { + return this.getParameter(BodyInformation.KEY_PARK_BRAKE_ACTIVE); + } + /** + * @param {IgnitionStableStatus} status - References signal "Ignition_Switch_Stable". See IgnitionStableStatus. + * @return {BodyInformation} + */ + + + setIgnitionStableStatus(status) { + this.validateType(IgnitionStableStatus, status); + this.setParameter(BodyInformation.KEY_IGNITION_STABLE_STATUS, status); + return this; + } + /** + * @return {IgnitionStableStatus} + */ + + + getIgnitionStableStatus() { + return this.getObject(IgnitionStableStatus, BodyInformation.KEY_IGNITION_STABLE_STATUS); + } + /** + * @param {IgnitionStatus} status - References signal "Ignition_status". See IgnitionStatus. + * @return {BodyInformation} + */ + + + setIgnitionStatus(status) { + this.validateType(IgnitionStatus, status); + this.setParameter(BodyInformation.KEY_IGNITION_STATUS, status); + return this; + } + /** + * @return {IgnitionStatus} + */ + + + getIgnitionStatus() { + return this.getObject(IgnitionStatus, BodyInformation.KEY_IGNITION_STATUS); + } + /** + * @param {Boolean} ajar - References signal "DrStatDrv_B_Actl". + * @return {BodyInformation} + */ + + + setDriverDoorAjar(ajar) { + this.setParameter(BodyInformation.KEY_DRIVER_DOOR_AJAR, ajar); + return this; + } + /** + * @return {Boolean} + */ + + + getDriverDoorAjar() { + return this.getParameter(BodyInformation.KEY_DRIVER_DOOR_AJAR); + } + /** + * @param {Boolean} ajar - References signal "DrStatPsngr_B_Actl". + * @return {BodyInformation} + */ + + + setPassengerDoorAjar(ajar) { + this.setParameter(BodyInformation.KEY_PASSENGER_DOOR_AJAR, ajar); + return this; + } + /** + * @return {Boolean} + */ + + + getPassengerDoorAjar() { + return this.getParameter(BodyInformation.KEY_PASSENGER_DOOR_AJAR); + } + /** + * @param {Boolean} ajar - References signal "DrStatRl_B_Actl". + * @return {BodyInformation} + */ + + + setRearLeftDoorAjar(ajar) { + this.setParameter(BodyInformation.KEY_REAR_LEFT_DOOR_AJAR, ajar); + return this; + } + /** + * @return {Boolean} + */ + + + getRearLeftDoorAjar() { + return this.getParameter(BodyInformation.KEY_REAR_LEFT_DOOR_AJAR); + } + /** + * @param {Boolean} ajar - References signal "DrStatRr_B_Actl". + * @return {BodyInformation} + */ + + + setRearRightDoorAjar(ajar) { + this.setParameter(BodyInformation.KEY_REAR_RIGHT_DOOR_AJAR, ajar); + return this; + } + /** + * @return {Boolean} + */ + + + getRearRightDoorAjar() { + return this.getParameter(BodyInformation.KEY_REAR_RIGHT_DOOR_AJAR); + } + + } + + BodyInformation.KEY_PARK_BRAKE_ACTIVE = 'parkBrakeActive'; + BodyInformation.KEY_IGNITION_STABLE_STATUS = 'ignitionStableStatus'; + BodyInformation.KEY_IGNITION_STATUS = 'ignitionStatus'; + BodyInformation.KEY_DRIVER_DOOR_AJAR = 'driverDoorAjar'; + BodyInformation.KEY_PASSENGER_DOOR_AJAR = 'passengerDoorAjar'; + BodyInformation.KEY_REAR_LEFT_DOOR_AJAR = 'rearLeftDoorAjar'; + BodyInformation.KEY_REAR_RIGHT_DOOR_AJAR = 'rearRightDoorAjar'; + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} TPMS + * @property {Object} _MAP + */ + + class TPMS extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * If set the status of the tire is not known. + * @return {String} + */ + + + static get UNKNOWN() { + return TPMS._MAP.UNKNOWN; + } + /** + * TPMS does not function. + * @return {String} + */ + + + static get SYSTEM_FAULT() { + return TPMS._MAP.SYSTEM_FAULT; + } + /** + * The sensor of the tire does not function. + * @return {String} + */ + + + static get SENSOR_FAULT() { + return TPMS._MAP.SENSOR_FAULT; + } + /** + * TPMS is reporting a low tire pressure for the tire. + * @return {String} + */ + + + static get LOW() { + return TPMS._MAP.LOW; + } + /** + * TPMS is active and the tire pressure is monitored. + * @return {String} + */ + + + static get SYSTEM_ACTIVE() { + return TPMS._MAP.SYSTEM_ACTIVE; + } + /** + * TPMS is reporting that the tire must be trained. + * @return {String} + */ + + + static get TRAIN() { + return TPMS._MAP.TRAIN; + } + /** + * TPMS reports the training for the tire is completed. + * @return {String} + */ + + + static get TRAINING_COMPLETE() { + return TPMS._MAP.TRAINING_COMPLETE; + } + /** + * TPMS reports the tire is not trained. + * @return {String} + */ + + + static get NOT_TRAINED() { + return TPMS._MAP.NOT_TRAINED; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return TPMS._valueForKey(key, TPMS._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return TPMS._keyForValue(value, TPMS._MAP); + } + + } + + TPMS._MAP = Object.freeze({ + 'UNKNOWN': 'UNKNOWN', + 'SYSTEM_FAULT': 'SYSTEM_FAULT', + 'SENSOR_FAULT': 'SENSOR_FAULT', + 'LOW': 'LOW', + 'SYSTEM_ACTIVE': 'SYSTEM_ACTIVE', + 'TRAIN': 'TRAIN', + 'TRAINING_COMPLETE': 'TRAINING_COMPLETE', + 'NOT_TRAINED': 'NOT_TRAINED' + }); + + /* eslint-disable camelcase */ + + class SingleTireStatus extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {ComponentVolumeStatus} status - See ComponentVolumeStatus. + * @return {SingleTireStatus} + */ + + + setStatus(status) { + this.validateType(ComponentVolumeStatus, status); + this.setParameter(SingleTireStatus.KEY_STATUS, status); + return this; + } + /** + * @return {ComponentVolumeStatus} + */ + + + getStatus() { + return this.getObject(ComponentVolumeStatus, SingleTireStatus.KEY_STATUS); + } + /** + * @param {TPMS} tpms - The status of TPMS according to the particular tire. + * @return {SingleTireStatus} + */ + + + setTpms(tpms) { + this.validateType(TPMS, tpms); + this.setParameter(SingleTireStatus.KEY_TPMS, tpms); + return this; + } + /** + * @return {TPMS} + */ + + + getTpms() { + return this.getObject(TPMS, SingleTireStatus.KEY_TPMS); + } + /** + * @param {Number} pressure - The pressure value of the particular tire in kilo pascal. + * @return {SingleTireStatus} + */ + + + setPressure(pressure) { + this.setParameter(SingleTireStatus.KEY_PRESSURE, pressure); + return this; + } + /** + * @return {Number} + */ + + + getPressure() { + return this.getParameter(SingleTireStatus.KEY_PRESSURE); + } + + } + + SingleTireStatus.KEY_STATUS = 'status'; + SingleTireStatus.KEY_TPMS = 'tpms'; + SingleTireStatus.KEY_PRESSURE = 'pressure'; + + /* eslint-disable camelcase */ + /** + * Reflects the status of a cluster instrument warning light. + * @typedef {Enum} WarningLightStatus + * @property {Object} _MAP + */ + + class WarningLightStatus extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get WLS_OFF() { + return WarningLightStatus._MAP.WLS_OFF; + } + /** + * @return {String} + */ + + + static get WLS_ON() { + return WarningLightStatus._MAP.WLS_ON; + } + /** + * @return {String} + */ + + + static get WLS_FLASH() { + return WarningLightStatus._MAP.WLS_FLASH; + } + /** + * @return {String} + */ + + + static get WLS_NOT_USED() { + return WarningLightStatus._MAP.WLS_NOT_USED; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return WarningLightStatus._valueForKey(key, WarningLightStatus._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return WarningLightStatus._keyForValue(value, WarningLightStatus._MAP); + } + + } + + WarningLightStatus._MAP = Object.freeze({ + 'WLS_OFF': 'OFF', + 'WLS_ON': 'ON', + 'WLS_FLASH': 'FLASH', + 'WLS_NOT_USED': 'NOT_USED' + }); + + /* eslint-disable camelcase */ + /** + * The status and pressure of the tires. + */ + + class TireStatus extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {WarningLightStatus} telltale - Status of the Tire Pressure Telltale. See WarningLightStatus. + * @return {TireStatus} + */ + + + setPressureTelltale(telltale) { + this.validateType(WarningLightStatus, telltale); + this.setParameter(TireStatus.KEY_PRESSURE_TELLTALE, telltale); + return this; + } + /** + * @return {WarningLightStatus} + */ + + + getPressureTelltale() { + return this.getObject(WarningLightStatus, TireStatus.KEY_PRESSURE_TELLTALE); + } + /** + * @param {SingleTireStatus} front - The status of the left front tire. + * @return {TireStatus} + */ + + + setLeftFront(front) { + this.validateType(SingleTireStatus, front); + this.setParameter(TireStatus.KEY_LEFT_FRONT, front); + return this; + } + /** + * @return {SingleTireStatus} + */ + + + getLeftFront() { + return this.getObject(SingleTireStatus, TireStatus.KEY_LEFT_FRONT); + } + /** + * @param {SingleTireStatus} front - The status of the right front tire. + * @return {TireStatus} + */ + + + setRightFront(front) { + this.validateType(SingleTireStatus, front); + this.setParameter(TireStatus.KEY_RIGHT_FRONT, front); + return this; + } + /** + * @return {SingleTireStatus} + */ + + + getRightFront() { + return this.getObject(SingleTireStatus, TireStatus.KEY_RIGHT_FRONT); + } + /** + * @param {SingleTireStatus} rear - The status of the left rear tire. + * @return {TireStatus} + */ + + + setLeftRear(rear) { + this.validateType(SingleTireStatus, rear); + this.setParameter(TireStatus.KEY_LEFT_REAR, rear); + return this; + } + /** + * @return {SingleTireStatus} + */ + + + getLeftRear() { + return this.getObject(SingleTireStatus, TireStatus.KEY_LEFT_REAR); + } + /** + * @param {SingleTireStatus} rear - The status of the right rear tire. + * @return {TireStatus} + */ + + + setRightRear(rear) { + this.validateType(SingleTireStatus, rear); + this.setParameter(TireStatus.KEY_RIGHT_REAR, rear); + return this; + } + /** + * @return {SingleTireStatus} + */ + + + getRightRear() { + return this.getObject(SingleTireStatus, TireStatus.KEY_RIGHT_REAR); + } + /** + * @param {SingleTireStatus} rear - The status of the inner left rear. + * @return {TireStatus} + */ + + + setInnerLeftRear(rear) { + this.validateType(SingleTireStatus, rear); + this.setParameter(TireStatus.KEY_INNER_LEFT_REAR, rear); + return this; + } + /** + * @return {SingleTireStatus} + */ + + + getInnerLeftRear() { + return this.getObject(SingleTireStatus, TireStatus.KEY_INNER_LEFT_REAR); + } + /** + * @param {SingleTireStatus} rear - The status of the inner right rear. + * @return {TireStatus} + */ + + + setInnerRightRear(rear) { + this.validateType(SingleTireStatus, rear); + this.setParameter(TireStatus.KEY_INNER_RIGHT_REAR, rear); + return this; + } + /** + * @return {SingleTireStatus} + */ + + + getInnerRightRear() { + return this.getObject(SingleTireStatus, TireStatus.KEY_INNER_RIGHT_REAR); + } + + } + + TireStatus.KEY_PRESSURE_TELLTALE = 'pressureTelltale'; + TireStatus.KEY_LEFT_FRONT = 'leftFront'; + TireStatus.KEY_RIGHT_FRONT = 'rightFront'; + TireStatus.KEY_LEFT_REAR = 'leftRear'; + TireStatus.KEY_RIGHT_REAR = 'rightRear'; + TireStatus.KEY_INNER_LEFT_REAR = 'innerLeftRear'; + TireStatus.KEY_INNER_RIGHT_REAR = 'innerRightRear'; + + /* eslint-disable camelcase */ + + class GetVehicleDataResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.GetVehicleData); + } + /** + * @param {GPSData} gps - See GPSData + * @return {GetVehicleDataResponse} + */ + + + setGps(gps) { + this.validateType(GPSData, gps); + this.setParameter(GetVehicleDataResponse.KEY_GPS, gps); + return this; + } + /** + * @return {GPSData} + */ + + + getGps() { + return this.getObject(GPSData, GetVehicleDataResponse.KEY_GPS); + } + /** + * @param {Number} speed - The vehicle speed in kilometers per hour + * @return {GetVehicleDataResponse} + */ + + + setSpeed(speed) { + this.setParameter(GetVehicleDataResponse.KEY_SPEED, speed); + return this; + } + /** + * @return {Number} + */ + + + getSpeed() { + return this.getParameter(GetVehicleDataResponse.KEY_SPEED); + } + /** + * @param {Number} rpm - The number of revolutions per minute of the engine + * @return {GetVehicleDataResponse} + */ + + + setRpm(rpm) { + this.setParameter(GetVehicleDataResponse.KEY_RPM, rpm); + return this; + } + /** + * @return {Number} + */ + + + getRpm() { + return this.getParameter(GetVehicleDataResponse.KEY_RPM); + } + /** + * @param {Number} level - The fuel level in the tank (percentage) + * @return {GetVehicleDataResponse} + */ + + + setFuelLevel(level) { + this.setParameter(GetVehicleDataResponse.KEY_FUEL_LEVEL, level); + return this; + } + /** + * @return {Number} + */ + + + getFuelLevel() { + return this.getParameter(GetVehicleDataResponse.KEY_FUEL_LEVEL); + } + /** + * @param {ComponentVolumeStatus} level_state - The fuel level state + * @return {GetVehicleDataResponse} + */ + + + setFuelLevel_State(level_state) { + this.validateType(ComponentVolumeStatus, level_state); + this.setParameter(GetVehicleDataResponse.KEY_FUEL_LEVEL_STATE, level_state); + return this; + } + /** + * @return {ComponentVolumeStatus} + */ + + + getFuelLevel_State() { + return this.getObject(ComponentVolumeStatus, GetVehicleDataResponse.KEY_FUEL_LEVEL_STATE); + } + /** + * @param {Number} consumption - The instantaneous fuel consumption in microlitres + * @return {GetVehicleDataResponse} + */ + + + setInstantFuelConsumption(consumption) { + this.setParameter(GetVehicleDataResponse.KEY_INSTANT_FUEL_CONSUMPTION, consumption); + return this; + } + /** + * @return {Number} + */ + + + getInstantFuelConsumption() { + return this.getParameter(GetVehicleDataResponse.KEY_INSTANT_FUEL_CONSUMPTION); + } + /** + * @param {FuelRange[]} range - The estimate range in KM the vehicle can travel based on fuel level and consumption + * @return {GetVehicleDataResponse} + */ + + + setFuelRange(range) { + this.validateType(FuelRange, range, true); + this.setParameter(GetVehicleDataResponse.KEY_FUEL_RANGE, range); + return this; + } + /** + * @return {FuelRange[]} + */ + + + getFuelRange() { + return this.getObject(FuelRange, GetVehicleDataResponse.KEY_FUEL_RANGE); + } + /** + * @param {Number} temperature - The external temperature in degrees celsius + * @return {GetVehicleDataResponse} + */ + + + setExternalTemperature(temperature) { + this.setParameter(GetVehicleDataResponse.KEY_EXTERNAL_TEMPERATURE, temperature); + return this; + } + /** + * @return {Number} + */ + + + getExternalTemperature() { + return this.getParameter(GetVehicleDataResponse.KEY_EXTERNAL_TEMPERATURE); + } + /** + * @param {TurnSignal} signal - See TurnSignal + * @return {GetVehicleDataResponse} + */ + + + setTurnSignal(signal) { + this.validateType(TurnSignal, signal); + this.setParameter(GetVehicleDataResponse.KEY_TURN_SIGNAL, signal); + return this; + } + /** + * @return {TurnSignal} + */ + + + getTurnSignal() { + return this.getObject(TurnSignal, GetVehicleDataResponse.KEY_TURN_SIGNAL); + } + /** + * @param {String} vin - Vehicle identification number + * @return {GetVehicleDataResponse} + */ + + + setVin(vin) { + this.setParameter(GetVehicleDataResponse.KEY_VIN, vin); + return this; + } + /** + * @return {String} + */ + + + getVin() { + return this.getParameter(GetVehicleDataResponse.KEY_VIN); + } + /** + * @param {PRNDL} prndl - See PRNDL + * @return {GetVehicleDataResponse} + */ + + + setPrndl(prndl) { + this.validateType(PRNDL, prndl); + this.setParameter(GetVehicleDataResponse.KEY_PRNDL, prndl); + return this; + } + /** + * @return {PRNDL} + */ + + + getPrndl() { + return this.getObject(PRNDL, GetVehicleDataResponse.KEY_PRNDL); + } + /** + * @param {TireStatus} pressure - See TireStatus + * @return {GetVehicleDataResponse} + */ + + + setTirePressure(pressure) { + this.validateType(TireStatus, pressure); + this.setParameter(GetVehicleDataResponse.KEY_TIRE_PRESSURE, pressure); + return this; + } + /** + * @return {TireStatus} + */ + + + getTirePressure() { + return this.getObject(TireStatus, GetVehicleDataResponse.KEY_TIRE_PRESSURE); + } + /** + * @param {Number} odometer - Odometer in km + * @return {GetVehicleDataResponse} + */ + + + setOdometer(odometer) { + this.setParameter(GetVehicleDataResponse.KEY_ODOMETER, odometer); + return this; + } + /** + * @return {Number} + */ + + + getOdometer() { + return this.getParameter(GetVehicleDataResponse.KEY_ODOMETER); + } + /** + * @param {BeltStatus} status - The status of the seat belts + * @return {GetVehicleDataResponse} + */ + + + setBeltStatus(status) { + this.validateType(BeltStatus, status); + this.setParameter(GetVehicleDataResponse.KEY_BELT_STATUS, status); + return this; + } + /** + * @return {BeltStatus} + */ + + + getBeltStatus() { + return this.getObject(BeltStatus, GetVehicleDataResponse.KEY_BELT_STATUS); + } + /** + * @param {BodyInformation} information - The body information including power modes + * @return {GetVehicleDataResponse} + */ + + + setBodyInformation(information) { + this.validateType(BodyInformation, information); + this.setParameter(GetVehicleDataResponse.KEY_BODY_INFORMATION, information); + return this; + } + /** + * @return {BodyInformation} + */ + + + getBodyInformation() { + return this.getObject(BodyInformation, GetVehicleDataResponse.KEY_BODY_INFORMATION); + } + /** + * @param {DeviceStatus} status - The device status including signal and battery strength + * @return {GetVehicleDataResponse} + */ + + + setDeviceStatus(status) { + this.validateType(DeviceStatus, status); + this.setParameter(GetVehicleDataResponse.KEY_DEVICE_STATUS, status); + return this; + } + /** + * @return {DeviceStatus} + */ + + + getDeviceStatus() { + return this.getObject(DeviceStatus, GetVehicleDataResponse.KEY_DEVICE_STATUS); + } + /** + * @param {VehicleDataEventStatus} braking - The status of the brake pedal + * @return {GetVehicleDataResponse} + */ + + + setDriverBraking(braking) { + this.validateType(VehicleDataEventStatus, braking); + this.setParameter(GetVehicleDataResponse.KEY_DRIVER_BRAKING, braking); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getDriverBraking() { + return this.getObject(VehicleDataEventStatus, GetVehicleDataResponse.KEY_DRIVER_BRAKING); + } + /** + * @param {WiperStatus} status - The status of the wipers + * @return {GetVehicleDataResponse} + */ + + + setWiperStatus(status) { + this.validateType(WiperStatus, status); + this.setParameter(GetVehicleDataResponse.KEY_WIPER_STATUS, status); + return this; + } + /** + * @return {WiperStatus} + */ + + + getWiperStatus() { + return this.getObject(WiperStatus, GetVehicleDataResponse.KEY_WIPER_STATUS); + } + /** + * @param {HeadLampStatus} status - Status of the head lamps + * @return {GetVehicleDataResponse} + */ + + + setHeadLampStatus(status) { + this.validateType(HeadLampStatus, status); + this.setParameter(GetVehicleDataResponse.KEY_HEAD_LAMP_STATUS, status); + return this; + } + /** + * @return {HeadLampStatus} + */ + + + getHeadLampStatus() { + return this.getObject(HeadLampStatus, GetVehicleDataResponse.KEY_HEAD_LAMP_STATUS); + } + /** + * @param {Number} torque - Torque value for engine (in Nm) on non-diesel variants + * @return {GetVehicleDataResponse} + */ + + + setEngineTorque(torque) { + this.setParameter(GetVehicleDataResponse.KEY_ENGINE_TORQUE, torque); + return this; + } + /** + * @return {Number} + */ + + + getEngineTorque() { + return this.getParameter(GetVehicleDataResponse.KEY_ENGINE_TORQUE); + } + /** + * @param {Number} position - Accelerator pedal position (percentage depressed) + * @return {GetVehicleDataResponse} + */ + + + setAccPedalPosition(position) { + this.setParameter(GetVehicleDataResponse.KEY_ACC_PEDAL_POSITION, position); + return this; + } + /** + * @return {Number} + */ + + + getAccPedalPosition() { + return this.getParameter(GetVehicleDataResponse.KEY_ACC_PEDAL_POSITION); + } + /** + * @param {Number} angle - Current angle of the steering wheel (in deg) + * @return {GetVehicleDataResponse} + */ + + + setSteeringWheelAngle(angle) { + this.setParameter(GetVehicleDataResponse.KEY_STEERING_WHEEL_ANGLE, angle); + return this; + } + /** + * @return {Number} + */ + + + getSteeringWheelAngle() { + return this.getParameter(GetVehicleDataResponse.KEY_STEERING_WHEEL_ANGLE); + } + /** + * @param {Number} life - The estimated percentage of remaining oil life of the engine. + * @return {GetVehicleDataResponse} + */ + + + setEngineOilLife(life) { + this.setParameter(GetVehicleDataResponse.KEY_ENGINE_OIL_LIFE, life); + return this; + } + /** + * @return {Number} + */ + + + getEngineOilLife() { + return this.getParameter(GetVehicleDataResponse.KEY_ENGINE_OIL_LIFE); + } + /** + * @param {ElectronicParkBrakeStatus} status - The status of the park brake as provided by Electric Park Brake (EPB) + * system. + * @return {GetVehicleDataResponse} + */ + + + setElectronicParkBrakeStatus(status) { + this.validateType(ElectronicParkBrakeStatus, status); + this.setParameter(GetVehicleDataResponse.KEY_ELECTRONIC_PARK_BRAKE_STATUS, status); + return this; + } + /** + * @return {ElectronicParkBrakeStatus} + */ + + + getElectronicParkBrakeStatus() { + return this.getObject(ElectronicParkBrakeStatus, GetVehicleDataResponse.KEY_ELECTRONIC_PARK_BRAKE_STATUS); + } + /** + * @param {String} id - Parameter used by cloud apps to identify a head unit + * @return {GetVehicleDataResponse} + */ + + + setCloudAppVehicleID(id) { + this.setParameter(GetVehicleDataResponse.KEY_CLOUD_APP_VEHICLE_ID, id); + return this; + } + /** + * @return {String} + */ + + + getCloudAppVehicleID() { + return this.getParameter(GetVehicleDataResponse.KEY_CLOUD_APP_VEHICLE_ID); + } + /** + * @param {ECallInfo} info - Emergency Call notification and confirmation data + * @return {GetVehicleDataResponse} + */ + + + setECallInfo(info) { + this.validateType(ECallInfo, info); + this.setParameter(GetVehicleDataResponse.KEY_E_CALL_INFO, info); + return this; + } + /** + * @return {ECallInfo} + */ + + + getECallInfo() { + return this.getObject(ECallInfo, GetVehicleDataResponse.KEY_E_CALL_INFO); + } + /** + * @param {AirbagStatus} status - The status of the air bags + * @return {GetVehicleDataResponse} + */ + + + setAirbagStatus(status) { + this.validateType(AirbagStatus, status); + this.setParameter(GetVehicleDataResponse.KEY_AIRBAG_STATUS, status); + return this; + } + /** + * @return {AirbagStatus} + */ + + + getAirbagStatus() { + return this.getObject(AirbagStatus, GetVehicleDataResponse.KEY_AIRBAG_STATUS); + } + /** + * @param {EmergencyEvent} event - Information related to an emergency event (and if it occurred) + * @return {GetVehicleDataResponse} + */ + + + setEmergencyEvent(event) { + this.validateType(EmergencyEvent, event); + this.setParameter(GetVehicleDataResponse.KEY_EMERGENCY_EVENT, event); + return this; + } + /** + * @return {EmergencyEvent} + */ + + + getEmergencyEvent() { + return this.getObject(EmergencyEvent, GetVehicleDataResponse.KEY_EMERGENCY_EVENT); + } + /** + * @param {ClusterModeStatus} status - The status modes of the cluster + * @return {GetVehicleDataResponse} + */ + + + setClusterModeStatus(status) { + this.validateType(ClusterModeStatus, status); + this.setParameter(GetVehicleDataResponse.KEY_CLUSTER_MODE_STATUS, status); + return this; + } + /** + * @return {ClusterModeStatus} + */ + + + getClusterModeStatus() { + return this.getObject(ClusterModeStatus, GetVehicleDataResponse.KEY_CLUSTER_MODE_STATUS); + } + /** + * @param {MyKey} key - Information related to the MyKey feature + * @return {GetVehicleDataResponse} + */ + + + setMyKey(key) { + this.validateType(MyKey, key); + this.setParameter(GetVehicleDataResponse.KEY_MY_KEY, key); + return this; + } + /** + * @return {MyKey} + */ + + + getMyKey() { + return this.getObject(MyKey, GetVehicleDataResponse.KEY_MY_KEY); + } + + } + + GetVehicleDataResponse.KEY_GPS = 'gps'; + GetVehicleDataResponse.KEY_SPEED = 'speed'; + GetVehicleDataResponse.KEY_RPM = 'rpm'; + GetVehicleDataResponse.KEY_FUEL_LEVEL = 'fuelLevel'; + GetVehicleDataResponse.KEY_FUEL_LEVEL_STATE = 'fuelLevel_State'; + GetVehicleDataResponse.KEY_INSTANT_FUEL_CONSUMPTION = 'instantFuelConsumption'; + GetVehicleDataResponse.KEY_FUEL_RANGE = 'fuelRange'; + GetVehicleDataResponse.KEY_EXTERNAL_TEMPERATURE = 'externalTemperature'; + GetVehicleDataResponse.KEY_TURN_SIGNAL = 'turnSignal'; + GetVehicleDataResponse.KEY_VIN = 'vin'; + GetVehicleDataResponse.KEY_PRNDL = 'prndl'; + GetVehicleDataResponse.KEY_TIRE_PRESSURE = 'tirePressure'; + GetVehicleDataResponse.KEY_ODOMETER = 'odometer'; + GetVehicleDataResponse.KEY_BELT_STATUS = 'beltStatus'; + GetVehicleDataResponse.KEY_BODY_INFORMATION = 'bodyInformation'; + GetVehicleDataResponse.KEY_DEVICE_STATUS = 'deviceStatus'; + GetVehicleDataResponse.KEY_DRIVER_BRAKING = 'driverBraking'; + GetVehicleDataResponse.KEY_WIPER_STATUS = 'wiperStatus'; + GetVehicleDataResponse.KEY_HEAD_LAMP_STATUS = 'headLampStatus'; + GetVehicleDataResponse.KEY_ENGINE_TORQUE = 'engineTorque'; + GetVehicleDataResponse.KEY_ACC_PEDAL_POSITION = 'accPedalPosition'; + GetVehicleDataResponse.KEY_STEERING_WHEEL_ANGLE = 'steeringWheelAngle'; + GetVehicleDataResponse.KEY_ENGINE_OIL_LIFE = 'engineOilLife'; + GetVehicleDataResponse.KEY_ELECTRONIC_PARK_BRAKE_STATUS = 'electronicParkBrakeStatus'; + GetVehicleDataResponse.KEY_CLOUD_APP_VEHICLE_ID = 'cloudAppVehicleID'; + GetVehicleDataResponse.KEY_E_CALL_INFO = 'eCallInfo'; + GetVehicleDataResponse.KEY_AIRBAG_STATUS = 'airbagStatus'; + GetVehicleDataResponse.KEY_EMERGENCY_EVENT = 'emergencyEvent'; + GetVehicleDataResponse.KEY_CLUSTER_MODE_STATUS = 'clusterModeStatus'; + GetVehicleDataResponse.KEY_MY_KEY = 'myKey'; + + /* eslint-disable camelcase */ + /** + * Non periodic vehicle data read request + */ + + class ReadDID extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.ReadDID); + } + /** + * @param {Number} name - Name of ECU. + * @return {ReadDID} + */ + + + setEcuName(name) { + this.setParameter(ReadDID.KEY_ECU_NAME, name); + return this; + } + /** + * @return {Number} + */ + + + getEcuName() { + return this.getParameter(ReadDID.KEY_ECU_NAME); + } + /** + * @param {Number[]} location - Get raw data from vehicle data DID location(s) + * @return {ReadDID} + */ + + + setDidLocation(location) { + this.setParameter(ReadDID.KEY_DID_LOCATION, location); + return this; + } + /** + * @return {Number[]} + */ + + + getDidLocation() { + return this.getParameter(ReadDID.KEY_DID_LOCATION); + } + + } + + ReadDID.KEY_ECU_NAME = 'ecuName'; + ReadDID.KEY_DID_LOCATION = 'didLocation'; + + /* eslint-disable camelcase */ + /** + * Individual requested DID result and data + */ + + class DIDResult extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {VehicleDataResultCode} code - Individual DID result code. + * @return {DIDResult} + */ + + + setResultCode(code) { + this.validateType(VehicleDataResultCode, code); + this.setParameter(DIDResult.KEY_RESULT_CODE, code); + return this; + } + /** + * @return {VehicleDataResultCode} + */ + + + getResultCode() { + return this.getObject(VehicleDataResultCode, DIDResult.KEY_RESULT_CODE); + } + /** + * @param {Number} location - Location of raw data from vehicle data DID + * @return {DIDResult} + */ + + + setDidLocation(location) { + this.setParameter(DIDResult.KEY_DID_LOCATION, location); + return this; + } + /** + * @return {Number} + */ + + + getDidLocation() { + return this.getParameter(DIDResult.KEY_DID_LOCATION); + } + /** + * @param {String} data - Raw DID-based data returned for requested element. + * @return {DIDResult} + */ + + + setData(data) { + this.setParameter(DIDResult.KEY_DATA, data); + return this; + } + /** + * @return {String} + */ + + + getData() { + return this.getParameter(DIDResult.KEY_DATA); + } + + } + + DIDResult.KEY_RESULT_CODE = 'resultCode'; + DIDResult.KEY_DID_LOCATION = 'didLocation'; + DIDResult.KEY_DATA = 'data'; + + /* eslint-disable camelcase */ + + class ReadDIDResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.ReadDID); + } + /** + * @param {DIDResult[]} result - Array of requested DID results (with data if available). + * @return {ReadDIDResponse} + */ + + + setDidResult(result) { + this.validateType(DIDResult, result, true); + this.setParameter(ReadDIDResponse.KEY_DID_RESULT, result); + return this; + } + /** + * @return {DIDResult[]} + */ + + + getDidResult() { + return this.getObject(DIDResult, ReadDIDResponse.KEY_DID_RESULT); + } + + } + + ReadDIDResponse.KEY_DID_RESULT = 'didResult'; + + /* eslint-disable camelcase */ + /** + * Vehicle module diagnostic trouble code request. + */ + + class GetDTCs extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.GetDTCs); + } + /** + * @param {Number} name - Name of ECU. + * @return {GetDTCs} + */ + + + setEcuName(name) { + this.setParameter(GetDTCs.KEY_ECU_NAME, name); + return this; + } + /** + * @return {Number} + */ + + + getEcuName() { + return this.getParameter(GetDTCs.KEY_ECU_NAME); + } + /** + * @param {Number} mask - DTC Mask Byte to be sent in diagnostic request to module . + * @return {GetDTCs} + */ + + + setDtcMask(mask) { + this.setParameter(GetDTCs.KEY_DTC_MASK, mask); + return this; + } + /** + * @return {Number} + */ + + + getDtcMask() { + return this.getParameter(GetDTCs.KEY_DTC_MASK); + } + + } + + GetDTCs.KEY_ECU_NAME = 'ecuName'; + GetDTCs.KEY_DTC_MASK = 'dtcMask'; + + /* eslint-disable camelcase */ + + class GetDTCsResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.GetDTCs); + } + /** + * @param {Number} header - 2 byte ECU Header for DTC response (as defined in VHR_Layout_Specification_DTCs.pdf) + * @return {GetDTCsResponse} + */ + + + setEcuHeader(header) { + this.setParameter(GetDTCsResponse.KEY_ECU_HEADER, header); + return this; + } + /** + * @return {Number} + */ + + + getEcuHeader() { + return this.getParameter(GetDTCsResponse.KEY_ECU_HEADER); + } + /** + * @param {String[]} dtc - Array of all reported DTCs on module (ecuHeader contains information if list is + * truncated). Each DTC is represented by 4 bytes (3 bytes of data and 1 byte status as + * defined in VHR_Layout_Specification_DTCs.pdf). + * @return {GetDTCsResponse} + */ + + + setDtc(dtc) { + this.setParameter(GetDTCsResponse.KEY_DTC, dtc); + return this; + } + /** + * @return {String[]} + */ + + + getDtc() { + return this.getParameter(GetDTCsResponse.KEY_DTC); + } + + } + + GetDTCsResponse.KEY_ECU_HEADER = 'ecuHeader'; + GetDTCsResponse.KEY_DTC = 'dtc'; + + /* eslint-disable camelcase */ + /** + * Non periodic vehicle diagnostic request + */ + + class DiagnosticMessage extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.DiagnosticMessage); + } + /** + * @param {Number} id - Name of target ECU. + * @return {DiagnosticMessage} + */ + + + setTargetID(id) { + this.setParameter(DiagnosticMessage.KEY_TARGET_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getTargetID() { + return this.getParameter(DiagnosticMessage.KEY_TARGET_ID); + } + /** + * @param {Number} length - Length of message (in bytes). + * @return {DiagnosticMessage} + */ + + + setMessageLength(length) { + this.setParameter(DiagnosticMessage.KEY_MESSAGE_LENGTH, length); + return this; + } + /** + * @return {Number} + */ + + + getMessageLength() { + return this.getParameter(DiagnosticMessage.KEY_MESSAGE_LENGTH); + } + /** + * @param {Number[]} data - Array of bytes comprising CAN message. + * @return {DiagnosticMessage} + */ + + + setMessageData(data) { + this.setParameter(DiagnosticMessage.KEY_MESSAGE_DATA, data); + return this; + } + /** + * @return {Number[]} + */ + + + getMessageData() { + return this.getParameter(DiagnosticMessage.KEY_MESSAGE_DATA); + } + + } + + DiagnosticMessage.KEY_TARGET_ID = 'targetID'; + DiagnosticMessage.KEY_MESSAGE_LENGTH = 'messageLength'; + DiagnosticMessage.KEY_MESSAGE_DATA = 'messageData'; + + /* eslint-disable camelcase */ + + class DiagnosticMessageResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.DiagnosticMessage); + } + /** + * @param {Number[]} result - Array of bytes comprising CAN message result. + * @return {DiagnosticMessageResponse} + */ + + + setMessageDataResult(result) { + this.setParameter(DiagnosticMessageResponse.KEY_MESSAGE_DATA_RESULT, result); + return this; + } + /** + * @return {Number[]} + */ + + + getMessageDataResult() { + return this.getParameter(DiagnosticMessageResponse.KEY_MESSAGE_DATA_RESULT); + } + + } + + DiagnosticMessageResponse.KEY_MESSAGE_DATA_RESULT = 'messageDataResult'; + + /* eslint-disable camelcase */ + /** + * Creates a full screen overlay containing a large block of formatted text that can be scrolled with up to 8 + * SoftButtons defined + */ + + class ScrollableMessage extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.ScrollableMessage); + } + /** + * @param {String} body - Body of text that can include newlines and tabs. + * @return {ScrollableMessage} + */ + + + setScrollableMessageBody(body) { + this.setParameter(ScrollableMessage.KEY_SCROLLABLE_MESSAGE_BODY, body); + return this; + } + /** + * @return {String} + */ + + + getScrollableMessageBody() { + return this.getParameter(ScrollableMessage.KEY_SCROLLABLE_MESSAGE_BODY); + } + /** + * @param {Number} timeout - App defined timeout. Indicates how long of a timeout from the last action (i.e. + * scrolling message resets timeout). + * @return {ScrollableMessage} + */ + + + setTimeout(timeout) { + this.setParameter(ScrollableMessage.KEY_TIMEOUT, timeout); + return this; + } + /** + * @return {Number} + */ + + + getTimeout() { + return this.getParameter(ScrollableMessage.KEY_TIMEOUT); + } + /** + * @param {SoftButton[]} buttons - App defined SoftButtons. If omitted on supported displays, only the system + * defined "Close" SoftButton will be displayed. + * @return {ScrollableMessage} + */ + + + setSoftButtons(buttons) { + this.validateType(SoftButton, buttons, true); + this.setParameter(ScrollableMessage.KEY_SOFT_BUTTONS, buttons); + return this; + } + /** + * @return {SoftButton[]} + */ + + + getSoftButtons() { + return this.getObject(SoftButton, ScrollableMessage.KEY_SOFT_BUTTONS); + } + /** + * @param {Number} id - An ID for this specific ScrollableMessage to allow cancellation through the + * `CancelInteraction` RPC. + * @return {ScrollableMessage} + */ + + + setCancelID(id) { + this.setParameter(ScrollableMessage.KEY_CANCEL_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getCancelID() { + return this.getParameter(ScrollableMessage.KEY_CANCEL_ID); + } + + } + + ScrollableMessage.KEY_SCROLLABLE_MESSAGE_BODY = 'scrollableMessageBody'; + ScrollableMessage.KEY_TIMEOUT = 'timeout'; + ScrollableMessage.KEY_SOFT_BUTTONS = 'softButtons'; + ScrollableMessage.KEY_CANCEL_ID = 'cancelID'; + + /* eslint-disable camelcase */ + + class ScrollableMessageResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.ScrollableMessage); + } + + } + + /* eslint-disable camelcase */ + /** + * Creates a full screen or pop-up overlay (depending on platform) with a single user controlled slider. + */ + + class Slider extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.Slider); + } + /** + * @param {Number} ticks - Number of selectable items on a horizontal axis + * @return {Slider} + */ + + + setNumTicks(ticks) { + this.setParameter(Slider.KEY_NUM_TICKS, ticks); + return this; + } + /** + * @return {Number} + */ + + + getNumTicks() { + return this.getParameter(Slider.KEY_NUM_TICKS); + } + /** + * @param {Number} position - Initial position of slider control (cannot exceed numTicks) + * @return {Slider} + */ + + + setPosition(position) { + this.setParameter(Slider.KEY_POSITION, position); + return this; + } + /** + * @return {Number} + */ + + + getPosition() { + return this.getParameter(Slider.KEY_POSITION); + } + /** + * @param {String} header - Text header to display + * @return {Slider} + */ + + + setSliderHeader(header) { + this.setParameter(Slider.KEY_SLIDER_HEADER, header); + return this; + } + /** + * @return {String} + */ + + + getSliderHeader() { + return this.getParameter(Slider.KEY_SLIDER_HEADER); + } + /** + * @param {String[]} footer - Text footer to display (meant to display min/max threshold descriptors). For a static + * text footer, only one footer string shall be provided in the array. For a dynamic text + * footer, the number of footer text string in the array must match the numTicks value. + * For a dynamic text footer, text array string should correlate with potential slider + * position index. If omitted on supported displays, no footer text shall be displayed. + * @return {Slider} + */ + + + setSliderFooter(footer) { + this.setParameter(Slider.KEY_SLIDER_FOOTER, footer); + return this; + } + /** + * @return {String[]} + */ + + + getSliderFooter() { + return this.getParameter(Slider.KEY_SLIDER_FOOTER); + } + /** + * @param {Number} timeout - App defined timeout. Indicates how long of a timeout from the last action (i.e. sliding + * control resets timeout). If omitted, the value is set to 10000. + * @return {Slider} + */ + + + setTimeout(timeout) { + this.setParameter(Slider.KEY_TIMEOUT, timeout); + return this; + } + /** + * @return {Number} + */ + + + getTimeout() { + return this.getParameter(Slider.KEY_TIMEOUT); + } + /** + * @param {Number} id - An ID for this specific Slider to allow cancellation through the `CancelInteraction` RPC. + * @return {Slider} + */ + + + setCancelID(id) { + this.setParameter(Slider.KEY_CANCEL_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getCancelID() { + return this.getParameter(Slider.KEY_CANCEL_ID); + } + + } + + Slider.KEY_NUM_TICKS = 'numTicks'; + Slider.KEY_POSITION = 'position'; + Slider.KEY_SLIDER_HEADER = 'sliderHeader'; + Slider.KEY_SLIDER_FOOTER = 'sliderFooter'; + Slider.KEY_TIMEOUT = 'timeout'; + Slider.KEY_CANCEL_ID = 'cancelID'; + + /* eslint-disable camelcase */ + + class SliderResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.Slider); + } + /** + * @param {Number} position - Current slider value returned when saved or canceled (aborted) This value is only + * returned for resultCodes "SAVED" or "ABORTED" + * @return {SliderResponse} + */ + + + setSliderPosition(position) { + this.setParameter(SliderResponse.KEY_SLIDER_POSITION, position); + return this; + } + /** + * @return {Number} + */ + + + getSliderPosition() { + return this.getParameter(SliderResponse.KEY_SLIDER_POSITION); + } + + } + + SliderResponse.KEY_SLIDER_POSITION = 'sliderPosition'; + + /* eslint-disable camelcase */ + + class ShowConstantTBT extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.ShowConstantTBT); + } + /** + * @param {String} text1 + * @return {ShowConstantTBT} + */ + + + setNavigationText1(text1) { + this.setParameter(ShowConstantTBT.KEY_NAVIGATION_TEXT_1, text1); + return this; + } + /** + * @return {String} + */ + + + getNavigationText1() { + return this.getParameter(ShowConstantTBT.KEY_NAVIGATION_TEXT_1); + } + /** + * @param {String} text2 + * @return {ShowConstantTBT} + */ + + + setNavigationText2(text2) { + this.setParameter(ShowConstantTBT.KEY_NAVIGATION_TEXT_2, text2); + return this; + } + /** + * @return {String} + */ + + + getNavigationText2() { + return this.getParameter(ShowConstantTBT.KEY_NAVIGATION_TEXT_2); + } + /** + * @param {String} eta + * @return {ShowConstantTBT} + */ + + + setEta(eta) { + this.setParameter(ShowConstantTBT.KEY_ETA, eta); + return this; + } + /** + * @return {String} + */ + + + getEta() { + return this.getParameter(ShowConstantTBT.KEY_ETA); + } + /** + * @param {String} destination + * @return {ShowConstantTBT} + */ + + + setTimeToDestination(destination) { + this.setParameter(ShowConstantTBT.KEY_TIME_TO_DESTINATION, destination); + return this; + } + /** + * @return {String} + */ + + + getTimeToDestination() { + return this.getParameter(ShowConstantTBT.KEY_TIME_TO_DESTINATION); + } + /** + * @param {String} distance + * @return {ShowConstantTBT} + */ + + + setTotalDistance(distance) { + this.setParameter(ShowConstantTBT.KEY_TOTAL_DISTANCE, distance); + return this; + } + /** + * @return {String} + */ + + + getTotalDistance() { + return this.getParameter(ShowConstantTBT.KEY_TOTAL_DISTANCE); + } + /** + * @param {Image} icon + * @return {ShowConstantTBT} + */ + + + setTurnIcon(icon) { + this.validateType(Image, icon); + this.setParameter(ShowConstantTBT.KEY_TURN_ICON, icon); + return this; + } + /** + * @return {Image} + */ + + + getTurnIcon() { + return this.getObject(Image, ShowConstantTBT.KEY_TURN_ICON); + } + /** + * @param {Image} icon + * @return {ShowConstantTBT} + */ + + + setNextTurnIcon(icon) { + this.validateType(Image, icon); + this.setParameter(ShowConstantTBT.KEY_NEXT_TURN_ICON, icon); + return this; + } + /** + * @return {Image} + */ + + + getNextTurnIcon() { + return this.getObject(Image, ShowConstantTBT.KEY_NEXT_TURN_ICON); + } + /** + * @param {Number} maneuver - Fraction of distance till next maneuver (starting from when AlertManeuver is + * triggered). Used to calculate progress bar. + * @return {ShowConstantTBT} + */ + + + setDistanceToManeuver(maneuver) { + this.setParameter(ShowConstantTBT.KEY_DISTANCE_TO_MANEUVER, maneuver); + return this; + } + /** + * @return {Number} + */ + + + getDistanceToManeuver() { + return this.getParameter(ShowConstantTBT.KEY_DISTANCE_TO_MANEUVER); + } + /** + * @param {Number} scale - Distance till next maneuver (starting from) from previous maneuver. Used to calculate + * progress bar. + * @return {ShowConstantTBT} + */ + + + setDistanceToManeuverScale(scale) { + this.setParameter(ShowConstantTBT.KEY_DISTANCE_TO_MANEUVER_SCALE, scale); + return this; + } + /** + * @return {Number} + */ + + + getDistanceToManeuverScale() { + return this.getParameter(ShowConstantTBT.KEY_DISTANCE_TO_MANEUVER_SCALE); + } + /** + * @param {Boolean} complete - If and when a maneuver has completed while an AlertManeuver is active, the app must + * send this value set to TRUE in order to clear the AlertManeuver overlay. If omitted + * the value will be assumed as FALSE. + * @return {ShowConstantTBT} + */ + + + setManeuverComplete(complete) { + this.setParameter(ShowConstantTBT.KEY_MANEUVER_COMPLETE, complete); + return this; + } + /** + * @return {Boolean} + */ + + + getManeuverComplete() { + return this.getParameter(ShowConstantTBT.KEY_MANEUVER_COMPLETE); + } + /** + * @param {SoftButton[]} buttons - Three dynamic SoftButtons available (first SoftButton is fixed to "Turns"). If + * omitted on supported displays, the currently displayed SoftButton values will not + * change. + * @return {ShowConstantTBT} + */ + + + setSoftButtons(buttons) { + this.validateType(SoftButton, buttons, true); + this.setParameter(ShowConstantTBT.KEY_SOFT_BUTTONS, buttons); + return this; + } + /** + * @return {SoftButton[]} + */ + + + getSoftButtons() { + return this.getObject(SoftButton, ShowConstantTBT.KEY_SOFT_BUTTONS); + } + + } + + ShowConstantTBT.KEY_NAVIGATION_TEXT_1 = 'navigationText1'; + ShowConstantTBT.KEY_NAVIGATION_TEXT_2 = 'navigationText2'; + ShowConstantTBT.KEY_ETA = 'eta'; + ShowConstantTBT.KEY_TIME_TO_DESTINATION = 'timeToDestination'; + ShowConstantTBT.KEY_TOTAL_DISTANCE = 'totalDistance'; + ShowConstantTBT.KEY_TURN_ICON = 'turnIcon'; + ShowConstantTBT.KEY_NEXT_TURN_ICON = 'nextTurnIcon'; + ShowConstantTBT.KEY_DISTANCE_TO_MANEUVER = 'distanceToManeuver'; + ShowConstantTBT.KEY_DISTANCE_TO_MANEUVER_SCALE = 'distanceToManeuverScale'; + ShowConstantTBT.KEY_MANEUVER_COMPLETE = 'maneuverComplete'; + ShowConstantTBT.KEY_SOFT_BUTTONS = 'softButtons'; + + /* eslint-disable camelcase */ + + class ShowConstantTBTResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.ShowConstantTBT); + } + + } + + /* eslint-disable camelcase */ + + class AlertManeuver extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.AlertManeuver); + } + /** + * @param {TTSChunk[]} chunks - An array of text chunks of type TTSChunk. See TTSChunk + * @return {AlertManeuver} + */ + + + setTtsChunks(chunks) { + this.validateType(TTSChunk, chunks, true); + this.setParameter(AlertManeuver.KEY_TTS_CHUNKS, chunks); + return this; + } + /** + * @return {TTSChunk[]} + */ + + + getTtsChunks() { + return this.getObject(TTSChunk, AlertManeuver.KEY_TTS_CHUNKS); + } + /** + * @param {SoftButton[]} buttons - If omitted on supported displays, only the system defined "Close" SoftButton + * shall be displayed. + * @return {AlertManeuver} + */ + + + setSoftButtons(buttons) { + this.validateType(SoftButton, buttons, true); + this.setParameter(AlertManeuver.KEY_SOFT_BUTTONS, buttons); + return this; + } + /** + * @return {SoftButton[]} + */ + + + getSoftButtons() { + return this.getObject(SoftButton, AlertManeuver.KEY_SOFT_BUTTONS); + } + + } + + AlertManeuver.KEY_TTS_CHUNKS = 'ttsChunks'; + AlertManeuver.KEY_SOFT_BUTTONS = 'softButtons'; + + /* eslint-disable camelcase */ + + class AlertManeuverResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.AlertManeuver); + } + + } + + /* eslint-disable camelcase */ + + class Turn extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {String} text - Individual turn text. Must provide at least text or icon for a given turn. + * @return {Turn} + */ + + + setNavigationText(text) { + this.setParameter(Turn.KEY_NAVIGATION_TEXT, text); + return this; + } + /** + * @return {String} + */ + + + getNavigationText() { + return this.getParameter(Turn.KEY_NAVIGATION_TEXT); + } + /** + * @param {Image} icon - Individual turn icon. Must provide at least text or icon for a given turn. + * @return {Turn} + */ + + + setTurnIcon(icon) { + this.validateType(Image, icon); + this.setParameter(Turn.KEY_TURN_ICON, icon); + return this; + } + /** + * @return {Image} + */ + + + getTurnIcon() { + return this.getObject(Image, Turn.KEY_TURN_ICON); + } + + } + + Turn.KEY_NAVIGATION_TEXT = 'navigationText'; + Turn.KEY_TURN_ICON = 'turnIcon'; + + /* eslint-disable camelcase */ + + class UpdateTurnList extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.UpdateTurnList); + } + /** + * @param {Turn[]} list + * @return {UpdateTurnList} + */ + + + setTurnList(list) { + this.validateType(Turn, list, true); + this.setParameter(UpdateTurnList.KEY_TURN_LIST, list); + return this; + } + /** + * @return {Turn[]} + */ + + + getTurnList() { + return this.getObject(Turn, UpdateTurnList.KEY_TURN_LIST); + } + /** + * @param {SoftButton[]} buttons - If omitted on supported displays, app-defined SoftButton will be left blank. + * @return {UpdateTurnList} + */ + + + setSoftButtons(buttons) { + this.validateType(SoftButton, buttons, true); + this.setParameter(UpdateTurnList.KEY_SOFT_BUTTONS, buttons); + return this; + } + /** + * @return {SoftButton[]} + */ + + + getSoftButtons() { + return this.getObject(SoftButton, UpdateTurnList.KEY_SOFT_BUTTONS); + } + + } + + UpdateTurnList.KEY_TURN_LIST = 'turnList'; + UpdateTurnList.KEY_SOFT_BUTTONS = 'softButtons'; + + /* eslint-disable camelcase */ + + class UpdateTurnListResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.UpdateTurnList); + } + + } + + /* eslint-disable camelcase */ + + class ChangeRegistration extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.ChangeRegistration); + } + /** + * @param {Language} language - Requested voice engine (VR+TTS) language registration + * @return {ChangeRegistration} + */ + + + setLanguage(language) { + this.validateType(Language, language); + this.setParameter(ChangeRegistration.KEY_LANGUAGE, language); + return this; + } + /** + * @return {Language} + */ + + + getLanguage() { + return this.getObject(Language, ChangeRegistration.KEY_LANGUAGE); + } + /** + * @param {Language} language - Request display language registration + * @return {ChangeRegistration} + */ + + + setHmiDisplayLanguage(language) { + this.validateType(Language, language); + this.setParameter(ChangeRegistration.KEY_HMI_DISPLAY_LANGUAGE, language); + return this; + } + /** + * @return {Language} + */ + + + getHmiDisplayLanguage() { + return this.getObject(Language, ChangeRegistration.KEY_HMI_DISPLAY_LANGUAGE); + } + /** + * @param {String} name - Request new app name registration + * @return {ChangeRegistration} + */ + + + setAppName(name) { + this.setParameter(ChangeRegistration.KEY_APP_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getAppName() { + return this.getParameter(ChangeRegistration.KEY_APP_NAME); + } + /** + * @param {TTSChunk[]} name - Request new ttsName registration + * @return {ChangeRegistration} + */ + + + setTtsName(name) { + this.validateType(TTSChunk, name, true); + this.setParameter(ChangeRegistration.KEY_TTS_NAME, name); + return this; + } + /** + * @return {TTSChunk[]} + */ + + + getTtsName() { + return this.getObject(TTSChunk, ChangeRegistration.KEY_TTS_NAME); + } + /** + * @param {String} name - Request new app short name registration + * @return {ChangeRegistration} + */ + + + setNgnMediaScreenAppName(name) { + this.setParameter(ChangeRegistration.KEY_NGN_MEDIA_SCREEN_APP_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getNgnMediaScreenAppName() { + return this.getParameter(ChangeRegistration.KEY_NGN_MEDIA_SCREEN_APP_NAME); + } + /** + * @param {String[]} synonyms - Request new VR synonyms registration + * @return {ChangeRegistration} + */ + + + setVrSynonyms(synonyms) { + this.setParameter(ChangeRegistration.KEY_VR_SYNONYMS, synonyms); + return this; + } + /** + * @return {String[]} + */ + + + getVrSynonyms() { + return this.getParameter(ChangeRegistration.KEY_VR_SYNONYMS); + } + + } + + ChangeRegistration.KEY_LANGUAGE = 'language'; + ChangeRegistration.KEY_HMI_DISPLAY_LANGUAGE = 'hmiDisplayLanguage'; + ChangeRegistration.KEY_APP_NAME = 'appName'; + ChangeRegistration.KEY_TTS_NAME = 'ttsName'; + ChangeRegistration.KEY_NGN_MEDIA_SCREEN_APP_NAME = 'ngnMediaScreenAppName'; + ChangeRegistration.KEY_VR_SYNONYMS = 'vrSynonyms'; + + /* eslint-disable camelcase */ + + class ChangeRegistrationResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.ChangeRegistration); + } + + } + + /* eslint-disable camelcase */ + /** + * Generic Response is sent, when the name of a received msg cannot be retrieved. Only used in case of an error. + * Currently, only resultCode INVALID_DATA is used. + */ + + class GenericResponseResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.GenericResponse); + } + + } + + /* eslint-disable camelcase */ + /** + * Used to push a binary data onto the module from a mobile device, such as icons and album art Not supported on first + * generation of SDL enabled modules. Binary data is in binary part of hybrid msg. + */ + + class PutFile extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.PutFile); + } // ------ Not part of the RPC spec itself ----- + + /** + * @param {Uint8Array} fileData + * @return {PutFile} + */ + + + setFileData(fileData) { + this.setBulkData(fileData); + return this; + } + /** + * @return {Uint8Array} + */ + + + getFileData() { + return this.getBulkData(); + } // ----------------- END ----------------------- + + /** + * @param {String} name - File reference name. + * @return {PutFile} + */ + + + setFileName(name) { + this.setParameter(PutFile.KEY_FILE_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getFileName() { + return this.getParameter(PutFile.KEY_FILE_NAME); + } + /** + * @param {FileType} type - Selected file type. + * @return {PutFile} + */ + + + setFileType(type) { + this.validateType(FileType, type); + this.setParameter(PutFile.KEY_FILE_TYPE, type); + return this; + } + /** + * @return {FileType} + */ + + + getFileType() { + return this.getObject(FileType, PutFile.KEY_FILE_TYPE); + } + /** + * @param {Boolean} file - Indicates if the file is meant to persist between sessions / ignition cycles. If set to + * TRUE, then the system will aim to persist this file through session / cycles. While files + * with this designation will have priority over others, they are subject to deletion by the + * system at any time. In the event of automatic deletion by the system, the app will + * receive a rejection and have to resend the file. If omitted, the value will be set to + * false. + * @return {PutFile} + */ + + + setPersistentFile(file) { + this.setParameter(PutFile.KEY_PERSISTENT_FILE, file); + return this; + } + /** + * @return {Boolean} + */ + + + getPersistentFile() { + return this.getParameter(PutFile.KEY_PERSISTENT_FILE); + } + /** + * @param {Boolean} file - Indicates if the file is meant to be passed thru core to elsewhere on the system. If set + * to TRUE, then the system will instead pass the data thru as it arrives to a predetermined + * area outside of core. If omitted, the value will be set to false. + * @return {PutFile} + */ + + + setSystemFile(file) { + this.setParameter(PutFile.KEY_SYSTEM_FILE, file); + return this; + } + /** + * @return {Boolean} + */ + + + getSystemFile() { + return this.getParameter(PutFile.KEY_SYSTEM_FILE); + } + /** + * @param {Number} offset - Optional offset in bytes for resuming partial data chunks + * @return {PutFile} + */ + + + setOffset(offset) { + this.setParameter(PutFile.KEY_OFFSET, offset); + return this; + } + /** + * @return {Number} + */ + + + getOffset() { + return this.getParameter(PutFile.KEY_OFFSET); + } + /** + * @param {Number} length - Optional length in bytes for resuming partial data chunks If offset is set to 0, then + * length is the total length of the file to be downloaded + * @return {PutFile} + */ + + + setLength(length) { + this.setParameter(PutFile.KEY_LENGTH, length); + return this; + } + /** + * @return {Number} + */ + + + getLength() { + return this.getParameter(PutFile.KEY_LENGTH); + } + /** + * @param {Number} crc - Additional CRC32 checksum to protect data integrity up to 512 Mbits + * @return {PutFile} + */ + + + setCrc(crc) { + this.setParameter(PutFile.KEY_CRC, crc); + return this; + } + /** + * @return {Number} + */ + + + getCrc() { + return this.getParameter(PutFile.KEY_CRC); + } + + } + + PutFile.KEY_FILE_NAME = 'syncFileName'; + PutFile.KEY_FILE_TYPE = 'fileType'; + PutFile.KEY_PERSISTENT_FILE = 'persistentFile'; + PutFile.KEY_SYSTEM_FILE = 'systemFile'; + PutFile.KEY_OFFSET = 'offset'; + PutFile.KEY_LENGTH = 'length'; + PutFile.KEY_CRC = 'crc'; + + /* eslint-disable camelcase */ + /** + * Response is sent, when the file data was copied (success case). Or when an error occurred. Not supported on first + * generation SDL enabled vehicles. + */ + + class PutFileResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.PutFile); + } + /** + * @param {Number} available - Provides the total local space available in SDL Core for the registered app. If the + * transfer has systemFile enabled, then the value will be set to 0 automatically. + * @return {PutFileResponse} + */ + + + setSpaceAvailable(available) { + this.setParameter(PutFileResponse.KEY_SPACE_AVAILABLE, available); + return this; + } + /** + * @return {Number} + */ + + + getSpaceAvailable() { + return this.getParameter(PutFileResponse.KEY_SPACE_AVAILABLE); + } + + } + + PutFileResponse.KEY_SPACE_AVAILABLE = 'spaceAvailable'; + + /* eslint-disable camelcase */ + /** + * This request is sent to the module to retrieve a file + */ + + class GetFile extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.GetFile); + } + /** + * @param {String} name - File name that should be retrieved + * @return {GetFile} + */ + + + setFileName(name) { + this.setParameter(GetFile.KEY_FILE_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getFileName() { + return this.getParameter(GetFile.KEY_FILE_NAME); + } + /** + * @param {String} id - ID of the service that should have uploaded the requested file. + * @return {GetFile} + */ + + + setAppServiceId(id) { + this.setParameter(GetFile.KEY_APP_SERVICE_ID, id); + return this; + } + /** + * @return {String} + */ + + + getAppServiceId() { + return this.getParameter(GetFile.KEY_APP_SERVICE_ID); + } + /** + * @param {FileType} type - Selected file type. + * @return {GetFile} + */ + + + setFileType(type) { + this.validateType(FileType, type); + this.setParameter(GetFile.KEY_FILE_TYPE, type); + return this; + } + /** + * @return {FileType} + */ + + + getFileType() { + return this.getObject(FileType, GetFile.KEY_FILE_TYPE); + } + /** + * @param {Number} offset - Optional offset in bytes for resuming partial data chunks + * @return {GetFile} + */ + + + setOffset(offset) { + this.setParameter(GetFile.KEY_OFFSET, offset); + return this; + } + /** + * @return {Number} + */ + + + getOffset() { + return this.getParameter(GetFile.KEY_OFFSET); + } + /** + * @param {Number} length - Optional length in bytes for resuming partial data chunks If offset is set to 0, then + * length is the total length of the file to be retrieved + * @return {GetFile} + */ + + + setLength(length) { + this.setParameter(GetFile.KEY_LENGTH, length); + return this; + } + /** + * @return {Number} + */ + + + getLength() { + return this.getParameter(GetFile.KEY_LENGTH); + } + + } + + GetFile.KEY_FILE_NAME = 'fileName'; + GetFile.KEY_APP_SERVICE_ID = 'appServiceId'; + GetFile.KEY_FILE_TYPE = 'fileType'; + GetFile.KEY_OFFSET = 'offset'; + GetFile.KEY_LENGTH = 'length'; + + /* eslint-disable camelcase */ + /** + * This response includes the data that is requested from the specific service + */ + + class GetFileResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.GetFile); + } + /** + * @param {Number} offset - Optional offset in bytes for resuming partial data chunks + * @return {GetFileResponse} + */ + + + setOffset(offset) { + this.setParameter(GetFileResponse.KEY_OFFSET, offset); + return this; + } + /** + * @return {Number} + */ + + + getOffset() { + return this.getParameter(GetFileResponse.KEY_OFFSET); + } + /** + * @param {Number} length - Optional length in bytes for resuming partial data chunks if offset is set to 0, then + * length is the total length of the file to be downloaded + * @return {GetFileResponse} + */ + + + setLength(length) { + this.setParameter(GetFileResponse.KEY_LENGTH, length); + return this; + } + /** + * @return {Number} + */ + + + getLength() { + return this.getParameter(GetFileResponse.KEY_LENGTH); + } + /** + * @param {FileType} type - File type that is being sent in response. + * @return {GetFileResponse} + */ + + + setFileType(type) { + this.validateType(FileType, type); + this.setParameter(GetFileResponse.KEY_FILE_TYPE, type); + return this; + } + /** + * @return {FileType} + */ + + + getFileType() { + return this.getObject(FileType, GetFileResponse.KEY_FILE_TYPE); + } + /** + * @param {Number} crc - Additional CRC32 checksum to protect data integrity up to 512 Mbits + * @return {GetFileResponse} + */ + + + setCrc(crc) { + this.setParameter(GetFileResponse.KEY_CRC, crc); + return this; + } + /** + * @return {Number} + */ + + + getCrc() { + return this.getParameter(GetFileResponse.KEY_CRC); + } + + } + + GetFileResponse.KEY_OFFSET = 'offset'; + GetFileResponse.KEY_LENGTH = 'length'; + GetFileResponse.KEY_FILE_TYPE = 'fileType'; + GetFileResponse.KEY_CRC = 'crc'; + + /* eslint-disable camelcase */ + /** + * Used to delete a file resident on the module in the app's local cache. Not supported on first generation SDL enabled + * vehicles. + */ + + class DeleteFile extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.DeleteFile); + } + /** + * @param {String} name - File reference name. + * @return {DeleteFile} + */ + + + setSdlFileName(name) { + this.setParameter(DeleteFile.KEY_SDL_FILE_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getSdlFileName() { + return this.getParameter(DeleteFile.KEY_SDL_FILE_NAME); + } + + } + + DeleteFile.KEY_SDL_FILE_NAME = 'syncFileName'; + + /* eslint-disable camelcase */ + /** + * Response is sent, when the file data was deleted (success case). Or when an error occurred. Not supported on First + * generation SDL enabled vehicles. + */ + + class DeleteFileResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.DeleteFile); + } + /** + * @param {Number} available - Provides the total local space available on the module for the registered app. + * @return {DeleteFileResponse} + */ + + + setSpaceAvailable(available) { + this.setParameter(DeleteFileResponse.KEY_SPACE_AVAILABLE, available); + return this; + } + /** + * @return {Number} + */ + + + getSpaceAvailable() { + return this.getParameter(DeleteFileResponse.KEY_SPACE_AVAILABLE); + } + + } + + DeleteFileResponse.KEY_SPACE_AVAILABLE = 'spaceAvailable'; + + /* eslint-disable camelcase */ + /** + * Requests the current list of resident filenames for the registered app. Not supported on first generation SDL + * enabled vehicles. + */ + + class ListFiles extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.ListFiles); + } + + } + + /* eslint-disable camelcase */ + /** + * Returns the current list of resident filenames for the registered app along with the current space available Not + * supported on First generation SDL enabled vehicles. + */ + + class ListFilesResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.ListFiles); + } + /** + * @param {String[]} filenames - An array of all filenames resident on the module for the given registered app. If + * omitted, then no files currently reside on the system. + * @return {ListFilesResponse} + */ + + + setFilenames(filenames) { + this.setParameter(ListFilesResponse.KEY_FILENAMES, filenames); + return this; + } + /** + * @return {String[]} + */ + + + getFilenames() { + return this.getParameter(ListFilesResponse.KEY_FILENAMES); + } + /** + * @param {Number} available - Provides the total local space available on the module for the registered app. + * @return {ListFilesResponse} + */ + + + setSpaceAvailable(available) { + this.setParameter(ListFilesResponse.KEY_SPACE_AVAILABLE, available); + return this; + } + /** + * @return {Number} + */ + + + getSpaceAvailable() { + return this.getParameter(ListFilesResponse.KEY_SPACE_AVAILABLE); + } + + } + + ListFilesResponse.KEY_FILENAMES = 'filenames'; + ListFilesResponse.KEY_SPACE_AVAILABLE = 'spaceAvailable'; + + /* eslint-disable camelcase */ + /** + * Used to set existing local file on the module as the app's icon Not supported on first generation SDL enabled + * vehicles. + */ + + class SetAppIcon extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SetAppIcon); + } + /** + * @param {String} name - File reference name. + * @return {SetAppIcon} + */ + + + setFileName(name) { + this.setParameter(SetAppIcon.KEY_FILE_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getFileName() { + return this.getParameter(SetAppIcon.KEY_FILE_NAME); + } + + } + + SetAppIcon.KEY_FILE_NAME = 'syncFileName'; + + /* eslint-disable camelcase */ + /** + * Response is sent, when the file data was copied (success case). Or when an error occurred. Not supported on First + * generation SDL enabled vehicles. + */ + + class SetAppIconResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SetAppIcon); + } + + } + + /* eslint-disable camelcase */ + /** + * This RPC is deprecated. Use Show RPC to change layout. + * @deprecated + */ + + class SetDisplayLayout extends RpcRequest { + /** + * @deprecated + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SetDisplayLayout); + } + /** + * @deprecated + * @param {String} layout - Predefined or dynamically created screen layout. Currently only predefined screen + * layouts are defined. + * @return {SetDisplayLayout} + */ + + + setDisplayLayout(layout) { + this.setParameter(SetDisplayLayout.KEY_DISPLAY_LAYOUT, layout); + return this; + } + /** + * @deprecated + * @return {String} + */ + + + getDisplayLayout() { + return this.getParameter(SetDisplayLayout.KEY_DISPLAY_LAYOUT); + } + /** + * @deprecated + * @param {TemplateColorScheme} scheme - A color scheme for all display layout templates. + * @return {SetDisplayLayout} + */ + + + setDayColorScheme(scheme) { + this.validateType(TemplateColorScheme, scheme); + this.setParameter(SetDisplayLayout.KEY_DAY_COLOR_SCHEME, scheme); + return this; + } + /** + * @deprecated + * @return {TemplateColorScheme} + */ + + + getDayColorScheme() { + return this.getObject(TemplateColorScheme, SetDisplayLayout.KEY_DAY_COLOR_SCHEME); + } + /** + * @deprecated + * @param {TemplateColorScheme} scheme - A color scheme for all display layout templates. + * @return {SetDisplayLayout} + */ + + + setNightColorScheme(scheme) { + this.validateType(TemplateColorScheme, scheme); + this.setParameter(SetDisplayLayout.KEY_NIGHT_COLOR_SCHEME, scheme); + return this; + } + /** + * @deprecated + * @return {TemplateColorScheme} + */ + + + getNightColorScheme() { + return this.getObject(TemplateColorScheme, SetDisplayLayout.KEY_NIGHT_COLOR_SCHEME); + } + + } + + SetDisplayLayout.KEY_DISPLAY_LAYOUT = 'displayLayout'; + SetDisplayLayout.KEY_DAY_COLOR_SCHEME = 'dayColorScheme'; + SetDisplayLayout.KEY_NIGHT_COLOR_SCHEME = 'nightColorScheme'; + + /* eslint-disable camelcase */ + /** + * This RPC is deprecated. Use Show RPC to change layout. + * @deprecated + */ + + class SetDisplayLayoutResponse extends RpcResponse { + /** + * @deprecated + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SetDisplayLayout); + } + /** + * @deprecated + * @param {DisplayCapabilities} capabilities - See DisplayCapabilities + * @return {SetDisplayLayoutResponse} + */ + + + setDisplayCapabilities(capabilities) { + this.validateType(DisplayCapabilities, capabilities); + this.setParameter(SetDisplayLayoutResponse.KEY_DISPLAY_CAPABILITIES, capabilities); + return this; + } + /** + * @deprecated + * @return {DisplayCapabilities} + */ + + + getDisplayCapabilities() { + return this.getObject(DisplayCapabilities, SetDisplayLayoutResponse.KEY_DISPLAY_CAPABILITIES); + } + /** + * @deprecated + * @param {ButtonCapabilities[]} capabilities - See ButtonCapabilities + * @return {SetDisplayLayoutResponse} + */ + + + setButtonCapabilities(capabilities) { + this.validateType(ButtonCapabilities, capabilities, true); + this.setParameter(SetDisplayLayoutResponse.KEY_BUTTON_CAPABILITIES, capabilities); + return this; + } + /** + * @deprecated + * @return {ButtonCapabilities[]} + */ + + + getButtonCapabilities() { + return this.getObject(ButtonCapabilities, SetDisplayLayoutResponse.KEY_BUTTON_CAPABILITIES); + } + /** + * @deprecated + * @param {SoftButtonCapabilities[]} capabilities - If returned, the platform supports on-screen SoftButtons; see + * SoftButtonCapabilities. + * @return {SetDisplayLayoutResponse} + */ + + + setSoftButtonCapabilities(capabilities) { + this.validateType(SoftButtonCapabilities, capabilities, true); + this.setParameter(SetDisplayLayoutResponse.KEY_SOFT_BUTTON_CAPABILITIES, capabilities); + return this; + } + /** + * @deprecated + * @return {SoftButtonCapabilities[]} + */ + + + getSoftButtonCapabilities() { + return this.getObject(SoftButtonCapabilities, SetDisplayLayoutResponse.KEY_SOFT_BUTTON_CAPABILITIES); + } + /** + * @deprecated + * @param {PresetBankCapabilities} capabilities - If returned, the platform supports custom on-screen Presets; see + * PresetBankCapabilities. + * @return {SetDisplayLayoutResponse} + */ + + + setPresetBankCapabilities(capabilities) { + this.validateType(PresetBankCapabilities, capabilities); + this.setParameter(SetDisplayLayoutResponse.KEY_PRESET_BANK_CAPABILITIES, capabilities); + return this; + } + /** + * @deprecated + * @return {PresetBankCapabilities} + */ + + + getPresetBankCapabilities() { + return this.getObject(PresetBankCapabilities, SetDisplayLayoutResponse.KEY_PRESET_BANK_CAPABILITIES); + } + + } + + SetDisplayLayoutResponse.KEY_DISPLAY_CAPABILITIES = 'displayCapabilities'; + SetDisplayLayoutResponse.KEY_BUTTON_CAPABILITIES = 'buttonCapabilities'; + SetDisplayLayoutResponse.KEY_SOFT_BUTTON_CAPABILITIES = 'softButtonCapabilities'; + SetDisplayLayoutResponse.KEY_PRESET_BANK_CAPABILITIES = 'presetBankCapabilities'; + + /* eslint-disable camelcase */ + /** + * Enumeration listing possible asynchronous requests. + * @typedef {Enum} RequestType + * @property {Object} _MAP + */ + + class RequestType extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get HTTP() { + return RequestType._MAP.HTTP; + } + /** + * @return {String} + */ + + + static get FILE_RESUME() { + return RequestType._MAP.FILE_RESUME; + } + /** + * @return {String} + */ + + + static get AUTH_REQUEST() { + return RequestType._MAP.AUTH_REQUEST; + } + /** + * @return {String} + */ + + + static get AUTH_CHALLENGE() { + return RequestType._MAP.AUTH_CHALLENGE; + } + /** + * @return {String} + */ + + + static get AUTH_ACK() { + return RequestType._MAP.AUTH_ACK; + } + /** + * @return {String} + */ + + + static get PROPRIETARY() { + return RequestType._MAP.PROPRIETARY; + } + /** + * @return {String} + */ + + + static get QUERY_APPS() { + return RequestType._MAP.QUERY_APPS; + } + /** + * @return {String} + */ + + + static get LAUNCH_APP() { + return RequestType._MAP.LAUNCH_APP; + } + /** + * @return {String} + */ + + + static get LOCK_SCREEN_ICON_URL() { + return RequestType._MAP.LOCK_SCREEN_ICON_URL; + } + /** + * @return {String} + */ + + + static get TRAFFIC_MESSAGE_CHANNEL() { + return RequestType._MAP.TRAFFIC_MESSAGE_CHANNEL; + } + /** + * @return {String} + */ + + + static get DRIVER_PROFILE() { + return RequestType._MAP.DRIVER_PROFILE; + } + /** + * @return {String} + */ + + + static get VOICE_SEARCH() { + return RequestType._MAP.VOICE_SEARCH; + } + /** + * @return {String} + */ + + + static get NAVIGATION() { + return RequestType._MAP.NAVIGATION; + } + /** + * @return {String} + */ + + + static get PHONE() { + return RequestType._MAP.PHONE; + } + /** + * @return {String} + */ + + + static get CLIMATE() { + return RequestType._MAP.CLIMATE; + } + /** + * @return {String} + */ + + + static get SETTINGS() { + return RequestType._MAP.SETTINGS; + } + /** + * @return {String} + */ + + + static get VEHICLE_DIAGNOSTICS() { + return RequestType._MAP.VEHICLE_DIAGNOSTICS; + } + /** + * @return {String} + */ + + + static get EMERGENCY() { + return RequestType._MAP.EMERGENCY; + } + /** + * @return {String} + */ + + + static get MEDIA() { + return RequestType._MAP.MEDIA; + } + /** + * @return {String} + */ + + + static get FOTA() { + return RequestType._MAP.FOTA; + } + /** + * @return {String} + */ + + + static get OEM_SPECIFIC() { + return RequestType._MAP.OEM_SPECIFIC; + } + /** + * @return {String} + */ + + + static get ICON_URL() { + return RequestType._MAP.ICON_URL; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return RequestType._valueForKey(key, RequestType._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return RequestType._keyForValue(value, RequestType._MAP); + } + + } + + RequestType._MAP = Object.freeze({ + 'HTTP': 'HTTP', + 'FILE_RESUME': 'FILE_RESUME', + 'AUTH_REQUEST': 'AUTH_REQUEST', + 'AUTH_CHALLENGE': 'AUTH_CHALLENGE', + 'AUTH_ACK': 'AUTH_ACK', + 'PROPRIETARY': 'PROPRIETARY', + 'QUERY_APPS': 'QUERY_APPS', + 'LAUNCH_APP': 'LAUNCH_APP', + 'LOCK_SCREEN_ICON_URL': 'LOCK_SCREEN_ICON_URL', + 'TRAFFIC_MESSAGE_CHANNEL': 'TRAFFIC_MESSAGE_CHANNEL', + 'DRIVER_PROFILE': 'DRIVER_PROFILE', + 'VOICE_SEARCH': 'VOICE_SEARCH', + 'NAVIGATION': 'NAVIGATION', + 'PHONE': 'PHONE', + 'CLIMATE': 'CLIMATE', + 'SETTINGS': 'SETTINGS', + 'VEHICLE_DIAGNOSTICS': 'VEHICLE_DIAGNOSTICS', + 'EMERGENCY': 'EMERGENCY', + 'MEDIA': 'MEDIA', + 'FOTA': 'FOTA', + 'OEM_SPECIFIC': 'OEM_SPECIFIC', + 'ICON_URL': 'ICON_URL' + }); + + /* eslint-disable camelcase */ + /** + * An asynchronous request from the device; binary data can be included in hybrid part of message for some requests + * (such as HTTP, Proprietary, or Authentication requests) + */ + + class SystemRequest extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SystemRequest); + } + /** + * @param {RequestType} type - The type of system request. Note that Proprietary requests should forward the binary + * data to the known proprietary module on the system. + * @return {SystemRequest} + */ + + + setRequestType(type) { + this.validateType(RequestType, type); + this.setParameter(SystemRequest.KEY_REQUEST_TYPE, type); + return this; + } + /** + * @return {RequestType} + */ + + + getRequestType() { + return this.getObject(RequestType, SystemRequest.KEY_REQUEST_TYPE); + } + /** + * @param {String} type - This parameter is filled for supporting OEM proprietary data exchanges. + * @return {SystemRequest} + */ + + + setRequestSubType(type) { + this.setParameter(SystemRequest.KEY_REQUEST_SUB_TYPE, type); + return this; + } + /** + * @return {String} + */ + + + getRequestSubType() { + return this.getParameter(SystemRequest.KEY_REQUEST_SUB_TYPE); + } + /** + * @param {String} name - Filename of HTTP data to store in predefined system staging area. Mandatory if requestType + * is HTTP. PROPRIETARY requestType should ignore this parameter. + * @return {SystemRequest} + */ + + + setFileName(name) { + this.setParameter(SystemRequest.KEY_FILE_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getFileName() { + return this.getParameter(SystemRequest.KEY_FILE_NAME); + } + + } + + SystemRequest.KEY_REQUEST_TYPE = 'requestType'; + SystemRequest.KEY_REQUEST_SUB_TYPE = 'requestSubType'; + SystemRequest.KEY_FILE_NAME = 'fileName'; + + /* eslint-disable camelcase */ + + class SystemRequestResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SystemRequest); + } + + } + + /* eslint-disable camelcase */ + /** + * The mode in which the SendLocation request is sent + * @typedef {Enum} DeliveryMode + * @property {Object} _MAP + */ + + class DeliveryMode extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get PROMPT() { + return DeliveryMode._MAP.PROMPT; + } + /** + * @return {String} + */ + + + static get DESTINATION() { + return DeliveryMode._MAP.DESTINATION; + } + /** + * @return {String} + */ + + + static get QUEUE() { + return DeliveryMode._MAP.QUEUE; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return DeliveryMode._valueForKey(key, DeliveryMode._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return DeliveryMode._keyForValue(value, DeliveryMode._MAP); + } + + } + + DeliveryMode._MAP = Object.freeze({ + 'PROMPT': 'PROMPT', + 'DESTINATION': 'DESTINATION', + 'QUEUE': 'QUEUE' + }); + + /* eslint-disable camelcase */ + + class DateTime extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Number} millisecond - Milliseconds + * @return {DateTime} + */ + + + setMillisecond(millisecond) { + this.setParameter(DateTime.KEY_MILLISECOND, millisecond); + return this; + } + /** + * @return {Number} + */ + + + getMillisecond() { + return this.getParameter(DateTime.KEY_MILLISECOND); + } + /** + * @param {Number} second - Seconds part of time + * @return {DateTime} + */ + + + setSecond(second) { + this.setParameter(DateTime.KEY_SECOND, second); + return this; + } + /** + * @return {Number} + */ + + + getSecond() { + return this.getParameter(DateTime.KEY_SECOND); + } + /** + * @param {Number} minute - Minutes part of time + * @return {DateTime} + */ + + + setMinute(minute) { + this.setParameter(DateTime.KEY_MINUTE, minute); + return this; + } + /** + * @return {Number} + */ + + + getMinute() { + return this.getParameter(DateTime.KEY_MINUTE); + } + /** + * @param {Number} hour - Hours part of time. Note that this structure accepts time only in 24 Hr format + * @return {DateTime} + */ + + + setHour(hour) { + this.setParameter(DateTime.KEY_HOUR, hour); + return this; + } + /** + * @return {Number} + */ + + + getHour() { + return this.getParameter(DateTime.KEY_HOUR); + } + /** + * @param {Number} day - Day of the month + * @return {DateTime} + */ + + + setDay(day) { + this.setParameter(DateTime.KEY_DAY, day); + return this; + } + /** + * @return {Number} + */ + + + getDay() { + return this.getParameter(DateTime.KEY_DAY); + } + /** + * @param {Number} month - Month of the year + * @return {DateTime} + */ + + + setMonth(month) { + this.setParameter(DateTime.KEY_MONTH, month); + return this; + } + /** + * @return {Number} + */ + + + getMonth() { + return this.getParameter(DateTime.KEY_MONTH); + } + /** + * @param {Number} year - The year in YYYY format + * @return {DateTime} + */ + + + setYear(year) { + this.setParameter(DateTime.KEY_YEAR, year); + return this; + } + /** + * @return {Number} + */ + + + getYear() { + return this.getParameter(DateTime.KEY_YEAR); + } + /** + * @param {Number} tz_hour - Time zone offset in Hours wrt UTC. + * @return {DateTime} + */ + + + setTz_hour(tz_hour) { + this.setParameter(DateTime.KEY_TZ_HOUR, tz_hour); + return this; + } + /** + * @return {Number} + */ + + + getTz_hour() { + return this.getParameter(DateTime.KEY_TZ_HOUR); + } + /** + * @param {Number} tz_minute - Time zone offset in Min wrt UTC. + * @return {DateTime} + */ + + + setTz_minute(tz_minute) { + this.setParameter(DateTime.KEY_TZ_MINUTE, tz_minute); + return this; + } + /** + * @return {Number} + */ + + + getTz_minute() { + return this.getParameter(DateTime.KEY_TZ_MINUTE); + } + + } + + DateTime.KEY_MILLISECOND = 'millisecond'; + DateTime.KEY_SECOND = 'second'; + DateTime.KEY_MINUTE = 'minute'; + DateTime.KEY_HOUR = 'hour'; + DateTime.KEY_DAY = 'day'; + DateTime.KEY_MONTH = 'month'; + DateTime.KEY_YEAR = 'year'; + DateTime.KEY_TZ_HOUR = 'tz_hour'; + DateTime.KEY_TZ_MINUTE = 'tz_minute'; + + /* eslint-disable camelcase */ + + class OASISAddress extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {String} name - Name of the country (localized) + * @return {OASISAddress} + */ + + + setCountryName(name) { + this.setParameter(OASISAddress.KEY_COUNTRY_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getCountryName() { + return this.getParameter(OASISAddress.KEY_COUNTRY_NAME); + } + /** + * @param {String} code - Name of country (ISO 3166-2) + * @return {OASISAddress} + */ + + + setCountryCode(code) { + this.setParameter(OASISAddress.KEY_COUNTRY_CODE, code); + return this; + } + /** + * @return {String} + */ + + + getCountryCode() { + return this.getParameter(OASISAddress.KEY_COUNTRY_CODE); + } + /** + * @param {String} code - (PLZ, ZIP, PIN, CAP etc.) + * @return {OASISAddress} + */ + + + setPostalCode(code) { + this.setParameter(OASISAddress.KEY_POSTAL_CODE, code); + return this; + } + /** + * @return {String} + */ + + + getPostalCode() { + return this.getParameter(OASISAddress.KEY_POSTAL_CODE); + } + /** + * @param {String} area - Portion of country (e.g. state) + * @return {OASISAddress} + */ + + + setAdministrativeArea(area) { + this.setParameter(OASISAddress.KEY_ADMINISTRATIVE_AREA, area); + return this; + } + /** + * @return {String} + */ + + + getAdministrativeArea() { + return this.getParameter(OASISAddress.KEY_ADMINISTRATIVE_AREA); + } + /** + * @param {String} area - Portion of e.g. state (e.g. county) + * @return {OASISAddress} + */ + + + setSubAdministrativeArea(area) { + this.setParameter(OASISAddress.KEY_SUB_ADMINISTRATIVE_AREA, area); + return this; + } + /** + * @return {String} + */ + + + getSubAdministrativeArea() { + return this.getParameter(OASISAddress.KEY_SUB_ADMINISTRATIVE_AREA); + } + /** + * @param {String} locality - Hypernym for e.g. city/village + * @return {OASISAddress} + */ + + + setLocality(locality) { + this.setParameter(OASISAddress.KEY_LOCALITY, locality); + return this; + } + /** + * @return {String} + */ + + + getLocality() { + return this.getParameter(OASISAddress.KEY_LOCALITY); + } + /** + * @param {String} locality - Hypernym for e.g. district + * @return {OASISAddress} + */ + + + setSubLocality(locality) { + this.setParameter(OASISAddress.KEY_SUB_LOCALITY, locality); + return this; + } + /** + * @return {String} + */ + + + getSubLocality() { + return this.getParameter(OASISAddress.KEY_SUB_LOCALITY); + } + /** + * @param {String} thoroughfare - Hypernym for street, road etc. + * @return {OASISAddress} + */ + + + setThoroughfare(thoroughfare) { + this.setParameter(OASISAddress.KEY_THOROUGHFARE, thoroughfare); + return this; + } + /** + * @return {String} + */ + + + getThoroughfare() { + return this.getParameter(OASISAddress.KEY_THOROUGHFARE); + } + /** + * @param {String} thoroughfare - Portion of thoroughfare e.g. house number + * @return {OASISAddress} + */ + + + setSubThoroughfare(thoroughfare) { + this.setParameter(OASISAddress.KEY_SUB_THOROUGHFARE, thoroughfare); + return this; + } + /** + * @return {String} + */ + + + getSubThoroughfare() { + return this.getParameter(OASISAddress.KEY_SUB_THOROUGHFARE); + } + + } + + OASISAddress.KEY_COUNTRY_NAME = 'countryName'; + OASISAddress.KEY_COUNTRY_CODE = 'countryCode'; + OASISAddress.KEY_POSTAL_CODE = 'postalCode'; + OASISAddress.KEY_ADMINISTRATIVE_AREA = 'administrativeArea'; + OASISAddress.KEY_SUB_ADMINISTRATIVE_AREA = 'subAdministrativeArea'; + OASISAddress.KEY_LOCALITY = 'locality'; + OASISAddress.KEY_SUB_LOCALITY = 'subLocality'; + OASISAddress.KEY_THOROUGHFARE = 'thoroughfare'; + OASISAddress.KEY_SUB_THOROUGHFARE = 'subThoroughfare'; + + /* eslint-disable camelcase */ + + class SendLocation extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SendLocation); + } + /** + * @param {Number} degrees + * @return {SendLocation} + */ + + + setLongitudeDegrees(degrees) { + this.setParameter(SendLocation.KEY_LONGITUDE_DEGREES, degrees); + return this; + } + /** + * @return {Number} + */ + + + getLongitudeDegrees() { + return this.getParameter(SendLocation.KEY_LONGITUDE_DEGREES); + } + /** + * @param {Number} degrees + * @return {SendLocation} + */ + + + setLatitudeDegrees(degrees) { + this.setParameter(SendLocation.KEY_LATITUDE_DEGREES, degrees); + return this; + } + /** + * @return {Number} + */ + + + getLatitudeDegrees() { + return this.getParameter(SendLocation.KEY_LATITUDE_DEGREES); + } + /** + * @param {String} name - Name / title of intended location + * @return {SendLocation} + */ + + + setLocationName(name) { + this.setParameter(SendLocation.KEY_LOCATION_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getLocationName() { + return this.getParameter(SendLocation.KEY_LOCATION_NAME); + } + /** + * @param {String} description - Description intended location / establishment (if applicable) + * @return {SendLocation} + */ + + + setLocationDescription(description) { + this.setParameter(SendLocation.KEY_LOCATION_DESCRIPTION, description); + return this; + } + /** + * @return {String} + */ + + + getLocationDescription() { + return this.getParameter(SendLocation.KEY_LOCATION_DESCRIPTION); + } + /** + * @param {String[]} lines - Location address (if applicable) + * @return {SendLocation} + */ + + + setAddressLines(lines) { + this.setParameter(SendLocation.KEY_ADDRESS_LINES, lines); + return this; + } + /** + * @return {String[]} + */ + + + getAddressLines() { + return this.getParameter(SendLocation.KEY_ADDRESS_LINES); + } + /** + * @param {String} number - Phone number of intended location / establishment (if applicable) + * @return {SendLocation} + */ + + + setPhoneNumber(number) { + this.setParameter(SendLocation.KEY_PHONE_NUMBER, number); + return this; + } + /** + * @return {String} + */ + + + getPhoneNumber() { + return this.getParameter(SendLocation.KEY_PHONE_NUMBER); + } + /** + * @param {Image} image - Image / icon of intended location (if applicable and supported) + * @return {SendLocation} + */ + + + setLocationImage(image) { + this.validateType(Image, image); + this.setParameter(SendLocation.KEY_LOCATION_IMAGE, image); + return this; + } + /** + * @return {Image} + */ + + + getLocationImage() { + return this.getObject(Image, SendLocation.KEY_LOCATION_IMAGE); + } + /** + * @param {DateTime} stamp - timestamp in ISO 8601 format + * @return {SendLocation} + */ + + + setTimeStamp(stamp) { + this.validateType(DateTime, stamp); + this.setParameter(SendLocation.KEY_TIME_STAMP, stamp); + return this; + } + /** + * @return {DateTime} + */ + + + getTimeStamp() { + return this.getObject(DateTime, SendLocation.KEY_TIME_STAMP); + } + /** + * @param {OASISAddress} address - Address to be used for setting destination + * @return {SendLocation} + */ + + + setAddress(address) { + this.validateType(OASISAddress, address); + this.setParameter(SendLocation.KEY_ADDRESS, address); + return this; + } + /** + * @return {OASISAddress} + */ + + + getAddress() { + return this.getObject(OASISAddress, SendLocation.KEY_ADDRESS); + } + /** + * @param {DeliveryMode} mode - Defines the mode of prompt for user + * @return {SendLocation} + */ + + + setDeliveryMode(mode) { + this.validateType(DeliveryMode, mode); + this.setParameter(SendLocation.KEY_DELIVERY_MODE, mode); + return this; + } + /** + * @return {DeliveryMode} + */ + + + getDeliveryMode() { + return this.getObject(DeliveryMode, SendLocation.KEY_DELIVERY_MODE); + } + + } + + SendLocation.KEY_LONGITUDE_DEGREES = 'longitudeDegrees'; + SendLocation.KEY_LATITUDE_DEGREES = 'latitudeDegrees'; + SendLocation.KEY_LOCATION_NAME = 'locationName'; + SendLocation.KEY_LOCATION_DESCRIPTION = 'locationDescription'; + SendLocation.KEY_ADDRESS_LINES = 'addressLines'; + SendLocation.KEY_PHONE_NUMBER = 'phoneNumber'; + SendLocation.KEY_LOCATION_IMAGE = 'locationImage'; + SendLocation.KEY_TIME_STAMP = 'timeStamp'; + SendLocation.KEY_ADDRESS = 'address'; + SendLocation.KEY_DELIVERY_MODE = 'deliveryMode'; + + /* eslint-disable camelcase */ + + class SendLocationResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SendLocation); + } + + } + + /* eslint-disable camelcase */ + /** + * Dials a phone number and switches to phone application. + */ + + class DialNumber extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.DialNumber); + } + /** + * @param {String} number - Phone number is a string, which can be up to 40 chars. All characters shall be stripped + * from string except digits 0-9 and * # , ; + + * @return {DialNumber} + */ + + + setNumber(number) { + this.setParameter(DialNumber.KEY_NUMBER, number); + return this; + } + /** + * @return {String} + */ + + + getNumber() { + return this.getParameter(DialNumber.KEY_NUMBER); + } + + } + + DialNumber.KEY_NUMBER = 'number'; + + /* eslint-disable camelcase */ + + class DialNumberResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.DialNumber); + } + + } + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} ButtonPressMode + * @property {Object} _MAP + */ + + class ButtonPressMode extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * A button was released, after it was pressed for a long time Actual timing is defined by the headunit and may + * vary + * @return {String} + */ + + + static get LONG() { + return ButtonPressMode._MAP.LONG; + } + /** + * A button was released, after it was pressed for a short time Actual timing is defined by the headunit and may + * vary + * @return {String} + */ + + + static get SHORT() { + return ButtonPressMode._MAP.SHORT; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return ButtonPressMode._valueForKey(key, ButtonPressMode._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return ButtonPressMode._keyForValue(value, ButtonPressMode._MAP); + } + + } + + ButtonPressMode._MAP = Object.freeze({ + 'LONG': 'LONG', + 'SHORT': 'SHORT' + }); + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} ModuleType + * @property {Object} _MAP + */ + + class ModuleType extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get CLIMATE() { + return ModuleType._MAP.CLIMATE; + } + /** + * @return {String} + */ + + + static get RADIO() { + return ModuleType._MAP.RADIO; + } + /** + * @return {String} + */ + + + static get SEAT() { + return ModuleType._MAP.SEAT; + } + /** + * @return {String} + */ + + + static get AUDIO() { + return ModuleType._MAP.AUDIO; + } + /** + * @return {String} + */ + + + static get LIGHT() { + return ModuleType._MAP.LIGHT; + } + /** + * @return {String} + */ + + + static get HMI_SETTINGS() { + return ModuleType._MAP.HMI_SETTINGS; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return ModuleType._valueForKey(key, ModuleType._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return ModuleType._keyForValue(value, ModuleType._MAP); + } + + } + + ModuleType._MAP = Object.freeze({ + 'CLIMATE': 'CLIMATE', + 'RADIO': 'RADIO', + 'SEAT': 'SEAT', + 'AUDIO': 'AUDIO', + 'LIGHT': 'LIGHT', + 'HMI_SETTINGS': 'HMI_SETTINGS' + }); + + /* eslint-disable camelcase */ + + class ButtonPress extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.ButtonPress); + } + /** + * @param {ModuleType} type - The module where the button should be pressed + * @return {ButtonPress} + */ + + + setModuleType(type) { + this.validateType(ModuleType, type); + this.setParameter(ButtonPress.KEY_MODULE_TYPE, type); + return this; + } + /** + * @return {ModuleType} + */ + + + getModuleType() { + return this.getObject(ModuleType, ButtonPress.KEY_MODULE_TYPE); + } + /** + * @param {String} id - Id of a module, published by System Capability. + * @return {ButtonPress} + */ + + + setModuleId(id) { + this.setParameter(ButtonPress.KEY_MODULE_ID, id); + return this; + } + /** + * @return {String} + */ + + + getModuleId() { + return this.getParameter(ButtonPress.KEY_MODULE_ID); + } + /** + * @param {ButtonName} name - The name of supported RC climate or radio button. + * @return {ButtonPress} + */ + + + setButtonName(name) { + this.validateType(ButtonName, name); + this.setParameter(ButtonPress.KEY_BUTTON_NAME, name); + return this; + } + /** + * @return {ButtonName} + */ + + + getButtonName() { + return this.getObject(ButtonName, ButtonPress.KEY_BUTTON_NAME); + } + /** + * @param {ButtonPressMode} mode - Indicates whether this is a LONG or SHORT button press event. + * @return {ButtonPress} + */ + + + setButtonPressMode(mode) { + this.validateType(ButtonPressMode, mode); + this.setParameter(ButtonPress.KEY_BUTTON_PRESS_MODE, mode); + return this; + } + /** + * @return {ButtonPressMode} + */ + + + getButtonPressMode() { + return this.getObject(ButtonPressMode, ButtonPress.KEY_BUTTON_PRESS_MODE); + } + + } + + ButtonPress.KEY_MODULE_TYPE = 'moduleType'; + ButtonPress.KEY_MODULE_ID = 'moduleId'; + ButtonPress.KEY_BUTTON_NAME = 'buttonName'; + ButtonPress.KEY_BUTTON_PRESS_MODE = 'buttonPressMode'; + + /* eslint-disable camelcase */ + + class ButtonPressResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.ButtonPress); + } + + } + + /* eslint-disable camelcase */ + + class GetInteriorVehicleData extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.GetInteriorVehicleData); + } + /** + * @param {ModuleType} type - The type of a RC module to retrieve module data from the vehicle. In the future, this + * should be the Identification of a module. + * @return {GetInteriorVehicleData} + */ + + + setModuleType(type) { + this.validateType(ModuleType, type); + this.setParameter(GetInteriorVehicleData.KEY_MODULE_TYPE, type); + return this; + } + /** + * @return {ModuleType} + */ + + + getModuleType() { + return this.getObject(ModuleType, GetInteriorVehicleData.KEY_MODULE_TYPE); + } + /** + * @param {String} id - Id of a module, published by System Capability. + * @return {GetInteriorVehicleData} + */ + + + setModuleId(id) { + this.setParameter(GetInteriorVehicleData.KEY_MODULE_ID, id); + return this; + } + /** + * @return {String} + */ + + + getModuleId() { + return this.getParameter(GetInteriorVehicleData.KEY_MODULE_ID); + } + /** + * @param {Boolean} subscribe - If subscribe is true, the head unit will register OnInteriorVehicleData + * notifications for the requested module (moduleId and moduleType). If subscribe is + * false, the head unit will unregister OnInteriorVehicleData notifications for the + * requested module (moduleId and moduleType). If subscribe is not included, the + * subscription status of the app for the requested module (moduleId and moduleType) + * will remain unchanged. + * @return {GetInteriorVehicleData} + */ + + + setSubscribe(subscribe) { + this.setParameter(GetInteriorVehicleData.KEY_SUBSCRIBE, subscribe); + return this; + } + /** + * @return {Boolean} + */ + + + getSubscribe() { + return this.getParameter(GetInteriorVehicleData.KEY_SUBSCRIBE); + } + + } + + GetInteriorVehicleData.KEY_MODULE_TYPE = 'moduleType'; + GetInteriorVehicleData.KEY_MODULE_ID = 'moduleId'; + GetInteriorVehicleData.KEY_SUBSCRIBE = 'subscribe'; + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} DisplayMode + * @property {Object} _MAP + */ + + class DisplayMode extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get DAY() { + return DisplayMode._MAP.DAY; + } + /** + * @return {String} + */ + + + static get NIGHT() { + return DisplayMode._MAP.NIGHT; + } + /** + * @return {String} + */ + + + static get AUTO() { + return DisplayMode._MAP.AUTO; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return DisplayMode._valueForKey(key, DisplayMode._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return DisplayMode._keyForValue(value, DisplayMode._MAP); + } + + } + + DisplayMode._MAP = Object.freeze({ + 'DAY': 'DAY', + 'NIGHT': 'NIGHT', + 'AUTO': 'AUTO' + }); + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} DistanceUnit + * @property {Object} _MAP + */ + + class DistanceUnit extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get MILES() { + return DistanceUnit._MAP.MILES; + } + /** + * @return {String} + */ + + + static get KILOMETERS() { + return DistanceUnit._MAP.KILOMETERS; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return DistanceUnit._valueForKey(key, DistanceUnit._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return DistanceUnit._keyForValue(value, DistanceUnit._MAP); + } + + } + + DistanceUnit._MAP = Object.freeze({ + 'MILES': 'MILES', + 'KILOMETERS': 'KILOMETERS' + }); + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} TemperatureUnit + * @property {Object} _MAP + */ + + class TemperatureUnit extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get FAHRENHEIT() { + return TemperatureUnit._MAP.FAHRENHEIT; + } + /** + * @return {String} + */ + + + static get CELSIUS() { + return TemperatureUnit._MAP.CELSIUS; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return TemperatureUnit._valueForKey(key, TemperatureUnit._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return TemperatureUnit._keyForValue(value, TemperatureUnit._MAP); + } + + } + + TemperatureUnit._MAP = Object.freeze({ + 'FAHRENHEIT': 'FAHRENHEIT', + 'CELSIUS': 'CELSIUS' + }); + + /* eslint-disable camelcase */ + /** + * Corresponds to "HMI_SETTINGS" ModuleType + */ + + class HMISettingsControlData extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {DisplayMode} mode + * @return {HMISettingsControlData} + */ + + + setDisplayMode(mode) { + this.validateType(DisplayMode, mode); + this.setParameter(HMISettingsControlData.KEY_DISPLAY_MODE, mode); + return this; + } + /** + * @return {DisplayMode} + */ + + + getDisplayMode() { + return this.getObject(DisplayMode, HMISettingsControlData.KEY_DISPLAY_MODE); + } + /** + * @param {TemperatureUnit} unit + * @return {HMISettingsControlData} + */ + + + setTemperatureUnit(unit) { + this.validateType(TemperatureUnit, unit); + this.setParameter(HMISettingsControlData.KEY_TEMPERATURE_UNIT, unit); + return this; + } + /** + * @return {TemperatureUnit} + */ + + + getTemperatureUnit() { + return this.getObject(TemperatureUnit, HMISettingsControlData.KEY_TEMPERATURE_UNIT); + } + /** + * @param {DistanceUnit} unit + * @return {HMISettingsControlData} + */ + + + setDistanceUnit(unit) { + this.validateType(DistanceUnit, unit); + this.setParameter(HMISettingsControlData.KEY_DISTANCE_UNIT, unit); + return this; + } + /** + * @return {DistanceUnit} + */ + + + getDistanceUnit() { + return this.getObject(DistanceUnit, HMISettingsControlData.KEY_DISTANCE_UNIT); + } + + } + + HMISettingsControlData.KEY_DISPLAY_MODE = 'displayMode'; + HMISettingsControlData.KEY_TEMPERATURE_UNIT = 'temperatureUnit'; + HMISettingsControlData.KEY_DISTANCE_UNIT = 'distanceUnit'; + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} RadioBand + * @property {Object} _MAP + */ + + class RadioBand extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get AM() { + return RadioBand._MAP.AM; + } + /** + * @return {String} + */ + + + static get FM() { + return RadioBand._MAP.FM; + } + /** + * @return {String} + */ + + + static get XM() { + return RadioBand._MAP.XM; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return RadioBand._valueForKey(key, RadioBand._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return RadioBand._keyForValue(value, RadioBand._MAP); + } + + } + + RadioBand._MAP = Object.freeze({ + 'AM': 'AM', + 'FM': 'FM', + 'XM': 'XM' + }); + + /* eslint-disable camelcase */ + + class RdsData extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {String} ps - Program Service Name + * @return {RdsData} + */ + + + setPS(ps) { + this.setParameter(RdsData.KEY_PS, ps); + return this; + } + /** + * @return {String} + */ + + + getPS() { + return this.getParameter(RdsData.KEY_PS); + } + /** + * @param {String} rt - Radio Text + * @return {RdsData} + */ + + + setRT(rt) { + this.setParameter(RdsData.KEY_RT, rt); + return this; + } + /** + * @return {String} + */ + + + getRT() { + return this.getParameter(RdsData.KEY_RT); + } + /** + * @param {String} ct - The clock text in UTC format as YYYY-MM-DDThh:mm:ss.sTZD + * @return {RdsData} + */ + + + setCT(ct) { + this.setParameter(RdsData.KEY_CT, ct); + return this; + } + /** + * @return {String} + */ + + + getCT() { + return this.getParameter(RdsData.KEY_CT); + } + /** + * @param {String} pi - Program Identification - the call sign for the radio station + * @return {RdsData} + */ + + + setPI(pi) { + this.setParameter(RdsData.KEY_PI, pi); + return this; + } + /** + * @return {String} + */ + + + getPI() { + return this.getParameter(RdsData.KEY_PI); + } + /** + * @param {Number} pty - The program type - The region should be used to differentiate between EU and North America + * program types + * @return {RdsData} + */ + + + setPTY(pty) { + this.setParameter(RdsData.KEY_PTY, pty); + return this; + } + /** + * @return {Number} + */ + + + getPTY() { + return this.getParameter(RdsData.KEY_PTY); + } + /** + * @param {Boolean} tp - Traffic Program Identification - Identifies a station that offers traffic + * @return {RdsData} + */ + + + setTP(tp) { + this.setParameter(RdsData.KEY_TP, tp); + return this; + } + /** + * @return {Boolean} + */ + + + getTP() { + return this.getParameter(RdsData.KEY_TP); + } + /** + * @param {Boolean} ta - Traffic Announcement Identification - Indicates an ongoing traffic announcement + * @return {RdsData} + */ + + + setTA(ta) { + this.setParameter(RdsData.KEY_TA, ta); + return this; + } + /** + * @return {Boolean} + */ + + + getTA() { + return this.getParameter(RdsData.KEY_TA); + } + /** + * @param {String} reg - Region + * @return {RdsData} + */ + + + setREG(reg) { + this.setParameter(RdsData.KEY_REG, reg); + return this; + } + /** + * @return {String} + */ + + + getREG() { + return this.getParameter(RdsData.KEY_REG); + } + + } + + RdsData.KEY_PS = 'PS'; + RdsData.KEY_RT = 'RT'; + RdsData.KEY_CT = 'CT'; + RdsData.KEY_PI = 'PI'; + RdsData.KEY_PTY = 'PTY'; + RdsData.KEY_TP = 'TP'; + RdsData.KEY_TA = 'TA'; + RdsData.KEY_REG = 'REG'; + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} RadioState + * @property {Object} _MAP + */ + + class RadioState extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get ACQUIRING() { + return RadioState._MAP.ACQUIRING; + } + /** + * @return {String} + */ + + + static get ACQUIRED() { + return RadioState._MAP.ACQUIRED; + } + /** + * @return {String} + */ + + + static get MULTICAST() { + return RadioState._MAP.MULTICAST; + } + /** + * @return {String} + */ + + + static get NOT_FOUND() { + return RadioState._MAP.NOT_FOUND; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return RadioState._valueForKey(key, RadioState._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return RadioState._keyForValue(value, RadioState._MAP); + } + + } + + RadioState._MAP = Object.freeze({ + 'ACQUIRING': 'ACQUIRING', + 'ACQUIRED': 'ACQUIRED', + 'MULTICAST': 'MULTICAST', + 'NOT_FOUND': 'NOT_FOUND' + }); + + /* eslint-disable camelcase */ + + class StationIDNumber extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Number} code - Binary Representation of ITU Country Code. USA Code is 001. + * @return {StationIDNumber} + */ + + + setCountryCode(code) { + this.setParameter(StationIDNumber.KEY_COUNTRY_CODE, code); + return this; + } + /** + * @return {Number} + */ + + + getCountryCode() { + return this.getParameter(StationIDNumber.KEY_COUNTRY_CODE); + } + /** + * @param {Number} id - Binary representation of unique facility ID assigned by the FCC; FCC controlled for U.S. + * territory + * @return {StationIDNumber} + */ + + + setFccFacilityId(id) { + this.setParameter(StationIDNumber.KEY_FCC_FACILITY_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getFccFacilityId() { + return this.getParameter(StationIDNumber.KEY_FCC_FACILITY_ID); + } + + } + + StationIDNumber.KEY_COUNTRY_CODE = 'countryCode'; + StationIDNumber.KEY_FCC_FACILITY_ID = 'fccFacilityId'; + + /* eslint-disable camelcase */ + + class SisData extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {String} name - Identifies the 4-alpha-character station call sign plus an optional (-FM) extension + * @return {SisData} + */ + + + setStationShortName(name) { + this.setParameter(SisData.KEY_STATION_SHORT_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getStationShortName() { + return this.getParameter(SisData.KEY_STATION_SHORT_NAME); + } + /** + * @param {StationIDNumber} number - Used for network Application. Consists of Country Code and FCC Facility ID. + * @return {SisData} + */ + + + setStationIDNumber(number) { + this.validateType(StationIDNumber, number); + this.setParameter(SisData.KEY_STATION_IDNUMBER, number); + return this; + } + /** + * @return {StationIDNumber} + */ + + + getStationIDNumber() { + return this.getObject(StationIDNumber, SisData.KEY_STATION_IDNUMBER); + } + /** + * @param {String} name - Identifies the station call sign or other identifying information in the long format. + * @return {SisData} + */ + + + setStationLongName(name) { + this.setParameter(SisData.KEY_STATION_LONG_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getStationLongName() { + return this.getParameter(SisData.KEY_STATION_LONG_NAME); + } + /** + * @param {GPSData} location - Provides the 3-dimensional geographic station location. + * @return {SisData} + */ + + + setStationLocation(location) { + this.validateType(GPSData, location); + this.setParameter(SisData.KEY_STATION_LOCATION, location); + return this; + } + /** + * @return {GPSData} + */ + + + getStationLocation() { + return this.getObject(GPSData, SisData.KEY_STATION_LOCATION); + } + /** + * @param {String} message - May be used to convey textual information of general interest to the consumer such as + * weather forecasts or public service announcements. Includes a high priority delivery + * feature to convey emergencies that may be in the listening area. + * @return {SisData} + */ + + + setStationMessage(message) { + this.setParameter(SisData.KEY_STATION_MESSAGE, message); + return this; + } + /** + * @return {String} + */ + + + getStationMessage() { + return this.getParameter(SisData.KEY_STATION_MESSAGE); + } + + } + + SisData.KEY_STATION_SHORT_NAME = 'stationShortName'; + SisData.KEY_STATION_IDNUMBER = 'stationIDNumber'; + SisData.KEY_STATION_LONG_NAME = 'stationLongName'; + SisData.KEY_STATION_LOCATION = 'stationLocation'; + SisData.KEY_STATION_MESSAGE = 'stationMessage'; + + /* eslint-disable camelcase */ + + class RadioControlData extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Number} integer - The integer part of the frequency ie for 101.7 this value should be 101 + * @return {RadioControlData} + */ + + + setFrequencyInteger(integer) { + this.setParameter(RadioControlData.KEY_FREQUENCY_INTEGER, integer); + return this; + } + /** + * @return {Number} + */ + + + getFrequencyInteger() { + return this.getParameter(RadioControlData.KEY_FREQUENCY_INTEGER); + } + /** + * @param {Number} fraction - The fractional part of the frequency for 101.7 is 7 + * @return {RadioControlData} + */ + + + setFrequencyFraction(fraction) { + this.setParameter(RadioControlData.KEY_FREQUENCY_FRACTION, fraction); + return this; + } + /** + * @return {Number} + */ + + + getFrequencyFraction() { + return this.getParameter(RadioControlData.KEY_FREQUENCY_FRACTION); + } + /** + * @param {RadioBand} band + * @return {RadioControlData} + */ + + + setBand(band) { + this.validateType(RadioBand, band); + this.setParameter(RadioControlData.KEY_BAND, band); + return this; + } + /** + * @return {RadioBand} + */ + + + getBand() { + return this.getObject(RadioBand, RadioControlData.KEY_BAND); + } + /** + * @param {RdsData} data + * @return {RadioControlData} + */ + + + setRdsData(data) { + this.validateType(RdsData, data); + this.setParameter(RadioControlData.KEY_RDS_DATA, data); + return this; + } + /** + * @return {RdsData} + */ + + + getRdsData() { + return this.getObject(RdsData, RadioControlData.KEY_RDS_DATA); + } + /** + * @param {Boolean} enable - True if the hd radio is on, false if the radio is off + * @return {RadioControlData} + */ + + + setHdRadioEnable(enable) { + this.setParameter(RadioControlData.KEY_HD_RADIO_ENABLE, enable); + return this; + } + /** + * @return {Boolean} + */ + + + getHdRadioEnable() { + return this.getParameter(RadioControlData.KEY_HD_RADIO_ENABLE); + } + /** + * @param {Number} ds - Number of HD sub-channels if available + * @return {RadioControlData} + */ + + + setAvailableHDs(ds) { + this.setParameter(RadioControlData.KEY_AVAILABLE_HDS, ds); + return this; + } + /** + * @return {Number} + */ + + + getAvailableHDs() { + return this.getParameter(RadioControlData.KEY_AVAILABLE_HDS); + } + /** + * @param {Number[]} channels - The list of available HD sub-channel indexes. Empty list means no Hd channel is + * available. Read-only. + * @return {RadioControlData} + */ + + + setAvailableHdChannels(channels) { + this.setParameter(RadioControlData.KEY_AVAILABLE_HD_CHANNELS, channels); + return this; + } + /** + * @return {Number[]} + */ + + + getAvailableHdChannels() { + return this.getParameter(RadioControlData.KEY_AVAILABLE_HD_CHANNELS); + } + /** + * @param {Number} channel - Current HD sub-channel if available + * @return {RadioControlData} + */ + + + setHdChannel(channel) { + this.setParameter(RadioControlData.KEY_HD_CHANNEL, channel); + return this; + } + /** + * @return {Number} + */ + + + getHdChannel() { + return this.getParameter(RadioControlData.KEY_HD_CHANNEL); + } + /** + * @param {Number} strength + * @return {RadioControlData} + */ + + + setSignalStrength(strength) { + this.setParameter(RadioControlData.KEY_SIGNAL_STRENGTH, strength); + return this; + } + /** + * @return {Number} + */ + + + getSignalStrength() { + return this.getParameter(RadioControlData.KEY_SIGNAL_STRENGTH); + } + /** + * @param {Number} threshold - If the signal strength falls below the set value for this parameter, the radio will + * tune to an alternative frequency + * @return {RadioControlData} + */ + + + setSignalChangeThreshold(threshold) { + this.setParameter(RadioControlData.KEY_SIGNAL_CHANGE_THRESHOLD, threshold); + return this; + } + /** + * @return {Number} + */ + + + getSignalChangeThreshold() { + return this.getParameter(RadioControlData.KEY_SIGNAL_CHANGE_THRESHOLD); + } + /** + * @param {Boolean} enable - True if the radio is on, false if the radio is off. If set to false, no other data will + * be included. + * @return {RadioControlData} + */ + + + setRadioEnable(enable) { + this.setParameter(RadioControlData.KEY_RADIO_ENABLE, enable); + return this; + } + /** + * @return {Boolean} + */ + + + getRadioEnable() { + return this.getParameter(RadioControlData.KEY_RADIO_ENABLE); + } + /** + * @param {RadioState} state + * @return {RadioControlData} + */ + + + setState(state) { + this.validateType(RadioState, state); + this.setParameter(RadioControlData.KEY_STATE, state); + return this; + } + /** + * @return {RadioState} + */ + + + getState() { + return this.getObject(RadioState, RadioControlData.KEY_STATE); + } + /** + * @param {SisData} data - Read-only Station Information Service (SIS) data provides basic information about the + * station such as call sign, as well as information not displayable to the consumer such as + * the station identification number + * @return {RadioControlData} + */ + + + setSisData(data) { + this.validateType(SisData, data); + this.setParameter(RadioControlData.KEY_SIS_DATA, data); + return this; + } + /** + * @return {SisData} + */ + + + getSisData() { + return this.getObject(SisData, RadioControlData.KEY_SIS_DATA); + } + + } + + RadioControlData.KEY_FREQUENCY_INTEGER = 'frequencyInteger'; + RadioControlData.KEY_FREQUENCY_FRACTION = 'frequencyFraction'; + RadioControlData.KEY_BAND = 'band'; + RadioControlData.KEY_RDS_DATA = 'rdsData'; + RadioControlData.KEY_HD_RADIO_ENABLE = 'hdRadioEnable'; + RadioControlData.KEY_AVAILABLE_HDS = 'availableHDs'; + RadioControlData.KEY_AVAILABLE_HD_CHANNELS = 'availableHdChannels'; + RadioControlData.KEY_HD_CHANNEL = 'hdChannel'; + RadioControlData.KEY_SIGNAL_STRENGTH = 'signalStrength'; + RadioControlData.KEY_SIGNAL_CHANGE_THRESHOLD = 'signalChangeThreshold'; + RadioControlData.KEY_RADIO_ENABLE = 'radioEnable'; + RadioControlData.KEY_STATE = 'state'; + RadioControlData.KEY_SIS_DATA = 'sisData'; + + /* eslint-disable camelcase */ + + class Temperature extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {TemperatureUnit} unit - Temperature Unit + * @return {Temperature} + */ + + + setUnit(unit) { + this.validateType(TemperatureUnit, unit); + this.setParameter(Temperature.KEY_UNIT, unit); + return this; + } + /** + * @return {TemperatureUnit} + */ + + + getUnit() { + return this.getObject(TemperatureUnit, Temperature.KEY_UNIT); + } + /** + * @param {Number} value - Temperature Value in TemperatureUnit specified unit. Range depends on OEM and is not + * checked by SDL. + * @return {Temperature} + */ + + + setValue(value) { + this.setParameter(Temperature.KEY_VALUE, value); + return this; + } + /** + * @return {Number} + */ + + + getValue() { + return this.getParameter(Temperature.KEY_VALUE); + } + + } + + Temperature.KEY_UNIT = 'unit'; + Temperature.KEY_VALUE = 'value'; + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} VentilationMode + * @property {Object} _MAP + */ + + class VentilationMode extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get UPPER() { + return VentilationMode._MAP.UPPER; + } + /** + * @return {String} + */ + + + static get LOWER() { + return VentilationMode._MAP.LOWER; + } + /** + * @return {String} + */ + + + static get BOTH() { + return VentilationMode._MAP.BOTH; + } + /** + * @return {String} + */ + + + static get NONE() { + return VentilationMode._MAP.NONE; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return VentilationMode._valueForKey(key, VentilationMode._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return VentilationMode._keyForValue(value, VentilationMode._MAP); + } + + } + + VentilationMode._MAP = Object.freeze({ + 'UPPER': 'UPPER', + 'LOWER': 'LOWER', + 'BOTH': 'BOTH', + 'NONE': 'NONE' + }); + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} DefrostZone + * @property {Object} _MAP + */ + + class DefrostZone extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get FRONT() { + return DefrostZone._MAP.FRONT; + } + /** + * @return {String} + */ + + + static get REAR() { + return DefrostZone._MAP.REAR; + } + /** + * @return {String} + */ + + + static get ALL() { + return DefrostZone._MAP.ALL; + } + /** + * @return {String} + */ + + + static get NONE() { + return DefrostZone._MAP.NONE; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return DefrostZone._valueForKey(key, DefrostZone._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return DefrostZone._keyForValue(value, DefrostZone._MAP); + } + + } + + DefrostZone._MAP = Object.freeze({ + 'FRONT': 'FRONT', + 'REAR': 'REAR', + 'ALL': 'ALL', + 'NONE': 'NONE' + }); + + /* eslint-disable camelcase */ + + class ClimateControlData extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Number} speed + * @return {ClimateControlData} + */ + + + setFanSpeed(speed) { + this.setParameter(ClimateControlData.KEY_FAN_SPEED, speed); + return this; + } + /** + * @return {Number} + */ + + + getFanSpeed() { + return this.getParameter(ClimateControlData.KEY_FAN_SPEED); + } + /** + * @param {Temperature} temperature + * @return {ClimateControlData} + */ + + + setCurrentTemperature(temperature) { + this.validateType(Temperature, temperature); + this.setParameter(ClimateControlData.KEY_CURRENT_TEMPERATURE, temperature); + return this; + } + /** + * @return {Temperature} + */ + + + getCurrentTemperature() { + return this.getObject(Temperature, ClimateControlData.KEY_CURRENT_TEMPERATURE); + } + /** + * @param {Temperature} temperature + * @return {ClimateControlData} + */ + + + setDesiredTemperature(temperature) { + this.validateType(Temperature, temperature); + this.setParameter(ClimateControlData.KEY_DESIRED_TEMPERATURE, temperature); + return this; + } + /** + * @return {Temperature} + */ + + + getDesiredTemperature() { + return this.getObject(Temperature, ClimateControlData.KEY_DESIRED_TEMPERATURE); + } + /** + * @param {Boolean} enable + * @return {ClimateControlData} + */ + + + setAcEnable(enable) { + this.setParameter(ClimateControlData.KEY_AC_ENABLE, enable); + return this; + } + /** + * @return {Boolean} + */ + + + getAcEnable() { + return this.getParameter(ClimateControlData.KEY_AC_ENABLE); + } + /** + * @param {Boolean} enable + * @return {ClimateControlData} + */ + + + setCirculateAirEnable(enable) { + this.setParameter(ClimateControlData.KEY_CIRCULATE_AIR_ENABLE, enable); + return this; + } + /** + * @return {Boolean} + */ + + + getCirculateAirEnable() { + return this.getParameter(ClimateControlData.KEY_CIRCULATE_AIR_ENABLE); + } + /** + * @param {Boolean} enable + * @return {ClimateControlData} + */ + + + setAutoModeEnable(enable) { + this.setParameter(ClimateControlData.KEY_AUTO_MODE_ENABLE, enable); + return this; + } + /** + * @return {Boolean} + */ + + + getAutoModeEnable() { + return this.getParameter(ClimateControlData.KEY_AUTO_MODE_ENABLE); + } + /** + * @param {DefrostZone} zone + * @return {ClimateControlData} + */ + + + setDefrostZone(zone) { + this.validateType(DefrostZone, zone); + this.setParameter(ClimateControlData.KEY_DEFROST_ZONE, zone); + return this; + } + /** + * @return {DefrostZone} + */ + + + getDefrostZone() { + return this.getObject(DefrostZone, ClimateControlData.KEY_DEFROST_ZONE); + } + /** + * @param {Boolean} enable + * @return {ClimateControlData} + */ + + + setDualModeEnable(enable) { + this.setParameter(ClimateControlData.KEY_DUAL_MODE_ENABLE, enable); + return this; + } + /** + * @return {Boolean} + */ + + + getDualModeEnable() { + return this.getParameter(ClimateControlData.KEY_DUAL_MODE_ENABLE); + } + /** + * @param {Boolean} enable + * @return {ClimateControlData} + */ + + + setAcMaxEnable(enable) { + this.setParameter(ClimateControlData.KEY_AC_MAX_ENABLE, enable); + return this; + } + /** + * @return {Boolean} + */ + + + getAcMaxEnable() { + return this.getParameter(ClimateControlData.KEY_AC_MAX_ENABLE); + } + /** + * @param {VentilationMode} mode + * @return {ClimateControlData} + */ + + + setVentilationMode(mode) { + this.validateType(VentilationMode, mode); + this.setParameter(ClimateControlData.KEY_VENTILATION_MODE, mode); + return this; + } + /** + * @return {VentilationMode} + */ + + + getVentilationMode() { + return this.getObject(VentilationMode, ClimateControlData.KEY_VENTILATION_MODE); + } + /** + * @param {Boolean} enable - value false means disabled/turn off, value true means enabled/turn on. + * @return {ClimateControlData} + */ + + + setHeatedSteeringWheelEnable(enable) { + this.setParameter(ClimateControlData.KEY_HEATED_STEERING_WHEEL_ENABLE, enable); + return this; + } + /** + * @return {Boolean} + */ + + + getHeatedSteeringWheelEnable() { + return this.getParameter(ClimateControlData.KEY_HEATED_STEERING_WHEEL_ENABLE); + } + /** + * @param {Boolean} enable - value false means disabled, value true means enabled. + * @return {ClimateControlData} + */ + + + setHeatedWindshieldEnable(enable) { + this.setParameter(ClimateControlData.KEY_HEATED_WINDSHIELD_ENABLE, enable); + return this; + } + /** + * @return {Boolean} + */ + + + getHeatedWindshieldEnable() { + return this.getParameter(ClimateControlData.KEY_HEATED_WINDSHIELD_ENABLE); + } + /** + * @param {Boolean} enable - value false means disabled, value true means enabled. + * @return {ClimateControlData} + */ + + + setHeatedRearWindowEnable(enable) { + this.setParameter(ClimateControlData.KEY_HEATED_REAR_WINDOW_ENABLE, enable); + return this; + } + /** + * @return {Boolean} + */ + + + getHeatedRearWindowEnable() { + return this.getParameter(ClimateControlData.KEY_HEATED_REAR_WINDOW_ENABLE); + } + /** + * @param {Boolean} enable - value false means disabled, value true means enabled. + * @return {ClimateControlData} + */ + + + setHeatedMirrorsEnable(enable) { + this.setParameter(ClimateControlData.KEY_HEATED_MIRRORS_ENABLE, enable); + return this; + } + /** + * @return {Boolean} + */ + + + getHeatedMirrorsEnable() { + return this.getParameter(ClimateControlData.KEY_HEATED_MIRRORS_ENABLE); + } + /** + * @param {Boolean} enable - True if the climate module is on, false if the climate module is off + * @return {ClimateControlData} + */ + + + setClimateEnable(enable) { + this.setParameter(ClimateControlData.KEY_CLIMATE_ENABLE, enable); + return this; + } + /** + * @return {Boolean} + */ + + + getClimateEnable() { + return this.getParameter(ClimateControlData.KEY_CLIMATE_ENABLE); + } + + } + + ClimateControlData.KEY_FAN_SPEED = 'fanSpeed'; + ClimateControlData.KEY_CURRENT_TEMPERATURE = 'currentTemperature'; + ClimateControlData.KEY_DESIRED_TEMPERATURE = 'desiredTemperature'; + ClimateControlData.KEY_AC_ENABLE = 'acEnable'; + ClimateControlData.KEY_CIRCULATE_AIR_ENABLE = 'circulateAirEnable'; + ClimateControlData.KEY_AUTO_MODE_ENABLE = 'autoModeEnable'; + ClimateControlData.KEY_DEFROST_ZONE = 'defrostZone'; + ClimateControlData.KEY_DUAL_MODE_ENABLE = 'dualModeEnable'; + ClimateControlData.KEY_AC_MAX_ENABLE = 'acMaxEnable'; + ClimateControlData.KEY_VENTILATION_MODE = 'ventilationMode'; + ClimateControlData.KEY_HEATED_STEERING_WHEEL_ENABLE = 'heatedSteeringWheelEnable'; + ClimateControlData.KEY_HEATED_WINDSHIELD_ENABLE = 'heatedWindshieldEnable'; + ClimateControlData.KEY_HEATED_REAR_WINDOW_ENABLE = 'heatedRearWindowEnable'; + ClimateControlData.KEY_HEATED_MIRRORS_ENABLE = 'heatedMirrorsEnable'; + ClimateControlData.KEY_CLIMATE_ENABLE = 'climateEnable'; + + /* eslint-disable camelcase */ + /** + * Defines the each Equalizer channel settings. + */ + + class EqualizerSettings extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Number} id + * @return {EqualizerSettings} + */ + + + setChannelId(id) { + this.setParameter(EqualizerSettings.KEY_CHANNEL_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getChannelId() { + return this.getParameter(EqualizerSettings.KEY_CHANNEL_ID); + } + /** + * @param {String} name - read-only channel / frequency name (e.i. "Treble, Midrange, Bass" or "125 Hz") + * @return {EqualizerSettings} + */ + + + setChannelName(name) { + this.setParameter(EqualizerSettings.KEY_CHANNEL_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getChannelName() { + return this.getParameter(EqualizerSettings.KEY_CHANNEL_NAME); + } + /** + * @param {Number} setting - Reflects the setting, from 0%-100%. + * @return {EqualizerSettings} + */ + + + setChannelSetting(setting) { + this.setParameter(EqualizerSettings.KEY_CHANNEL_SETTING, setting); + return this; + } + /** + * @return {Number} + */ + + + getChannelSetting() { + return this.getParameter(EqualizerSettings.KEY_CHANNEL_SETTING); + } + + } + + EqualizerSettings.KEY_CHANNEL_ID = 'channelId'; + EqualizerSettings.KEY_CHANNEL_NAME = 'channelName'; + EqualizerSettings.KEY_CHANNEL_SETTING = 'channelSetting'; + + /* eslint-disable camelcase */ + + class AudioControlData extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {PrimaryAudioSource} source - In a getter response or a notification, it is the current primary audio + * source of the system. In a setter request, it is the target audio source + * that the system shall switch to. If the value is MOBILE_APP, the system + * shall switch to the mobile media app that issues the setter RPC. + * @return {AudioControlData} + */ + + + setSource(source) { + this.validateType(PrimaryAudioSource, source); + this.setParameter(AudioControlData.KEY_SOURCE, source); + return this; + } + /** + * @return {PrimaryAudioSource} + */ + + + getSource() { + return this.getObject(PrimaryAudioSource, AudioControlData.KEY_SOURCE); + } + /** + * @param {Boolean} context - This parameter shall not be present in any getter responses or notifications. This + * parameter is optional in a setter request. The default value is false if it is not + * included. If it is false, the system not only changes the audio source but also brings + * the default application or system UI associated with the audio source to foreground. + * If it is true, the system only changes the audio source, but keeps the current + * application in foreground. + * @return {AudioControlData} + */ + + + setKeepContext(context) { + this.setParameter(AudioControlData.KEY_KEEP_CONTEXT, context); + return this; + } + /** + * @return {Boolean} + */ + + + getKeepContext() { + return this.getParameter(AudioControlData.KEY_KEEP_CONTEXT); + } + /** + * @param {Number} volume - Reflects the volume of audio, from 0%-100%. + * @return {AudioControlData} + */ + + + setVolume(volume) { + this.setParameter(AudioControlData.KEY_VOLUME, volume); + return this; + } + /** + * @return {Number} + */ + + + getVolume() { + return this.getParameter(AudioControlData.KEY_VOLUME); + } + /** + * @param {EqualizerSettings[]} settings - Defines the list of supported channels (band) and their current/desired + * settings on HMI + * @return {AudioControlData} + */ + + + setEqualizerSettings(settings) { + this.validateType(EqualizerSettings, settings, true); + this.setParameter(AudioControlData.KEY_EQUALIZER_SETTINGS, settings); + return this; + } + /** + * @return {EqualizerSettings[]} + */ + + + getEqualizerSettings() { + return this.getObject(EqualizerSettings, AudioControlData.KEY_EQUALIZER_SETTINGS); + } + + } + + AudioControlData.KEY_SOURCE = 'source'; + AudioControlData.KEY_KEEP_CONTEXT = 'keepContext'; + AudioControlData.KEY_VOLUME = 'volume'; + AudioControlData.KEY_EQUALIZER_SETTINGS = 'equalizerSettings'; + + /* eslint-disable camelcase */ + /** + * List possible cushions of a multi-contour massage seat. + * @typedef {Enum} MassageCushion + * @property {Object} _MAP + */ + + class MassageCushion extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get TOP_LUMBAR() { + return MassageCushion._MAP.TOP_LUMBAR; + } + /** + * @return {String} + */ + + + static get MIDDLE_LUMBAR() { + return MassageCushion._MAP.MIDDLE_LUMBAR; + } + /** + * @return {String} + */ + + + static get BOTTOM_LUMBAR() { + return MassageCushion._MAP.BOTTOM_LUMBAR; + } + /** + * @return {String} + */ + + + static get BACK_BOLSTERS() { + return MassageCushion._MAP.BACK_BOLSTERS; + } + /** + * @return {String} + */ + + + static get SEAT_BOLSTERS() { + return MassageCushion._MAP.SEAT_BOLSTERS; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return MassageCushion._valueForKey(key, MassageCushion._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return MassageCushion._keyForValue(value, MassageCushion._MAP); + } + + } + + MassageCushion._MAP = Object.freeze({ + 'TOP_LUMBAR': 'TOP_LUMBAR', + 'MIDDLE_LUMBAR': 'MIDDLE_LUMBAR', + 'BOTTOM_LUMBAR': 'BOTTOM_LUMBAR', + 'BACK_BOLSTERS': 'BACK_BOLSTERS', + 'SEAT_BOLSTERS': 'SEAT_BOLSTERS' + }); + + /* eslint-disable camelcase */ + /** + * The intensity or firmness of a cushion. + */ + + class MassageCushionFirmness extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {MassageCushion} cushion - List possible cushions of a multi-contour massage seat. + * @return {MassageCushionFirmness} + */ + + + setCushion(cushion) { + this.validateType(MassageCushion, cushion); + this.setParameter(MassageCushionFirmness.KEY_CUSHION, cushion); + return this; + } + /** + * @return {MassageCushion} + */ + + + getCushion() { + return this.getObject(MassageCushion, MassageCushionFirmness.KEY_CUSHION); + } + /** + * @param {Number} firmness + * @return {MassageCushionFirmness} + */ + + + setFirmness(firmness) { + this.setParameter(MassageCushionFirmness.KEY_FIRMNESS, firmness); + return this; + } + /** + * @return {Number} + */ + + + getFirmness() { + return this.getParameter(MassageCushionFirmness.KEY_FIRMNESS); + } + + } + + MassageCushionFirmness.KEY_CUSHION = 'cushion'; + MassageCushionFirmness.KEY_FIRMNESS = 'firmness'; + + /* eslint-disable camelcase */ + /** + * List possible seats that is a remote controllable seat. + * @deprecated + * @typedef {Enum} SupportedSeat + * @property {Object} _MAP + */ + + class SupportedSeat extends Enum { + /** + * @deprecated + * @constructor + */ + constructor() { + super(); + } + /** + * @deprecated + * @return {String} + */ + + + static get DRIVER() { + return SupportedSeat._MAP.DRIVER; + } + /** + * @deprecated + * @return {String} + */ + + + static get FRONT_PASSENGER() { + return SupportedSeat._MAP.FRONT_PASSENGER; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return SupportedSeat._valueForKey(key, SupportedSeat._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return SupportedSeat._keyForValue(value, SupportedSeat._MAP); + } + + } + + SupportedSeat._MAP = Object.freeze({ + 'DRIVER': 'DRIVER', + 'FRONT_PASSENGER': 'FRONT_PASSENGER' + }); + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} SeatMemoryActionType + * @property {Object} _MAP + */ + + class SeatMemoryActionType extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * Save current seat postions and settings to seat memory. + * @return {String} + */ + + + static get SAVE() { + return SeatMemoryActionType._MAP.SAVE; + } + /** + * Restore / apply the seat memory settings to the current seat. + * @return {String} + */ + + + static get RESTORE() { + return SeatMemoryActionType._MAP.RESTORE; + } + /** + * No action to be performed. + * @return {String} + */ + + + static get NONE() { + return SeatMemoryActionType._MAP.NONE; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return SeatMemoryActionType._valueForKey(key, SeatMemoryActionType._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return SeatMemoryActionType._keyForValue(value, SeatMemoryActionType._MAP); + } + + } + + SeatMemoryActionType._MAP = Object.freeze({ + 'SAVE': 'SAVE', + 'RESTORE': 'RESTORE', + 'NONE': 'NONE' + }); + + /* eslint-disable camelcase */ + + class SeatMemoryAction extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Number} id + * @return {SeatMemoryAction} + */ + + + setId(id) { + this.setParameter(SeatMemoryAction.KEY_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getId() { + return this.getParameter(SeatMemoryAction.KEY_ID); + } + /** + * @param {String} label + * @return {SeatMemoryAction} + */ + + + setLabel(label) { + this.setParameter(SeatMemoryAction.KEY_LABEL, label); + return this; + } + /** + * @return {String} + */ + + + getLabel() { + return this.getParameter(SeatMemoryAction.KEY_LABEL); + } + /** + * @param {SeatMemoryActionType} action + * @return {SeatMemoryAction} + */ + + + setAction(action) { + this.validateType(SeatMemoryActionType, action); + this.setParameter(SeatMemoryAction.KEY_ACTION, action); + return this; + } + /** + * @return {SeatMemoryActionType} + */ + + + getAction() { + return this.getObject(SeatMemoryActionType, SeatMemoryAction.KEY_ACTION); + } + + } + + SeatMemoryAction.KEY_ID = 'id'; + SeatMemoryAction.KEY_LABEL = 'label'; + SeatMemoryAction.KEY_ACTION = 'action'; + + /* eslint-disable camelcase */ + /** + * List possible zones of a multi-contour massage seat. + * @typedef {Enum} MassageZone + * @property {Object} _MAP + */ + + class MassageZone extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * The back of a multi-contour massage seat. or SEAT_BACK + * @return {String} + */ + + + static get LUMBAR() { + return MassageZone._MAP.LUMBAR; + } + /** + * The bottom a multi-contour massage seat. or SEAT_BOTTOM + * @return {String} + */ + + + static get SEAT_CUSHION() { + return MassageZone._MAP.SEAT_CUSHION; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return MassageZone._valueForKey(key, MassageZone._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return MassageZone._keyForValue(value, MassageZone._MAP); + } + + } + + MassageZone._MAP = Object.freeze({ + 'LUMBAR': 'LUMBAR', + 'SEAT_CUSHION': 'SEAT_CUSHION' + }); + + /* eslint-disable camelcase */ + /** + * List possible modes of a massage zone. + * @typedef {Enum} MassageMode + * @property {Object} _MAP + */ + + class MassageMode extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get OFF() { + return MassageMode._MAP.OFF; + } + /** + * @return {String} + */ + + + static get LOW() { + return MassageMode._MAP.LOW; + } + /** + * @return {String} + */ + + + static get HIGH() { + return MassageMode._MAP.HIGH; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return MassageMode._valueForKey(key, MassageMode._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return MassageMode._keyForValue(value, MassageMode._MAP); + } + + } + + MassageMode._MAP = Object.freeze({ + 'OFF': 'OFF', + 'LOW': 'LOW', + 'HIGH': 'HIGH' + }); + + /* eslint-disable camelcase */ + /** + * Specify the mode of a massage zone. + */ + + class MassageModeData extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {MassageZone} zone - List possible zones of a multi-contour massage seat. + * @return {MassageModeData} + */ + + + setMassageZone(zone) { + this.validateType(MassageZone, zone); + this.setParameter(MassageModeData.KEY_MASSAGE_ZONE, zone); + return this; + } + /** + * @return {MassageZone} + */ + + + getMassageZone() { + return this.getObject(MassageZone, MassageModeData.KEY_MASSAGE_ZONE); + } + /** + * @param {MassageMode} mode - List possible modes of a massage zone. + * @return {MassageModeData} + */ + + + setMassageMode(mode) { + this.validateType(MassageMode, mode); + this.setParameter(MassageModeData.KEY_MASSAGE_MODE, mode); + return this; + } + /** + * @return {MassageMode} + */ + + + getMassageMode() { + return this.getObject(MassageMode, MassageModeData.KEY_MASSAGE_MODE); + } + + } + + MassageModeData.KEY_MASSAGE_ZONE = 'massageZone'; + MassageModeData.KEY_MASSAGE_MODE = 'massageMode'; + + /* eslint-disable camelcase */ + /** + * Seat control data corresponds to "SEAT" ModuleType. + */ + + class SeatControlData extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {SupportedSeat} id - List possible seats that is a remote controllable seat. + * @return {SeatControlData} + */ + + + setId(id) { + this.validateType(SupportedSeat, id); + this.setParameter(SeatControlData.KEY_ID, id); + return this; + } + /** + * @return {SupportedSeat} + */ + + + getId() { + return this.getObject(SupportedSeat, SeatControlData.KEY_ID); + } + /** + * @param {Boolean} enabled + * @return {SeatControlData} + */ + + + setHeatingEnabled(enabled) { + this.setParameter(SeatControlData.KEY_HEATING_ENABLED, enabled); + return this; + } + /** + * @return {Boolean} + */ + + + getHeatingEnabled() { + return this.getParameter(SeatControlData.KEY_HEATING_ENABLED); + } + /** + * @param {Boolean} enabled + * @return {SeatControlData} + */ + + + setCoolingEnabled(enabled) { + this.setParameter(SeatControlData.KEY_COOLING_ENABLED, enabled); + return this; + } + /** + * @return {Boolean} + */ + + + getCoolingEnabled() { + return this.getParameter(SeatControlData.KEY_COOLING_ENABLED); + } + /** + * @param {Number} level + * @return {SeatControlData} + */ + + + setHeatingLevel(level) { + this.setParameter(SeatControlData.KEY_HEATING_LEVEL, level); + return this; + } + /** + * @return {Number} + */ + + + getHeatingLevel() { + return this.getParameter(SeatControlData.KEY_HEATING_LEVEL); + } + /** + * @param {Number} level + * @return {SeatControlData} + */ + + + setCoolingLevel(level) { + this.setParameter(SeatControlData.KEY_COOLING_LEVEL, level); + return this; + } + /** + * @return {Number} + */ + + + getCoolingLevel() { + return this.getParameter(SeatControlData.KEY_COOLING_LEVEL); + } + /** + * @param {Number} position + * @return {SeatControlData} + */ + + + setHorizontalPosition(position) { + this.setParameter(SeatControlData.KEY_HORIZONTAL_POSITION, position); + return this; + } + /** + * @return {Number} + */ + + + getHorizontalPosition() { + return this.getParameter(SeatControlData.KEY_HORIZONTAL_POSITION); + } + /** + * @param {Number} position + * @return {SeatControlData} + */ + + + setVerticalPosition(position) { + this.setParameter(SeatControlData.KEY_VERTICAL_POSITION, position); + return this; + } + /** + * @return {Number} + */ + + + getVerticalPosition() { + return this.getParameter(SeatControlData.KEY_VERTICAL_POSITION); + } + /** + * @param {Number} position + * @return {SeatControlData} + */ + + + setFrontVerticalPosition(position) { + this.setParameter(SeatControlData.KEY_FRONT_VERTICAL_POSITION, position); + return this; + } + /** + * @return {Number} + */ + + + getFrontVerticalPosition() { + return this.getParameter(SeatControlData.KEY_FRONT_VERTICAL_POSITION); + } + /** + * @param {Number} position + * @return {SeatControlData} + */ + + + setBackVerticalPosition(position) { + this.setParameter(SeatControlData.KEY_BACK_VERTICAL_POSITION, position); + return this; + } + /** + * @return {Number} + */ + + + getBackVerticalPosition() { + return this.getParameter(SeatControlData.KEY_BACK_VERTICAL_POSITION); + } + /** + * @param {Number} angle + * @return {SeatControlData} + */ + + + setBackTiltAngle(angle) { + this.setParameter(SeatControlData.KEY_BACK_TILT_ANGLE, angle); + return this; + } + /** + * @return {Number} + */ + + + getBackTiltAngle() { + return this.getParameter(SeatControlData.KEY_BACK_TILT_ANGLE); + } + /** + * @param {Number} position + * @return {SeatControlData} + */ + + + setHeadSupportHorizontalPosition(position) { + this.setParameter(SeatControlData.KEY_HEAD_SUPPORT_HORIZONTAL_POSITION, position); + return this; + } + /** + * @return {Number} + */ + + + getHeadSupportHorizontalPosition() { + return this.getParameter(SeatControlData.KEY_HEAD_SUPPORT_HORIZONTAL_POSITION); + } + /** + * @param {Number} position + * @return {SeatControlData} + */ + + + setHeadSupportVerticalPosition(position) { + this.setParameter(SeatControlData.KEY_HEAD_SUPPORT_VERTICAL_POSITION, position); + return this; + } + /** + * @return {Number} + */ + + + getHeadSupportVerticalPosition() { + return this.getParameter(SeatControlData.KEY_HEAD_SUPPORT_VERTICAL_POSITION); + } + /** + * @param {Boolean} enabled + * @return {SeatControlData} + */ + + + setMassageEnabled(enabled) { + this.setParameter(SeatControlData.KEY_MASSAGE_ENABLED, enabled); + return this; + } + /** + * @return {Boolean} + */ + + + getMassageEnabled() { + return this.getParameter(SeatControlData.KEY_MASSAGE_ENABLED); + } + /** + * @param {MassageModeData[]} mode - Specify the mode of a massage zone. + * @return {SeatControlData} + */ + + + setMassageMode(mode) { + this.validateType(MassageModeData, mode, true); + this.setParameter(SeatControlData.KEY_MASSAGE_MODE, mode); + return this; + } + /** + * @return {MassageModeData[]} + */ + + + getMassageMode() { + return this.getObject(MassageModeData, SeatControlData.KEY_MASSAGE_MODE); + } + /** + * @param {MassageCushionFirmness[]} firmness - The intensity or firmness of a cushion. + * @return {SeatControlData} + */ + + + setMassageCushionFirmness(firmness) { + this.validateType(MassageCushionFirmness, firmness, true); + this.setParameter(SeatControlData.KEY_MASSAGE_CUSHION_FIRMNESS, firmness); + return this; + } + /** + * @return {MassageCushionFirmness[]} + */ + + + getMassageCushionFirmness() { + return this.getObject(MassageCushionFirmness, SeatControlData.KEY_MASSAGE_CUSHION_FIRMNESS); + } + /** + * @param {SeatMemoryAction} memory + * @return {SeatControlData} + */ + + + setMemory(memory) { + this.validateType(SeatMemoryAction, memory); + this.setParameter(SeatControlData.KEY_MEMORY, memory); + return this; + } + /** + * @return {SeatMemoryAction} + */ + + + getMemory() { + return this.getObject(SeatMemoryAction, SeatControlData.KEY_MEMORY); + } + + } + + SeatControlData.KEY_ID = 'id'; + SeatControlData.KEY_HEATING_ENABLED = 'heatingEnabled'; + SeatControlData.KEY_COOLING_ENABLED = 'coolingEnabled'; + SeatControlData.KEY_HEATING_LEVEL = 'heatingLevel'; + SeatControlData.KEY_COOLING_LEVEL = 'coolingLevel'; + SeatControlData.KEY_HORIZONTAL_POSITION = 'horizontalPosition'; + SeatControlData.KEY_VERTICAL_POSITION = 'verticalPosition'; + SeatControlData.KEY_FRONT_VERTICAL_POSITION = 'frontVerticalPosition'; + SeatControlData.KEY_BACK_VERTICAL_POSITION = 'backVerticalPosition'; + SeatControlData.KEY_BACK_TILT_ANGLE = 'backTiltAngle'; + SeatControlData.KEY_HEAD_SUPPORT_HORIZONTAL_POSITION = 'headSupportHorizontalPosition'; + SeatControlData.KEY_HEAD_SUPPORT_VERTICAL_POSITION = 'headSupportVerticalPosition'; + SeatControlData.KEY_MASSAGE_ENABLED = 'massageEnabled'; + SeatControlData.KEY_MASSAGE_MODE = 'massageMode'; + SeatControlData.KEY_MASSAGE_CUSHION_FIRMNESS = 'massageCushionFirmness'; + SeatControlData.KEY_MEMORY = 'memory'; + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} LightStatus + * @property {Object} _MAP + */ + + class LightStatus extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get ON() { + return LightStatus._MAP.ON; + } + /** + * @return {String} + */ + + + static get OFF() { + return LightStatus._MAP.OFF; + } + /** + * @return {String} + */ + + + static get RAMP_UP() { + return LightStatus._MAP.RAMP_UP; + } + /** + * @return {String} + */ + + + static get RAMP_DOWN() { + return LightStatus._MAP.RAMP_DOWN; + } + /** + * @return {String} + */ + + + static get UNKNOWN() { + return LightStatus._MAP.UNKNOWN; + } + /** + * @return {String} + */ + + + static get INVALID() { + return LightStatus._MAP.INVALID; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return LightStatus._valueForKey(key, LightStatus._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return LightStatus._keyForValue(value, LightStatus._MAP); + } + + } + + LightStatus._MAP = Object.freeze({ + 'ON': 'ON', + 'OFF': 'OFF', + 'RAMP_UP': 'RAMP_UP', + 'RAMP_DOWN': 'RAMP_DOWN', + 'UNKNOWN': 'UNKNOWN', + 'INVALID': 'INVALID' + }); + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} LightName + * @property {Object} _MAP + */ + + class LightName extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {Number} + */ + + + static get FRONT_LEFT_HIGH_BEAM() { + return LightName._MAP.FRONT_LEFT_HIGH_BEAM; + } + /** + * @return {Number} + */ + + + static get FRONT_RIGHT_HIGH_BEAM() { + return LightName._MAP.FRONT_RIGHT_HIGH_BEAM; + } + /** + * @return {Number} + */ + + + static get FRONT_LEFT_LOW_BEAM() { + return LightName._MAP.FRONT_LEFT_LOW_BEAM; + } + /** + * @return {Number} + */ + + + static get FRONT_RIGHT_LOW_BEAM() { + return LightName._MAP.FRONT_RIGHT_LOW_BEAM; + } + /** + * @return {Number} + */ + + + static get FRONT_LEFT_PARKING_LIGHT() { + return LightName._MAP.FRONT_LEFT_PARKING_LIGHT; + } + /** + * @return {Number} + */ + + + static get FRONT_RIGHT_PARKING_LIGHT() { + return LightName._MAP.FRONT_RIGHT_PARKING_LIGHT; + } + /** + * @return {Number} + */ + + + static get FRONT_LEFT_FOG_LIGHT() { + return LightName._MAP.FRONT_LEFT_FOG_LIGHT; + } + /** + * @return {Number} + */ + + + static get FRONT_RIGHT_FOG_LIGHT() { + return LightName._MAP.FRONT_RIGHT_FOG_LIGHT; + } + /** + * @return {Number} + */ + + + static get FRONT_LEFT_DAYTIME_RUNNING_LIGHT() { + return LightName._MAP.FRONT_LEFT_DAYTIME_RUNNING_LIGHT; + } + /** + * @return {Number} + */ + + + static get FRONT_RIGHT_DAYTIME_RUNNING_LIGHT() { + return LightName._MAP.FRONT_RIGHT_DAYTIME_RUNNING_LIGHT; + } + /** + * @return {Number} + */ + + + static get FRONT_LEFT_TURN_LIGHT() { + return LightName._MAP.FRONT_LEFT_TURN_LIGHT; + } + /** + * @return {Number} + */ + + + static get FRONT_RIGHT_TURN_LIGHT() { + return LightName._MAP.FRONT_RIGHT_TURN_LIGHT; + } + /** + * @return {Number} + */ + + + static get REAR_LEFT_FOG_LIGHT() { + return LightName._MAP.REAR_LEFT_FOG_LIGHT; + } + /** + * @return {Number} + */ + + + static get REAR_RIGHT_FOG_LIGHT() { + return LightName._MAP.REAR_RIGHT_FOG_LIGHT; + } + /** + * @return {Number} + */ + + + static get REAR_LEFT_TAIL_LIGHT() { + return LightName._MAP.REAR_LEFT_TAIL_LIGHT; + } + /** + * @return {Number} + */ + + + static get REAR_RIGHT_TAIL_LIGHT() { + return LightName._MAP.REAR_RIGHT_TAIL_LIGHT; + } + /** + * @return {Number} + */ + + + static get REAR_LEFT_BRAKE_LIGHT() { + return LightName._MAP.REAR_LEFT_BRAKE_LIGHT; + } + /** + * @return {Number} + */ + + + static get REAR_RIGHT_BRAKE_LIGHT() { + return LightName._MAP.REAR_RIGHT_BRAKE_LIGHT; + } + /** + * @return {Number} + */ + + + static get REAR_LEFT_TURN_LIGHT() { + return LightName._MAP.REAR_LEFT_TURN_LIGHT; + } + /** + * @return {Number} + */ + + + static get REAR_RIGHT_TURN_LIGHT() { + return LightName._MAP.REAR_RIGHT_TURN_LIGHT; + } + /** + * @return {Number} + */ + + + static get REAR_REGISTRATION_PLATE_LIGHT() { + return LightName._MAP.REAR_REGISTRATION_PLATE_LIGHT; + } + /** + * Include all high beam lights: front_left and front_right. + * @return {Number} + */ + + + static get HIGH_BEAMS() { + return LightName._MAP.HIGH_BEAMS; + } + /** + * Include all low beam lights: front_left and front_right. + * @return {Number} + */ + + + static get LOW_BEAMS() { + return LightName._MAP.LOW_BEAMS; + } + /** + * Include all fog lights: front_left, front_right, rear_left and rear_right. + * @return {Number} + */ + + + static get FOG_LIGHTS() { + return LightName._MAP.FOG_LIGHTS; + } + /** + * Include all daytime running lights: front_left and front_right. + * @return {Number} + */ + + + static get RUNNING_LIGHTS() { + return LightName._MAP.RUNNING_LIGHTS; + } + /** + * Include all parking lights: front_left and front_right. + * @return {Number} + */ + + + static get PARKING_LIGHTS() { + return LightName._MAP.PARKING_LIGHTS; + } + /** + * Include all brake lights: rear_left and rear_right. + * @return {Number} + */ + + + static get BRAKE_LIGHTS() { + return LightName._MAP.BRAKE_LIGHTS; + } + /** + * @return {Number} + */ + + + static get REAR_REVERSING_LIGHTS() { + return LightName._MAP.REAR_REVERSING_LIGHTS; + } + /** + * @return {Number} + */ + + + static get SIDE_MARKER_LIGHTS() { + return LightName._MAP.SIDE_MARKER_LIGHTS; + } + /** + * Include all left turn signal lights: front_left, rear_left, left_side and mirror_mounted. + * @return {Number} + */ + + + static get LEFT_TURN_LIGHTS() { + return LightName._MAP.LEFT_TURN_LIGHTS; + } + /** + * Include all right turn signal lights: front_right, rear_right, right_side and mirror_mounted. + * @return {Number} + */ + + + static get RIGHT_TURN_LIGHTS() { + return LightName._MAP.RIGHT_TURN_LIGHTS; + } + /** + * Include all hazard lights: front_left, front_right, rear_left and rear_right. + * @return {Number} + */ + + + static get HAZARD_LIGHTS() { + return LightName._MAP.HAZARD_LIGHTS; + } + /** + * Cargo lamps illuminate the cargo area. + * @return {Number} + */ + + + static get REAR_CARGO_LIGHTS() { + return LightName._MAP.REAR_CARGO_LIGHTS; + } + /** + * Truck bed lamps light up the bed of the truck. + * @return {Number} + */ + + + static get REAR_TRUCK_BED_LIGHTS() { + return LightName._MAP.REAR_TRUCK_BED_LIGHTS; + } + /** + * Trailer lights are lamps mounted on a trailer hitch. + * @return {Number} + */ + + + static get REAR_TRAILER_LIGHTS() { + return LightName._MAP.REAR_TRAILER_LIGHTS; + } + /** + * It is the spotlights mounted on the left side of a vehicle. + * @return {Number} + */ + + + static get LEFT_SPOT_LIGHTS() { + return LightName._MAP.LEFT_SPOT_LIGHTS; + } + /** + * It is the spotlights mounted on the right side of a vehicle. + * @return {Number} + */ + + + static get RIGHT_SPOT_LIGHTS() { + return LightName._MAP.RIGHT_SPOT_LIGHTS; + } + /** + * Puddle lamps illuminate the ground beside the door as the customer is opening or approaching the door. + * @return {Number} + */ + + + static get LEFT_PUDDLE_LIGHTS() { + return LightName._MAP.LEFT_PUDDLE_LIGHTS; + } + /** + * Puddle lamps illuminate the ground beside the door as the customer is opening or approaching the door. + * @return {Number} + */ + + + static get RIGHT_PUDDLE_LIGHTS() { + return LightName._MAP.RIGHT_PUDDLE_LIGHTS; + } + /** + * @return {Number} + */ + + + static get AMBIENT_LIGHTS() { + return LightName._MAP.AMBIENT_LIGHTS; + } + /** + * @return {Number} + */ + + + static get OVERHEAD_LIGHTS() { + return LightName._MAP.OVERHEAD_LIGHTS; + } + /** + * @return {Number} + */ + + + static get READING_LIGHTS() { + return LightName._MAP.READING_LIGHTS; + } + /** + * @return {Number} + */ + + + static get TRUNK_LIGHTS() { + return LightName._MAP.TRUNK_LIGHTS; + } + /** + * Include exterior lights located in front of the vehicle. For example, fog lights and low beams. + * @return {Number} + */ + + + static get EXTERIOR_FRONT_LIGHTS() { + return LightName._MAP.EXTERIOR_FRONT_LIGHTS; + } + /** + * Include exterior lights located at the back of the vehicle. For example, license plate lights, reverse lights, + * cargo lights, bed lights and trailer assist lights. + * @return {Number} + */ + + + static get EXTERIOR_REAR_LIGHTS() { + return LightName._MAP.EXTERIOR_REAR_LIGHTS; + } + /** + * Include exterior lights located at the left side of the vehicle. For example, left puddle lights and spot + * lights. + * @return {Number} + */ + + + static get EXTERIOR_LEFT_LIGHTS() { + return LightName._MAP.EXTERIOR_LEFT_LIGHTS; + } + /** + * Include exterior lights located at the right side of the vehicle. For example, right puddle lights and spot + * lights. + * @return {Number} + */ + + + static get EXTERIOR_RIGHT_LIGHTS() { + return LightName._MAP.EXTERIOR_RIGHT_LIGHTS; + } + /** + * Include all exterior lights around the vehicle. + * @return {Number} + */ + + + static get EXTERIOR_ALL_LIGHTS() { + return LightName._MAP.EXTERIOR_ALL_LIGHTS; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return LightName._valueForKey(key, LightName._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return LightName._keyForValue(value, LightName._MAP); + } + + } + + LightName._MAP = Object.freeze({ + 'FRONT_LEFT_HIGH_BEAM': 0, + 'FRONT_RIGHT_HIGH_BEAM': 1, + 'FRONT_LEFT_LOW_BEAM': 2, + 'FRONT_RIGHT_LOW_BEAM': 3, + 'FRONT_LEFT_PARKING_LIGHT': 4, + 'FRONT_RIGHT_PARKING_LIGHT': 5, + 'FRONT_LEFT_FOG_LIGHT': 6, + 'FRONT_RIGHT_FOG_LIGHT': 7, + 'FRONT_LEFT_DAYTIME_RUNNING_LIGHT': 8, + 'FRONT_RIGHT_DAYTIME_RUNNING_LIGHT': 9, + 'FRONT_LEFT_TURN_LIGHT': 10, + 'FRONT_RIGHT_TURN_LIGHT': 11, + 'REAR_LEFT_FOG_LIGHT': 12, + 'REAR_RIGHT_FOG_LIGHT': 13, + 'REAR_LEFT_TAIL_LIGHT': 14, + 'REAR_RIGHT_TAIL_LIGHT': 15, + 'REAR_LEFT_BRAKE_LIGHT': 16, + 'REAR_RIGHT_BRAKE_LIGHT': 17, + 'REAR_LEFT_TURN_LIGHT': 18, + 'REAR_RIGHT_TURN_LIGHT': 19, + 'REAR_REGISTRATION_PLATE_LIGHT': 20, + 'HIGH_BEAMS': 501, + 'LOW_BEAMS': 502, + 'FOG_LIGHTS': 503, + 'RUNNING_LIGHTS': 504, + 'PARKING_LIGHTS': 505, + 'BRAKE_LIGHTS': 506, + 'REAR_REVERSING_LIGHTS': 507, + 'SIDE_MARKER_LIGHTS': 508, + 'LEFT_TURN_LIGHTS': 509, + 'RIGHT_TURN_LIGHTS': 510, + 'HAZARD_LIGHTS': 511, + 'REAR_CARGO_LIGHTS': 512, + 'REAR_TRUCK_BED_LIGHTS': 513, + 'REAR_TRAILER_LIGHTS': 514, + 'LEFT_SPOT_LIGHTS': 515, + 'RIGHT_SPOT_LIGHTS': 516, + 'LEFT_PUDDLE_LIGHTS': 517, + 'RIGHT_PUDDLE_LIGHTS': 518, + 'AMBIENT_LIGHTS': 801, + 'OVERHEAD_LIGHTS': 802, + 'READING_LIGHTS': 803, + 'TRUNK_LIGHTS': 804, + 'EXTERIOR_FRONT_LIGHTS': 901, + 'EXTERIOR_REAR_LIGHTS': 902, + 'EXTERIOR_LEFT_LIGHTS': 903, + 'EXTERIOR_RIGHT_LIGHTS': 904, + 'EXTERIOR_ALL_LIGHTS': 905 + }); + + /* eslint-disable camelcase */ + + class LightState extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {LightName} id - The name of a light or a group of lights. + * @return {LightState} + */ + + + setId(id) { + this.validateType(LightName, id); + this.setParameter(LightState.KEY_ID, id); + return this; + } + /** + * @return {LightName} + */ + + + getId() { + return this.getObject(LightName, LightState.KEY_ID); + } + /** + * @param {LightStatus} status + * @return {LightState} + */ + + + setStatus(status) { + this.validateType(LightStatus, status); + this.setParameter(LightState.KEY_STATUS, status); + return this; + } + /** + * @return {LightStatus} + */ + + + getStatus() { + return this.getObject(LightStatus, LightState.KEY_STATUS); + } + /** + * @param {Number} density + * @return {LightState} + */ + + + setDensity(density) { + this.setParameter(LightState.KEY_DENSITY, density); + return this; + } + /** + * @return {Number} + */ + + + getDensity() { + return this.getParameter(LightState.KEY_DENSITY); + } + /** + * @param {RGBColor} color + * @return {LightState} + */ + + + setColor(color) { + this.validateType(RGBColor, color); + this.setParameter(LightState.KEY_COLOR, color); + return this; + } + /** + * @return {RGBColor} + */ + + + getColor() { + return this.getObject(RGBColor, LightState.KEY_COLOR); + } + + } + + LightState.KEY_ID = 'id'; + LightState.KEY_STATUS = 'status'; + LightState.KEY_DENSITY = 'density'; + LightState.KEY_COLOR = 'color'; + + /* eslint-disable camelcase */ + + class LightControlData extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {LightState[]} state - An array of LightNames and their current or desired status. No change to the status + * of the LightNames that are not listed in the array. + * @return {LightControlData} + */ + + + setLightState(state) { + this.validateType(LightState, state, true); + this.setParameter(LightControlData.KEY_LIGHT_STATE, state); + return this; + } + /** + * @return {LightState[]} + */ + + + getLightState() { + return this.getObject(LightState, LightControlData.KEY_LIGHT_STATE); + } + + } + + LightControlData.KEY_LIGHT_STATE = 'lightState'; + + /* eslint-disable camelcase */ + /** + * The moduleType indicates which type of data should be changed and identifies which data object exists in this + * struct. For example, if the moduleType is CLIMATE then a "climateControlData" should exist + */ + + class ModuleData extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {ModuleType} type + * @return {ModuleData} + */ + + + setModuleType(type) { + this.validateType(ModuleType, type); + this.setParameter(ModuleData.KEY_MODULE_TYPE, type); + return this; + } + /** + * @return {ModuleType} + */ + + + getModuleType() { + return this.getObject(ModuleType, ModuleData.KEY_MODULE_TYPE); + } + /** + * @param {String} id - Id of a module, published by System Capability. + * @return {ModuleData} + */ + + + setModuleId(id) { + this.setParameter(ModuleData.KEY_MODULE_ID, id); + return this; + } + /** + * @return {String} + */ + + + getModuleId() { + return this.getParameter(ModuleData.KEY_MODULE_ID); + } + /** + * @param {RadioControlData} data + * @return {ModuleData} + */ + + + setRadioControlData(data) { + this.validateType(RadioControlData, data); + this.setParameter(ModuleData.KEY_RADIO_CONTROL_DATA, data); + return this; + } + /** + * @return {RadioControlData} + */ + + + getRadioControlData() { + return this.getObject(RadioControlData, ModuleData.KEY_RADIO_CONTROL_DATA); + } + /** + * @param {ClimateControlData} data + * @return {ModuleData} + */ + + + setClimateControlData(data) { + this.validateType(ClimateControlData, data); + this.setParameter(ModuleData.KEY_CLIMATE_CONTROL_DATA, data); + return this; + } + /** + * @return {ClimateControlData} + */ + + + getClimateControlData() { + return this.getObject(ClimateControlData, ModuleData.KEY_CLIMATE_CONTROL_DATA); + } + /** + * @param {SeatControlData} data - Seat control data corresponds to "SEAT" ModuleType. + * @return {ModuleData} + */ + + + setSeatControlData(data) { + this.validateType(SeatControlData, data); + this.setParameter(ModuleData.KEY_SEAT_CONTROL_DATA, data); + return this; + } + /** + * @return {SeatControlData} + */ + + + getSeatControlData() { + return this.getObject(SeatControlData, ModuleData.KEY_SEAT_CONTROL_DATA); + } + /** + * @param {AudioControlData} data + * @return {ModuleData} + */ + + + setAudioControlData(data) { + this.validateType(AudioControlData, data); + this.setParameter(ModuleData.KEY_AUDIO_CONTROL_DATA, data); + return this; + } + /** + * @return {AudioControlData} + */ + + + getAudioControlData() { + return this.getObject(AudioControlData, ModuleData.KEY_AUDIO_CONTROL_DATA); + } + /** + * @param {LightControlData} data + * @return {ModuleData} + */ + + + setLightControlData(data) { + this.validateType(LightControlData, data); + this.setParameter(ModuleData.KEY_LIGHT_CONTROL_DATA, data); + return this; + } + /** + * @return {LightControlData} + */ + + + getLightControlData() { + return this.getObject(LightControlData, ModuleData.KEY_LIGHT_CONTROL_DATA); + } + /** + * @param {HMISettingsControlData} data - Corresponds to "HMI_SETTINGS" ModuleType + * @return {ModuleData} + */ + + + setHmiSettingsControlData(data) { + this.validateType(HMISettingsControlData, data); + this.setParameter(ModuleData.KEY_HMI_SETTINGS_CONTROL_DATA, data); + return this; + } + /** + * @return {HMISettingsControlData} + */ + + + getHmiSettingsControlData() { + return this.getObject(HMISettingsControlData, ModuleData.KEY_HMI_SETTINGS_CONTROL_DATA); + } + + } + + ModuleData.KEY_MODULE_TYPE = 'moduleType'; + ModuleData.KEY_MODULE_ID = 'moduleId'; + ModuleData.KEY_RADIO_CONTROL_DATA = 'radioControlData'; + ModuleData.KEY_CLIMATE_CONTROL_DATA = 'climateControlData'; + ModuleData.KEY_SEAT_CONTROL_DATA = 'seatControlData'; + ModuleData.KEY_AUDIO_CONTROL_DATA = 'audioControlData'; + ModuleData.KEY_LIGHT_CONTROL_DATA = 'lightControlData'; + ModuleData.KEY_HMI_SETTINGS_CONTROL_DATA = 'hmiSettingsControlData'; + + /* eslint-disable camelcase */ + + class GetInteriorVehicleDataResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.GetInteriorVehicleData); + } + /** + * @param {ModuleData} data - The moduleType indicates which type of data should be changed and identifies which + * data object exists in this struct. For example, if the moduleType is CLIMATE then a + * "climateControlData" should exist + * @return {GetInteriorVehicleDataResponse} + */ + + + setModuleData(data) { + this.validateType(ModuleData, data); + this.setParameter(GetInteriorVehicleDataResponse.KEY_MODULE_DATA, data); + return this; + } + /** + * @return {ModuleData} + */ + + + getModuleData() { + return this.getObject(ModuleData, GetInteriorVehicleDataResponse.KEY_MODULE_DATA); + } + /** + * @param {Boolean} subscribed - It is a conditional-mandatory parameter: must be returned in case "subscribe" + * parameter was present in the related request. if "true" - the "moduleType" from + * request is successfully subscribed and the head unit will send + * onInteriorVehicleData notifications for the moduleType. if "false" - the + * "moduleType" from request is either unsubscribed or failed to subscribe. + * @return {GetInteriorVehicleDataResponse} + */ + + + setIsSubscribed(subscribed) { + this.setParameter(GetInteriorVehicleDataResponse.KEY_IS_SUBSCRIBED, subscribed); + return this; + } + /** + * @return {Boolean} + */ + + + getIsSubscribed() { + return this.getParameter(GetInteriorVehicleDataResponse.KEY_IS_SUBSCRIBED); + } + + } + + GetInteriorVehicleDataResponse.KEY_MODULE_DATA = 'moduleData'; + GetInteriorVehicleDataResponse.KEY_IS_SUBSCRIBED = 'isSubscribed'; + + /* eslint-disable camelcase */ + + class GetInteriorVehicleDataConsent extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.GetInteriorVehicleDataConsent); + } + /** + * @param {ModuleType} type - The module type that the app requests to control. + * @return {GetInteriorVehicleDataConsent} + */ + + + setModuleType(type) { + this.validateType(ModuleType, type); + this.setParameter(GetInteriorVehicleDataConsent.KEY_MODULE_TYPE, type); + return this; + } + /** + * @return {ModuleType} + */ + + + getModuleType() { + return this.getObject(ModuleType, GetInteriorVehicleDataConsent.KEY_MODULE_TYPE); + } + /** + * @param {String[]} ids - Ids of a module of same type, published by System Capability. + * @return {GetInteriorVehicleDataConsent} + */ + + + setModuleIds(ids) { + this.setParameter(GetInteriorVehicleDataConsent.KEY_MODULE_IDS, ids); + return this; + } + /** + * @return {String[]} + */ + + + getModuleIds() { + return this.getParameter(GetInteriorVehicleDataConsent.KEY_MODULE_IDS); + } + + } + + GetInteriorVehicleDataConsent.KEY_MODULE_TYPE = 'moduleType'; + GetInteriorVehicleDataConsent.KEY_MODULE_IDS = 'moduleIds'; + + /* eslint-disable camelcase */ + + class GetInteriorVehicleDataConsentResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.GetInteriorVehicleDataConsent); + } + /** + * @param {Boolean[]} allowed - This array has the same size as "moduleIds" in the request and each element + * corresponds to one moduleId If true, SDL grants the permission for the requested + * module If false, SDL denies the permission for the requested module. + * @return {GetInteriorVehicleDataConsentResponse} + */ + + + setAllowed(allowed) { + this.setParameter(GetInteriorVehicleDataConsentResponse.KEY_ALLOWED, allowed); + return this; + } + /** + * @return {Boolean[]} + */ + + + getAllowed() { + return this.getParameter(GetInteriorVehicleDataConsentResponse.KEY_ALLOWED); + } + + } + + GetInteriorVehicleDataConsentResponse.KEY_ALLOWED = 'allowed'; + + /* eslint-disable camelcase */ + + class ReleaseInteriorVehicleDataModule extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.ReleaseInteriorVehicleDataModule); + } + /** + * @param {ModuleType} type + * @return {ReleaseInteriorVehicleDataModule} + */ + + + setModuleType(type) { + this.validateType(ModuleType, type); + this.setParameter(ReleaseInteriorVehicleDataModule.KEY_MODULE_TYPE, type); + return this; + } + /** + * @return {ModuleType} + */ + + + getModuleType() { + return this.getObject(ModuleType, ReleaseInteriorVehicleDataModule.KEY_MODULE_TYPE); + } + /** + * @param {String} id - Id of a module, published by System Capability. + * @return {ReleaseInteriorVehicleDataModule} + */ + + + setModuleId(id) { + this.setParameter(ReleaseInteriorVehicleDataModule.KEY_MODULE_ID, id); + return this; + } + /** + * @return {String} + */ + + + getModuleId() { + return this.getParameter(ReleaseInteriorVehicleDataModule.KEY_MODULE_ID); + } + + } + + ReleaseInteriorVehicleDataModule.KEY_MODULE_TYPE = 'moduleType'; + ReleaseInteriorVehicleDataModule.KEY_MODULE_ID = 'moduleId'; + + /* eslint-disable camelcase */ + + class ReleaseInteriorVehicleDataModuleResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.ReleaseInteriorVehicleDataModule); + } + + } + + /* eslint-disable camelcase */ + + class SetInteriorVehicleData extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SetInteriorVehicleData); + } + /** + * @param {ModuleData} data - The module data to set for the requested RC module. + * @return {SetInteriorVehicleData} + */ + + + setModuleData(data) { + this.validateType(ModuleData, data); + this.setParameter(SetInteriorVehicleData.KEY_MODULE_DATA, data); + return this; + } + /** + * @return {ModuleData} + */ + + + getModuleData() { + return this.getObject(ModuleData, SetInteriorVehicleData.KEY_MODULE_DATA); + } + + } + + SetInteriorVehicleData.KEY_MODULE_DATA = 'moduleData'; + + /* eslint-disable camelcase */ + /** + * Used to set the values of one remote control module + */ + + class SetInteriorVehicleDataResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SetInteriorVehicleData); + } + /** + * @param {ModuleData} data - The moduleType indicates which type of data should be changed and identifies which + * data object exists in this struct. For example, if the moduleType is CLIMATE then a + * "climateControlData" should exist + * @return {SetInteriorVehicleDataResponse} + */ + + + setModuleData(data) { + this.validateType(ModuleData, data); + this.setParameter(SetInteriorVehicleDataResponse.KEY_MODULE_DATA, data); + return this; + } + /** + * @return {ModuleData} + */ + + + getModuleData() { + return this.getObject(ModuleData, SetInteriorVehicleDataResponse.KEY_MODULE_DATA); + } + + } + + SetInteriorVehicleDataResponse.KEY_MODULE_DATA = 'moduleData'; + + /* eslint-disable camelcase */ + /** + * To subscribe in getting changes for Waypoints/destinations + */ + + class SubscribeWayPoints extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SubscribeWayPoints); + } + + } + + /* eslint-disable camelcase */ + + class SubscribeWayPointsResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SubscribeWayPoints); + } + + } + + /* eslint-disable camelcase */ + /** + * Describes what kind of waypoint is requested/provided. + * @typedef {Enum} WayPointType + * @property {Object} _MAP + */ + + class WayPointType extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get ALL() { + return WayPointType._MAP.ALL; + } + /** + * @return {String} + */ + + + static get DESTINATION() { + return WayPointType._MAP.DESTINATION; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return WayPointType._valueForKey(key, WayPointType._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return WayPointType._keyForValue(value, WayPointType._MAP); + } + + } + + WayPointType._MAP = Object.freeze({ + 'ALL': 'ALL', + 'DESTINATION': 'DESTINATION' + }); + + /* eslint-disable camelcase */ + /** + * Request for getting waypoint/destination data. + */ + + class GetWayPoints extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.GetWayPoints); + } + /** + * @param {WayPointType} type - To request for either the destination only or for all waypoints including + * destination + * @return {GetWayPoints} + */ + + + setWayPointType(type) { + this.validateType(WayPointType, type); + this.setParameter(GetWayPoints.KEY_WAY_POINT_TYPE, type); + return this; + } + /** + * @return {WayPointType} + */ + + + getWayPointType() { + return this.getObject(WayPointType, GetWayPoints.KEY_WAY_POINT_TYPE); + } + + } + + GetWayPoints.KEY_WAY_POINT_TYPE = 'wayPointType'; + + /* eslint-disable camelcase */ + + class Coordinate extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Number} degrees - Latitude of the location. + * @return {Coordinate} + */ + + + setLatitudeDegrees(degrees) { + this.setParameter(Coordinate.KEY_LATITUDE_DEGREES, degrees); + return this; + } + /** + * @return {Number} + */ + + + getLatitudeDegrees() { + return this.getParameter(Coordinate.KEY_LATITUDE_DEGREES); + } + /** + * @param {Number} degrees - Longitude of the location. + * @return {Coordinate} + */ + + + setLongitudeDegrees(degrees) { + this.setParameter(Coordinate.KEY_LONGITUDE_DEGREES, degrees); + return this; + } + /** + * @return {Number} + */ + + + getLongitudeDegrees() { + return this.getParameter(Coordinate.KEY_LONGITUDE_DEGREES); + } + + } + + Coordinate.KEY_LATITUDE_DEGREES = 'latitudeDegrees'; + Coordinate.KEY_LONGITUDE_DEGREES = 'longitudeDegrees'; + + /* eslint-disable camelcase */ + + class LocationDetails extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Coordinate} coordinate - Latitude/Longitude of the location. + * @return {LocationDetails} + */ + + + setCoordinate(coordinate) { + this.validateType(Coordinate, coordinate); + this.setParameter(LocationDetails.KEY_COORDINATE, coordinate); + return this; + } + /** + * @return {Coordinate} + */ + + + getCoordinate() { + return this.getObject(Coordinate, LocationDetails.KEY_COORDINATE); + } + /** + * @param {String} name - Name of location. + * @return {LocationDetails} + */ + + + setLocationName(name) { + this.setParameter(LocationDetails.KEY_LOCATION_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getLocationName() { + return this.getParameter(LocationDetails.KEY_LOCATION_NAME); + } + /** + * @param {String[]} lines - Location address for display purposes only + * @return {LocationDetails} + */ + + + setAddressLines(lines) { + this.setParameter(LocationDetails.KEY_ADDRESS_LINES, lines); + return this; + } + /** + * @return {String[]} + */ + + + getAddressLines() { + return this.getParameter(LocationDetails.KEY_ADDRESS_LINES); + } + /** + * @param {String} description - Description intended location / establishment (if applicable) + * @return {LocationDetails} + */ + + + setLocationDescription(description) { + this.setParameter(LocationDetails.KEY_LOCATION_DESCRIPTION, description); + return this; + } + /** + * @return {String} + */ + + + getLocationDescription() { + return this.getParameter(LocationDetails.KEY_LOCATION_DESCRIPTION); + } + /** + * @param {String} number - Phone number of location / establishment. + * @return {LocationDetails} + */ + + + setPhoneNumber(number) { + this.setParameter(LocationDetails.KEY_PHONE_NUMBER, number); + return this; + } + /** + * @return {String} + */ + + + getPhoneNumber() { + return this.getParameter(LocationDetails.KEY_PHONE_NUMBER); + } + /** + * @param {Image} image - Image / icon of intended location. + * @return {LocationDetails} + */ + + + setLocationImage(image) { + this.validateType(Image, image); + this.setParameter(LocationDetails.KEY_LOCATION_IMAGE, image); + return this; + } + /** + * @return {Image} + */ + + + getLocationImage() { + return this.getObject(Image, LocationDetails.KEY_LOCATION_IMAGE); + } + /** + * @param {OASISAddress} address - Address to be used by navigation engines for search + * @return {LocationDetails} + */ + + + setSearchAddress(address) { + this.validateType(OASISAddress, address); + this.setParameter(LocationDetails.KEY_SEARCH_ADDRESS, address); + return this; + } + /** + * @return {OASISAddress} + */ + + + getSearchAddress() { + return this.getObject(OASISAddress, LocationDetails.KEY_SEARCH_ADDRESS); + } + + } + + LocationDetails.KEY_COORDINATE = 'coordinate'; + LocationDetails.KEY_LOCATION_NAME = 'locationName'; + LocationDetails.KEY_ADDRESS_LINES = 'addressLines'; + LocationDetails.KEY_LOCATION_DESCRIPTION = 'locationDescription'; + LocationDetails.KEY_PHONE_NUMBER = 'phoneNumber'; + LocationDetails.KEY_LOCATION_IMAGE = 'locationImage'; + LocationDetails.KEY_SEARCH_ADDRESS = 'searchAddress'; + + /* eslint-disable camelcase */ + + class GetWayPointsResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.GetWayPoints); + } + /** + * @param {LocationDetails[]} points - See LocationDetails + * @return {GetWayPointsResponse} + */ + + + setWayPoints(points) { + this.validateType(LocationDetails, points, true); + this.setParameter(GetWayPointsResponse.KEY_WAY_POINTS, points); + return this; + } + /** + * @return {LocationDetails[]} + */ + + + getWayPoints() { + return this.getObject(LocationDetails, GetWayPointsResponse.KEY_WAY_POINTS); + } + + } + + GetWayPointsResponse.KEY_WAY_POINTS = 'wayPoints'; + + /* eslint-disable camelcase */ + /** + * Request to unsubscribe from WayPoints and Destination + */ + + class UnsubscribeWayPoints extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.UnsubscribeWayPoints); + } + + } + + /* eslint-disable camelcase */ + + class UnsubscribeWayPointsResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.UnsubscribeWayPoints); + } + /** + * @param {LocationDetails[]} points - See LocationDetails + * @return {UnsubscribeWayPointsResponse} + */ + + + setWayPoints(points) { + this.validateType(LocationDetails, points, true); + this.setParameter(UnsubscribeWayPointsResponse.KEY_WAY_POINTS, points); + return this; + } + /** + * @return {LocationDetails[]} + */ + + + getWayPoints() { + return this.getObject(LocationDetails, UnsubscribeWayPointsResponse.KEY_WAY_POINTS); + } + + } + + UnsubscribeWayPointsResponse.KEY_WAY_POINTS = 'wayPoints'; + + /* eslint-disable camelcase */ + /** + * Enumerations of all available system capability types + * @typedef {Enum} SystemCapabilityType + * @property {Object} _MAP + */ + + class SystemCapabilityType extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get NAVIGATION() { + return SystemCapabilityType._MAP.NAVIGATION; + } + /** + * @return {String} + */ + + + static get PHONE_CALL() { + return SystemCapabilityType._MAP.PHONE_CALL; + } + /** + * @return {String} + */ + + + static get VIDEO_STREAMING() { + return SystemCapabilityType._MAP.VIDEO_STREAMING; + } + /** + * @return {String} + */ + + + static get REMOTE_CONTROL() { + return SystemCapabilityType._MAP.REMOTE_CONTROL; + } + /** + * @return {String} + */ + + + static get APP_SERVICES() { + return SystemCapabilityType._MAP.APP_SERVICES; + } + /** + * @return {String} + */ + + + static get SEAT_LOCATION() { + return SystemCapabilityType._MAP.SEAT_LOCATION; + } + /** + * @return {String} + */ + + + static get DISPLAYS() { + return SystemCapabilityType._MAP.DISPLAYS; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return SystemCapabilityType._valueForKey(key, SystemCapabilityType._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return SystemCapabilityType._keyForValue(value, SystemCapabilityType._MAP); + } + + } + + SystemCapabilityType._MAP = Object.freeze({ + 'NAVIGATION': 'NAVIGATION', + 'PHONE_CALL': 'PHONE_CALL', + 'VIDEO_STREAMING': 'VIDEO_STREAMING', + 'REMOTE_CONTROL': 'REMOTE_CONTROL', + 'APP_SERVICES': 'APP_SERVICES', + 'SEAT_LOCATION': 'SEAT_LOCATION', + 'DISPLAYS': 'DISPLAYS' + }); + + /* eslint-disable camelcase */ + /** + * Request for expanded information about a supported system/HMI capability + */ + + class GetSystemCapability extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.GetSystemCapability); + } + /** + * @param {SystemCapabilityType} type - The type of system capability to get more information on + * @return {GetSystemCapability} + */ + + + setSystemCapabilityType(type) { + this.validateType(SystemCapabilityType, type); + this.setParameter(GetSystemCapability.KEY_SYSTEM_CAPABILITY_TYPE, type); + return this; + } + /** + * @return {SystemCapabilityType} + */ + + + getSystemCapabilityType() { + return this.getObject(SystemCapabilityType, GetSystemCapability.KEY_SYSTEM_CAPABILITY_TYPE); + } + /** + * @param {Boolean} subscribe - Flag to subscribe to updates of the supplied service capability type. If true, the + * requester will be subscribed. If false, the requester will not be subscribed and be + * removed as a subscriber if it was previously subscribed. + * @return {GetSystemCapability} + */ + + + setSubscribe(subscribe) { + this.setParameter(GetSystemCapability.KEY_SUBSCRIBE, subscribe); + return this; + } + /** + * @return {Boolean} + */ + + + getSubscribe() { + return this.getParameter(GetSystemCapability.KEY_SUBSCRIBE); + } + + } + + GetSystemCapability.KEY_SYSTEM_CAPABILITY_TYPE = 'systemCapabilityType'; + GetSystemCapability.KEY_SUBSCRIBE = 'subscribe'; + + /* eslint-disable camelcase */ + /** + * Enum for each type of video streaming codec. + * @typedef {Enum} VideoStreamingCodec + * @property {Object} _MAP + */ + + class VideoStreamingCodec extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * A block-oriented motion-compensation-based video compression standard. As of 2014 it is one of the most + * commonly used formats for the recording, compression, and distribution of video content. + * @return {String} + */ + + + static get H264() { + return VideoStreamingCodec._MAP.H264; + } + /** + * High Efficiency Video Coding (HEVC), also known as H.265 and MPEG-H Part 2, is a video compression standard, + * one of several potential successors to the widely used AVC (H.264 or MPEG-4 Part 10). In comparison to AVC, + * HEVC offers about double the data compression ratio at the same level of video quality, or substantially + * improved video quality at the same bit rate. It supports resolutions up to 8192x4320, including 8K UHD. + * @return {String} + */ + + + static get H265() { + return VideoStreamingCodec._MAP.H265; + } + /** + * Theora is derived from the formerly proprietary VP3 codec, released into the public domain by On2 Technologies. + * It is broadly comparable in design and bitrate efficiency to MPEG-4 Part 2, early versions of Windows Media + * Video, and RealVideo while lacking some of the features present in some of these other codecs. It is comparable + * in open standards philosophy to the BBC's Dirac codec. + * @return {String} + */ + + + static get Theora() { + return VideoStreamingCodec._MAP.Theora; + } + /** + * VP8 can be multiplexed into the Matroska-based container format WebM along with Vorbis and Opus audio. The + * image format WebP is based on VP8's intra-frame coding. VP8's direct successor, VP9, and the emerging royalty- + * free internet video format AV1 from the Alliance for Open Media (AOMedia) are based on VP8. + * @return {String} + */ + + + static get VP8() { + return VideoStreamingCodec._MAP.VP8; + } + /** + * Similar to VP8, but VP9 is customized for video resolutions beyond high-definition video (UHD) and also enables + * lossless compression. + * @return {String} + */ + + + static get VP9() { + return VideoStreamingCodec._MAP.VP9; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return VideoStreamingCodec._valueForKey(key, VideoStreamingCodec._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return VideoStreamingCodec._keyForValue(value, VideoStreamingCodec._MAP); + } + + } + + VideoStreamingCodec._MAP = Object.freeze({ + 'H264': 'H264', + 'H265': 'H265', + 'Theora': 'Theora', + 'VP8': 'VP8', + 'VP9': 'VP9' + }); + + /* eslint-disable camelcase */ + /** + * Enum for each type of video streaming protocol type. + * @typedef {Enum} VideoStreamingProtocol + * @property {Object} _MAP + */ + + class VideoStreamingProtocol extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * Raw stream bytes that contains no timestamp data and is the lowest supported video streaming + * @return {String} + */ + + + static get RAW() { + return VideoStreamingProtocol._MAP.RAW; + } + /** + * RTP facilitates the transfer of real-time data. Information provided by this protocol include timestamps (for + * synchronization), sequence numbers (for packet loss and reordering detection) and the payload format which + * indicates the encoded format of the data. + * @return {String} + */ + + + static get RTP() { + return VideoStreamingProtocol._MAP.RTP; + } + /** + * The transmission of streaming data itself is not a task of RTSP. Most RTSP servers use the Real-time Transport + * Protocol (RTP) in conjunction with Real-time Control Protocol (RTCP) for media stream delivery. However, some + * vendors implement proprietary transport protocols. + * @return {String} + */ + + + static get RTSP() { + return VideoStreamingProtocol._MAP.RTSP; + } + /** + * Real-Time Messaging Protocol (RTMP) was initially a proprietary protocol developed by Macromedia for streaming + * audio, video and data over the Internet, between a Flash player and a server. Macromedia is now owned by Adobe, + * which has released an incomplete version of the specification of the protocol for public use. + * @return {String} + */ + + + static get RTMP() { + return VideoStreamingProtocol._MAP.RTMP; + } + /** + * The WebM container is based on a profile of Matroska. WebM initially supported VP8 video and Vorbis audio + * streams. In 2013 it was updated to accommodate VP9 video and Opus audio. + * @return {String} + */ + + + static get WEBM() { + return VideoStreamingProtocol._MAP.WEBM; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return VideoStreamingProtocol._valueForKey(key, VideoStreamingProtocol._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return VideoStreamingProtocol._keyForValue(value, VideoStreamingProtocol._MAP); + } + + } + + VideoStreamingProtocol._MAP = Object.freeze({ + 'RAW': 'RAW', + 'RTP': 'RTP', + 'RTSP': 'RTSP', + 'RTMP': 'RTMP', + 'WEBM': 'WEBM' + }); + + /* eslint-disable camelcase */ + /** + * Video streaming formats and their specifications. + */ + + class VideoStreamingFormat extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {VideoStreamingProtocol} protocol - Protocol type, see VideoStreamingProtocol + * @return {VideoStreamingFormat} + */ + + + setProtocol(protocol) { + this.validateType(VideoStreamingProtocol, protocol); + this.setParameter(VideoStreamingFormat.KEY_PROTOCOL, protocol); + return this; + } + /** + * @return {VideoStreamingProtocol} + */ + + + getProtocol() { + return this.getObject(VideoStreamingProtocol, VideoStreamingFormat.KEY_PROTOCOL); + } + /** + * @param {VideoStreamingCodec} codec - Codec type, see VideoStreamingCodec + * @return {VideoStreamingFormat} + */ + + + setCodec(codec) { + this.validateType(VideoStreamingCodec, codec); + this.setParameter(VideoStreamingFormat.KEY_CODEC, codec); + return this; + } + /** + * @return {VideoStreamingCodec} + */ + + + getCodec() { + return this.getObject(VideoStreamingCodec, VideoStreamingFormat.KEY_CODEC); } } @@ -25209,6 +42126,9841 @@ VideoStreamingFormat.KEY_PROTOCOL = 'protocol'; VideoStreamingFormat.KEY_CODEC = 'codec'; + /* eslint-disable camelcase */ + /** + * Contains information about this system's video streaming capabilities. + */ + + class VideoStreamingCapability extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {ImageResolution} resolution - The preferred resolution of a video stream for decoding and rendering on + * HMI. + * @return {VideoStreamingCapability} + */ + + + setPreferredResolution(resolution) { + this.validateType(ImageResolution, resolution); + this.setParameter(VideoStreamingCapability.KEY_PREFERRED_RESOLUTION, resolution); + return this; + } + /** + * @return {ImageResolution} + */ + + + getPreferredResolution() { + return this.getObject(ImageResolution, VideoStreamingCapability.KEY_PREFERRED_RESOLUTION); + } + /** + * @param {Number} bitrate - The maximum bitrate of video stream that is supported, in kbps. + * @return {VideoStreamingCapability} + */ + + + setMaxBitrate(bitrate) { + this.setParameter(VideoStreamingCapability.KEY_MAX_BITRATE, bitrate); + return this; + } + /** + * @return {Number} + */ + + + getMaxBitrate() { + return this.getParameter(VideoStreamingCapability.KEY_MAX_BITRATE); + } + /** + * @param {VideoStreamingFormat[]} formats - Detailed information on each format supported by this system, in its + * preferred order (i.e. the first element in the array is most preferable + * to the system). Each object will contain a VideoStreamingFormat that + * describes what can be expected. + * @return {VideoStreamingCapability} + */ + + + setSupportedFormats(formats) { + this.validateType(VideoStreamingFormat, formats, true); + this.setParameter(VideoStreamingCapability.KEY_SUPPORTED_FORMATS, formats); + return this; + } + /** + * @return {VideoStreamingFormat[]} + */ + + + getSupportedFormats() { + return this.getObject(VideoStreamingFormat, VideoStreamingCapability.KEY_SUPPORTED_FORMATS); + } + /** + * @param {Boolean} supported - True if the system can utilize the haptic spatial data from the source being + * streamed. If not included, it can be assumed the module doesn't support haptic + * spatial data'. + * @return {VideoStreamingCapability} + */ + + + setHapticSpatialDataSupported(supported) { + this.setParameter(VideoStreamingCapability.KEY_HAPTIC_SPATIAL_DATA_SUPPORTED, supported); + return this; + } + /** + * @return {Boolean} + */ + + + getHapticSpatialDataSupported() { + return this.getParameter(VideoStreamingCapability.KEY_HAPTIC_SPATIAL_DATA_SUPPORTED); + } + /** + * @param {Number} size - The diagonal screen size in inches. + * @return {VideoStreamingCapability} + */ + + + setDiagonalScreenSize(size) { + this.setParameter(VideoStreamingCapability.KEY_DIAGONAL_SCREEN_SIZE, size); + return this; + } + /** + * @return {Number} + */ + + + getDiagonalScreenSize() { + return this.getParameter(VideoStreamingCapability.KEY_DIAGONAL_SCREEN_SIZE); + } + /** + * @param {Number} inch - PPI is the diagonal resolution in pixels divided by the diagonal screen size in inches. + * @return {VideoStreamingCapability} + */ + + + setPixelPerInch(inch) { + this.setParameter(VideoStreamingCapability.KEY_PIXEL_PER_INCH, inch); + return this; + } + /** + * @return {Number} + */ + + + getPixelPerInch() { + return this.getParameter(VideoStreamingCapability.KEY_PIXEL_PER_INCH); + } + /** + * @param {Number} scale - The scaling factor the app should use to change the size of the projecting view. + * @return {VideoStreamingCapability} + */ + + + setScale(scale) { + this.setParameter(VideoStreamingCapability.KEY_SCALE, scale); + return this; + } + /** + * @return {Number} + */ + + + getScale() { + return this.getParameter(VideoStreamingCapability.KEY_SCALE); + } + + } + + VideoStreamingCapability.KEY_PREFERRED_RESOLUTION = 'preferredResolution'; + VideoStreamingCapability.KEY_MAX_BITRATE = 'maxBitrate'; + VideoStreamingCapability.KEY_SUPPORTED_FORMATS = 'supportedFormats'; + VideoStreamingCapability.KEY_HAPTIC_SPATIAL_DATA_SUPPORTED = 'hapticSpatialDataSupported'; + VideoStreamingCapability.KEY_DIAGONAL_SCREEN_SIZE = 'diagonalScreenSize'; + VideoStreamingCapability.KEY_PIXEL_PER_INCH = 'pixelPerInch'; + VideoStreamingCapability.KEY_SCALE = 'scale'; + + /* eslint-disable camelcase */ + /** + * Extended capabilities of the module's phone feature + */ + + class PhoneCapability extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Boolean} enabled - If the module has the ability to perform dial number + * @return {PhoneCapability} + */ + + + setDialNumberEnabled(enabled) { + this.setParameter(PhoneCapability.KEY_DIAL_NUMBER_ENABLED, enabled); + return this; + } + /** + * @return {Boolean} + */ + + + getDialNumberEnabled() { + return this.getParameter(PhoneCapability.KEY_DIAL_NUMBER_ENABLED); + } + + } + + PhoneCapability.KEY_DIAL_NUMBER_ENABLED = 'dialNumberEnabled'; + + /* eslint-disable camelcase */ + + class WindowTypeCapabilities extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {WindowType} type + * @return {WindowTypeCapabilities} + */ + + + setType(type) { + this.validateType(WindowType, type); + this.setParameter(WindowTypeCapabilities.KEY_TYPE, type); + return this; + } + /** + * @return {WindowType} + */ + + + getType() { + return this.getObject(WindowType, WindowTypeCapabilities.KEY_TYPE); + } + /** + * @param {Number} windows + * @return {WindowTypeCapabilities} + */ + + + setMaximumNumberOfWindows(windows) { + this.setParameter(WindowTypeCapabilities.KEY_MAXIMUM_NUMBER_OF_WINDOWS, windows); + return this; + } + /** + * @return {Number} + */ + + + getMaximumNumberOfWindows() { + return this.getParameter(WindowTypeCapabilities.KEY_MAXIMUM_NUMBER_OF_WINDOWS); + } + + } + + WindowTypeCapabilities.KEY_TYPE = 'type'; + WindowTypeCapabilities.KEY_MAXIMUM_NUMBER_OF_WINDOWS = 'maximumNumberOfWindows'; + + /* eslint-disable camelcase */ + + class WindowCapability extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Number} id - The specified ID of the window. This ID is either one used when sending the CreateWindow + * request, or one of the predefined window ID values from the enum PredefinedWindows. If + * ommited, value is assumed to be the main window on the main display. + * @return {WindowCapability} + */ + + + setWindowID(id) { + this.setParameter(WindowCapability.KEY_WINDOW_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getWindowID() { + return this.getParameter(WindowCapability.KEY_WINDOW_ID); + } + /** + * @param {TextField[]} fields - A set of all fields that support text data. See TextField + * @return {WindowCapability} + */ + + + setTextFields(fields) { + this.validateType(TextField, fields, true); + this.setParameter(WindowCapability.KEY_TEXT_FIELDS, fields); + return this; + } + /** + * @return {TextField[]} + */ + + + getTextFields() { + return this.getObject(TextField, WindowCapability.KEY_TEXT_FIELDS); + } + /** + * @param {ImageField[]} fields - A set of all fields that support images. See ImageField + * @return {WindowCapability} + */ + + + setImageFields(fields) { + this.validateType(ImageField, fields, true); + this.setParameter(WindowCapability.KEY_IMAGE_FIELDS, fields); + return this; + } + /** + * @return {ImageField[]} + */ + + + getImageFields() { + return this.getObject(ImageField, WindowCapability.KEY_IMAGE_FIELDS); + } + /** + * @param {ImageType[]} supported - Provides information about image types supported by the system. + * @return {WindowCapability} + */ + + + setImageTypeSupported(supported) { + this.validateType(ImageType, supported, true); + this.setParameter(WindowCapability.KEY_IMAGE_TYPE_SUPPORTED, supported); + return this; + } + /** + * @return {ImageType[]} + */ + + + getImageTypeSupported() { + return this.getObject(ImageType, WindowCapability.KEY_IMAGE_TYPE_SUPPORTED); + } + /** + * @param {String[]} available - A set of all window templates available on the head unit. + * @return {WindowCapability} + */ + + + setTemplatesAvailable(available) { + this.setParameter(WindowCapability.KEY_TEMPLATES_AVAILABLE, available); + return this; + } + /** + * @return {String[]} + */ + + + getTemplatesAvailable() { + return this.getParameter(WindowCapability.KEY_TEMPLATES_AVAILABLE); + } + /** + * @param {Number} available - The number of on-window custom presets available (if any); otherwise omitted. + * @return {WindowCapability} + */ + + + setNumCustomPresetsAvailable(available) { + this.setParameter(WindowCapability.KEY_NUM_CUSTOM_PRESETS_AVAILABLE, available); + return this; + } + /** + * @return {Number} + */ + + + getNumCustomPresetsAvailable() { + return this.getParameter(WindowCapability.KEY_NUM_CUSTOM_PRESETS_AVAILABLE); + } + /** + * @param {ButtonCapabilities[]} capabilities - The number of buttons and the capabilities of each on-window button. + * @return {WindowCapability} + */ + + + setButtonCapabilities(capabilities) { + this.validateType(ButtonCapabilities, capabilities, true); + this.setParameter(WindowCapability.KEY_BUTTON_CAPABILITIES, capabilities); + return this; + } + /** + * @return {ButtonCapabilities[]} + */ + + + getButtonCapabilities() { + return this.getObject(ButtonCapabilities, WindowCapability.KEY_BUTTON_CAPABILITIES); + } + /** + * @param {SoftButtonCapabilities[]} capabilities - The number of soft buttons available on-window and the + * capabilities for each button. + * @return {WindowCapability} + */ + + + setSoftButtonCapabilities(capabilities) { + this.validateType(SoftButtonCapabilities, capabilities, true); + this.setParameter(WindowCapability.KEY_SOFT_BUTTON_CAPABILITIES, capabilities); + return this; + } + /** + * @return {SoftButtonCapabilities[]} + */ + + + getSoftButtonCapabilities() { + return this.getObject(SoftButtonCapabilities, WindowCapability.KEY_SOFT_BUTTON_CAPABILITIES); + } + /** + * @param {MenuLayout[]} available - An array of available menu layouts. If this parameter is not provided, only the + * `LIST` layout is assumed to be available + * @return {WindowCapability} + */ + + + setMenuLayoutsAvailable(available) { + this.validateType(MenuLayout, available, true); + this.setParameter(WindowCapability.KEY_MENU_LAYOUTS_AVAILABLE, available); + return this; + } + /** + * @return {MenuLayout[]} + */ + + + getMenuLayoutsAvailable() { + return this.getObject(MenuLayout, WindowCapability.KEY_MENU_LAYOUTS_AVAILABLE); + } + + } + + WindowCapability.KEY_WINDOW_ID = 'windowID'; + WindowCapability.KEY_TEXT_FIELDS = 'textFields'; + WindowCapability.KEY_IMAGE_FIELDS = 'imageFields'; + WindowCapability.KEY_IMAGE_TYPE_SUPPORTED = 'imageTypeSupported'; + WindowCapability.KEY_TEMPLATES_AVAILABLE = 'templatesAvailable'; + WindowCapability.KEY_NUM_CUSTOM_PRESETS_AVAILABLE = 'numCustomPresetsAvailable'; + WindowCapability.KEY_BUTTON_CAPABILITIES = 'buttonCapabilities'; + WindowCapability.KEY_SOFT_BUTTON_CAPABILITIES = 'softButtonCapabilities'; + WindowCapability.KEY_MENU_LAYOUTS_AVAILABLE = 'menuLayoutsAvailable'; + + /* eslint-disable camelcase */ + + class DisplayCapability extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {String} name + * @return {DisplayCapability} + */ + + + setDisplayName(name) { + this.setParameter(DisplayCapability.KEY_DISPLAY_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getDisplayName() { + return this.getParameter(DisplayCapability.KEY_DISPLAY_NAME); + } + /** + * @param {WindowTypeCapabilities[]} supported - Informs the application how many windows the app is allowed to + * create per type. + * @return {DisplayCapability} + */ + + + setWindowTypeSupported(supported) { + this.validateType(WindowTypeCapabilities, supported, true); + this.setParameter(DisplayCapability.KEY_WINDOW_TYPE_SUPPORTED, supported); + return this; + } + /** + * @return {WindowTypeCapabilities[]} + */ + + + getWindowTypeSupported() { + return this.getObject(WindowTypeCapabilities, DisplayCapability.KEY_WINDOW_TYPE_SUPPORTED); + } + /** + * @param {WindowCapability[]} capabilities - Contains a list of capabilities of all windows related to the app. + * Once the app has registered the capabilities of all windows are + * provided. GetSystemCapability still allows requesting window + * capabilities of all windows. After registration, only windows with + * capabilities changed will be included. Following cases will cause only + * affected windows to be included: 1. App creates a new window. After + * the window is created, a system capability notification will be sent + * related only to the created window. 2. App sets a new layout to the + * window. The new layout changes window capabilties. The notification + * will reflect those changes to the single window. + * @return {DisplayCapability} + */ + + + setWindowCapabilities(capabilities) { + this.validateType(WindowCapability, capabilities, true); + this.setParameter(DisplayCapability.KEY_WINDOW_CAPABILITIES, capabilities); + return this; + } + /** + * @return {WindowCapability[]} + */ + + + getWindowCapabilities() { + return this.getObject(WindowCapability, DisplayCapability.KEY_WINDOW_CAPABILITIES); + } + + } + + DisplayCapability.KEY_DISPLAY_NAME = 'displayName'; + DisplayCapability.KEY_WINDOW_TYPE_SUPPORTED = 'windowTypeSupported'; + DisplayCapability.KEY_WINDOW_CAPABILITIES = 'windowCapabilities'; + + /* eslint-disable camelcase */ + + class AudioControlCapabilities extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {String} name - The short friendly name of the light control module. It should not be used to identify a + * module by mobile application. + * @return {AudioControlCapabilities} + */ + + + setModuleName(name) { + this.setParameter(AudioControlCapabilities.KEY_MODULE_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getModuleName() { + return this.getParameter(AudioControlCapabilities.KEY_MODULE_NAME); + } + /** + * @param {ModuleInfo} info - Information about a RC module, including its id. + * @return {AudioControlCapabilities} + */ + + + setModuleInfo(info) { + this.validateType(ModuleInfo, info); + this.setParameter(AudioControlCapabilities.KEY_MODULE_INFO, info); + return this; + } + /** + * @return {ModuleInfo} + */ + + + getModuleInfo() { + return this.getObject(ModuleInfo, AudioControlCapabilities.KEY_MODULE_INFO); + } + /** + * @param {Boolean} available - Availability of the control of audio source. + * @return {AudioControlCapabilities} + */ + + + setSourceAvailable(available) { + this.setParameter(AudioControlCapabilities.KEY_SOURCE_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getSourceAvailable() { + return this.getParameter(AudioControlCapabilities.KEY_SOURCE_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the keepContext parameter. + * @return {AudioControlCapabilities} + */ + + + setKeepContextAvailable(available) { + this.setParameter(AudioControlCapabilities.KEY_KEEP_CONTEXT_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getKeepContextAvailable() { + return this.getParameter(AudioControlCapabilities.KEY_KEEP_CONTEXT_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the control of audio volume. + * @return {AudioControlCapabilities} + */ + + + setVolumeAvailable(available) { + this.setParameter(AudioControlCapabilities.KEY_VOLUME_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getVolumeAvailable() { + return this.getParameter(AudioControlCapabilities.KEY_VOLUME_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the control of Equalizer Settings. + * @return {AudioControlCapabilities} + */ + + + setEqualizerAvailable(available) { + this.setParameter(AudioControlCapabilities.KEY_EQUALIZER_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getEqualizerAvailable() { + return this.getParameter(AudioControlCapabilities.KEY_EQUALIZER_AVAILABLE); + } + /** + * @param {Number} id - Must be included if equalizerAvailable=true, and assume all IDs starting from 1 to this + * value are valid + * @return {AudioControlCapabilities} + */ + + + setEqualizerMaxChannelId(id) { + this.setParameter(AudioControlCapabilities.KEY_EQUALIZER_MAX_CHANNEL_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getEqualizerMaxChannelId() { + return this.getParameter(AudioControlCapabilities.KEY_EQUALIZER_MAX_CHANNEL_ID); + } + + } + + AudioControlCapabilities.KEY_MODULE_NAME = 'moduleName'; + AudioControlCapabilities.KEY_MODULE_INFO = 'moduleInfo'; + AudioControlCapabilities.KEY_SOURCE_AVAILABLE = 'sourceAvailable'; + AudioControlCapabilities.KEY_KEEP_CONTEXT_AVAILABLE = 'keepContextAvailable'; + AudioControlCapabilities.KEY_VOLUME_AVAILABLE = 'volumeAvailable'; + AudioControlCapabilities.KEY_EQUALIZER_AVAILABLE = 'equalizerAvailable'; + AudioControlCapabilities.KEY_EQUALIZER_MAX_CHANNEL_ID = 'equalizerMaxChannelId'; + + /* eslint-disable camelcase */ + + class LightCapabilities extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {LightName} name + * @return {LightCapabilities} + */ + + + setName(name) { + this.validateType(LightName, name); + this.setParameter(LightCapabilities.KEY_NAME, name); + return this; + } + /** + * @return {LightName} + */ + + + getName() { + return this.getObject(LightName, LightCapabilities.KEY_NAME); + } + /** + * @param {Boolean} available - Indicates if the status (ON/OFF) can be set remotely. App shall not use read-only + * values (RAMP_UP/RAMP_DOWN/UNKNOWN/INVALID) in a setInteriorVehicleData request. + * @return {LightCapabilities} + */ + + + setStatusAvailable(available) { + this.setParameter(LightCapabilities.KEY_STATUS_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getStatusAvailable() { + return this.getParameter(LightCapabilities.KEY_STATUS_AVAILABLE); + } + /** + * @param {Boolean} available - Indicates if the light's density can be set remotely (similar to a dimmer). + * @return {LightCapabilities} + */ + + + setDensityAvailable(available) { + this.setParameter(LightCapabilities.KEY_DENSITY_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getDensityAvailable() { + return this.getParameter(LightCapabilities.KEY_DENSITY_AVAILABLE); + } + /** + * @param {Boolean} available - Indicates if the light's color can be set remotely by using the sRGB color space. + * @return {LightCapabilities} + */ + + + setRgbColorSpaceAvailable(available) { + this.setParameter(LightCapabilities.KEY_RGB_COLOR_SPACE_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getRgbColorSpaceAvailable() { + return this.getParameter(LightCapabilities.KEY_RGB_COLOR_SPACE_AVAILABLE); + } + + } + + LightCapabilities.KEY_NAME = 'name'; + LightCapabilities.KEY_STATUS_AVAILABLE = 'statusAvailable'; + LightCapabilities.KEY_DENSITY_AVAILABLE = 'densityAvailable'; + LightCapabilities.KEY_RGB_COLOR_SPACE_AVAILABLE = 'rgbColorSpaceAvailable'; + + /* eslint-disable camelcase */ + + class LightControlCapabilities extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {String} name - The short friendly name of the light control module. It should not be used to identify a + * module by mobile application. + * @return {LightControlCapabilities} + */ + + + setModuleName(name) { + this.setParameter(LightControlCapabilities.KEY_MODULE_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getModuleName() { + return this.getParameter(LightControlCapabilities.KEY_MODULE_NAME); + } + /** + * @param {ModuleInfo} info - Information about a RC module, including its id. + * @return {LightControlCapabilities} + */ + + + setModuleInfo(info) { + this.validateType(ModuleInfo, info); + this.setParameter(LightControlCapabilities.KEY_MODULE_INFO, info); + return this; + } + /** + * @return {ModuleInfo} + */ + + + getModuleInfo() { + return this.getObject(ModuleInfo, LightControlCapabilities.KEY_MODULE_INFO); + } + /** + * @param {LightCapabilities[]} lights - An array of available LightCapabilities that are controllable. + * @return {LightControlCapabilities} + */ + + + setSupportedLights(lights) { + this.validateType(LightCapabilities, lights, true); + this.setParameter(LightControlCapabilities.KEY_SUPPORTED_LIGHTS, lights); + return this; + } + /** + * @return {LightCapabilities[]} + */ + + + getSupportedLights() { + return this.getObject(LightCapabilities, LightControlCapabilities.KEY_SUPPORTED_LIGHTS); + } + + } + + LightControlCapabilities.KEY_MODULE_NAME = 'moduleName'; + LightControlCapabilities.KEY_MODULE_INFO = 'moduleInfo'; + LightControlCapabilities.KEY_SUPPORTED_LIGHTS = 'supportedLights'; + + /* eslint-disable camelcase */ + /** + * Contains information about a climate control module's capabilities. + */ + + class ClimateControlCapabilities extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {String} name - The short friendly name of the climate control module. It should not be used to identify a + * module by mobile application. + * @return {ClimateControlCapabilities} + */ + + + setModuleName(name) { + this.setParameter(ClimateControlCapabilities.KEY_MODULE_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getModuleName() { + return this.getParameter(ClimateControlCapabilities.KEY_MODULE_NAME); + } + /** + * @param {ModuleInfo} info - Information about a RC module, including its id. + * @return {ClimateControlCapabilities} + */ + + + setModuleInfo(info) { + this.validateType(ModuleInfo, info); + this.setParameter(ClimateControlCapabilities.KEY_MODULE_INFO, info); + return this; + } + /** + * @return {ModuleInfo} + */ + + + getModuleInfo() { + return this.getObject(ModuleInfo, ClimateControlCapabilities.KEY_MODULE_INFO); + } + /** + * @param {Boolean} available - Availability of the reading of current temperature. True: Available, False: Not + * Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + + + setCurrentTemperatureAvailable(available) { + this.setParameter(ClimateControlCapabilities.KEY_CURRENT_TEMPERATURE_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getCurrentTemperatureAvailable() { + return this.getParameter(ClimateControlCapabilities.KEY_CURRENT_TEMPERATURE_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the control of fan speed. True: Available, False: Not Available, Not + * present: Not Available. + * @return {ClimateControlCapabilities} + */ + + + setFanSpeedAvailable(available) { + this.setParameter(ClimateControlCapabilities.KEY_FAN_SPEED_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getFanSpeedAvailable() { + return this.getParameter(ClimateControlCapabilities.KEY_FAN_SPEED_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the control of desired temperature. True: Available, False: Not + * Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + + + setDesiredTemperatureAvailable(available) { + this.setParameter(ClimateControlCapabilities.KEY_DESIRED_TEMPERATURE_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getDesiredTemperatureAvailable() { + return this.getParameter(ClimateControlCapabilities.KEY_DESIRED_TEMPERATURE_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the control of turn on/off AC. True: Available, False: Not + * Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + + + setAcEnableAvailable(available) { + this.setParameter(ClimateControlCapabilities.KEY_AC_ENABLE_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getAcEnableAvailable() { + return this.getParameter(ClimateControlCapabilities.KEY_AC_ENABLE_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the control of enable/disable air conditioning is ON on the maximum + * level. True: Available, False: Not Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + + + setAcMaxEnableAvailable(available) { + this.setParameter(ClimateControlCapabilities.KEY_AC_MAX_ENABLE_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getAcMaxEnableAvailable() { + return this.getParameter(ClimateControlCapabilities.KEY_AC_MAX_ENABLE_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the control of enable/disable circulate Air mode. True: Available, + * False: Not Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + + + setCirculateAirEnableAvailable(available) { + this.setParameter(ClimateControlCapabilities.KEY_CIRCULATE_AIR_ENABLE_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getCirculateAirEnableAvailable() { + return this.getParameter(ClimateControlCapabilities.KEY_CIRCULATE_AIR_ENABLE_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the control of enable/disable auto mode. True: Available, False: Not + * Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + + + setAutoModeEnableAvailable(available) { + this.setParameter(ClimateControlCapabilities.KEY_AUTO_MODE_ENABLE_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getAutoModeEnableAvailable() { + return this.getParameter(ClimateControlCapabilities.KEY_AUTO_MODE_ENABLE_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the control of enable/disable dual mode. True: Available, False: Not + * Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + + + setDualModeEnableAvailable(available) { + this.setParameter(ClimateControlCapabilities.KEY_DUAL_MODE_ENABLE_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getDualModeEnableAvailable() { + return this.getParameter(ClimateControlCapabilities.KEY_DUAL_MODE_ENABLE_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the control of defrost zones. True: Available, False: Not Available, + * Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + + + setDefrostZoneAvailable(available) { + this.setParameter(ClimateControlCapabilities.KEY_DEFROST_ZONE_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getDefrostZoneAvailable() { + return this.getParameter(ClimateControlCapabilities.KEY_DEFROST_ZONE_AVAILABLE); + } + /** + * @param {DefrostZone[]} zone - A set of all defrost zones that are controllable. + * @return {ClimateControlCapabilities} + */ + + + setDefrostZone(zone) { + this.validateType(DefrostZone, zone, true); + this.setParameter(ClimateControlCapabilities.KEY_DEFROST_ZONE, zone); + return this; + } + /** + * @return {DefrostZone[]} + */ + + + getDefrostZone() { + return this.getObject(DefrostZone, ClimateControlCapabilities.KEY_DEFROST_ZONE); + } + /** + * @param {Boolean} available - Availability of the control of air ventilation mode. True: Available, False: Not + * Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + + + setVentilationModeAvailable(available) { + this.setParameter(ClimateControlCapabilities.KEY_VENTILATION_MODE_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getVentilationModeAvailable() { + return this.getParameter(ClimateControlCapabilities.KEY_VENTILATION_MODE_AVAILABLE); + } + /** + * @param {VentilationMode[]} mode - A set of all ventilation modes that are controllable. + * @return {ClimateControlCapabilities} + */ + + + setVentilationMode(mode) { + this.validateType(VentilationMode, mode, true); + this.setParameter(ClimateControlCapabilities.KEY_VENTILATION_MODE, mode); + return this; + } + /** + * @return {VentilationMode[]} + */ + + + getVentilationMode() { + return this.getObject(VentilationMode, ClimateControlCapabilities.KEY_VENTILATION_MODE); + } + /** + * @param {Boolean} available - Availability of the control (enable/disable) of heated Steering Wheel. True: + * Available, False: Not Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + + + setHeatedSteeringWheelAvailable(available) { + this.setParameter(ClimateControlCapabilities.KEY_HEATED_STEERING_WHEEL_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getHeatedSteeringWheelAvailable() { + return this.getParameter(ClimateControlCapabilities.KEY_HEATED_STEERING_WHEEL_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the control (enable/disable) of heated Windshield. True: Available, + * False: Not Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + + + setHeatedWindshieldAvailable(available) { + this.setParameter(ClimateControlCapabilities.KEY_HEATED_WINDSHIELD_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getHeatedWindshieldAvailable() { + return this.getParameter(ClimateControlCapabilities.KEY_HEATED_WINDSHIELD_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the control (enable/disable) of heated Rear Window. True: Available, + * False: Not Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + + + setHeatedRearWindowAvailable(available) { + this.setParameter(ClimateControlCapabilities.KEY_HEATED_REAR_WINDOW_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getHeatedRearWindowAvailable() { + return this.getParameter(ClimateControlCapabilities.KEY_HEATED_REAR_WINDOW_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the control (enable/disable) of heated Mirrors. True: Available, + * False: Not Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + + + setHeatedMirrorsAvailable(available) { + this.setParameter(ClimateControlCapabilities.KEY_HEATED_MIRRORS_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getHeatedMirrorsAvailable() { + return this.getParameter(ClimateControlCapabilities.KEY_HEATED_MIRRORS_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the control of enable/disable climate control. True: Available, + * False: Not Available, Not present: Not Available. + * @return {ClimateControlCapabilities} + */ + + + setClimateEnableAvailable(available) { + this.setParameter(ClimateControlCapabilities.KEY_CLIMATE_ENABLE_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getClimateEnableAvailable() { + return this.getParameter(ClimateControlCapabilities.KEY_CLIMATE_ENABLE_AVAILABLE); + } + + } + + ClimateControlCapabilities.KEY_MODULE_NAME = 'moduleName'; + ClimateControlCapabilities.KEY_MODULE_INFO = 'moduleInfo'; + ClimateControlCapabilities.KEY_CURRENT_TEMPERATURE_AVAILABLE = 'currentTemperatureAvailable'; + ClimateControlCapabilities.KEY_FAN_SPEED_AVAILABLE = 'fanSpeedAvailable'; + ClimateControlCapabilities.KEY_DESIRED_TEMPERATURE_AVAILABLE = 'desiredTemperatureAvailable'; + ClimateControlCapabilities.KEY_AC_ENABLE_AVAILABLE = 'acEnableAvailable'; + ClimateControlCapabilities.KEY_AC_MAX_ENABLE_AVAILABLE = 'acMaxEnableAvailable'; + ClimateControlCapabilities.KEY_CIRCULATE_AIR_ENABLE_AVAILABLE = 'circulateAirEnableAvailable'; + ClimateControlCapabilities.KEY_AUTO_MODE_ENABLE_AVAILABLE = 'autoModeEnableAvailable'; + ClimateControlCapabilities.KEY_DUAL_MODE_ENABLE_AVAILABLE = 'dualModeEnableAvailable'; + ClimateControlCapabilities.KEY_DEFROST_ZONE_AVAILABLE = 'defrostZoneAvailable'; + ClimateControlCapabilities.KEY_DEFROST_ZONE = 'defrostZone'; + ClimateControlCapabilities.KEY_VENTILATION_MODE_AVAILABLE = 'ventilationModeAvailable'; + ClimateControlCapabilities.KEY_VENTILATION_MODE = 'ventilationMode'; + ClimateControlCapabilities.KEY_HEATED_STEERING_WHEEL_AVAILABLE = 'heatedSteeringWheelAvailable'; + ClimateControlCapabilities.KEY_HEATED_WINDSHIELD_AVAILABLE = 'heatedWindshieldAvailable'; + ClimateControlCapabilities.KEY_HEATED_REAR_WINDOW_AVAILABLE = 'heatedRearWindowAvailable'; + ClimateControlCapabilities.KEY_HEATED_MIRRORS_AVAILABLE = 'heatedMirrorsAvailable'; + ClimateControlCapabilities.KEY_CLIMATE_ENABLE_AVAILABLE = 'climateEnableAvailable'; + + /* eslint-disable camelcase */ + + class SeatControlCapabilities extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {String} name - The short friendly name of the light control module. It should not be used to identify a + * module by mobile application. + * @return {SeatControlCapabilities} + */ + + + setModuleName(name) { + this.setParameter(SeatControlCapabilities.KEY_MODULE_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getModuleName() { + return this.getParameter(SeatControlCapabilities.KEY_MODULE_NAME); + } + /** + * @param {ModuleInfo} info - Information about a RC module, including its id. + * @return {SeatControlCapabilities} + */ + + + setModuleInfo(info) { + this.validateType(ModuleInfo, info); + this.setParameter(SeatControlCapabilities.KEY_MODULE_INFO, info); + return this; + } + /** + * @return {ModuleInfo} + */ + + + getModuleInfo() { + return this.getObject(ModuleInfo, SeatControlCapabilities.KEY_MODULE_INFO); + } + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + + + setHeatingEnabledAvailable(available) { + this.setParameter(SeatControlCapabilities.KEY_HEATING_ENABLED_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getHeatingEnabledAvailable() { + return this.getParameter(SeatControlCapabilities.KEY_HEATING_ENABLED_AVAILABLE); + } + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + + + setCoolingEnabledAvailable(available) { + this.setParameter(SeatControlCapabilities.KEY_COOLING_ENABLED_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getCoolingEnabledAvailable() { + return this.getParameter(SeatControlCapabilities.KEY_COOLING_ENABLED_AVAILABLE); + } + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + + + setHeatingLevelAvailable(available) { + this.setParameter(SeatControlCapabilities.KEY_HEATING_LEVEL_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getHeatingLevelAvailable() { + return this.getParameter(SeatControlCapabilities.KEY_HEATING_LEVEL_AVAILABLE); + } + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + + + setCoolingLevelAvailable(available) { + this.setParameter(SeatControlCapabilities.KEY_COOLING_LEVEL_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getCoolingLevelAvailable() { + return this.getParameter(SeatControlCapabilities.KEY_COOLING_LEVEL_AVAILABLE); + } + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + + + setHorizontalPositionAvailable(available) { + this.setParameter(SeatControlCapabilities.KEY_HORIZONTAL_POSITION_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getHorizontalPositionAvailable() { + return this.getParameter(SeatControlCapabilities.KEY_HORIZONTAL_POSITION_AVAILABLE); + } + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + + + setVerticalPositionAvailable(available) { + this.setParameter(SeatControlCapabilities.KEY_VERTICAL_POSITION_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getVerticalPositionAvailable() { + return this.getParameter(SeatControlCapabilities.KEY_VERTICAL_POSITION_AVAILABLE); + } + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + + + setFrontVerticalPositionAvailable(available) { + this.setParameter(SeatControlCapabilities.KEY_FRONT_VERTICAL_POSITION_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getFrontVerticalPositionAvailable() { + return this.getParameter(SeatControlCapabilities.KEY_FRONT_VERTICAL_POSITION_AVAILABLE); + } + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + + + setBackVerticalPositionAvailable(available) { + this.setParameter(SeatControlCapabilities.KEY_BACK_VERTICAL_POSITION_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getBackVerticalPositionAvailable() { + return this.getParameter(SeatControlCapabilities.KEY_BACK_VERTICAL_POSITION_AVAILABLE); + } + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + + + setBackTiltAngleAvailable(available) { + this.setParameter(SeatControlCapabilities.KEY_BACK_TILT_ANGLE_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getBackTiltAngleAvailable() { + return this.getParameter(SeatControlCapabilities.KEY_BACK_TILT_ANGLE_AVAILABLE); + } + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + + + setHeadSupportHorizontalPositionAvailable(available) { + this.setParameter(SeatControlCapabilities.KEY_HEAD_SUPPORT_HORIZONTAL_POSITION_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getHeadSupportHorizontalPositionAvailable() { + return this.getParameter(SeatControlCapabilities.KEY_HEAD_SUPPORT_HORIZONTAL_POSITION_AVAILABLE); + } + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + + + setHeadSupportVerticalPositionAvailable(available) { + this.setParameter(SeatControlCapabilities.KEY_HEAD_SUPPORT_VERTICAL_POSITION_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getHeadSupportVerticalPositionAvailable() { + return this.getParameter(SeatControlCapabilities.KEY_HEAD_SUPPORT_VERTICAL_POSITION_AVAILABLE); + } + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + + + setMassageEnabledAvailable(available) { + this.setParameter(SeatControlCapabilities.KEY_MASSAGE_ENABLED_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getMassageEnabledAvailable() { + return this.getParameter(SeatControlCapabilities.KEY_MASSAGE_ENABLED_AVAILABLE); + } + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + + + setMassageModeAvailable(available) { + this.setParameter(SeatControlCapabilities.KEY_MASSAGE_MODE_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getMassageModeAvailable() { + return this.getParameter(SeatControlCapabilities.KEY_MASSAGE_MODE_AVAILABLE); + } + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + + + setMassageCushionFirmnessAvailable(available) { + this.setParameter(SeatControlCapabilities.KEY_MASSAGE_CUSHION_FIRMNESS_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getMassageCushionFirmnessAvailable() { + return this.getParameter(SeatControlCapabilities.KEY_MASSAGE_CUSHION_FIRMNESS_AVAILABLE); + } + /** + * @param {Boolean} available + * @return {SeatControlCapabilities} + */ + + + setMemoryAvailable(available) { + this.setParameter(SeatControlCapabilities.KEY_MEMORY_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getMemoryAvailable() { + return this.getParameter(SeatControlCapabilities.KEY_MEMORY_AVAILABLE); + } + + } + + SeatControlCapabilities.KEY_MODULE_NAME = 'moduleName'; + SeatControlCapabilities.KEY_MODULE_INFO = 'moduleInfo'; + SeatControlCapabilities.KEY_HEATING_ENABLED_AVAILABLE = 'heatingEnabledAvailable'; + SeatControlCapabilities.KEY_COOLING_ENABLED_AVAILABLE = 'coolingEnabledAvailable'; + SeatControlCapabilities.KEY_HEATING_LEVEL_AVAILABLE = 'heatingLevelAvailable'; + SeatControlCapabilities.KEY_COOLING_LEVEL_AVAILABLE = 'coolingLevelAvailable'; + SeatControlCapabilities.KEY_HORIZONTAL_POSITION_AVAILABLE = 'horizontalPositionAvailable'; + SeatControlCapabilities.KEY_VERTICAL_POSITION_AVAILABLE = 'verticalPositionAvailable'; + SeatControlCapabilities.KEY_FRONT_VERTICAL_POSITION_AVAILABLE = 'frontVerticalPositionAvailable'; + SeatControlCapabilities.KEY_BACK_VERTICAL_POSITION_AVAILABLE = 'backVerticalPositionAvailable'; + SeatControlCapabilities.KEY_BACK_TILT_ANGLE_AVAILABLE = 'backTiltAngleAvailable'; + SeatControlCapabilities.KEY_HEAD_SUPPORT_HORIZONTAL_POSITION_AVAILABLE = 'headSupportHorizontalPositionAvailable'; + SeatControlCapabilities.KEY_HEAD_SUPPORT_VERTICAL_POSITION_AVAILABLE = 'headSupportVerticalPositionAvailable'; + SeatControlCapabilities.KEY_MASSAGE_ENABLED_AVAILABLE = 'massageEnabledAvailable'; + SeatControlCapabilities.KEY_MASSAGE_MODE_AVAILABLE = 'massageModeAvailable'; + SeatControlCapabilities.KEY_MASSAGE_CUSHION_FIRMNESS_AVAILABLE = 'massageCushionFirmnessAvailable'; + SeatControlCapabilities.KEY_MEMORY_AVAILABLE = 'memoryAvailable'; + + /* eslint-disable camelcase */ + /** + * Contains information about a radio control module's capabilities. + */ + + class RadioControlCapabilities extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {String} name - The short friendly name of the climate control module. It should not be used to identify a + * module by mobile application. + * @return {RadioControlCapabilities} + */ + + + setModuleName(name) { + this.setParameter(RadioControlCapabilities.KEY_MODULE_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getModuleName() { + return this.getParameter(RadioControlCapabilities.KEY_MODULE_NAME); + } + /** + * @param {ModuleInfo} info - Information about a RC module, including its id. + * @return {RadioControlCapabilities} + */ + + + setModuleInfo(info) { + this.validateType(ModuleInfo, info); + this.setParameter(RadioControlCapabilities.KEY_MODULE_INFO, info); + return this; + } + /** + * @return {ModuleInfo} + */ + + + getModuleInfo() { + return this.getObject(ModuleInfo, RadioControlCapabilities.KEY_MODULE_INFO); + } + /** + * @param {Boolean} available - Availability of the control of enable/disable radio. True: Available, False: Not + * Available, Not present: Not Available. + * @return {RadioControlCapabilities} + */ + + + setRadioEnableAvailable(available) { + this.setParameter(RadioControlCapabilities.KEY_RADIO_ENABLE_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getRadioEnableAvailable() { + return this.getParameter(RadioControlCapabilities.KEY_RADIO_ENABLE_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the control of radio band. True: Available, False: Not Available, + * Not present: Not Available. + * @return {RadioControlCapabilities} + */ + + + setRadioBandAvailable(available) { + this.setParameter(RadioControlCapabilities.KEY_RADIO_BAND_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getRadioBandAvailable() { + return this.getParameter(RadioControlCapabilities.KEY_RADIO_BAND_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the control of radio frequency. True: Available, False: Not + * Available, Not present: Not Available. + * @return {RadioControlCapabilities} + */ + + + setRadioFrequencyAvailable(available) { + this.setParameter(RadioControlCapabilities.KEY_RADIO_FREQUENCY_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getRadioFrequencyAvailable() { + return this.getParameter(RadioControlCapabilities.KEY_RADIO_FREQUENCY_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the control of HD radio channel. True: Available, False: Not + * Available, Not present: Not Available. + * @return {RadioControlCapabilities} + */ + + + setHdChannelAvailable(available) { + this.setParameter(RadioControlCapabilities.KEY_HD_CHANNEL_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getHdChannelAvailable() { + return this.getParameter(RadioControlCapabilities.KEY_HD_CHANNEL_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the getting Radio Data System (RDS) data. True: Available, False: + * Not Available, Not present: Not Available. + * @return {RadioControlCapabilities} + */ + + + setRdsDataAvailable(available) { + this.setParameter(RadioControlCapabilities.KEY_RDS_DATA_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getRdsDataAvailable() { + return this.getParameter(RadioControlCapabilities.KEY_RDS_DATA_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the getting the number of available HD channels. True: Available, + * False: Not Available, Not present: Not Available. + * @return {RadioControlCapabilities} + */ + + + setAvailableHDsAvailable(available) { + this.setParameter(RadioControlCapabilities.KEY_AVAILABLE_HDS_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getAvailableHDsAvailable() { + return this.getParameter(RadioControlCapabilities.KEY_AVAILABLE_HDS_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the list of available HD sub-channel indexes. True: Available, + * False: Not Available, Not present: Not Available. + * @return {RadioControlCapabilities} + */ + + + setAvailableHdChannelsAvailable(available) { + this.setParameter(RadioControlCapabilities.KEY_AVAILABLE_HD_CHANNELS_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getAvailableHdChannelsAvailable() { + return this.getParameter(RadioControlCapabilities.KEY_AVAILABLE_HD_CHANNELS_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the getting the Radio state. True: Available, False: Not Available, + * Not present: Not Available. + * @return {RadioControlCapabilities} + */ + + + setStateAvailable(available) { + this.setParameter(RadioControlCapabilities.KEY_STATE_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getStateAvailable() { + return this.getParameter(RadioControlCapabilities.KEY_STATE_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the getting the signal strength. True: Available, False: Not + * Available, Not present: Not Available. + * @return {RadioControlCapabilities} + */ + + + setSignalStrengthAvailable(available) { + this.setParameter(RadioControlCapabilities.KEY_SIGNAL_STRENGTH_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getSignalStrengthAvailable() { + return this.getParameter(RadioControlCapabilities.KEY_SIGNAL_STRENGTH_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the getting the signal Change Threshold. True: Available, False: Not + * Available, Not present: Not Available. + * @return {RadioControlCapabilities} + */ + + + setSignalChangeThresholdAvailable(available) { + this.setParameter(RadioControlCapabilities.KEY_SIGNAL_CHANGE_THRESHOLD_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getSignalChangeThresholdAvailable() { + return this.getParameter(RadioControlCapabilities.KEY_SIGNAL_CHANGE_THRESHOLD_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the getting HD radio Station Information Service (SIS) data. True: + * Available, False: Not Available, Not present: Not Available. + * @return {RadioControlCapabilities} + */ + + + setSisDataAvailable(available) { + this.setParameter(RadioControlCapabilities.KEY_SIS_DATA_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getSisDataAvailable() { + return this.getParameter(RadioControlCapabilities.KEY_SIS_DATA_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the control of enable/disable HD radio. True: Available, False: Not + * Available, Not present: Not Available. + * @return {RadioControlCapabilities} + */ + + + setHdRadioEnableAvailable(available) { + this.setParameter(RadioControlCapabilities.KEY_HD_RADIO_ENABLE_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getHdRadioEnableAvailable() { + return this.getParameter(RadioControlCapabilities.KEY_HD_RADIO_ENABLE_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of sirius XM radio. True: Available, False: Not Available, Not present: + * Not Available. + * @return {RadioControlCapabilities} + */ + + + setSiriusxmRadioAvailable(available) { + this.setParameter(RadioControlCapabilities.KEY_SIRIUSXM_RADIO_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getSiriusxmRadioAvailable() { + return this.getParameter(RadioControlCapabilities.KEY_SIRIUSXM_RADIO_AVAILABLE); + } + + } + + RadioControlCapabilities.KEY_MODULE_NAME = 'moduleName'; + RadioControlCapabilities.KEY_MODULE_INFO = 'moduleInfo'; + RadioControlCapabilities.KEY_RADIO_ENABLE_AVAILABLE = 'radioEnableAvailable'; + RadioControlCapabilities.KEY_RADIO_BAND_AVAILABLE = 'radioBandAvailable'; + RadioControlCapabilities.KEY_RADIO_FREQUENCY_AVAILABLE = 'radioFrequencyAvailable'; + RadioControlCapabilities.KEY_HD_CHANNEL_AVAILABLE = 'hdChannelAvailable'; + RadioControlCapabilities.KEY_RDS_DATA_AVAILABLE = 'rdsDataAvailable'; + RadioControlCapabilities.KEY_AVAILABLE_HDS_AVAILABLE = 'availableHDsAvailable'; + RadioControlCapabilities.KEY_AVAILABLE_HD_CHANNELS_AVAILABLE = 'availableHdChannelsAvailable'; + RadioControlCapabilities.KEY_STATE_AVAILABLE = 'stateAvailable'; + RadioControlCapabilities.KEY_SIGNAL_STRENGTH_AVAILABLE = 'signalStrengthAvailable'; + RadioControlCapabilities.KEY_SIGNAL_CHANGE_THRESHOLD_AVAILABLE = 'signalChangeThresholdAvailable'; + RadioControlCapabilities.KEY_SIS_DATA_AVAILABLE = 'sisDataAvailable'; + RadioControlCapabilities.KEY_HD_RADIO_ENABLE_AVAILABLE = 'hdRadioEnableAvailable'; + RadioControlCapabilities.KEY_SIRIUSXM_RADIO_AVAILABLE = 'siriusxmRadioAvailable'; + + /* eslint-disable camelcase */ + + class HMISettingsControlCapabilities extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {String} name - The short friendly name of the hmi setting module. It should not be used to identify a + * module by mobile application. + * @return {HMISettingsControlCapabilities} + */ + + + setModuleName(name) { + this.setParameter(HMISettingsControlCapabilities.KEY_MODULE_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getModuleName() { + return this.getParameter(HMISettingsControlCapabilities.KEY_MODULE_NAME); + } + /** + * @param {ModuleInfo} info - Information about a RC module, including its id. + * @return {HMISettingsControlCapabilities} + */ + + + setModuleInfo(info) { + this.validateType(ModuleInfo, info); + this.setParameter(HMISettingsControlCapabilities.KEY_MODULE_INFO, info); + return this; + } + /** + * @return {ModuleInfo} + */ + + + getModuleInfo() { + return this.getObject(ModuleInfo, HMISettingsControlCapabilities.KEY_MODULE_INFO); + } + /** + * @param {Boolean} available - Availability of the control of distance unit. + * @return {HMISettingsControlCapabilities} + */ + + + setDistanceUnitAvailable(available) { + this.setParameter(HMISettingsControlCapabilities.KEY_DISTANCE_UNIT_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getDistanceUnitAvailable() { + return this.getParameter(HMISettingsControlCapabilities.KEY_DISTANCE_UNIT_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the control of temperature unit. + * @return {HMISettingsControlCapabilities} + */ + + + setTemperatureUnitAvailable(available) { + this.setParameter(HMISettingsControlCapabilities.KEY_TEMPERATURE_UNIT_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getTemperatureUnitAvailable() { + return this.getParameter(HMISettingsControlCapabilities.KEY_TEMPERATURE_UNIT_AVAILABLE); + } + /** + * @param {Boolean} available - Availability of the control of HMI display mode. + * @return {HMISettingsControlCapabilities} + */ + + + setDisplayModeUnitAvailable(available) { + this.setParameter(HMISettingsControlCapabilities.KEY_DISPLAY_MODE_UNIT_AVAILABLE, available); + return this; + } + /** + * @return {Boolean} + */ + + + getDisplayModeUnitAvailable() { + return this.getParameter(HMISettingsControlCapabilities.KEY_DISPLAY_MODE_UNIT_AVAILABLE); + } + + } + + HMISettingsControlCapabilities.KEY_MODULE_NAME = 'moduleName'; + HMISettingsControlCapabilities.KEY_MODULE_INFO = 'moduleInfo'; + HMISettingsControlCapabilities.KEY_DISTANCE_UNIT_AVAILABLE = 'distanceUnitAvailable'; + HMISettingsControlCapabilities.KEY_TEMPERATURE_UNIT_AVAILABLE = 'temperatureUnitAvailable'; + HMISettingsControlCapabilities.KEY_DISPLAY_MODE_UNIT_AVAILABLE = 'displayModeUnitAvailable'; + + /* eslint-disable camelcase */ + + class RemoteControlCapabilities extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {ClimateControlCapabilities[]} capabilities - If included, the platform supports RC climate controls. For + * this baseline version, maxsize=1. i.e. only one climate + * control module is supported. + * @return {RemoteControlCapabilities} + */ + + + setClimateControlCapabilities(capabilities) { + this.validateType(ClimateControlCapabilities, capabilities, true); + this.setParameter(RemoteControlCapabilities.KEY_CLIMATE_CONTROL_CAPABILITIES, capabilities); + return this; + } + /** + * @return {ClimateControlCapabilities[]} + */ + + + getClimateControlCapabilities() { + return this.getObject(ClimateControlCapabilities, RemoteControlCapabilities.KEY_CLIMATE_CONTROL_CAPABILITIES); + } + /** + * @param {RadioControlCapabilities[]} capabilities - If included, the platform supports RC radio controls.For this + * baseline version, maxsize=1. i.e. only one radio control + * module is supported. + * @return {RemoteControlCapabilities} + */ + + + setRadioControlCapabilities(capabilities) { + this.validateType(RadioControlCapabilities, capabilities, true); + this.setParameter(RemoteControlCapabilities.KEY_RADIO_CONTROL_CAPABILITIES, capabilities); + return this; + } + /** + * @return {RadioControlCapabilities[]} + */ + + + getRadioControlCapabilities() { + return this.getObject(RadioControlCapabilities, RemoteControlCapabilities.KEY_RADIO_CONTROL_CAPABILITIES); + } + /** + * @param {ButtonCapabilities[]} capabilities - If included, the platform supports RC button controls with the + * included button names. + * @return {RemoteControlCapabilities} + */ + + + setButtonCapabilities(capabilities) { + this.validateType(ButtonCapabilities, capabilities, true); + this.setParameter(RemoteControlCapabilities.KEY_BUTTON_CAPABILITIES, capabilities); + return this; + } + /** + * @return {ButtonCapabilities[]} + */ + + + getButtonCapabilities() { + return this.getObject(ButtonCapabilities, RemoteControlCapabilities.KEY_BUTTON_CAPABILITIES); + } + /** + * @param {AudioControlCapabilities[]} capabilities - If included, the platform supports audio controls. + * @return {RemoteControlCapabilities} + */ + + + setAudioControlCapabilities(capabilities) { + this.validateType(AudioControlCapabilities, capabilities, true); + this.setParameter(RemoteControlCapabilities.KEY_AUDIO_CONTROL_CAPABILITIES, capabilities); + return this; + } + /** + * @return {AudioControlCapabilities[]} + */ + + + getAudioControlCapabilities() { + return this.getObject(AudioControlCapabilities, RemoteControlCapabilities.KEY_AUDIO_CONTROL_CAPABILITIES); + } + /** + * @param {HMISettingsControlCapabilities} capabilities - If included, the platform supports hmi setting controls. + * @return {RemoteControlCapabilities} + */ + + + setHmiSettingsControlCapabilities(capabilities) { + this.validateType(HMISettingsControlCapabilities, capabilities); + this.setParameter(RemoteControlCapabilities.KEY_HMI_SETTINGS_CONTROL_CAPABILITIES, capabilities); + return this; + } + /** + * @return {HMISettingsControlCapabilities} + */ + + + getHmiSettingsControlCapabilities() { + return this.getObject(HMISettingsControlCapabilities, RemoteControlCapabilities.KEY_HMI_SETTINGS_CONTROL_CAPABILITIES); + } + /** + * @param {LightControlCapabilities} capabilities - If included, the platform supports light controls. + * @return {RemoteControlCapabilities} + */ + + + setLightControlCapabilities(capabilities) { + this.validateType(LightControlCapabilities, capabilities); + this.setParameter(RemoteControlCapabilities.KEY_LIGHT_CONTROL_CAPABILITIES, capabilities); + return this; + } + /** + * @return {LightControlCapabilities} + */ + + + getLightControlCapabilities() { + return this.getObject(LightControlCapabilities, RemoteControlCapabilities.KEY_LIGHT_CONTROL_CAPABILITIES); + } + /** + * @param {SeatControlCapabilities[]} capabilities - If included, the platform supports seat controls. + * @return {RemoteControlCapabilities} + */ + + + setSeatControlCapabilities(capabilities) { + this.validateType(SeatControlCapabilities, capabilities, true); + this.setParameter(RemoteControlCapabilities.KEY_SEAT_CONTROL_CAPABILITIES, capabilities); + return this; + } + /** + * @return {SeatControlCapabilities[]} + */ + + + getSeatControlCapabilities() { + return this.getObject(SeatControlCapabilities, RemoteControlCapabilities.KEY_SEAT_CONTROL_CAPABILITIES); + } + + } + + RemoteControlCapabilities.KEY_CLIMATE_CONTROL_CAPABILITIES = 'climateControlCapabilities'; + RemoteControlCapabilities.KEY_RADIO_CONTROL_CAPABILITIES = 'radioControlCapabilities'; + RemoteControlCapabilities.KEY_BUTTON_CAPABILITIES = 'buttonCapabilities'; + RemoteControlCapabilities.KEY_AUDIO_CONTROL_CAPABILITIES = 'audioControlCapabilities'; + RemoteControlCapabilities.KEY_HMI_SETTINGS_CONTROL_CAPABILITIES = 'hmiSettingsControlCapabilities'; + RemoteControlCapabilities.KEY_LIGHT_CONTROL_CAPABILITIES = 'lightControlCapabilities'; + RemoteControlCapabilities.KEY_SEAT_CONTROL_CAPABILITIES = 'seatControlCapabilities'; + + /* eslint-disable camelcase */ + /** + * Contains information about the locations of each seat + */ + + class SeatLocationCapability extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Number} rows + * @return {SeatLocationCapability} + */ + + + setRows(rows) { + this.setParameter(SeatLocationCapability.KEY_ROWS, rows); + return this; + } + /** + * @return {Number} + */ + + + getRows() { + return this.getParameter(SeatLocationCapability.KEY_ROWS); + } + /** + * @param {Number} columns + * @return {SeatLocationCapability} + */ + + + setColumns(columns) { + this.setParameter(SeatLocationCapability.KEY_COLUMNS, columns); + return this; + } + /** + * @return {Number} + */ + + + getColumns() { + return this.getParameter(SeatLocationCapability.KEY_COLUMNS); + } + /** + * @param {Number} levels + * @return {SeatLocationCapability} + */ + + + setLevels(levels) { + this.setParameter(SeatLocationCapability.KEY_LEVELS, levels); + return this; + } + /** + * @return {Number} + */ + + + getLevels() { + return this.getParameter(SeatLocationCapability.KEY_LEVELS); + } + /** + * @param {SeatLocation[]} seats - Contains a list of SeatLocation in the vehicle + * @return {SeatLocationCapability} + */ + + + setSeats(seats) { + this.validateType(SeatLocation, seats, true); + this.setParameter(SeatLocationCapability.KEY_SEATS, seats); + return this; + } + /** + * @return {SeatLocation[]} + */ + + + getSeats() { + return this.getObject(SeatLocation, SeatLocationCapability.KEY_SEATS); + } + + } + + SeatLocationCapability.KEY_ROWS = 'rows'; + SeatLocationCapability.KEY_COLUMNS = 'columns'; + SeatLocationCapability.KEY_LEVELS = 'levels'; + SeatLocationCapability.KEY_SEATS = 'seats'; + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} ServiceUpdateReason + * @property {Object} _MAP + */ + + class ServiceUpdateReason extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * The service has just been published with the module and once activated to the primary service of its type, it + * will be ready for possible consumption. + * @return {String} + */ + + + static get PUBLISHED() { + return ServiceUpdateReason._MAP.PUBLISHED; + } + /** + * The service has just been unpublished with the module and is no longer accessible + * @return {String} + */ + + + static get REMOVED() { + return ServiceUpdateReason._MAP.REMOVED; + } + /** + * The service is activated as the primary service of this type. All requests dealing with this service type will + * be handled by this service. + * @return {String} + */ + + + static get ACTIVATED() { + return ServiceUpdateReason._MAP.ACTIVATED; + } + /** + * The service has been deactivated as the primary service of its type + * @return {String} + */ + + + static get DEACTIVATED() { + return ServiceUpdateReason._MAP.DEACTIVATED; + } + /** + * The service has updated its manifest. This could imply updated capabilities + * @return {String} + */ + + + static get MANIFEST_UPDATE() { + return ServiceUpdateReason._MAP.MANIFEST_UPDATE; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return ServiceUpdateReason._valueForKey(key, ServiceUpdateReason._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return ServiceUpdateReason._keyForValue(value, ServiceUpdateReason._MAP); + } + + } + + ServiceUpdateReason._MAP = Object.freeze({ + 'PUBLISHED': 'PUBLISHED', + 'REMOVED': 'REMOVED', + 'ACTIVATED': 'ACTIVATED', + 'DEACTIVATED': 'DEACTIVATED', + 'MANIFEST_UPDATE': 'MANIFEST_UPDATE' + }); + + /* eslint-disable camelcase */ + + class NavigationServiceManifest extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Boolean} points - Informs the subscriber if this service can actually accept way points. + * @return {NavigationServiceManifest} + */ + + + setAcceptsWayPoints(points) { + this.setParameter(NavigationServiceManifest.KEY_ACCEPTS_WAY_POINTS, points); + return this; + } + /** + * @return {Boolean} + */ + + + getAcceptsWayPoints() { + return this.getParameter(NavigationServiceManifest.KEY_ACCEPTS_WAY_POINTS); + } + + } + + NavigationServiceManifest.KEY_ACCEPTS_WAY_POINTS = 'acceptsWayPoints'; + + /* eslint-disable camelcase */ + + class WeatherServiceManifest extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Boolean} supported + * @return {WeatherServiceManifest} + */ + + + setCurrentForecastSupported(supported) { + this.setParameter(WeatherServiceManifest.KEY_CURRENT_FORECAST_SUPPORTED, supported); + return this; + } + /** + * @return {Boolean} + */ + + + getCurrentForecastSupported() { + return this.getParameter(WeatherServiceManifest.KEY_CURRENT_FORECAST_SUPPORTED); + } + /** + * @param {Number} amount + * @return {WeatherServiceManifest} + */ + + + setMaxMultidayForecastAmount(amount) { + this.setParameter(WeatherServiceManifest.KEY_MAX_MULTIDAY_FORECAST_AMOUNT, amount); + return this; + } + /** + * @return {Number} + */ + + + getMaxMultidayForecastAmount() { + return this.getParameter(WeatherServiceManifest.KEY_MAX_MULTIDAY_FORECAST_AMOUNT); + } + /** + * @param {Number} amount + * @return {WeatherServiceManifest} + */ + + + setMaxHourlyForecastAmount(amount) { + this.setParameter(WeatherServiceManifest.KEY_MAX_HOURLY_FORECAST_AMOUNT, amount); + return this; + } + /** + * @return {Number} + */ + + + getMaxHourlyForecastAmount() { + return this.getParameter(WeatherServiceManifest.KEY_MAX_HOURLY_FORECAST_AMOUNT); + } + /** + * @param {Number} amount + * @return {WeatherServiceManifest} + */ + + + setMaxMinutelyForecastAmount(amount) { + this.setParameter(WeatherServiceManifest.KEY_MAX_MINUTELY_FORECAST_AMOUNT, amount); + return this; + } + /** + * @return {Number} + */ + + + getMaxMinutelyForecastAmount() { + return this.getParameter(WeatherServiceManifest.KEY_MAX_MINUTELY_FORECAST_AMOUNT); + } + /** + * @param {Boolean} supported + * @return {WeatherServiceManifest} + */ + + + setWeatherForLocationSupported(supported) { + this.setParameter(WeatherServiceManifest.KEY_WEATHER_FOR_LOCATION_SUPPORTED, supported); + return this; + } + /** + * @return {Boolean} + */ + + + getWeatherForLocationSupported() { + return this.getParameter(WeatherServiceManifest.KEY_WEATHER_FOR_LOCATION_SUPPORTED); + } + + } + + WeatherServiceManifest.KEY_CURRENT_FORECAST_SUPPORTED = 'currentForecastSupported'; + WeatherServiceManifest.KEY_MAX_MULTIDAY_FORECAST_AMOUNT = 'maxMultidayForecastAmount'; + WeatherServiceManifest.KEY_MAX_HOURLY_FORECAST_AMOUNT = 'maxHourlyForecastAmount'; + WeatherServiceManifest.KEY_MAX_MINUTELY_FORECAST_AMOUNT = 'maxMinutelyForecastAmount'; + WeatherServiceManifest.KEY_WEATHER_FOR_LOCATION_SUPPORTED = 'weatherForLocationSupported'; + + /* eslint-disable camelcase */ + + class MediaServiceManifest extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + + } + + /* eslint-disable camelcase */ + /** + * This manifest contains all the information necessary for the service to be published, activated, and consumers able + * to interact with it + */ + + class AppServiceManifest extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {String} name - Unique name of this service + * @return {AppServiceManifest} + */ + + + setServiceName(name) { + this.setParameter(AppServiceManifest.KEY_SERVICE_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getServiceName() { + return this.getParameter(AppServiceManifest.KEY_SERVICE_NAME); + } + /** + * @param {String} type - The type of service that is to be offered by this app. See AppServiceType for known enum + * equivalent types. Parameter is a string to allow for new service types to be used by apps + * on older versions of SDL Core. + * @return {AppServiceManifest} + */ + + + setServiceType(type) { + this.setParameter(AppServiceManifest.KEY_SERVICE_TYPE, type); + return this; + } + /** + * @return {String} + */ + + + getServiceType() { + return this.getParameter(AppServiceManifest.KEY_SERVICE_TYPE); + } + /** + * @param {Image} icon - The icon to be associated with this service. Most likely the same as the appIcon. + * @return {AppServiceManifest} + */ + + + setServiceIcon(icon) { + this.validateType(Image, icon); + this.setParameter(AppServiceManifest.KEY_SERVICE_ICON, icon); + return this; + } + /** + * @return {Image} + */ + + + getServiceIcon() { + return this.getObject(Image, AppServiceManifest.KEY_SERVICE_ICON); + } + /** + * @param {Boolean} consumers - If true, app service consumers beyond the IVI system will be able to access this + * service. If false, only the IVI system will be able consume the service. If not + * provided, it is assumed to be false. + * @return {AppServiceManifest} + */ + + + setAllowAppConsumers(consumers) { + this.setParameter(AppServiceManifest.KEY_ALLOW_APP_CONSUMERS, consumers); + return this; + } + /** + * @return {Boolean} + */ + + + getAllowAppConsumers() { + return this.getParameter(AppServiceManifest.KEY_ALLOW_APP_CONSUMERS); + } + /** + * @param {SdlMsgVersion} version - This is the max RPC Spec version the app service understands. This is important + * during the RPC passthrough functionality. If not included, it is assumed the max + * version of the module is acceptable. + * @return {AppServiceManifest} + */ + + + setRpcSpecVersion(version) { + this.validateType(SdlMsgVersion, version); + this.setParameter(AppServiceManifest.KEY_RPC_SPEC_VERSION, version); + return this; + } + /** + * @return {SdlMsgVersion} + */ + + + getRpcSpecVersion() { + return this.getObject(SdlMsgVersion, AppServiceManifest.KEY_RPC_SPEC_VERSION); + } + /** + * @param {Number[]} cs - This field contains the Function IDs for the RPCs that this service intends to handle + * correctly. This means the service will provide meaningful responses. + * @return {AppServiceManifest} + */ + + + setHandledRPCs(cs) { + this.setParameter(AppServiceManifest.KEY_HANDLED_RPCS, cs); + return this; + } + /** + * @return {Number[]} + */ + + + getHandledRPCs() { + return this.getParameter(AppServiceManifest.KEY_HANDLED_RPCS); + } + /** + * @param {MediaServiceManifest} manifest + * @return {AppServiceManifest} + */ + + + setMediaServiceManifest(manifest) { + this.validateType(MediaServiceManifest, manifest); + this.setParameter(AppServiceManifest.KEY_MEDIA_SERVICE_MANIFEST, manifest); + return this; + } + /** + * @return {MediaServiceManifest} + */ + + + getMediaServiceManifest() { + return this.getObject(MediaServiceManifest, AppServiceManifest.KEY_MEDIA_SERVICE_MANIFEST); + } + /** + * @param {WeatherServiceManifest} manifest + * @return {AppServiceManifest} + */ + + + setWeatherServiceManifest(manifest) { + this.validateType(WeatherServiceManifest, manifest); + this.setParameter(AppServiceManifest.KEY_WEATHER_SERVICE_MANIFEST, manifest); + return this; + } + /** + * @return {WeatherServiceManifest} + */ + + + getWeatherServiceManifest() { + return this.getObject(WeatherServiceManifest, AppServiceManifest.KEY_WEATHER_SERVICE_MANIFEST); + } + /** + * @param {NavigationServiceManifest} manifest + * @return {AppServiceManifest} + */ + + + setNavigationServiceManifest(manifest) { + this.validateType(NavigationServiceManifest, manifest); + this.setParameter(AppServiceManifest.KEY_NAVIGATION_SERVICE_MANIFEST, manifest); + return this; + } + /** + * @return {NavigationServiceManifest} + */ + + + getNavigationServiceManifest() { + return this.getObject(NavigationServiceManifest, AppServiceManifest.KEY_NAVIGATION_SERVICE_MANIFEST); + } + + } + + AppServiceManifest.KEY_SERVICE_NAME = 'serviceName'; + AppServiceManifest.KEY_SERVICE_TYPE = 'serviceType'; + AppServiceManifest.KEY_SERVICE_ICON = 'serviceIcon'; + AppServiceManifest.KEY_ALLOW_APP_CONSUMERS = 'allowAppConsumers'; + AppServiceManifest.KEY_RPC_SPEC_VERSION = 'rpcSpecVersion'; + AppServiceManifest.KEY_HANDLED_RPCS = 'handledRPCs'; + AppServiceManifest.KEY_MEDIA_SERVICE_MANIFEST = 'mediaServiceManifest'; + AppServiceManifest.KEY_WEATHER_SERVICE_MANIFEST = 'weatherServiceManifest'; + AppServiceManifest.KEY_NAVIGATION_SERVICE_MANIFEST = 'navigationServiceManifest'; + + /* eslint-disable camelcase */ + /** + * This is the record of an app service publisher that the module has. It should contain the most up to date + * information including the service's active state + */ + + class AppServiceRecord extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {String} id - A unique ID tied to this specific service record. The ID is supplied by the module that + * services publish themselves. + * @return {AppServiceRecord} + */ + + + setServiceID(id) { + this.setParameter(AppServiceRecord.KEY_SERVICE_ID, id); + return this; + } + /** + * @return {String} + */ + + + getServiceID() { + return this.getParameter(AppServiceRecord.KEY_SERVICE_ID); + } + /** + * @param {AppServiceManifest} manifest - Manifest for the service that this record is for. + * @return {AppServiceRecord} + */ + + + setServiceManifest(manifest) { + this.validateType(AppServiceManifest, manifest); + this.setParameter(AppServiceRecord.KEY_SERVICE_MANIFEST, manifest); + return this; + } + /** + * @return {AppServiceManifest} + */ + + + getServiceManifest() { + return this.getObject(AppServiceManifest, AppServiceRecord.KEY_SERVICE_MANIFEST); + } + /** + * @param {Boolean} published - If true, the service is published and available. If false, the service has likely + * just been unpublished, and should be considered unavailable. + * @return {AppServiceRecord} + */ + + + setServicePublished(published) { + this.setParameter(AppServiceRecord.KEY_SERVICE_PUBLISHED, published); + return this; + } + /** + * @return {Boolean} + */ + + + getServicePublished() { + return this.getParameter(AppServiceRecord.KEY_SERVICE_PUBLISHED); + } + /** + * @param {Boolean} active - If true, the service is the active primary service of the supplied service type. It + * will receive all potential RPCs that are passed through to that service type. If false, + * it is not the primary service of the supplied type. See servicePublished for its + * availability. + * @return {AppServiceRecord} + */ + + + setServiceActive(active) { + this.setParameter(AppServiceRecord.KEY_SERVICE_ACTIVE, active); + return this; + } + /** + * @return {Boolean} + */ + + + getServiceActive() { + return this.getParameter(AppServiceRecord.KEY_SERVICE_ACTIVE); + } + + } + + AppServiceRecord.KEY_SERVICE_ID = 'serviceID'; + AppServiceRecord.KEY_SERVICE_MANIFEST = 'serviceManifest'; + AppServiceRecord.KEY_SERVICE_PUBLISHED = 'servicePublished'; + AppServiceRecord.KEY_SERVICE_ACTIVE = 'serviceActive'; + + /* eslint-disable camelcase */ + + class AppServiceCapability extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {ServiceUpdateReason} reason - Only included in OnSystemCapabilityUpdated. Update reason for service + * record. + * @return {AppServiceCapability} + */ + + + setUpdateReason(reason) { + this.validateType(ServiceUpdateReason, reason); + this.setParameter(AppServiceCapability.KEY_UPDATE_REASON, reason); + return this; + } + /** + * @return {ServiceUpdateReason} + */ + + + getUpdateReason() { + return this.getObject(ServiceUpdateReason, AppServiceCapability.KEY_UPDATE_REASON); + } + /** + * @param {AppServiceRecord} record - Service record for a specific app service provider + * @return {AppServiceCapability} + */ + + + setUpdatedAppServiceRecord(record) { + this.validateType(AppServiceRecord, record); + this.setParameter(AppServiceCapability.KEY_UPDATED_APP_SERVICE_RECORD, record); + return this; + } + /** + * @return {AppServiceRecord} + */ + + + getUpdatedAppServiceRecord() { + return this.getObject(AppServiceRecord, AppServiceCapability.KEY_UPDATED_APP_SERVICE_RECORD); + } + + } + + AppServiceCapability.KEY_UPDATE_REASON = 'updateReason'; + AppServiceCapability.KEY_UPDATED_APP_SERVICE_RECORD = 'updatedAppServiceRecord'; + + /* eslint-disable camelcase */ + /** + * Capabilities of app services including what service types are supported and the current state of services. + */ + + class AppServicesCapabilities extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {AppServiceCapability[]} services - An array of currently available services. If this is an update to the + * capability the affected services will include an update reason in that + * item + * @return {AppServicesCapabilities} + */ + + + setAppServices(services) { + this.validateType(AppServiceCapability, services, true); + this.setParameter(AppServicesCapabilities.KEY_APP_SERVICES, services); + return this; + } + /** + * @return {AppServiceCapability[]} + */ + + + getAppServices() { + return this.getObject(AppServiceCapability, AppServicesCapabilities.KEY_APP_SERVICES); + } + + } + + AppServicesCapabilities.KEY_APP_SERVICES = 'appServices'; + + /* eslint-disable camelcase */ + /** + * Extended capabilities for an onboard navigation system + */ + + class NavigationCapability extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Boolean} enabled - If the module has the ability to add locations to the onboard nav + * @return {NavigationCapability} + */ + + + setSendLocationEnabled(enabled) { + this.setParameter(NavigationCapability.KEY_SEND_LOCATION_ENABLED, enabled); + return this; + } + /** + * @return {Boolean} + */ + + + getSendLocationEnabled() { + return this.getParameter(NavigationCapability.KEY_SEND_LOCATION_ENABLED); + } + /** + * @param {Boolean} enabled - If the module has the ability to return way points from onboard nav + * @return {NavigationCapability} + */ + + + setGetWayPointsEnabled(enabled) { + this.setParameter(NavigationCapability.KEY_GET_WAY_POINTS_ENABLED, enabled); + return this; + } + /** + * @return {Boolean} + */ + + + getGetWayPointsEnabled() { + return this.getParameter(NavigationCapability.KEY_GET_WAY_POINTS_ENABLED); + } + + } + + NavigationCapability.KEY_SEND_LOCATION_ENABLED = 'sendLocationEnabled'; + NavigationCapability.KEY_GET_WAY_POINTS_ENABLED = 'getWayPointsEnabled'; + + /* eslint-disable camelcase */ + /** + * The systemCapabilityType identifies which data object exists in this struct. For example, if the SystemCapability + * Type is NAVIGATION then a "navigationCapability" should exist + */ + + class SystemCapability extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {SystemCapabilityType} type - Used as a descriptor of what data to expect in this struct. The + * corresponding param to this enum should be included and the only other param + * included. + * @return {SystemCapability} + */ + + + setSystemCapabilityType(type) { + this.validateType(SystemCapabilityType, type); + this.setParameter(SystemCapability.KEY_SYSTEM_CAPABILITY_TYPE, type); + return this; + } + /** + * @return {SystemCapabilityType} + */ + + + getSystemCapabilityType() { + return this.getObject(SystemCapabilityType, SystemCapability.KEY_SYSTEM_CAPABILITY_TYPE); + } + /** + * @param {NavigationCapability} capability - Describes extended capabilities for onboard navigation system + * @return {SystemCapability} + */ + + + setNavigationCapability(capability) { + this.validateType(NavigationCapability, capability); + this.setParameter(SystemCapability.KEY_NAVIGATION_CAPABILITY, capability); + return this; + } + /** + * @return {NavigationCapability} + */ + + + getNavigationCapability() { + return this.getObject(NavigationCapability, SystemCapability.KEY_NAVIGATION_CAPABILITY); + } + /** + * @param {PhoneCapability} capability - Describes extended capabilities of the module's phone feature + * @return {SystemCapability} + */ + + + setPhoneCapability(capability) { + this.validateType(PhoneCapability, capability); + this.setParameter(SystemCapability.KEY_PHONE_CAPABILITY, capability); + return this; + } + /** + * @return {PhoneCapability} + */ + + + getPhoneCapability() { + return this.getObject(PhoneCapability, SystemCapability.KEY_PHONE_CAPABILITY); + } + /** + * @param {VideoStreamingCapability} capability - Describes extended capabilities of the module's phone feature + * @return {SystemCapability} + */ + + + setVideoStreamingCapability(capability) { + this.validateType(VideoStreamingCapability, capability); + this.setParameter(SystemCapability.KEY_VIDEO_STREAMING_CAPABILITY, capability); + return this; + } + /** + * @return {VideoStreamingCapability} + */ + + + getVideoStreamingCapability() { + return this.getObject(VideoStreamingCapability, SystemCapability.KEY_VIDEO_STREAMING_CAPABILITY); + } + /** + * @param {RemoteControlCapabilities} capability - Describes extended capabilities of the module's phone feature + * @return {SystemCapability} + */ + + + setRemoteControlCapability(capability) { + this.validateType(RemoteControlCapabilities, capability); + this.setParameter(SystemCapability.KEY_REMOTE_CONTROL_CAPABILITY, capability); + return this; + } + /** + * @return {RemoteControlCapabilities} + */ + + + getRemoteControlCapability() { + return this.getObject(RemoteControlCapabilities, SystemCapability.KEY_REMOTE_CONTROL_CAPABILITY); + } + /** + * @param {AppServicesCapabilities} capabilities - An array of currently available services. If this is an update to + * the capability the affected services will include an update + * reason in that item + * @return {SystemCapability} + */ + + + setAppServicesCapabilities(capabilities) { + this.validateType(AppServicesCapabilities, capabilities); + this.setParameter(SystemCapability.KEY_APP_SERVICES_CAPABILITIES, capabilities); + return this; + } + /** + * @return {AppServicesCapabilities} + */ + + + getAppServicesCapabilities() { + return this.getObject(AppServicesCapabilities, SystemCapability.KEY_APP_SERVICES_CAPABILITIES); + } + /** + * @param {SeatLocationCapability} capability - Contains information about the locations of each seat + * @return {SystemCapability} + */ + + + setSeatLocationCapability(capability) { + this.validateType(SeatLocationCapability, capability); + this.setParameter(SystemCapability.KEY_SEAT_LOCATION_CAPABILITY, capability); + return this; + } + /** + * @return {SeatLocationCapability} + */ + + + getSeatLocationCapability() { + return this.getObject(SeatLocationCapability, SystemCapability.KEY_SEAT_LOCATION_CAPABILITY); + } + /** + * @param {DisplayCapability[]} capabilities + * @return {SystemCapability} + */ + + + setDisplayCapabilities(capabilities) { + this.validateType(DisplayCapability, capabilities, true); + this.setParameter(SystemCapability.KEY_DISPLAY_CAPABILITIES, capabilities); + return this; + } + /** + * @return {DisplayCapability[]} + */ + + + getDisplayCapabilities() { + return this.getObject(DisplayCapability, SystemCapability.KEY_DISPLAY_CAPABILITIES); + } + + } + + SystemCapability.KEY_SYSTEM_CAPABILITY_TYPE = 'systemCapabilityType'; + SystemCapability.KEY_NAVIGATION_CAPABILITY = 'navigationCapability'; + SystemCapability.KEY_PHONE_CAPABILITY = 'phoneCapability'; + SystemCapability.KEY_VIDEO_STREAMING_CAPABILITY = 'videoStreamingCapability'; + SystemCapability.KEY_REMOTE_CONTROL_CAPABILITY = 'remoteControlCapability'; + SystemCapability.KEY_APP_SERVICES_CAPABILITIES = 'appServicesCapabilities'; + SystemCapability.KEY_SEAT_LOCATION_CAPABILITY = 'seatLocationCapability'; + SystemCapability.KEY_DISPLAY_CAPABILITIES = 'displayCapabilities'; + + /* eslint-disable camelcase */ + + class GetSystemCapabilityResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.GetSystemCapability); + } + /** + * @param {SystemCapability} capability - The systemCapabilityType identifies which data object exists in this + * struct. For example, if the SystemCapability Type is NAVIGATION then a + * "navigationCapability" should exist + * @return {GetSystemCapabilityResponse} + */ + + + setSystemCapability(capability) { + this.validateType(SystemCapability, capability); + this.setParameter(GetSystemCapabilityResponse.KEY_SYSTEM_CAPABILITY, capability); + return this; + } + /** + * @return {SystemCapability} + */ + + + getSystemCapability() { + return this.getObject(SystemCapability, GetSystemCapabilityResponse.KEY_SYSTEM_CAPABILITY); + } + + } + + GetSystemCapabilityResponse.KEY_SYSTEM_CAPABILITY = 'systemCapability'; + + /* eslint-disable camelcase */ + + class Rectangle extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Number} x - The upper left X-coordinate of the rectangle + * @return {Rectangle} + */ + + + setX(x) { + this.setParameter(Rectangle.KEY_X, x); + return this; + } + /** + * @return {Number} + */ + + + getX() { + return this.getParameter(Rectangle.KEY_X); + } + /** + * @param {Number} y - The upper left Y-coordinate of the rectangle + * @return {Rectangle} + */ + + + setY(y) { + this.setParameter(Rectangle.KEY_Y, y); + return this; + } + /** + * @return {Number} + */ + + + getY() { + return this.getParameter(Rectangle.KEY_Y); + } + /** + * @param {Number} width - The width of the rectangle + * @return {Rectangle} + */ + + + setWidth(width) { + this.setParameter(Rectangle.KEY_WIDTH, width); + return this; + } + /** + * @return {Number} + */ + + + getWidth() { + return this.getParameter(Rectangle.KEY_WIDTH); + } + /** + * @param {Number} height - The height of the rectangle + * @return {Rectangle} + */ + + + setHeight(height) { + this.setParameter(Rectangle.KEY_HEIGHT, height); + return this; + } + /** + * @return {Number} + */ + + + getHeight() { + return this.getParameter(Rectangle.KEY_HEIGHT); + } + + } + + Rectangle.KEY_X = 'x'; + Rectangle.KEY_Y = 'y'; + Rectangle.KEY_WIDTH = 'width'; + Rectangle.KEY_HEIGHT = 'height'; + + /* eslint-disable camelcase */ + /** + * Defines haptic data for each user control object for video streaming application + */ + + class HapticRect extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Number} id - A user control spatial identifier + * @return {HapticRect} + */ + + + setId(id) { + this.setParameter(HapticRect.KEY_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getId() { + return this.getParameter(HapticRect.KEY_ID); + } + /** + * @param {Rectangle} rect - The position of the haptic rectangle to be highlighted. The center of this rectangle + * will be "touched" when a press occurs. + * @return {HapticRect} + */ + + + setRect(rect) { + this.validateType(Rectangle, rect); + this.setParameter(HapticRect.KEY_RECT, rect); + return this; + } + /** + * @return {Rectangle} + */ + + + getRect() { + return this.getObject(Rectangle, HapticRect.KEY_RECT); + } + + } + + HapticRect.KEY_ID = 'id'; + HapticRect.KEY_RECT = 'rect'; + + /* eslint-disable camelcase */ + /** + * Send the spatial data gathered from SDLCarWindow or VirtualDisplayEncoder to the HMI. This data will be utilized by + * the HMI to determine how and when haptic events should occur + */ + + class SendHapticData extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SendHapticData); + } + /** + * @param {HapticRect[]} data - Array of spatial data structures that represent the locations of all user controls + * present on the HMI. This data should be updated if/when the application presents a + * new screen. When a request is sent, if successful, it will replace all spatial data + * previously sent through RPC. If an empty array is sent, the existing spatial data + * will be cleared + * @return {SendHapticData} + */ + + + setHapticRectData(data) { + this.validateType(HapticRect, data, true); + this.setParameter(SendHapticData.KEY_HAPTIC_RECT_DATA, data); + return this; + } + /** + * @return {HapticRect[]} + */ + + + getHapticRectData() { + return this.getObject(HapticRect, SendHapticData.KEY_HAPTIC_RECT_DATA); + } + + } + + SendHapticData.KEY_HAPTIC_RECT_DATA = 'hapticRectData'; + + /* eslint-disable camelcase */ + + class SendHapticDataResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SendHapticData); + } + + } + + /* eslint-disable camelcase */ + /** + * Enumeration for the user's preference of which app type to use when both are available + * @typedef {Enum} HybridAppPreference + * @property {Object} _MAP + */ + + class HybridAppPreference extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get MOBILE() { + return HybridAppPreference._MAP.MOBILE; + } + /** + * @return {String} + */ + + + static get CLOUD() { + return HybridAppPreference._MAP.CLOUD; + } + /** + * @return {String} + */ + + + static get BOTH() { + return HybridAppPreference._MAP.BOTH; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return HybridAppPreference._valueForKey(key, HybridAppPreference._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return HybridAppPreference._keyForValue(value, HybridAppPreference._MAP); + } + + } + + HybridAppPreference._MAP = Object.freeze({ + 'MOBILE': 'MOBILE', + 'CLOUD': 'CLOUD', + 'BOTH': 'BOTH' + }); + + /* eslint-disable camelcase */ + + class CloudAppProperties extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {String[]} nicknames - An array of app names a cloud app is allowed to register with. If included in a + * SetCloudAppProperties request, this value will overwrite the existing "nicknames" + * field in the app policies section of the policy table. + * @return {CloudAppProperties} + */ + + + setNicknames(nicknames) { + this.setParameter(CloudAppProperties.KEY_NICKNAMES, nicknames); + return this; + } + /** + * @return {String[]} + */ + + + getNicknames() { + return this.getParameter(CloudAppProperties.KEY_NICKNAMES); + } + /** + * @param {String} id + * @return {CloudAppProperties} + */ + + + setAppID(id) { + this.setParameter(CloudAppProperties.KEY_APP_ID, id); + return this; + } + /** + * @return {String} + */ + + + getAppID() { + return this.getParameter(CloudAppProperties.KEY_APP_ID); + } + /** + * @param {Boolean} enabled - If true, cloud app will be included in HMI RPC UpdateAppList + * @return {CloudAppProperties} + */ + + + setEnabled(enabled) { + this.setParameter(CloudAppProperties.KEY_ENABLED, enabled); + return this; + } + /** + * @return {Boolean} + */ + + + getEnabled() { + return this.getParameter(CloudAppProperties.KEY_ENABLED); + } + /** + * @param {String} token - Used to authenticate websocket connection on app activation + * @return {CloudAppProperties} + */ + + + setAuthToken(token) { + this.setParameter(CloudAppProperties.KEY_AUTH_TOKEN, token); + return this; + } + /** + * @return {String} + */ + + + getAuthToken() { + return this.getParameter(CloudAppProperties.KEY_AUTH_TOKEN); + } + /** + * @param {String} type - Specifies the connection type Core should use + * @return {CloudAppProperties} + */ + + + setCloudTransportType(type) { + this.setParameter(CloudAppProperties.KEY_CLOUD_TRANSPORT_TYPE, type); + return this; + } + /** + * @return {String} + */ + + + getCloudTransportType() { + return this.getParameter(CloudAppProperties.KEY_CLOUD_TRANSPORT_TYPE); + } + /** + * @param {HybridAppPreference} preference - Specifies the user preference to use the cloud app version or mobile + * app version when both are available + * @return {CloudAppProperties} + */ + + + setHybridAppPreference(preference) { + this.validateType(HybridAppPreference, preference); + this.setParameter(CloudAppProperties.KEY_HYBRID_APP_PREFERENCE, preference); + return this; + } + /** + * @return {HybridAppPreference} + */ + + + getHybridAppPreference() { + return this.getObject(HybridAppPreference, CloudAppProperties.KEY_HYBRID_APP_PREFERENCE); + } + /** + * @param {String} endpoint - Specifies the endpoint which Core will attempt to connect to when this app is selected + * @return {CloudAppProperties} + */ + + + setEndpoint(endpoint) { + this.setParameter(CloudAppProperties.KEY_ENDPOINT, endpoint); + return this; + } + /** + * @return {String} + */ + + + getEndpoint() { + return this.getParameter(CloudAppProperties.KEY_ENDPOINT); + } + + } + + CloudAppProperties.KEY_NICKNAMES = 'nicknames'; + CloudAppProperties.KEY_APP_ID = 'appID'; + CloudAppProperties.KEY_ENABLED = 'enabled'; + CloudAppProperties.KEY_AUTH_TOKEN = 'authToken'; + CloudAppProperties.KEY_CLOUD_TRANSPORT_TYPE = 'cloudTransportType'; + CloudAppProperties.KEY_HYBRID_APP_PREFERENCE = 'hybridAppPreference'; + CloudAppProperties.KEY_ENDPOINT = 'endpoint'; + + /* eslint-disable camelcase */ + /** + * RPC used to enable/disable a cloud application and set its cloud-related policy properties + */ + + class SetCloudAppProperties extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SetCloudAppProperties); + } + /** + * @param {CloudAppProperties} properties - The new cloud application properties + * @return {SetCloudAppProperties} + */ + + + setProperties(properties) { + this.validateType(CloudAppProperties, properties); + this.setParameter(SetCloudAppProperties.KEY_PROPERTIES, properties); + return this; + } + /** + * @return {CloudAppProperties} + */ + + + getProperties() { + return this.getObject(CloudAppProperties, SetCloudAppProperties.KEY_PROPERTIES); + } + + } + + SetCloudAppProperties.KEY_PROPERTIES = 'properties'; + + /* eslint-disable camelcase */ + /** + * The response to SetCloudAppProperties + */ + + class SetCloudAppPropertiesResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.SetCloudAppProperties); + } + + } + + /* eslint-disable camelcase */ + /** + * RPC used to get the current properties of a cloud application + */ + + class GetCloudAppProperties extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.GetCloudAppProperties); + } + /** + * @param {String} id + * @return {GetCloudAppProperties} + */ + + + setAppID(id) { + this.setParameter(GetCloudAppProperties.KEY_APP_ID, id); + return this; + } + /** + * @return {String} + */ + + + getAppID() { + return this.getParameter(GetCloudAppProperties.KEY_APP_ID); + } + + } + + GetCloudAppProperties.KEY_APP_ID = 'appID'; + + /* eslint-disable camelcase */ + /** + * The response to GetCloudAppProperties + */ + + class GetCloudAppPropertiesResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.GetCloudAppProperties); + } + /** + * @param {CloudAppProperties} properties - The requested cloud application properties + * @return {GetCloudAppPropertiesResponse} + */ + + + setProperties(properties) { + this.validateType(CloudAppProperties, properties); + this.setParameter(GetCloudAppPropertiesResponse.KEY_PROPERTIES, properties); + return this; + } + /** + * @return {CloudAppProperties} + */ + + + getProperties() { + return this.getObject(CloudAppProperties, GetCloudAppPropertiesResponse.KEY_PROPERTIES); + } + + } + + GetCloudAppPropertiesResponse.KEY_PROPERTIES = 'properties'; + + /* eslint-disable camelcase */ + /** + * Registers a service offered by this app on the module. Subsequent calls with the same service type will update the + * manifest for that service. + */ + + class PublishAppService extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.PublishAppService); + } + /** + * @param {AppServiceManifest} manifest - The manifest of the service that wishes to be published. If already + * published, the updated manifest for this service. + * @return {PublishAppService} + */ + + + setAppServiceManifest(manifest) { + this.validateType(AppServiceManifest, manifest); + this.setParameter(PublishAppService.KEY_APP_SERVICE_MANIFEST, manifest); + return this; + } + /** + * @return {AppServiceManifest} + */ + + + getAppServiceManifest() { + return this.getObject(AppServiceManifest, PublishAppService.KEY_APP_SERVICE_MANIFEST); + } + + } + + PublishAppService.KEY_APP_SERVICE_MANIFEST = 'appServiceManifest'; + + /* eslint-disable camelcase */ + /** + * Response to the request to register a service offered by this app on the module + */ + + class PublishAppServiceResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.PublishAppService); + } + /** + * @param {AppServiceRecord} record - If the request was successful, this object will be the current status of the + * service record for the published service. This will include the Core supplied + * service ID. + * @return {PublishAppServiceResponse} + */ + + + setAppServiceRecord(record) { + this.validateType(AppServiceRecord, record); + this.setParameter(PublishAppServiceResponse.KEY_APP_SERVICE_RECORD, record); + return this; + } + /** + * @return {AppServiceRecord} + */ + + + getAppServiceRecord() { + return this.getObject(AppServiceRecord, PublishAppServiceResponse.KEY_APP_SERVICE_RECORD); + } + + } + + PublishAppServiceResponse.KEY_APP_SERVICE_RECORD = 'appServiceRecord'; + + /* eslint-disable camelcase */ + /** + * Unpublish an existing service published by this application. + */ + + class UnpublishAppService extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.UnpublishAppService); + } + /** + * @param {String} id - The ID of the service to be unpublished. + * @return {UnpublishAppService} + */ + + + setServiceID(id) { + this.setParameter(UnpublishAppService.KEY_SERVICE_ID, id); + return this; + } + /** + * @return {String} + */ + + + getServiceID() { + return this.getParameter(UnpublishAppService.KEY_SERVICE_ID); + } + + } + + UnpublishAppService.KEY_SERVICE_ID = 'serviceID'; + + /* eslint-disable camelcase */ + /** + * The response to UnpublishAppService + */ + + class UnpublishAppServiceResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.UnpublishAppService); + } + + } + + /* eslint-disable camelcase */ + /** + * This request asks the module for current data related to the specific service. It also includes an option to + * subscribe to that service for future updates + */ + + class GetAppServiceData extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.GetAppServiceData); + } + /** + * @param {String} type - The type of service that is to be offered by this app. See AppServiceType for known enum + * equivalent types. Parameter is a string to allow for new service types to be used by apps + * on older versions of SDL Core. + * @return {GetAppServiceData} + */ + + + setServiceType(type) { + this.setParameter(GetAppServiceData.KEY_SERVICE_TYPE, type); + return this; + } + /** + * @return {String} + */ + + + getServiceType() { + return this.getParameter(GetAppServiceData.KEY_SERVICE_TYPE); + } + /** + * @param {Boolean} subscribe - If true, the consumer is requesting to subscribe to all future updates from the + * service publisher. If false, the consumer doesn't wish to subscribe and should be + * unsubscribed if it was previously subscribed. + * @return {GetAppServiceData} + */ + + + setSubscribe(subscribe) { + this.setParameter(GetAppServiceData.KEY_SUBSCRIBE, subscribe); + return this; + } + /** + * @return {Boolean} + */ + + + getSubscribe() { + return this.getParameter(GetAppServiceData.KEY_SUBSCRIBE); + } + + } + + GetAppServiceData.KEY_SERVICE_TYPE = 'serviceType'; + GetAppServiceData.KEY_SUBSCRIBE = 'subscribe'; + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} NavigationJunction + * @property {Object} _MAP + */ + + class NavigationJunction extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * A junction that represents a standard intersection with a single road crossing another. + * @return {String} + */ + + + static get REGULAR() { + return NavigationJunction._MAP.REGULAR; + } + /** + * A junction where the road splits off into two paths; a fork in the road. + * @return {String} + */ + + + static get BIFURCATION() { + return NavigationJunction._MAP.BIFURCATION; + } + /** + * A junction that has multiple intersections and paths. + * @return {String} + */ + + + static get MULTI_CARRIAGEWAY() { + return NavigationJunction._MAP.MULTI_CARRIAGEWAY; + } + /** + * A junction where traffic moves in a single direction around a central, non-traversable point to reach one of + * the connecting roads. + * @return {String} + */ + + + static get ROUNDABOUT() { + return NavigationJunction._MAP.ROUNDABOUT; + } + /** + * Similar to a roundabout, however the center of the roundabout is fully traversable. Also known as a mini- + * roundabout. + * @return {String} + */ + + + static get TRAVERSABLE_ROUNDABOUT() { + return NavigationJunction._MAP.TRAVERSABLE_ROUNDABOUT; + } + /** + * A junction where lefts diverge to the right, then curve to the left, converting a left turn to a crossing + * maneuver. + * @return {String} + */ + + + static get JUGHANDLE() { + return NavigationJunction._MAP.JUGHANDLE; + } + /** + * Multiple way intersection that allows traffic to flow based on priority; most commonly right of way and first + * in, first out. + * @return {String} + */ + + + static get ALL_WAY_YIELD() { + return NavigationJunction._MAP.ALL_WAY_YIELD; + } + /** + * A junction designated for traffic turn arounds. + * @return {String} + */ + + + static get TURN_AROUND() { + return NavigationJunction._MAP.TURN_AROUND; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return NavigationJunction._valueForKey(key, NavigationJunction._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return NavigationJunction._keyForValue(value, NavigationJunction._MAP); + } + + } + + NavigationJunction._MAP = Object.freeze({ + 'REGULAR': 'REGULAR', + 'BIFURCATION': 'BIFURCATION', + 'MULTI_CARRIAGEWAY': 'MULTI_CARRIAGEWAY', + 'ROUNDABOUT': 'ROUNDABOUT', + 'TRAVERSABLE_ROUNDABOUT': 'TRAVERSABLE_ROUNDABOUT', + 'JUGHANDLE': 'JUGHANDLE', + 'ALL_WAY_YIELD': 'ALL_WAY_YIELD', + 'TURN_AROUND': 'TURN_AROUND' + }); + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} Direction + * @property {Object} _MAP + */ + + class Direction extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get LEFT() { + return Direction._MAP.LEFT; + } + /** + * @return {String} + */ + + + static get RIGHT() { + return Direction._MAP.RIGHT; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return Direction._valueForKey(key, Direction._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return Direction._keyForValue(value, Direction._MAP); + } + + } + + Direction._MAP = Object.freeze({ + 'LEFT': 'LEFT', + 'RIGHT': 'RIGHT' + }); + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} NavigationAction + * @property {Object} _MAP + */ + + class NavigationAction extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * Using this action plus a supplied direction can give the type of turn. + * @return {String} + */ + + + static get TURN() { + return NavigationAction._MAP.TURN; + } + /** + * @return {String} + */ + + + static get EXIT() { + return NavigationAction._MAP.EXIT; + } + /** + * @return {String} + */ + + + static get STAY() { + return NavigationAction._MAP.STAY; + } + /** + * @return {String} + */ + + + static get MERGE() { + return NavigationAction._MAP.MERGE; + } + /** + * @return {String} + */ + + + static get FERRY() { + return NavigationAction._MAP.FERRY; + } + /** + * @return {String} + */ + + + static get CAR_SHUTTLE_TRAIN() { + return NavigationAction._MAP.CAR_SHUTTLE_TRAIN; + } + /** + * @return {String} + */ + + + static get WAYPOINT() { + return NavigationAction._MAP.WAYPOINT; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return NavigationAction._valueForKey(key, NavigationAction._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return NavigationAction._keyForValue(value, NavigationAction._MAP); + } + + } + + NavigationAction._MAP = Object.freeze({ + 'TURN': 'TURN', + 'EXIT': 'EXIT', + 'STAY': 'STAY', + 'MERGE': 'MERGE', + 'FERRY': 'FERRY', + 'CAR_SHUTTLE_TRAIN': 'CAR_SHUTTLE_TRAIN', + 'WAYPOINT': 'WAYPOINT' + }); + + /* eslint-disable camelcase */ + + class NavigationInstruction extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {LocationDetails} details + * @return {NavigationInstruction} + */ + + + setLocationDetails(details) { + this.validateType(LocationDetails, details); + this.setParameter(NavigationInstruction.KEY_LOCATION_DETAILS, details); + return this; + } + /** + * @return {LocationDetails} + */ + + + getLocationDetails() { + return this.getObject(LocationDetails, NavigationInstruction.KEY_LOCATION_DETAILS); + } + /** + * @param {NavigationAction} action + * @return {NavigationInstruction} + */ + + + setAction(action) { + this.validateType(NavigationAction, action); + this.setParameter(NavigationInstruction.KEY_ACTION, action); + return this; + } + /** + * @return {NavigationAction} + */ + + + getAction() { + return this.getObject(NavigationAction, NavigationInstruction.KEY_ACTION); + } + /** + * @param {DateTime} eta + * @return {NavigationInstruction} + */ + + + setEta(eta) { + this.validateType(DateTime, eta); + this.setParameter(NavigationInstruction.KEY_ETA, eta); + return this; + } + /** + * @return {DateTime} + */ + + + getEta() { + return this.getObject(DateTime, NavigationInstruction.KEY_ETA); + } + /** + * @param {Number} bearing - The angle at which this instruction takes place. For example, 0 would mean straight, + * less than 45 is bearing right, greater than 135 is sharp right, between 45 and 135 is a + * regular right, and 180 is a U-Turn, etc. + * @return {NavigationInstruction} + */ + + + setBearing(bearing) { + this.setParameter(NavigationInstruction.KEY_BEARING, bearing); + return this; + } + /** + * @return {Number} + */ + + + getBearing() { + return this.getParameter(NavigationInstruction.KEY_BEARING); + } + /** + * @param {NavigationJunction} type + * @return {NavigationInstruction} + */ + + + setJunctionType(type) { + this.validateType(NavigationJunction, type); + this.setParameter(NavigationInstruction.KEY_JUNCTION_TYPE, type); + return this; + } + /** + * @return {NavigationJunction} + */ + + + getJunctionType() { + return this.getObject(NavigationJunction, NavigationInstruction.KEY_JUNCTION_TYPE); + } + /** + * @param {Direction} side - Used to infer which side of the road this instruction takes place. For a U-Turn + * (action=TURN, bearing=180) this will determine which direction the turn should take + * place. + * @return {NavigationInstruction} + */ + + + setDrivingSide(side) { + this.validateType(Direction, side); + this.setParameter(NavigationInstruction.KEY_DRIVING_SIDE, side); + return this; + } + /** + * @return {Direction} + */ + + + getDrivingSide() { + return this.getObject(Direction, NavigationInstruction.KEY_DRIVING_SIDE); + } + /** + * @param {String} details - This is a string representation of this instruction, used to display instructions to + * the users. This is not intended to be read aloud to the users, see the param prompt in + * NavigationServiceData for that. + * @return {NavigationInstruction} + */ + + + setDetails(details) { + this.setParameter(NavigationInstruction.KEY_DETAILS, details); + return this; + } + /** + * @return {String} + */ + + + getDetails() { + return this.getParameter(NavigationInstruction.KEY_DETAILS); + } + /** + * @param {Image} image - An image representation of this instruction. + * @return {NavigationInstruction} + */ + + + setImage(image) { + this.validateType(Image, image); + this.setParameter(NavigationInstruction.KEY_IMAGE, image); + return this; + } + /** + * @return {Image} + */ + + + getImage() { + return this.getObject(Image, NavigationInstruction.KEY_IMAGE); + } + + } + + NavigationInstruction.KEY_LOCATION_DETAILS = 'locationDetails'; + NavigationInstruction.KEY_ACTION = 'action'; + NavigationInstruction.KEY_ETA = 'eta'; + NavigationInstruction.KEY_BEARING = 'bearing'; + NavigationInstruction.KEY_JUNCTION_TYPE = 'junctionType'; + NavigationInstruction.KEY_DRIVING_SIDE = 'drivingSide'; + NavigationInstruction.KEY_DETAILS = 'details'; + NavigationInstruction.KEY_IMAGE = 'image'; + + /* eslint-disable camelcase */ + /** + * This data is related to what a navigation service would provide. + */ + + class NavigationServiceData extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {DateTime} stamp - This is the timestamp of when the data was generated. This is to ensure any time or + * distance given in the data can accurately be adjusted if necessary. + * @return {NavigationServiceData} + */ + + + setTimeStamp(stamp) { + this.validateType(DateTime, stamp); + this.setParameter(NavigationServiceData.KEY_TIME_STAMP, stamp); + return this; + } + /** + * @return {DateTime} + */ + + + getTimeStamp() { + return this.getObject(DateTime, NavigationServiceData.KEY_TIME_STAMP); + } + /** + * @param {LocationDetails} origin + * @return {NavigationServiceData} + */ + + + setOrigin(origin) { + this.validateType(LocationDetails, origin); + this.setParameter(NavigationServiceData.KEY_ORIGIN, origin); + return this; + } + /** + * @return {LocationDetails} + */ + + + getOrigin() { + return this.getObject(LocationDetails, NavigationServiceData.KEY_ORIGIN); + } + /** + * @param {LocationDetails} destination + * @return {NavigationServiceData} + */ + + + setDestination(destination) { + this.validateType(LocationDetails, destination); + this.setParameter(NavigationServiceData.KEY_DESTINATION, destination); + return this; + } + /** + * @return {LocationDetails} + */ + + + getDestination() { + return this.getObject(LocationDetails, NavigationServiceData.KEY_DESTINATION); + } + /** + * @param {DateTime} eta + * @return {NavigationServiceData} + */ + + + setDestinationETA(eta) { + this.validateType(DateTime, eta); + this.setParameter(NavigationServiceData.KEY_DESTINATION_ETA, eta); + return this; + } + /** + * @return {DateTime} + */ + + + getDestinationETA() { + return this.getObject(DateTime, NavigationServiceData.KEY_DESTINATION_ETA); + } + /** + * @param {NavigationInstruction[]} instructions - This array should be ordered with all remaining instructions. The + * start of this array should always contain the next instruction. + * @return {NavigationServiceData} + */ + + + setInstructions(instructions) { + this.validateType(NavigationInstruction, instructions, true); + this.setParameter(NavigationServiceData.KEY_INSTRUCTIONS, instructions); + return this; + } + /** + * @return {NavigationInstruction[]} + */ + + + getInstructions() { + return this.getObject(NavigationInstruction, NavigationServiceData.KEY_INSTRUCTIONS); + } + /** + * @param {DateTime} eta + * @return {NavigationServiceData} + */ + + + setNextInstructionETA(eta) { + this.validateType(DateTime, eta); + this.setParameter(NavigationServiceData.KEY_NEXT_INSTRUCTION_ETA, eta); + return this; + } + /** + * @return {DateTime} + */ + + + getNextInstructionETA() { + return this.getObject(DateTime, NavigationServiceData.KEY_NEXT_INSTRUCTION_ETA); + } + /** + * @param {Number} distance - The distance to this instruction from current location. This should only be updated + * ever .1 unit of distance. For more accuracy the consumer can use the GPS location of + * itself and the next instruction. + * @return {NavigationServiceData} + */ + + + setNextInstructionDistance(distance) { + this.setParameter(NavigationServiceData.KEY_NEXT_INSTRUCTION_DISTANCE, distance); + return this; + } + /** + * @return {Number} + */ + + + getNextInstructionDistance() { + return this.getParameter(NavigationServiceData.KEY_NEXT_INSTRUCTION_DISTANCE); + } + /** + * @param {Number} scale - Distance till next maneuver (starting from) from previous maneuver. + * @return {NavigationServiceData} + */ + + + setNextInstructionDistanceScale(scale) { + this.setParameter(NavigationServiceData.KEY_NEXT_INSTRUCTION_DISTANCE_SCALE, scale); + return this; + } + /** + * @return {Number} + */ + + + getNextInstructionDistanceScale() { + return this.getParameter(NavigationServiceData.KEY_NEXT_INSTRUCTION_DISTANCE_SCALE); + } + /** + * @param {String} prompt - This is a prompt message that should be conveyed to the user through either display or + * voice (TTS). This param will change often as it should represent the following: + * approaching instruction, post instruction, alerts that affect the current navigation + * session, etc. + * @return {NavigationServiceData} + */ + + + setPrompt(prompt) { + this.setParameter(NavigationServiceData.KEY_PROMPT, prompt); + return this; + } + /** + * @return {String} + */ + + + getPrompt() { + return this.getParameter(NavigationServiceData.KEY_PROMPT); + } + + } + + NavigationServiceData.KEY_TIME_STAMP = 'timeStamp'; + NavigationServiceData.KEY_ORIGIN = 'origin'; + NavigationServiceData.KEY_DESTINATION = 'destination'; + NavigationServiceData.KEY_DESTINATION_ETA = 'destinationETA'; + NavigationServiceData.KEY_INSTRUCTIONS = 'instructions'; + NavigationServiceData.KEY_NEXT_INSTRUCTION_ETA = 'nextInstructionETA'; + NavigationServiceData.KEY_NEXT_INSTRUCTION_DISTANCE = 'nextInstructionDistance'; + NavigationServiceData.KEY_NEXT_INSTRUCTION_DISTANCE_SCALE = 'nextInstructionDistanceScale'; + NavigationServiceData.KEY_PROMPT = 'prompt'; + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} MediaType + * @property {Object} _MAP + */ + + class MediaType extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get MUSIC() { + return MediaType._MAP.MUSIC; + } + /** + * @return {String} + */ + + + static get PODCAST() { + return MediaType._MAP.PODCAST; + } + /** + * @return {String} + */ + + + static get AUDIOBOOK() { + return MediaType._MAP.AUDIOBOOK; + } + /** + * @return {String} + */ + + + static get OTHER() { + return MediaType._MAP.OTHER; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return MediaType._valueForKey(key, MediaType._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return MediaType._keyForValue(value, MediaType._MAP); + } + + } + + MediaType._MAP = Object.freeze({ + 'MUSIC': 'MUSIC', + 'PODCAST': 'PODCAST', + 'AUDIOBOOK': 'AUDIOBOOK', + 'OTHER': 'OTHER' + }); + + /* eslint-disable camelcase */ + /** + * This data is related to what a media service should provide + */ + + class MediaServiceData extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {MediaType} type - The type of the currently playing or paused track. + * @return {MediaServiceData} + */ + + + setMediaType(type) { + this.validateType(MediaType, type); + this.setParameter(MediaServiceData.KEY_MEDIA_TYPE, type); + return this; + } + /** + * @return {MediaType} + */ + + + getMediaType() { + return this.getObject(MediaType, MediaServiceData.KEY_MEDIA_TYPE); + } + /** + * @param {String} title - Music: The name of the current track Podcast: The name of the current episode Audiobook: + * The name of the current chapter + * @return {MediaServiceData} + */ + + + setMediaTitle(title) { + this.setParameter(MediaServiceData.KEY_MEDIA_TITLE, title); + return this; + } + /** + * @return {String} + */ + + + getMediaTitle() { + return this.getParameter(MediaServiceData.KEY_MEDIA_TITLE); + } + /** + * @param {String} artist - Music: The name of the current album artist Podcast: The provider of the podcast (hosts, + * network, company) Audiobook: The book author's name + * @return {MediaServiceData} + */ + + + setMediaArtist(artist) { + this.setParameter(MediaServiceData.KEY_MEDIA_ARTIST, artist); + return this; + } + /** + * @return {String} + */ + + + getMediaArtist() { + return this.getParameter(MediaServiceData.KEY_MEDIA_ARTIST); + } + /** + * @param {String} album - Music: The name of the current album Podcast: The name of the current podcast show + * Audiobook: The name of the current book + * @return {MediaServiceData} + */ + + + setMediaAlbum(album) { + this.setParameter(MediaServiceData.KEY_MEDIA_ALBUM, album); + return this; + } + /** + * @return {String} + */ + + + getMediaAlbum() { + return this.getParameter(MediaServiceData.KEY_MEDIA_ALBUM); + } + /** + * @param {String} name - Music: The name of the playlist or radio station, if the user is playing from a playlist, + * otherwise, Null Podcast: The name of the playlist, if the user is playing from a playlist, + * otherwise, Null Audiobook: Likely not applicable, possibly a collection or "playlist" of + * books + * @return {MediaServiceData} + */ + + + setPlaylistName(name) { + this.setParameter(MediaServiceData.KEY_PLAYLIST_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getPlaylistName() { + return this.getParameter(MediaServiceData.KEY_PLAYLIST_NAME); + } + /** + * @param {Boolean} explicit - Whether or not the content currently playing (e.g. the track, episode, or book) + * contains explicit content + * @return {MediaServiceData} + */ + + + setIsExplicit(explicit) { + this.setParameter(MediaServiceData.KEY_IS_EXPLICIT, explicit); + return this; + } + /** + * @return {Boolean} + */ + + + getIsExplicit() { + return this.getParameter(MediaServiceData.KEY_IS_EXPLICIT); + } + /** + * @param {Number} progress - Music: The current progress of the track in seconds Podcast: The current progress of + * the episode in seconds Audiobook: The current progress of the current segment (e.g. + * the chapter) in seconds + * @return {MediaServiceData} + */ + + + setTrackPlaybackProgress(progress) { + this.setParameter(MediaServiceData.KEY_TRACK_PLAYBACK_PROGRESS, progress); + return this; + } + /** + * @return {Number} + */ + + + getTrackPlaybackProgress() { + return this.getParameter(MediaServiceData.KEY_TRACK_PLAYBACK_PROGRESS); + } + /** + * @param {Number} duration - Music: The total duration of the track in seconds Podcast: The total duration of the + * episode in seconds Audiobook: The total duration of the current segment (e.g. the + * chapter) in seconds + * @return {MediaServiceData} + */ + + + setTrackPlaybackDuration(duration) { + this.setParameter(MediaServiceData.KEY_TRACK_PLAYBACK_DURATION, duration); + return this; + } + /** + * @return {Number} + */ + + + getTrackPlaybackDuration() { + return this.getParameter(MediaServiceData.KEY_TRACK_PLAYBACK_DURATION); + } + /** + * @param {Number} progress - Music: The current progress of the playback queue in seconds Podcast: The current + * progress of the playback queue in seconds Audiobook: The current progress of the + * playback queue (e.g. the book) in seconds + * @return {MediaServiceData} + */ + + + setQueuePlaybackProgress(progress) { + this.setParameter(MediaServiceData.KEY_QUEUE_PLAYBACK_PROGRESS, progress); + return this; + } + /** + * @return {Number} + */ + + + getQueuePlaybackProgress() { + return this.getParameter(MediaServiceData.KEY_QUEUE_PLAYBACK_PROGRESS); + } + /** + * @param {Number} duration - Music: The total duration of the playback queue in seconds Podcast: The total duration + * of the playback queue in seconds Audiobook: The total duration of the playback queue + * (e.g. the book) in seconds + * @return {MediaServiceData} + */ + + + setQueuePlaybackDuration(duration) { + this.setParameter(MediaServiceData.KEY_QUEUE_PLAYBACK_DURATION, duration); + return this; + } + /** + * @return {Number} + */ + + + getQueuePlaybackDuration() { + return this.getParameter(MediaServiceData.KEY_QUEUE_PLAYBACK_DURATION); + } + /** + * @param {Number} number - Music: The current number (1 based) of the track in the playback queue Podcast: The + * current number (1 based) of the episode in the playback queue Audiobook: The current + * number (1 based) of the episode in the playback queue (e.g. the chapter number in the + * book) + * @return {MediaServiceData} + */ + + + setQueueCurrentTrackNumber(number) { + this.setParameter(MediaServiceData.KEY_QUEUE_CURRENT_TRACK_NUMBER, number); + return this; + } + /** + * @return {Number} + */ + + + getQueueCurrentTrackNumber() { + return this.getParameter(MediaServiceData.KEY_QUEUE_CURRENT_TRACK_NUMBER); + } + /** + * @param {Number} count - Music: The total number of tracks in the playback queue Podcast: The total number of + * episodes in the playback queue Audiobook: The total number of sections in the playback + * queue (e.g. the number of chapters in the book) + * @return {MediaServiceData} + */ + + + setQueueTotalTrackCount(count) { + this.setParameter(MediaServiceData.KEY_QUEUE_TOTAL_TRACK_COUNT, count); + return this; + } + /** + * @return {Number} + */ + + + getQueueTotalTrackCount() { + return this.getParameter(MediaServiceData.KEY_QUEUE_TOTAL_TRACK_COUNT); + } + /** + * @param {Image} image - Music: The album art of the current track Podcast: The podcast or chapter artwork of the + * current podcast episode Audiobook: The book or chapter artwork of the current audiobook + * @return {MediaServiceData} + */ + + + setMediaImage(image) { + this.validateType(Image, image); + this.setParameter(MediaServiceData.KEY_MEDIA_IMAGE, image); + return this; + } + /** + * @return {Image} + */ + + + getMediaImage() { + return this.getObject(Image, MediaServiceData.KEY_MEDIA_IMAGE); + } + + } + + MediaServiceData.KEY_MEDIA_TYPE = 'mediaType'; + MediaServiceData.KEY_MEDIA_TITLE = 'mediaTitle'; + MediaServiceData.KEY_MEDIA_ARTIST = 'mediaArtist'; + MediaServiceData.KEY_MEDIA_ALBUM = 'mediaAlbum'; + MediaServiceData.KEY_PLAYLIST_NAME = 'playlistName'; + MediaServiceData.KEY_IS_EXPLICIT = 'isExplicit'; + MediaServiceData.KEY_TRACK_PLAYBACK_PROGRESS = 'trackPlaybackProgress'; + MediaServiceData.KEY_TRACK_PLAYBACK_DURATION = 'trackPlaybackDuration'; + MediaServiceData.KEY_QUEUE_PLAYBACK_PROGRESS = 'queuePlaybackProgress'; + MediaServiceData.KEY_QUEUE_PLAYBACK_DURATION = 'queuePlaybackDuration'; + MediaServiceData.KEY_QUEUE_CURRENT_TRACK_NUMBER = 'queueCurrentTrackNumber'; + MediaServiceData.KEY_QUEUE_TOTAL_TRACK_COUNT = 'queueTotalTrackCount'; + MediaServiceData.KEY_MEDIA_IMAGE = 'mediaImage'; + + /* eslint-disable camelcase */ + + class WeatherData extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Temperature} temperature + * @return {WeatherData} + */ + + + setCurrentTemperature(temperature) { + this.validateType(Temperature, temperature); + this.setParameter(WeatherData.KEY_CURRENT_TEMPERATURE, temperature); + return this; + } + /** + * @return {Temperature} + */ + + + getCurrentTemperature() { + return this.getObject(Temperature, WeatherData.KEY_CURRENT_TEMPERATURE); + } + /** + * @param {Temperature} high + * @return {WeatherData} + */ + + + setTemperatureHigh(high) { + this.validateType(Temperature, high); + this.setParameter(WeatherData.KEY_TEMPERATURE_HIGH, high); + return this; + } + /** + * @return {Temperature} + */ + + + getTemperatureHigh() { + return this.getObject(Temperature, WeatherData.KEY_TEMPERATURE_HIGH); + } + /** + * @param {Temperature} low + * @return {WeatherData} + */ + + + setTemperatureLow(low) { + this.validateType(Temperature, low); + this.setParameter(WeatherData.KEY_TEMPERATURE_LOW, low); + return this; + } + /** + * @return {Temperature} + */ + + + getTemperatureLow() { + return this.getObject(Temperature, WeatherData.KEY_TEMPERATURE_LOW); + } + /** + * @param {Temperature} temperature + * @return {WeatherData} + */ + + + setApparentTemperature(temperature) { + this.validateType(Temperature, temperature); + this.setParameter(WeatherData.KEY_APPARENT_TEMPERATURE, temperature); + return this; + } + /** + * @return {Temperature} + */ + + + getApparentTemperature() { + return this.getObject(Temperature, WeatherData.KEY_APPARENT_TEMPERATURE); + } + /** + * @param {Temperature} high + * @return {WeatherData} + */ + + + setApparentTemperatureHigh(high) { + this.validateType(Temperature, high); + this.setParameter(WeatherData.KEY_APPARENT_TEMPERATURE_HIGH, high); + return this; + } + /** + * @return {Temperature} + */ + + + getApparentTemperatureHigh() { + return this.getObject(Temperature, WeatherData.KEY_APPARENT_TEMPERATURE_HIGH); + } + /** + * @param {Temperature} low + * @return {WeatherData} + */ + + + setApparentTemperatureLow(low) { + this.validateType(Temperature, low); + this.setParameter(WeatherData.KEY_APPARENT_TEMPERATURE_LOW, low); + return this; + } + /** + * @return {Temperature} + */ + + + getApparentTemperatureLow() { + return this.getObject(Temperature, WeatherData.KEY_APPARENT_TEMPERATURE_LOW); + } + /** + * @param {String} summary + * @return {WeatherData} + */ + + + setWeatherSummary(summary) { + this.setParameter(WeatherData.KEY_WEATHER_SUMMARY, summary); + return this; + } + /** + * @return {String} + */ + + + getWeatherSummary() { + return this.getParameter(WeatherData.KEY_WEATHER_SUMMARY); + } + /** + * @param {DateTime} time + * @return {WeatherData} + */ + + + setTime(time) { + this.validateType(DateTime, time); + this.setParameter(WeatherData.KEY_TIME, time); + return this; + } + /** + * @return {DateTime} + */ + + + getTime() { + return this.getObject(DateTime, WeatherData.KEY_TIME); + } + /** + * @param {Number} humidity - 0 to 1, percentage humidity + * @return {WeatherData} + */ + + + setHumidity(humidity) { + this.setParameter(WeatherData.KEY_HUMIDITY, humidity); + return this; + } + /** + * @return {Number} + */ + + + getHumidity() { + return this.getParameter(WeatherData.KEY_HUMIDITY); + } + /** + * @param {Number} cover - 0 to 1, percentage cloud cover + * @return {WeatherData} + */ + + + setCloudCover(cover) { + this.setParameter(WeatherData.KEY_CLOUD_COVER, cover); + return this; + } + /** + * @return {Number} + */ + + + getCloudCover() { + return this.getParameter(WeatherData.KEY_CLOUD_COVER); + } + /** + * @param {Number} phase - 0 to 1, percentage of the moon seen, e.g. 0 = no moon, 0.25 = quarter moon + * @return {WeatherData} + */ + + + setMoonPhase(phase) { + this.setParameter(WeatherData.KEY_MOON_PHASE, phase); + return this; + } + /** + * @return {Number} + */ + + + getMoonPhase() { + return this.getParameter(WeatherData.KEY_MOON_PHASE); + } + /** + * @param {Number} bearing - In degrees, true north at 0 degrees + * @return {WeatherData} + */ + + + setWindBearing(bearing) { + this.setParameter(WeatherData.KEY_WIND_BEARING, bearing); + return this; + } + /** + * @return {Number} + */ + + + getWindBearing() { + return this.getParameter(WeatherData.KEY_WIND_BEARING); + } + /** + * @param {Number} gust - km/hr + * @return {WeatherData} + */ + + + setWindGust(gust) { + this.setParameter(WeatherData.KEY_WIND_GUST, gust); + return this; + } + /** + * @return {Number} + */ + + + getWindGust() { + return this.getParameter(WeatherData.KEY_WIND_GUST); + } + /** + * @param {Number} speed - km/hr + * @return {WeatherData} + */ + + + setWindSpeed(speed) { + this.setParameter(WeatherData.KEY_WIND_SPEED, speed); + return this; + } + /** + * @return {Number} + */ + + + getWindSpeed() { + return this.getParameter(WeatherData.KEY_WIND_SPEED); + } + /** + * @param {Number} bearing - In degrees, true north at 0 degrees + * @return {WeatherData} + */ + + + setNearestStormBearing(bearing) { + this.setParameter(WeatherData.KEY_NEAREST_STORM_BEARING, bearing); + return this; + } + /** + * @return {Number} + */ + + + getNearestStormBearing() { + return this.getParameter(WeatherData.KEY_NEAREST_STORM_BEARING); + } + /** + * @param {Number} distance - In km + * @return {WeatherData} + */ + + + setNearestStormDistance(distance) { + this.setParameter(WeatherData.KEY_NEAREST_STORM_DISTANCE, distance); + return this; + } + /** + * @return {Number} + */ + + + getNearestStormDistance() { + return this.getParameter(WeatherData.KEY_NEAREST_STORM_DISTANCE); + } + /** + * @param {Number} accumulation - cm + * @return {WeatherData} + */ + + + setPrecipAccumulation(accumulation) { + this.setParameter(WeatherData.KEY_PRECIP_ACCUMULATION, accumulation); + return this; + } + /** + * @return {Number} + */ + + + getPrecipAccumulation() { + return this.getParameter(WeatherData.KEY_PRECIP_ACCUMULATION); + } + /** + * @param {Number} intensity - cm of water per hour + * @return {WeatherData} + */ + + + setPrecipIntensity(intensity) { + this.setParameter(WeatherData.KEY_PRECIP_INTENSITY, intensity); + return this; + } + /** + * @return {Number} + */ + + + getPrecipIntensity() { + return this.getParameter(WeatherData.KEY_PRECIP_INTENSITY); + } + /** + * @param {Number} probability - 0 to 1, percentage chance + * @return {WeatherData} + */ + + + setPrecipProbability(probability) { + this.setParameter(WeatherData.KEY_PRECIP_PROBABILITY, probability); + return this; + } + /** + * @return {Number} + */ + + + getPrecipProbability() { + return this.getParameter(WeatherData.KEY_PRECIP_PROBABILITY); + } + /** + * @param {String} type - e.g. "rain", "snow", "sleet", "hail" + * @return {WeatherData} + */ + + + setPrecipType(type) { + this.setParameter(WeatherData.KEY_PRECIP_TYPE, type); + return this; + } + /** + * @return {String} + */ + + + getPrecipType() { + return this.getParameter(WeatherData.KEY_PRECIP_TYPE); + } + /** + * @param {Number} visibility - In km + * @return {WeatherData} + */ + + + setVisibility(visibility) { + this.setParameter(WeatherData.KEY_VISIBILITY, visibility); + return this; + } + /** + * @return {Number} + */ + + + getVisibility() { + return this.getParameter(WeatherData.KEY_VISIBILITY); + } + /** + * @param {Image} icon + * @return {WeatherData} + */ + + + setWeatherIcon(icon) { + this.validateType(Image, icon); + this.setParameter(WeatherData.KEY_WEATHER_ICON, icon); + return this; + } + /** + * @return {Image} + */ + + + getWeatherIcon() { + return this.getObject(Image, WeatherData.KEY_WEATHER_ICON); + } + + } + + WeatherData.KEY_CURRENT_TEMPERATURE = 'currentTemperature'; + WeatherData.KEY_TEMPERATURE_HIGH = 'temperatureHigh'; + WeatherData.KEY_TEMPERATURE_LOW = 'temperatureLow'; + WeatherData.KEY_APPARENT_TEMPERATURE = 'apparentTemperature'; + WeatherData.KEY_APPARENT_TEMPERATURE_HIGH = 'apparentTemperatureHigh'; + WeatherData.KEY_APPARENT_TEMPERATURE_LOW = 'apparentTemperatureLow'; + WeatherData.KEY_WEATHER_SUMMARY = 'weatherSummary'; + WeatherData.KEY_TIME = 'time'; + WeatherData.KEY_HUMIDITY = 'humidity'; + WeatherData.KEY_CLOUD_COVER = 'cloudCover'; + WeatherData.KEY_MOON_PHASE = 'moonPhase'; + WeatherData.KEY_WIND_BEARING = 'windBearing'; + WeatherData.KEY_WIND_GUST = 'windGust'; + WeatherData.KEY_WIND_SPEED = 'windSpeed'; + WeatherData.KEY_NEAREST_STORM_BEARING = 'nearestStormBearing'; + WeatherData.KEY_NEAREST_STORM_DISTANCE = 'nearestStormDistance'; + WeatherData.KEY_PRECIP_ACCUMULATION = 'precipAccumulation'; + WeatherData.KEY_PRECIP_INTENSITY = 'precipIntensity'; + WeatherData.KEY_PRECIP_PROBABILITY = 'precipProbability'; + WeatherData.KEY_PRECIP_TYPE = 'precipType'; + WeatherData.KEY_VISIBILITY = 'visibility'; + WeatherData.KEY_WEATHER_ICON = 'weatherIcon'; + + /* eslint-disable camelcase */ + + class WeatherAlert extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {String} title + * @return {WeatherAlert} + */ + + + setTitle(title) { + this.setParameter(WeatherAlert.KEY_TITLE, title); + return this; + } + /** + * @return {String} + */ + + + getTitle() { + return this.getParameter(WeatherAlert.KEY_TITLE); + } + /** + * @param {String} summary + * @return {WeatherAlert} + */ + + + setSummary(summary) { + this.setParameter(WeatherAlert.KEY_SUMMARY, summary); + return this; + } + /** + * @return {String} + */ + + + getSummary() { + return this.getParameter(WeatherAlert.KEY_SUMMARY); + } + /** + * @param {DateTime} expires + * @return {WeatherAlert} + */ + + + setExpires(expires) { + this.validateType(DateTime, expires); + this.setParameter(WeatherAlert.KEY_EXPIRES, expires); + return this; + } + /** + * @return {DateTime} + */ + + + getExpires() { + return this.getObject(DateTime, WeatherAlert.KEY_EXPIRES); + } + /** + * @param {String[]} regions + * @return {WeatherAlert} + */ + + + setRegions(regions) { + this.setParameter(WeatherAlert.KEY_REGIONS, regions); + return this; + } + /** + * @return {String[]} + */ + + + getRegions() { + return this.getParameter(WeatherAlert.KEY_REGIONS); + } + /** + * @param {String} severity + * @return {WeatherAlert} + */ + + + setSeverity(severity) { + this.setParameter(WeatherAlert.KEY_SEVERITY, severity); + return this; + } + /** + * @return {String} + */ + + + getSeverity() { + return this.getParameter(WeatherAlert.KEY_SEVERITY); + } + /** + * @param {DateTime} issued + * @return {WeatherAlert} + */ + + + setTimeIssued(issued) { + this.validateType(DateTime, issued); + this.setParameter(WeatherAlert.KEY_TIME_ISSUED, issued); + return this; + } + /** + * @return {DateTime} + */ + + + getTimeIssued() { + return this.getObject(DateTime, WeatherAlert.KEY_TIME_ISSUED); + } + + } + + WeatherAlert.KEY_TITLE = 'title'; + WeatherAlert.KEY_SUMMARY = 'summary'; + WeatherAlert.KEY_EXPIRES = 'expires'; + WeatherAlert.KEY_REGIONS = 'regions'; + WeatherAlert.KEY_SEVERITY = 'severity'; + WeatherAlert.KEY_TIME_ISSUED = 'timeIssued'; + + /* eslint-disable camelcase */ + /** + * This data is related to what a weather service would provide + */ + + class WeatherServiceData extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {LocationDetails} location + * @return {WeatherServiceData} + */ + + + setLocation(location) { + this.validateType(LocationDetails, location); + this.setParameter(WeatherServiceData.KEY_LOCATION, location); + return this; + } + /** + * @return {LocationDetails} + */ + + + getLocation() { + return this.getObject(LocationDetails, WeatherServiceData.KEY_LOCATION); + } + /** + * @param {WeatherData} forecast + * @return {WeatherServiceData} + */ + + + setCurrentForecast(forecast) { + this.validateType(WeatherData, forecast); + this.setParameter(WeatherServiceData.KEY_CURRENT_FORECAST, forecast); + return this; + } + /** + * @return {WeatherData} + */ + + + getCurrentForecast() { + return this.getObject(WeatherData, WeatherServiceData.KEY_CURRENT_FORECAST); + } + /** + * @param {WeatherData[]} forecast + * @return {WeatherServiceData} + */ + + + setMinuteForecast(forecast) { + this.validateType(WeatherData, forecast, true); + this.setParameter(WeatherServiceData.KEY_MINUTE_FORECAST, forecast); + return this; + } + /** + * @return {WeatherData[]} + */ + + + getMinuteForecast() { + return this.getObject(WeatherData, WeatherServiceData.KEY_MINUTE_FORECAST); + } + /** + * @param {WeatherData[]} forecast + * @return {WeatherServiceData} + */ + + + setHourlyForecast(forecast) { + this.validateType(WeatherData, forecast, true); + this.setParameter(WeatherServiceData.KEY_HOURLY_FORECAST, forecast); + return this; + } + /** + * @return {WeatherData[]} + */ + + + getHourlyForecast() { + return this.getObject(WeatherData, WeatherServiceData.KEY_HOURLY_FORECAST); + } + /** + * @param {WeatherData[]} forecast + * @return {WeatherServiceData} + */ + + + setMultidayForecast(forecast) { + this.validateType(WeatherData, forecast, true); + this.setParameter(WeatherServiceData.KEY_MULTIDAY_FORECAST, forecast); + return this; + } + /** + * @return {WeatherData[]} + */ + + + getMultidayForecast() { + return this.getObject(WeatherData, WeatherServiceData.KEY_MULTIDAY_FORECAST); + } + /** + * @param {WeatherAlert[]} alerts - This array should be ordered with the first object being the current day + * @return {WeatherServiceData} + */ + + + setAlerts(alerts) { + this.validateType(WeatherAlert, alerts, true); + this.setParameter(WeatherServiceData.KEY_ALERTS, alerts); + return this; + } + /** + * @return {WeatherAlert[]} + */ + + + getAlerts() { + return this.getObject(WeatherAlert, WeatherServiceData.KEY_ALERTS); + } + + } + + WeatherServiceData.KEY_LOCATION = 'location'; + WeatherServiceData.KEY_CURRENT_FORECAST = 'currentForecast'; + WeatherServiceData.KEY_MINUTE_FORECAST = 'minuteForecast'; + WeatherServiceData.KEY_HOURLY_FORECAST = 'hourlyForecast'; + WeatherServiceData.KEY_MULTIDAY_FORECAST = 'multidayForecast'; + WeatherServiceData.KEY_ALERTS = 'alerts'; + + /* eslint-disable camelcase */ + /** + * Contains all the current data of the app service. The serviceType will link to which of the service data objects are + * included in this object (e.g. if the service type is MEDIA, the mediaServiceData param should be included). + */ + + class AppServiceData extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {String} type - The type of service that is to be offered by this app. See AppServiceType for known enum + * equivalent types. Parameter is a string to allow for new service types to be used by apps + * on older versions of SDL Core. + * @return {AppServiceData} + */ + + + setServiceType(type) { + this.setParameter(AppServiceData.KEY_SERVICE_TYPE, type); + return this; + } + /** + * @return {String} + */ + + + getServiceType() { + return this.getParameter(AppServiceData.KEY_SERVICE_TYPE); + } + /** + * @param {String} id + * @return {AppServiceData} + */ + + + setServiceID(id) { + this.setParameter(AppServiceData.KEY_SERVICE_ID, id); + return this; + } + /** + * @return {String} + */ + + + getServiceID() { + return this.getParameter(AppServiceData.KEY_SERVICE_ID); + } + /** + * @param {MediaServiceData} data - This data is related to what a media service should provide + * @return {AppServiceData} + */ + + + setMediaServiceData(data) { + this.validateType(MediaServiceData, data); + this.setParameter(AppServiceData.KEY_MEDIA_SERVICE_DATA, data); + return this; + } + /** + * @return {MediaServiceData} + */ + + + getMediaServiceData() { + return this.getObject(MediaServiceData, AppServiceData.KEY_MEDIA_SERVICE_DATA); + } + /** + * @param {WeatherServiceData} data - This data is related to what a weather service would provide + * @return {AppServiceData} + */ + + + setWeatherServiceData(data) { + this.validateType(WeatherServiceData, data); + this.setParameter(AppServiceData.KEY_WEATHER_SERVICE_DATA, data); + return this; + } + /** + * @return {WeatherServiceData} + */ + + + getWeatherServiceData() { + return this.getObject(WeatherServiceData, AppServiceData.KEY_WEATHER_SERVICE_DATA); + } + /** + * @param {NavigationServiceData} data - This data is related to what a navigation service would provide. + * @return {AppServiceData} + */ + + + setNavigationServiceData(data) { + this.validateType(NavigationServiceData, data); + this.setParameter(AppServiceData.KEY_NAVIGATION_SERVICE_DATA, data); + return this; + } + /** + * @return {NavigationServiceData} + */ + + + getNavigationServiceData() { + return this.getObject(NavigationServiceData, AppServiceData.KEY_NAVIGATION_SERVICE_DATA); + } + + } + + AppServiceData.KEY_SERVICE_TYPE = 'serviceType'; + AppServiceData.KEY_SERVICE_ID = 'serviceID'; + AppServiceData.KEY_MEDIA_SERVICE_DATA = 'mediaServiceData'; + AppServiceData.KEY_WEATHER_SERVICE_DATA = 'weatherServiceData'; + AppServiceData.KEY_NAVIGATION_SERVICE_DATA = 'navigationServiceData'; + + /* eslint-disable camelcase */ + /** + * This response includes the data that was requested from the specific service + */ + + class GetAppServiceDataResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.GetAppServiceData); + } + /** + * @param {AppServiceData} data - Contains all the current data of the app service. The serviceType will link to + * which of the service data objects are included in this object (e.g. if the service + * type is MEDIA, the mediaServiceData param should be included). + * @return {GetAppServiceDataResponse} + */ + + + setServiceData(data) { + this.validateType(AppServiceData, data); + this.setParameter(GetAppServiceDataResponse.KEY_SERVICE_DATA, data); + return this; + } + /** + * @return {AppServiceData} + */ + + + getServiceData() { + return this.getObject(AppServiceData, GetAppServiceDataResponse.KEY_SERVICE_DATA); + } + + } + + GetAppServiceDataResponse.KEY_SERVICE_DATA = 'serviceData'; + + /* eslint-disable camelcase */ + + class PerformAppServiceInteraction extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.PerformAppServiceInteraction); + } + /** + * @param {String} uri - Fully qualified URI based on a predetermined scheme provided by the app service. SDL makes + * no guarantee that this URI is correct. + * @return {PerformAppServiceInteraction} + */ + + + setServiceUri(uri) { + this.setParameter(PerformAppServiceInteraction.KEY_SERVICE_URI, uri); + return this; + } + /** + * @return {String} + */ + + + getServiceUri() { + return this.getParameter(PerformAppServiceInteraction.KEY_SERVICE_URI); + } + /** + * @param {String} id - The service ID that the app consumer wishes to send this URI. + * @return {PerformAppServiceInteraction} + */ + + + setServiceID(id) { + this.setParameter(PerformAppServiceInteraction.KEY_SERVICE_ID, id); + return this; + } + /** + * @return {String} + */ + + + getServiceID() { + return this.getParameter(PerformAppServiceInteraction.KEY_SERVICE_ID); + } + /** + * @param {String} app - This string is the appID of the app requesting the app service provider take the specific + * action. + * @return {PerformAppServiceInteraction} + */ + + + setOriginApp(app) { + this.setParameter(PerformAppServiceInteraction.KEY_ORIGIN_APP, app); + return this; + } + /** + * @return {String} + */ + + + getOriginApp() { + return this.getParameter(PerformAppServiceInteraction.KEY_ORIGIN_APP); + } + /** + * @param {Boolean} active - This flag signals the requesting consumer would like this service to become the active + * primary service of the destination's type. + * @return {PerformAppServiceInteraction} + */ + + + setRequestServiceActive(active) { + this.setParameter(PerformAppServiceInteraction.KEY_REQUEST_SERVICE_ACTIVE, active); + return this; + } + /** + * @return {Boolean} + */ + + + getRequestServiceActive() { + return this.getParameter(PerformAppServiceInteraction.KEY_REQUEST_SERVICE_ACTIVE); + } + + } + + PerformAppServiceInteraction.KEY_SERVICE_URI = 'serviceUri'; + PerformAppServiceInteraction.KEY_SERVICE_ID = 'serviceID'; + PerformAppServiceInteraction.KEY_ORIGIN_APP = 'originApp'; + PerformAppServiceInteraction.KEY_REQUEST_SERVICE_ACTIVE = 'requestServiceActive'; + + /* eslint-disable camelcase */ + + class PerformAppServiceInteractionResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.PerformAppServiceInteraction); + } + /** + * @param {String} result - The service can provide specific result strings to the consumer through this param. + * @return {PerformAppServiceInteractionResponse} + */ + + + setServiceSpecificResult(result) { + this.setParameter(PerformAppServiceInteractionResponse.KEY_SERVICE_SPECIFIC_RESULT, result); + return this; + } + /** + * @return {String} + */ + + + getServiceSpecificResult() { + return this.getParameter(PerformAppServiceInteractionResponse.KEY_SERVICE_SPECIFIC_RESULT); + } + + } + + PerformAppServiceInteractionResponse.KEY_SERVICE_SPECIFIC_RESULT = 'serviceSpecificResult'; + + /* eslint-disable camelcase */ + /** + * Close an active interaction on the HMI. + */ + + class CancelInteraction extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.CancelInteraction); + } + /** + * @param {Number} id - The ID of the specific interaction you want to dismiss. If not set, the most recent of the + * RPC type set in functionID will be dismissed. + * @return {CancelInteraction} + */ + + + setCancelID(id) { + this.setParameter(CancelInteraction.KEY_CANCEL_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getCancelID() { + return this.getParameter(CancelInteraction.KEY_CANCEL_ID); + } + /** + * @param {Number} id - The ID of the type of interaction the developer wants to dismiss. Only values 10, + * (PerformInteractionID), 12 (AlertID), 25 (ScrollableMessageID), and 26 (SliderID) are + * permitted. + * @return {CancelInteraction} + */ + + + setFunctionID(id) { + this.setParameter(CancelInteraction.KEY_FUNCTION_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getFunctionID() { + return this.getParameter(CancelInteraction.KEY_FUNCTION_ID); + } + + } + + CancelInteraction.KEY_CANCEL_ID = 'cancelID'; + CancelInteraction.KEY_FUNCTION_ID = 'functionID'; + + /* eslint-disable camelcase */ + /** + * If no applicable request can be dismissed, the result will be IGNORED. + */ + + class CancelInteractionResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.CancelInteraction); + } + + } + + /* eslint-disable camelcase */ + /** + * Request from the application to exit the foreground and enter HMI_NONE. + */ + + class CloseApplication extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.CloseApplication); + } + + } + + /* eslint-disable camelcase */ + + class CloseApplicationResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.CloseApplication); + } + + } + + /* eslint-disable camelcase */ + /** + * Enumeration that describes possible contexts an app's HMI might be in. Communicated to whichever app is in HMI FULL, + * except Alert. + * @typedef {Enum} SystemContext + * @property {Object} _MAP + */ + + class SystemContext extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * The app's persistent display (whether media/non-media/navigation) is fully visible onscreen. + * @return {String} + */ + + + static get SYSCTXT_MAIN() { + return SystemContext._MAP.SYSCTXT_MAIN; + } + /** + * The system is currently in a VR session (with whatever dedicated VR screen being overlaid onscreen). + * @return {String} + */ + + + static get SYSCTXT_VRSESSION() { + return SystemContext._MAP.SYSCTXT_VRSESSION; + } + /** + * The system is currently displaying an in-App menu onscreen. + * @return {String} + */ + + + static get SYSCTXT_MENU() { + return SystemContext._MAP.SYSCTXT_MENU; + } + /** + * The app's display HMI is currently being obscured by either a system or other app's overlay. + * @return {String} + */ + + + static get SYSCTXT_HMI_OBSCURED() { + return SystemContext._MAP.SYSCTXT_HMI_OBSCURED; + } + /** + * Broadcast only to whichever app has an alert currently being displayed. + * @return {String} + */ + + + static get SYSCTXT_ALERT() { + return SystemContext._MAP.SYSCTXT_ALERT; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return SystemContext._valueForKey(key, SystemContext._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return SystemContext._keyForValue(value, SystemContext._MAP); + } + + } + + SystemContext._MAP = Object.freeze({ + 'SYSCTXT_MAIN': 'MAIN', + 'SYSCTXT_VRSESSION': 'VRSESSION', + 'SYSCTXT_MENU': 'MENU', + 'SYSCTXT_HMI_OBSCURED': 'HMI_OBSCURED', + 'SYSCTXT_ALERT': 'ALERT' + }); + + /* + * Copyright (c) 2019, Livio, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Livio Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + class RpcNotification extends RpcMessage { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setRPCType(RpcType.NOTIFICATION); + } + + } + + /* eslint-disable camelcase */ + /** + * Enumeration that describes possible states of audio streaming. + * @typedef {Enum} AudioStreamingState + * @property {Object} _MAP + */ + + class AudioStreamingState extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get AUDIBLE() { + return AudioStreamingState._MAP.AUDIBLE; + } + /** + * @return {String} + */ + + + static get ATTENUATED() { + return AudioStreamingState._MAP.ATTENUATED; + } + /** + * @return {String} + */ + + + static get NOT_AUDIBLE() { + return AudioStreamingState._MAP.NOT_AUDIBLE; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return AudioStreamingState._valueForKey(key, AudioStreamingState._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return AudioStreamingState._keyForValue(value, AudioStreamingState._MAP); + } + + } + + AudioStreamingState._MAP = Object.freeze({ + 'AUDIBLE': 'AUDIBLE', + 'ATTENUATED': 'ATTENUATED', + 'NOT_AUDIBLE': 'NOT_AUDIBLE' + }); + + /* eslint-disable camelcase */ + /** + * Enumeration that describes current levels of HMI. + * @typedef {Enum} HMILevel + * @property {Object} _MAP + */ + + class HMILevel extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get HMI_FULL() { + return HMILevel._MAP.HMI_FULL; + } + /** + * @return {String} + */ + + + static get HMI_LIMITED() { + return HMILevel._MAP.HMI_LIMITED; + } + /** + * @return {String} + */ + + + static get HMI_BACKGROUND() { + return HMILevel._MAP.HMI_BACKGROUND; + } + /** + * @return {String} + */ + + + static get HMI_NONE() { + return HMILevel._MAP.HMI_NONE; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return HMILevel._valueForKey(key, HMILevel._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return HMILevel._keyForValue(value, HMILevel._MAP); + } + + } + + HMILevel._MAP = Object.freeze({ + 'HMI_FULL': 'FULL', + 'HMI_LIMITED': 'LIMITED', + 'HMI_BACKGROUND': 'BACKGROUND', + 'HMI_NONE': 'NONE' + }); + + /* eslint-disable camelcase */ + /** + * Enumeration that describes possible states of video streaming. + * @typedef {Enum} VideoStreamingState + * @property {Object} _MAP + */ + + class VideoStreamingState extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get STREAMABLE() { + return VideoStreamingState._MAP.STREAMABLE; + } + /** + * @return {String} + */ + + + static get NOT_STREAMABLE() { + return VideoStreamingState._MAP.NOT_STREAMABLE; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return VideoStreamingState._valueForKey(key, VideoStreamingState._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return VideoStreamingState._keyForValue(value, VideoStreamingState._MAP); + } + + } + + VideoStreamingState._MAP = Object.freeze({ + 'STREAMABLE': 'STREAMABLE', + 'NOT_STREAMABLE': 'NOT_STREAMABLE' + }); + + /* eslint-disable camelcase */ + + class OnHMIStatus extends RpcNotification { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnHMIStatus); + } + /** + * @param {HMILevel} level - See HMILevel + * @return {OnHMIStatus} + */ + + + setHmiLevel(level) { + this.validateType(HMILevel, level); + this.setParameter(OnHMIStatus.KEY_HMI_LEVEL, level); + return this; + } + /** + * @return {HMILevel} + */ + + + getHmiLevel() { + return this.getObject(HMILevel, OnHMIStatus.KEY_HMI_LEVEL); + } + /** + * @param {AudioStreamingState} state - See AudioStreamingState + * @return {OnHMIStatus} + */ + + + setAudioStreamingState(state) { + this.validateType(AudioStreamingState, state); + this.setParameter(OnHMIStatus.KEY_AUDIO_STREAMING_STATE, state); + return this; + } + /** + * @return {AudioStreamingState} + */ + + + getAudioStreamingState() { + return this.getObject(AudioStreamingState, OnHMIStatus.KEY_AUDIO_STREAMING_STATE); + } + /** + * @param {SystemContext} context - See SystemContext + * @return {OnHMIStatus} + */ + + + setSystemContext(context) { + this.validateType(SystemContext, context); + this.setParameter(OnHMIStatus.KEY_SYSTEM_CONTEXT, context); + return this; + } + /** + * @return {SystemContext} + */ + + + getSystemContext() { + return this.getObject(SystemContext, OnHMIStatus.KEY_SYSTEM_CONTEXT); + } + /** + * @param {VideoStreamingState} state - See VideoStreamingState. If it is NOT_STREAMABLE, the app must stop + * streaming video to SDL Core(stop service). + * @return {OnHMIStatus} + */ + + + setVideoStreamingState(state) { + this.validateType(VideoStreamingState, state); + this.setParameter(OnHMIStatus.KEY_VIDEO_STREAMING_STATE, state); + return this; + } + /** + * @return {VideoStreamingState} + */ + + + getVideoStreamingState() { + return this.getObject(VideoStreamingState, OnHMIStatus.KEY_VIDEO_STREAMING_STATE); + } + /** + * @param {Number} id - This is the unique ID assigned to the window that this RPC is intended. If this param is not + * included, it will be assumed that this request is specifically for the main window on the + * main display. See PredefinedWindows enum. + * @return {OnHMIStatus} + */ + + + setWindowID(id) { + this.setParameter(OnHMIStatus.KEY_WINDOW_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getWindowID() { + return this.getParameter(OnHMIStatus.KEY_WINDOW_ID); + } + + } + + OnHMIStatus.KEY_HMI_LEVEL = 'hmiLevel'; + OnHMIStatus.KEY_AUDIO_STREAMING_STATE = 'audioStreamingState'; + OnHMIStatus.KEY_SYSTEM_CONTEXT = 'systemContext'; + OnHMIStatus.KEY_VIDEO_STREAMING_STATE = 'videoStreamingState'; + OnHMIStatus.KEY_WINDOW_ID = 'windowID'; + + /* eslint-disable camelcase */ + /** + * Error code, which comes from the module side. + * @typedef {Enum} AppInterfaceUnregisteredReason + * @property {Object} _MAP + */ + + class AppInterfaceUnregisteredReason extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get IGNITION_OFF() { + return AppInterfaceUnregisteredReason._MAP.IGNITION_OFF; + } + /** + * @return {String} + */ + + + static get BLUETOOTH_OFF() { + return AppInterfaceUnregisteredReason._MAP.BLUETOOTH_OFF; + } + /** + * @return {String} + */ + + + static get USB_DISCONNECTED() { + return AppInterfaceUnregisteredReason._MAP.USB_DISCONNECTED; + } + /** + * @return {String} + */ + + + static get REQUEST_WHILE_IN_NONE_HMI_LEVEL() { + return AppInterfaceUnregisteredReason._MAP.REQUEST_WHILE_IN_NONE_HMI_LEVEL; + } + /** + * @return {String} + */ + + + static get TOO_MANY_REQUESTS() { + return AppInterfaceUnregisteredReason._MAP.TOO_MANY_REQUESTS; + } + /** + * @return {String} + */ + + + static get DRIVER_DISTRACTION_VIOLATION() { + return AppInterfaceUnregisteredReason._MAP.DRIVER_DISTRACTION_VIOLATION; + } + /** + * @return {String} + */ + + + static get LANGUAGE_CHANGE() { + return AppInterfaceUnregisteredReason._MAP.LANGUAGE_CHANGE; + } + /** + * @return {String} + */ + + + static get MASTER_RESET() { + return AppInterfaceUnregisteredReason._MAP.MASTER_RESET; + } + /** + * @return {String} + */ + + + static get FACTORY_DEFAULTS() { + return AppInterfaceUnregisteredReason._MAP.FACTORY_DEFAULTS; + } + /** + * @return {String} + */ + + + static get APP_UNAUTHORIZED() { + return AppInterfaceUnregisteredReason._MAP.APP_UNAUTHORIZED; + } + /** + * @return {String} + */ + + + static get PROTOCOL_VIOLATION() { + return AppInterfaceUnregisteredReason._MAP.PROTOCOL_VIOLATION; + } + /** + * @return {String} + */ + + + static get UNSUPPORTED_HMI_RESOURCE() { + return AppInterfaceUnregisteredReason._MAP.UNSUPPORTED_HMI_RESOURCE; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return AppInterfaceUnregisteredReason._valueForKey(key, AppInterfaceUnregisteredReason._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return AppInterfaceUnregisteredReason._keyForValue(value, AppInterfaceUnregisteredReason._MAP); + } + + } + + AppInterfaceUnregisteredReason._MAP = Object.freeze({ + 'IGNITION_OFF': 'IGNITION_OFF', + 'BLUETOOTH_OFF': 'BLUETOOTH_OFF', + 'USB_DISCONNECTED': 'USB_DISCONNECTED', + 'REQUEST_WHILE_IN_NONE_HMI_LEVEL': 'REQUEST_WHILE_IN_NONE_HMI_LEVEL', + 'TOO_MANY_REQUESTS': 'TOO_MANY_REQUESTS', + 'DRIVER_DISTRACTION_VIOLATION': 'DRIVER_DISTRACTION_VIOLATION', + 'LANGUAGE_CHANGE': 'LANGUAGE_CHANGE', + 'MASTER_RESET': 'MASTER_RESET', + 'FACTORY_DEFAULTS': 'FACTORY_DEFAULTS', + 'APP_UNAUTHORIZED': 'APP_UNAUTHORIZED', + 'PROTOCOL_VIOLATION': 'PROTOCOL_VIOLATION', + 'UNSUPPORTED_HMI_RESOURCE': 'UNSUPPORTED_HMI_RESOURCE' + }); + + /* eslint-disable camelcase */ + + class OnAppInterfaceUnregistered extends RpcNotification { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnAppInterfaceUnregistered); + } + /** + * @param {AppInterfaceUnregisteredReason} reason - See AppInterfaceUnregisteredReason + * @return {OnAppInterfaceUnregistered} + */ + + + setReason(reason) { + this.validateType(AppInterfaceUnregisteredReason, reason); + this.setParameter(OnAppInterfaceUnregistered.KEY_REASON, reason); + return this; + } + /** + * @return {AppInterfaceUnregisteredReason} + */ + + + getReason() { + return this.getObject(AppInterfaceUnregisteredReason, OnAppInterfaceUnregistered.KEY_REASON); + } + + } + + OnAppInterfaceUnregistered.KEY_REASON = 'reason'; + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} ButtonEventMode + * @property {Object} _MAP + */ + + class ButtonEventMode extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * A button has been released up + * @return {String} + */ + + + static get BUTTONUP() { + return ButtonEventMode._MAP.BUTTONUP; + } + /** + * A button has been pressed down + * @return {String} + */ + + + static get BUTTONDOWN() { + return ButtonEventMode._MAP.BUTTONDOWN; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return ButtonEventMode._valueForKey(key, ButtonEventMode._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return ButtonEventMode._keyForValue(value, ButtonEventMode._MAP); + } + + } + + ButtonEventMode._MAP = Object.freeze({ + 'BUTTONUP': 'BUTTONUP', + 'BUTTONDOWN': 'BUTTONDOWN' + }); + + /* eslint-disable camelcase */ + /** + * Notifies application of UP/DOWN events for buttons to which the application is subscribed. + */ + + class OnButtonEvent extends RpcNotification { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnButtonEvent); + } + /** + * @param {ButtonName} name - Defines the hard (physical) and soft (touchscreen) buttons available from the module + * @return {OnButtonEvent} + */ + + + setButtonName(name) { + this.validateType(ButtonName, name); + this.setParameter(OnButtonEvent.KEY_BUTTON_NAME, name); + return this; + } + /** + * @return {ButtonName} + */ + + + getButtonName() { + return this.getObject(ButtonName, OnButtonEvent.KEY_BUTTON_NAME); + } + /** + * @param {ButtonEventMode} mode - Indicates whether this is an UP or DOWN event. + * @return {OnButtonEvent} + */ + + + setButtonEventMode(mode) { + this.validateType(ButtonEventMode, mode); + this.setParameter(OnButtonEvent.KEY_BUTTON_EVENT_MODE, mode); + return this; + } + /** + * @return {ButtonEventMode} + */ + + + getButtonEventMode() { + return this.getObject(ButtonEventMode, OnButtonEvent.KEY_BUTTON_EVENT_MODE); + } + /** + * @param {Number} id - If ButtonName is "CUSTOM_BUTTON", this references the integer ID passed by a custom button. + * (e.g. softButton ID) + * @return {OnButtonEvent} + */ + + + setCustomButtonID(id) { + this.setParameter(OnButtonEvent.KEY_CUSTOM_BUTTON_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getCustomButtonID() { + return this.getParameter(OnButtonEvent.KEY_CUSTOM_BUTTON_ID); + } + + } + + OnButtonEvent.KEY_BUTTON_NAME = 'buttonName'; + OnButtonEvent.KEY_BUTTON_EVENT_MODE = 'buttonEventMode'; + OnButtonEvent.KEY_CUSTOM_BUTTON_ID = 'customButtonID'; + + /* eslint-disable camelcase */ + /** + * Notifies application of LONG/SHORT press events for buttons to which the application is subscribed. + */ + + class OnButtonPress extends RpcNotification { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnButtonPress); + } + /** + * @param {ButtonName} name - Defines the hard (physical) and soft (touchscreen) buttons available from the module + * @return {OnButtonPress} + */ + + + setButtonName(name) { + this.validateType(ButtonName, name); + this.setParameter(OnButtonPress.KEY_BUTTON_NAME, name); + return this; + } + /** + * @return {ButtonName} + */ + + + getButtonName() { + return this.getObject(ButtonName, OnButtonPress.KEY_BUTTON_NAME); + } + /** + * @param {ButtonPressMode} mode - Indicates whether this is a LONG or SHORT button press event. + * @return {OnButtonPress} + */ + + + setButtonPressMode(mode) { + this.validateType(ButtonPressMode, mode); + this.setParameter(OnButtonPress.KEY_BUTTON_PRESS_MODE, mode); + return this; + } + /** + * @return {ButtonPressMode} + */ + + + getButtonPressMode() { + return this.getObject(ButtonPressMode, OnButtonPress.KEY_BUTTON_PRESS_MODE); + } + /** + * @param {Number} id - If ButtonName is "CUSTOM_BUTTON", this references the integer ID passed by a custom button. + * (e.g. softButton ID) + * @return {OnButtonPress} + */ + + + setCustomButtonID(id) { + this.setParameter(OnButtonPress.KEY_CUSTOM_BUTTON_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getCustomButtonID() { + return this.getParameter(OnButtonPress.KEY_CUSTOM_BUTTON_ID); + } + + } + + OnButtonPress.KEY_BUTTON_NAME = 'buttonName'; + OnButtonPress.KEY_BUTTON_PRESS_MODE = 'buttonPressMode'; + OnButtonPress.KEY_CUSTOM_BUTTON_ID = 'customButtonID'; + + /* eslint-disable camelcase */ + /** + * Callback for the periodic and non periodic vehicle data read function. + */ + + class OnVehicleData extends RpcNotification { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnVehicleData); + } + /** + * @param {GPSData} gps - See GPSData + * @return {OnVehicleData} + */ + + + setGps(gps) { + this.validateType(GPSData, gps); + this.setParameter(OnVehicleData.KEY_GPS, gps); + return this; + } + /** + * @return {GPSData} + */ + + + getGps() { + return this.getObject(GPSData, OnVehicleData.KEY_GPS); + } + /** + * @param {Number} speed - The vehicle speed in kilometers per hour + * @return {OnVehicleData} + */ + + + setSpeed(speed) { + this.setParameter(OnVehicleData.KEY_SPEED, speed); + return this; + } + /** + * @return {Number} + */ + + + getSpeed() { + return this.getParameter(OnVehicleData.KEY_SPEED); + } + /** + * @param {Number} rpm - The number of revolutions per minute of the engine + * @return {OnVehicleData} + */ + + + setRpm(rpm) { + this.setParameter(OnVehicleData.KEY_RPM, rpm); + return this; + } + /** + * @return {Number} + */ + + + getRpm() { + return this.getParameter(OnVehicleData.KEY_RPM); + } + /** + * @param {Number} level - The fuel level in the tank (percentage) + * @return {OnVehicleData} + */ + + + setFuelLevel(level) { + this.setParameter(OnVehicleData.KEY_FUEL_LEVEL, level); + return this; + } + /** + * @return {Number} + */ + + + getFuelLevel() { + return this.getParameter(OnVehicleData.KEY_FUEL_LEVEL); + } + /** + * @param {ComponentVolumeStatus} level_state - The fuel level state + * @return {OnVehicleData} + */ + + + setFuelLevel_State(level_state) { + this.validateType(ComponentVolumeStatus, level_state); + this.setParameter(OnVehicleData.KEY_FUEL_LEVEL_STATE, level_state); + return this; + } + /** + * @return {ComponentVolumeStatus} + */ + + + getFuelLevel_State() { + return this.getObject(ComponentVolumeStatus, OnVehicleData.KEY_FUEL_LEVEL_STATE); + } + /** + * @param {Number} consumption - The instantaneous fuel consumption in microlitres + * @return {OnVehicleData} + */ + + + setInstantFuelConsumption(consumption) { + this.setParameter(OnVehicleData.KEY_INSTANT_FUEL_CONSUMPTION, consumption); + return this; + } + /** + * @return {Number} + */ + + + getInstantFuelConsumption() { + return this.getParameter(OnVehicleData.KEY_INSTANT_FUEL_CONSUMPTION); + } + /** + * @param {FuelRange[]} range - The estimate range in KM the vehicle can travel based on fuel level and consumption + * @return {OnVehicleData} + */ + + + setFuelRange(range) { + this.validateType(FuelRange, range, true); + this.setParameter(OnVehicleData.KEY_FUEL_RANGE, range); + return this; + } + /** + * @return {FuelRange[]} + */ + + + getFuelRange() { + return this.getObject(FuelRange, OnVehicleData.KEY_FUEL_RANGE); + } + /** + * @param {Number} temperature - The external temperature in degrees celsius + * @return {OnVehicleData} + */ + + + setExternalTemperature(temperature) { + this.setParameter(OnVehicleData.KEY_EXTERNAL_TEMPERATURE, temperature); + return this; + } + /** + * @return {Number} + */ + + + getExternalTemperature() { + return this.getParameter(OnVehicleData.KEY_EXTERNAL_TEMPERATURE); + } + /** + * @param {TurnSignal} signal - See TurnSignal + * @return {OnVehicleData} + */ + + + setTurnSignal(signal) { + this.validateType(TurnSignal, signal); + this.setParameter(OnVehicleData.KEY_TURN_SIGNAL, signal); + return this; + } + /** + * @return {TurnSignal} + */ + + + getTurnSignal() { + return this.getObject(TurnSignal, OnVehicleData.KEY_TURN_SIGNAL); + } + /** + * @param {String} vin - Vehicle identification number. + * @return {OnVehicleData} + */ + + + setVin(vin) { + this.setParameter(OnVehicleData.KEY_VIN, vin); + return this; + } + /** + * @return {String} + */ + + + getVin() { + return this.getParameter(OnVehicleData.KEY_VIN); + } + /** + * @param {PRNDL} prndl - See PRNDL + * @return {OnVehicleData} + */ + + + setPrndl(prndl) { + this.validateType(PRNDL, prndl); + this.setParameter(OnVehicleData.KEY_PRNDL, prndl); + return this; + } + /** + * @return {PRNDL} + */ + + + getPrndl() { + return this.getObject(PRNDL, OnVehicleData.KEY_PRNDL); + } + /** + * @param {TireStatus} pressure - See TireStatus + * @return {OnVehicleData} + */ + + + setTirePressure(pressure) { + this.validateType(TireStatus, pressure); + this.setParameter(OnVehicleData.KEY_TIRE_PRESSURE, pressure); + return this; + } + /** + * @return {TireStatus} + */ + + + getTirePressure() { + return this.getObject(TireStatus, OnVehicleData.KEY_TIRE_PRESSURE); + } + /** + * @param {Number} odometer - Odometer in km + * @return {OnVehicleData} + */ + + + setOdometer(odometer) { + this.setParameter(OnVehicleData.KEY_ODOMETER, odometer); + return this; + } + /** + * @return {Number} + */ + + + getOdometer() { + return this.getParameter(OnVehicleData.KEY_ODOMETER); + } + /** + * @param {BeltStatus} status - The status of the seat belts + * @return {OnVehicleData} + */ + + + setBeltStatus(status) { + this.validateType(BeltStatus, status); + this.setParameter(OnVehicleData.KEY_BELT_STATUS, status); + return this; + } + /** + * @return {BeltStatus} + */ + + + getBeltStatus() { + return this.getObject(BeltStatus, OnVehicleData.KEY_BELT_STATUS); + } + /** + * @param {BodyInformation} information - The body information including power modes + * @return {OnVehicleData} + */ + + + setBodyInformation(information) { + this.validateType(BodyInformation, information); + this.setParameter(OnVehicleData.KEY_BODY_INFORMATION, information); + return this; + } + /** + * @return {BodyInformation} + */ + + + getBodyInformation() { + return this.getObject(BodyInformation, OnVehicleData.KEY_BODY_INFORMATION); + } + /** + * @param {DeviceStatus} status - The device status including signal and battery strength + * @return {OnVehicleData} + */ + + + setDeviceStatus(status) { + this.validateType(DeviceStatus, status); + this.setParameter(OnVehicleData.KEY_DEVICE_STATUS, status); + return this; + } + /** + * @return {DeviceStatus} + */ + + + getDeviceStatus() { + return this.getObject(DeviceStatus, OnVehicleData.KEY_DEVICE_STATUS); + } + /** + * @param {VehicleDataEventStatus} braking - The status of the brake pedal + * @return {OnVehicleData} + */ + + + setDriverBraking(braking) { + this.validateType(VehicleDataEventStatus, braking); + this.setParameter(OnVehicleData.KEY_DRIVER_BRAKING, braking); + return this; + } + /** + * @return {VehicleDataEventStatus} + */ + + + getDriverBraking() { + return this.getObject(VehicleDataEventStatus, OnVehicleData.KEY_DRIVER_BRAKING); + } + /** + * @param {WiperStatus} status - The status of the wipers + * @return {OnVehicleData} + */ + + + setWiperStatus(status) { + this.validateType(WiperStatus, status); + this.setParameter(OnVehicleData.KEY_WIPER_STATUS, status); + return this; + } + /** + * @return {WiperStatus} + */ + + + getWiperStatus() { + return this.getObject(WiperStatus, OnVehicleData.KEY_WIPER_STATUS); + } + /** + * @param {HeadLampStatus} status - Status of the head lamps + * @return {OnVehicleData} + */ + + + setHeadLampStatus(status) { + this.validateType(HeadLampStatus, status); + this.setParameter(OnVehicleData.KEY_HEAD_LAMP_STATUS, status); + return this; + } + /** + * @return {HeadLampStatus} + */ + + + getHeadLampStatus() { + return this.getObject(HeadLampStatus, OnVehicleData.KEY_HEAD_LAMP_STATUS); + } + /** + * @param {Number} torque - Torque value for engine (in Nm) on non-diesel variants + * @return {OnVehicleData} + */ + + + setEngineTorque(torque) { + this.setParameter(OnVehicleData.KEY_ENGINE_TORQUE, torque); + return this; + } + /** + * @return {Number} + */ + + + getEngineTorque() { + return this.getParameter(OnVehicleData.KEY_ENGINE_TORQUE); + } + /** + * @param {Number} position - Accelerator pedal position (percentage depressed) + * @return {OnVehicleData} + */ + + + setAccPedalPosition(position) { + this.setParameter(OnVehicleData.KEY_ACC_PEDAL_POSITION, position); + return this; + } + /** + * @return {Number} + */ + + + getAccPedalPosition() { + return this.getParameter(OnVehicleData.KEY_ACC_PEDAL_POSITION); + } + /** + * @param {Number} angle - Current angle of the steering wheel (in deg) + * @return {OnVehicleData} + */ + + + setSteeringWheelAngle(angle) { + this.setParameter(OnVehicleData.KEY_STEERING_WHEEL_ANGLE, angle); + return this; + } + /** + * @return {Number} + */ + + + getSteeringWheelAngle() { + return this.getParameter(OnVehicleData.KEY_STEERING_WHEEL_ANGLE); + } + /** + * @param {Number} life - The estimated percentage of remaining oil life of the engine. + * @return {OnVehicleData} + */ + + + setEngineOilLife(life) { + this.setParameter(OnVehicleData.KEY_ENGINE_OIL_LIFE, life); + return this; + } + /** + * @return {Number} + */ + + + getEngineOilLife() { + return this.getParameter(OnVehicleData.KEY_ENGINE_OIL_LIFE); + } + /** + * @param {ElectronicParkBrakeStatus} status - The status of the park brake as provided by Electric Park Brake (EPB) + * system. + * @return {OnVehicleData} + */ + + + setElectronicParkBrakeStatus(status) { + this.validateType(ElectronicParkBrakeStatus, status); + this.setParameter(OnVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS, status); + return this; + } + /** + * @return {ElectronicParkBrakeStatus} + */ + + + getElectronicParkBrakeStatus() { + return this.getObject(ElectronicParkBrakeStatus, OnVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS); + } + /** + * @param {String} id - Parameter used by cloud apps to identify a head unit + * @return {OnVehicleData} + */ + + + setCloudAppVehicleID(id) { + this.setParameter(OnVehicleData.KEY_CLOUD_APP_VEHICLE_ID, id); + return this; + } + /** + * @return {String} + */ + + + getCloudAppVehicleID() { + return this.getParameter(OnVehicleData.KEY_CLOUD_APP_VEHICLE_ID); + } + /** + * @param {ECallInfo} info - Emergency Call notification and confirmation data + * @return {OnVehicleData} + */ + + + setECallInfo(info) { + this.validateType(ECallInfo, info); + this.setParameter(OnVehicleData.KEY_E_CALL_INFO, info); + return this; + } + /** + * @return {ECallInfo} + */ + + + getECallInfo() { + return this.getObject(ECallInfo, OnVehicleData.KEY_E_CALL_INFO); + } + /** + * @param {AirbagStatus} status - The status of the air bags + * @return {OnVehicleData} + */ + + + setAirbagStatus(status) { + this.validateType(AirbagStatus, status); + this.setParameter(OnVehicleData.KEY_AIRBAG_STATUS, status); + return this; + } + /** + * @return {AirbagStatus} + */ + + + getAirbagStatus() { + return this.getObject(AirbagStatus, OnVehicleData.KEY_AIRBAG_STATUS); + } + /** + * @param {EmergencyEvent} event - Information related to an emergency event (and if it occurred) + * @return {OnVehicleData} + */ + + + setEmergencyEvent(event) { + this.validateType(EmergencyEvent, event); + this.setParameter(OnVehicleData.KEY_EMERGENCY_EVENT, event); + return this; + } + /** + * @return {EmergencyEvent} + */ + + + getEmergencyEvent() { + return this.getObject(EmergencyEvent, OnVehicleData.KEY_EMERGENCY_EVENT); + } + /** + * @param {ClusterModeStatus} status - The status modes of the cluster + * @return {OnVehicleData} + */ + + + setClusterModeStatus(status) { + this.validateType(ClusterModeStatus, status); + this.setParameter(OnVehicleData.KEY_CLUSTER_MODE_STATUS, status); + return this; + } + /** + * @return {ClusterModeStatus} + */ + + + getClusterModeStatus() { + return this.getObject(ClusterModeStatus, OnVehicleData.KEY_CLUSTER_MODE_STATUS); + } + /** + * @param {MyKey} key - Information related to the MyKey feature + * @return {OnVehicleData} + */ + + + setMyKey(key) { + this.validateType(MyKey, key); + this.setParameter(OnVehicleData.KEY_MY_KEY, key); + return this; + } + /** + * @return {MyKey} + */ + + + getMyKey() { + return this.getObject(MyKey, OnVehicleData.KEY_MY_KEY); + } + + } + + OnVehicleData.KEY_GPS = 'gps'; + OnVehicleData.KEY_SPEED = 'speed'; + OnVehicleData.KEY_RPM = 'rpm'; + OnVehicleData.KEY_FUEL_LEVEL = 'fuelLevel'; + OnVehicleData.KEY_FUEL_LEVEL_STATE = 'fuelLevel_State'; + OnVehicleData.KEY_INSTANT_FUEL_CONSUMPTION = 'instantFuelConsumption'; + OnVehicleData.KEY_FUEL_RANGE = 'fuelRange'; + OnVehicleData.KEY_EXTERNAL_TEMPERATURE = 'externalTemperature'; + OnVehicleData.KEY_TURN_SIGNAL = 'turnSignal'; + OnVehicleData.KEY_VIN = 'vin'; + OnVehicleData.KEY_PRNDL = 'prndl'; + OnVehicleData.KEY_TIRE_PRESSURE = 'tirePressure'; + OnVehicleData.KEY_ODOMETER = 'odometer'; + OnVehicleData.KEY_BELT_STATUS = 'beltStatus'; + OnVehicleData.KEY_BODY_INFORMATION = 'bodyInformation'; + OnVehicleData.KEY_DEVICE_STATUS = 'deviceStatus'; + OnVehicleData.KEY_DRIVER_BRAKING = 'driverBraking'; + OnVehicleData.KEY_WIPER_STATUS = 'wiperStatus'; + OnVehicleData.KEY_HEAD_LAMP_STATUS = 'headLampStatus'; + OnVehicleData.KEY_ENGINE_TORQUE = 'engineTorque'; + OnVehicleData.KEY_ACC_PEDAL_POSITION = 'accPedalPosition'; + OnVehicleData.KEY_STEERING_WHEEL_ANGLE = 'steeringWheelAngle'; + OnVehicleData.KEY_ENGINE_OIL_LIFE = 'engineOilLife'; + OnVehicleData.KEY_ELECTRONIC_PARK_BRAKE_STATUS = 'electronicParkBrakeStatus'; + OnVehicleData.KEY_CLOUD_APP_VEHICLE_ID = 'cloudAppVehicleID'; + OnVehicleData.KEY_E_CALL_INFO = 'eCallInfo'; + OnVehicleData.KEY_AIRBAG_STATUS = 'airbagStatus'; + OnVehicleData.KEY_EMERGENCY_EVENT = 'emergencyEvent'; + OnVehicleData.KEY_CLUSTER_MODE_STATUS = 'clusterModeStatus'; + OnVehicleData.KEY_MY_KEY = 'myKey'; + + /* eslint-disable camelcase */ + + class OnCommand extends RpcNotification { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnCommand); + } + /** + * @param {Number} id - Command ID, which is related to a specific menu entry + * @return {OnCommand} + */ + + + setCmdID(id) { + this.setParameter(OnCommand.KEY_CMD_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getCmdID() { + return this.getParameter(OnCommand.KEY_CMD_ID); + } + /** + * @param {TriggerSource} source - See TriggerSource + * @return {OnCommand} + */ + + + setTriggerSource(source) { + this.validateType(TriggerSource, source); + this.setParameter(OnCommand.KEY_TRIGGER_SOURCE, source); + return this; + } + /** + * @return {TriggerSource} + */ + + + getTriggerSource() { + return this.getObject(TriggerSource, OnCommand.KEY_TRIGGER_SOURCE); + } + + } + + OnCommand.KEY_CMD_ID = 'cmdID'; + OnCommand.KEY_TRIGGER_SOURCE = 'triggerSource'; + + /* eslint-disable camelcase */ + /** + * Enumeration that describes possible states of turn-by-turn client or SmartDeviceLink app. + * @typedef {Enum} TBTState + * @property {Object} _MAP + */ + + class TBTState extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get ROUTE_UPDATE_REQUEST() { + return TBTState._MAP.ROUTE_UPDATE_REQUEST; + } + /** + * @return {String} + */ + + + static get ROUTE_ACCEPTED() { + return TBTState._MAP.ROUTE_ACCEPTED; + } + /** + * @return {String} + */ + + + static get ROUTE_REFUSED() { + return TBTState._MAP.ROUTE_REFUSED; + } + /** + * @return {String} + */ + + + static get ROUTE_CANCELLED() { + return TBTState._MAP.ROUTE_CANCELLED; + } + /** + * @return {String} + */ + + + static get ETA_REQUEST() { + return TBTState._MAP.ETA_REQUEST; + } + /** + * @return {String} + */ + + + static get NEXT_TURN_REQUEST() { + return TBTState._MAP.NEXT_TURN_REQUEST; + } + /** + * @return {String} + */ + + + static get ROUTE_STATUS_REQUEST() { + return TBTState._MAP.ROUTE_STATUS_REQUEST; + } + /** + * @return {String} + */ + + + static get ROUTE_SUMMARY_REQUEST() { + return TBTState._MAP.ROUTE_SUMMARY_REQUEST; + } + /** + * @return {String} + */ + + + static get TRIP_STATUS_REQUEST() { + return TBTState._MAP.TRIP_STATUS_REQUEST; + } + /** + * @return {String} + */ + + + static get ROUTE_UPDATE_REQUEST_TIMEOUT() { + return TBTState._MAP.ROUTE_UPDATE_REQUEST_TIMEOUT; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return TBTState._valueForKey(key, TBTState._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return TBTState._keyForValue(value, TBTState._MAP); + } + + } + + TBTState._MAP = Object.freeze({ + 'ROUTE_UPDATE_REQUEST': 'ROUTE_UPDATE_REQUEST', + 'ROUTE_ACCEPTED': 'ROUTE_ACCEPTED', + 'ROUTE_REFUSED': 'ROUTE_REFUSED', + 'ROUTE_CANCELLED': 'ROUTE_CANCELLED', + 'ETA_REQUEST': 'ETA_REQUEST', + 'NEXT_TURN_REQUEST': 'NEXT_TURN_REQUEST', + 'ROUTE_STATUS_REQUEST': 'ROUTE_STATUS_REQUEST', + 'ROUTE_SUMMARY_REQUEST': 'ROUTE_SUMMARY_REQUEST', + 'TRIP_STATUS_REQUEST': 'TRIP_STATUS_REQUEST', + 'ROUTE_UPDATE_REQUEST_TIMEOUT': 'ROUTE_UPDATE_REQUEST_TIMEOUT' + }); + + /* eslint-disable camelcase */ + /** + * Provides applications with notifications specific to the current TBT client status on the module + */ + + class OnTBTClientState extends RpcNotification { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnTBTClientState); + } + /** + * @param {TBTState} state - Current State of TBT client + * @return {OnTBTClientState} + */ + + + setState(state) { + this.validateType(TBTState, state); + this.setParameter(OnTBTClientState.KEY_STATE, state); + return this; + } + /** + * @return {TBTState} + */ + + + getState() { + return this.getObject(TBTState, OnTBTClientState.KEY_STATE); + } + + } + + OnTBTClientState.KEY_STATE = 'state'; + + /* eslint-disable camelcase */ + /** + * Enumeration that describes possible states of driver distraction. + * @typedef {Enum} DriverDistractionState + * @property {Object} _MAP + */ + + class DriverDistractionState extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get DD_ON() { + return DriverDistractionState._MAP.DD_ON; + } + /** + * @return {String} + */ + + + static get DD_OFF() { + return DriverDistractionState._MAP.DD_OFF; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return DriverDistractionState._valueForKey(key, DriverDistractionState._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return DriverDistractionState._keyForValue(value, DriverDistractionState._MAP); + } + + } + + DriverDistractionState._MAP = Object.freeze({ + 'DD_ON': 'DD_ON', + 'DD_OFF': 'DD_OFF' + }); + + /* eslint-disable camelcase */ + /** + * Provides driver distraction state to mobile applications + */ + + class OnDriverDistraction extends RpcNotification { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnDriverDistraction); + } + /** + * @param {DriverDistractionState} state - Current State of Driver Distraction + * @return {OnDriverDistraction} + */ + + + setState(state) { + this.validateType(DriverDistractionState, state); + this.setParameter(OnDriverDistraction.KEY_STATE, state); + return this; + } + /** + * @return {DriverDistractionState} + */ + + + getState() { + return this.getObject(DriverDistractionState, OnDriverDistraction.KEY_STATE); + } + /** + * @param {Boolean} enabled - If enabled, the lock screen will be able to be dismissed while connected to SDL, + * allowing users the ability to interact with the app. Dismissals should include a + * warning to the user and ensure that they are not the driver. + * @return {OnDriverDistraction} + */ + + + setLockScreenDismissalEnabled(enabled) { + this.setParameter(OnDriverDistraction.KEY_LOCK_SCREEN_DISMISSAL_ENABLED, enabled); + return this; + } + /** + * @return {Boolean} + */ + + + getLockScreenDismissalEnabled() { + return this.getParameter(OnDriverDistraction.KEY_LOCK_SCREEN_DISMISSAL_ENABLED); + } + /** + * @param {String} warning - Warning message to be displayed on the lock screen when dismissal is enabled. This + * warning should be used to ensure that the user is not the driver of the vehicle, ex. + * `Swipe down to dismiss, acknowledging that you are not the driver.`. This parameter + * must be present if "lockScreenDismissalEnabled" is set to true. + * @return {OnDriverDistraction} + */ + + + setLockScreenDismissalWarning(warning) { + this.setParameter(OnDriverDistraction.KEY_LOCK_SCREEN_DISMISSAL_WARNING, warning); + return this; + } + /** + * @return {String} + */ + + + getLockScreenDismissalWarning() { + return this.getParameter(OnDriverDistraction.KEY_LOCK_SCREEN_DISMISSAL_WARNING); + } + + } + + OnDriverDistraction.KEY_STATE = 'state'; + OnDriverDistraction.KEY_LOCK_SCREEN_DISMISSAL_ENABLED = 'lockScreenDismissalEnabled'; + OnDriverDistraction.KEY_LOCK_SCREEN_DISMISSAL_WARNING = 'lockScreenDismissalWarning'; + + /* eslint-disable camelcase */ + + class HMIPermissions extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {HMILevel[]} allowed - A set of all HMI levels that are permitted for this given RPC. + * @return {HMIPermissions} + */ + + + setAllowed(allowed) { + this.validateType(HMILevel, allowed, true); + this.setParameter(HMIPermissions.KEY_ALLOWED, allowed); + return this; + } + /** + * @return {HMILevel[]} + */ + + + getAllowed() { + return this.getObject(HMILevel, HMIPermissions.KEY_ALLOWED); + } + /** + * @param {HMILevel[]} disallowed - A set of all HMI levels that are prohibited for this given RPC. + * @return {HMIPermissions} + */ + + + setUserDisallowed(disallowed) { + this.validateType(HMILevel, disallowed, true); + this.setParameter(HMIPermissions.KEY_USER_DISALLOWED, disallowed); + return this; + } + /** + * @return {HMILevel[]} + */ + + + getUserDisallowed() { + return this.getObject(HMILevel, HMIPermissions.KEY_USER_DISALLOWED); + } + + } + + HMIPermissions.KEY_ALLOWED = 'allowed'; + HMIPermissions.KEY_USER_DISALLOWED = 'userDisallowed'; + + /* eslint-disable camelcase */ + + class ParameterPermissions extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {String[]} allowed - A set of all parameters that are permitted for this given RPC. + * @return {ParameterPermissions} + */ + + + setAllowed(allowed) { + this.setParameter(ParameterPermissions.KEY_ALLOWED, allowed); + return this; + } + /** + * @return {String[]} + */ + + + getAllowed() { + return this.getParameter(ParameterPermissions.KEY_ALLOWED); + } + /** + * @param {String[]} disallowed - A set of all parameters that are prohibited for this given RPC. + * @return {ParameterPermissions} + */ + + + setUserDisallowed(disallowed) { + this.setParameter(ParameterPermissions.KEY_USER_DISALLOWED, disallowed); + return this; + } + /** + * @return {String[]} + */ + + + getUserDisallowed() { + return this.getParameter(ParameterPermissions.KEY_USER_DISALLOWED); + } + + } + + ParameterPermissions.KEY_ALLOWED = 'allowed'; + ParameterPermissions.KEY_USER_DISALLOWED = 'userDisallowed'; + + /* eslint-disable camelcase */ + + class PermissionItem extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {String} name - Name of the individual RPC in the policy table. + * @return {PermissionItem} + */ + + + setRpcName(name) { + this.setParameter(PermissionItem.KEY_RPC_NAME, name); + return this; + } + /** + * @return {String} + */ + + + getRpcName() { + return this.getParameter(PermissionItem.KEY_RPC_NAME); + } + /** + * @param {HMIPermissions} permissions + * @return {PermissionItem} + */ + + + setHmiPermissions(permissions) { + this.validateType(HMIPermissions, permissions); + this.setParameter(PermissionItem.KEY_HMI_PERMISSIONS, permissions); + return this; + } + /** + * @return {HMIPermissions} + */ + + + getHmiPermissions() { + return this.getObject(HMIPermissions, PermissionItem.KEY_HMI_PERMISSIONS); + } + /** + * @param {ParameterPermissions} permissions + * @return {PermissionItem} + */ + + + setParameterPermissions(permissions) { + this.validateType(ParameterPermissions, permissions); + this.setParameter(PermissionItem.KEY_PARAMETER_PERMISSIONS, permissions); + return this; + } + /** + * @return {ParameterPermissions} + */ + + + getParameterPermissions() { + return this.getObject(ParameterPermissions, PermissionItem.KEY_PARAMETER_PERMISSIONS); + } + /** + * @param {Boolean} encryption + * @return {PermissionItem} + */ + + + setRequireEncryption(encryption) { + this.setParameter(PermissionItem.KEY_REQUIRE_ENCRYPTION, encryption); + return this; + } + /** + * @return {Boolean} + */ + + + getRequireEncryption() { + return this.getParameter(PermissionItem.KEY_REQUIRE_ENCRYPTION); + } + + } + + PermissionItem.KEY_RPC_NAME = 'rpcName'; + PermissionItem.KEY_HMI_PERMISSIONS = 'hmiPermissions'; + PermissionItem.KEY_PARAMETER_PERMISSIONS = 'parameterPermissions'; + PermissionItem.KEY_REQUIRE_ENCRYPTION = 'requireEncryption'; + + /* eslint-disable camelcase */ + /** + * Provides update to app of which policy-table-enabled functions are available + */ + + class OnPermissionsChange extends RpcNotification { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnPermissionsChange); + } + /** + * @param {PermissionItem[]} item - Change in permissions for a given set of RPCs + * @return {OnPermissionsChange} + */ + + + setPermissionItem(item) { + this.validateType(PermissionItem, item, true); + this.setParameter(OnPermissionsChange.KEY_PERMISSION_ITEM, item); + return this; + } + /** + * @return {PermissionItem[]} + */ + + + getPermissionItem() { + return this.getObject(PermissionItem, OnPermissionsChange.KEY_PERMISSION_ITEM); + } + /** + * @param {Boolean} encryption + * @return {OnPermissionsChange} + */ + + + setRequireEncryption(encryption) { + this.setParameter(OnPermissionsChange.KEY_REQUIRE_ENCRYPTION, encryption); + return this; + } + /** + * @return {Boolean} + */ + + + getRequireEncryption() { + return this.getParameter(OnPermissionsChange.KEY_REQUIRE_ENCRYPTION); + } + + } + + OnPermissionsChange.KEY_PERMISSION_ITEM = 'permissionItem'; + OnPermissionsChange.KEY_REQUIRE_ENCRYPTION = 'requireEncryption'; + + /* eslint-disable camelcase */ + /** + * Binary data is in binary part of hybrid msg + */ + + class OnAudioPassThru extends RpcNotification { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnAudioPassThru); + } + + } + + /* eslint-disable camelcase */ + + class OnLanguageChange extends RpcNotification { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnLanguageChange); + } + /** + * @param {Language} language - Current SDL voice engine (VR+TTS) language + * @return {OnLanguageChange} + */ + + + setLanguage(language) { + this.validateType(Language, language); + this.setParameter(OnLanguageChange.KEY_LANGUAGE, language); + return this; + } + /** + * @return {Language} + */ + + + getLanguage() { + return this.getObject(Language, OnLanguageChange.KEY_LANGUAGE); + } + /** + * @param {Language} language - Current display language + * @return {OnLanguageChange} + */ + + + setHmiDisplayLanguage(language) { + this.validateType(Language, language); + this.setParameter(OnLanguageChange.KEY_HMI_DISPLAY_LANGUAGE, language); + return this; + } + /** + * @return {Language} + */ + + + getHmiDisplayLanguage() { + return this.getObject(Language, OnLanguageChange.KEY_HMI_DISPLAY_LANGUAGE); + } + + } + + OnLanguageChange.KEY_LANGUAGE = 'language'; + OnLanguageChange.KEY_HMI_DISPLAY_LANGUAGE = 'hmiDisplayLanguage'; + + /* eslint-disable camelcase */ + /** + * Enumeration listing possible keyboard events. + * @typedef {Enum} KeyboardEvent + * @property {Object} _MAP + */ + + class KeyboardEvent extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get KEYPRESS() { + return KeyboardEvent._MAP.KEYPRESS; + } + /** + * @return {String} + */ + + + static get ENTRY_SUBMITTED() { + return KeyboardEvent._MAP.ENTRY_SUBMITTED; + } + /** + * @return {String} + */ + + + static get ENTRY_VOICE() { + return KeyboardEvent._MAP.ENTRY_VOICE; + } + /** + * @return {String} + */ + + + static get ENTRY_CANCELLED() { + return KeyboardEvent._MAP.ENTRY_CANCELLED; + } + /** + * @return {String} + */ + + + static get ENTRY_ABORTED() { + return KeyboardEvent._MAP.ENTRY_ABORTED; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return KeyboardEvent._valueForKey(key, KeyboardEvent._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return KeyboardEvent._keyForValue(value, KeyboardEvent._MAP); + } + + } + + KeyboardEvent._MAP = Object.freeze({ + 'KEYPRESS': 'KEYPRESS', + 'ENTRY_SUBMITTED': 'ENTRY_SUBMITTED', + 'ENTRY_VOICE': 'ENTRY_VOICE', + 'ENTRY_CANCELLED': 'ENTRY_CANCELLED', + 'ENTRY_ABORTED': 'ENTRY_ABORTED' + }); + + /* eslint-disable camelcase */ + /** + * On-screen keyboard event. Can be full string or individual keypresses depending on keyboard mode. + */ + + class OnKeyboardInput extends RpcNotification { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnKeyboardInput); + } + /** + * @param {KeyboardEvent} event - On-screen keyboard input data. + * @return {OnKeyboardInput} + */ + + + setEvent(event) { + this.validateType(KeyboardEvent, event); + this.setParameter(OnKeyboardInput.KEY_EVENT, event); + return this; + } + /** + * @return {KeyboardEvent} + */ + + + getEvent() { + return this.getObject(KeyboardEvent, OnKeyboardInput.KEY_EVENT); + } + /** + * @param {String} data - On-screen keyboard input data. For dynamic keypress events, this will be the current + * compounded string of entry text. For entry submission events, this will be the full text + * entry (this will always return regardless of the mode). For entry cancelled and entry + * aborted events, this data param will be omitted. + * @return {OnKeyboardInput} + */ + + + setData(data) { + this.setParameter(OnKeyboardInput.KEY_DATA, data); + return this; + } + /** + * @return {String} + */ + + + getData() { + return this.getParameter(OnKeyboardInput.KEY_DATA); + } + + } + + OnKeyboardInput.KEY_EVENT = 'event'; + OnKeyboardInput.KEY_DATA = 'data'; + + /* eslint-disable camelcase */ + + class TouchCoord extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Number} x - The x coordinate of the touch. + * @return {TouchCoord} + */ + + + setX(x) { + this.setParameter(TouchCoord.KEY_X, x); + return this; + } + /** + * @return {Number} + */ + + + getX() { + return this.getParameter(TouchCoord.KEY_X); + } + /** + * @param {Number} y - The y coordinate of the touch. + * @return {TouchCoord} + */ + + + setY(y) { + this.setParameter(TouchCoord.KEY_Y, y); + return this; + } + /** + * @return {Number} + */ + + + getY() { + return this.getParameter(TouchCoord.KEY_Y); + } + + } + + TouchCoord.KEY_X = 'x'; + TouchCoord.KEY_Y = 'y'; + + /* eslint-disable camelcase */ + + class TouchEvent extends RpcStruct { + /** + * @constructor + */ + constructor(parameters) { + super(parameters); + } + /** + * @param {Number} id - A touch's unique identifier. The application can track the current touch events by id. If a + * touch event has type begin, the id should be added to the set of touches. If a touch event + * has type end, the id should be removed from the set of touches. + * @return {TouchEvent} + */ + + + setId(id) { + this.setParameter(TouchEvent.KEY_ID, id); + return this; + } + /** + * @return {Number} + */ + + + getId() { + return this.getParameter(TouchEvent.KEY_ID); + } + /** + * @param {Number[]} ts - The time that the touch was recorded. This number can the time since the beginning of the + * session or something else as long as the units are in milliseconds. The timestamp is used + * to determined the rate of change of position of a touch. The application also uses the + * time to verify whether two touches, with different ids, are part of a single action by the + * user. If there is only a single timestamp in this array, it is the same for every + * coordinate in the coordinates array. + * @return {TouchEvent} + */ + + + setTs(ts) { + this.setParameter(TouchEvent.KEY_TS, ts); + return this; + } + /** + * @return {Number[]} + */ + + + getTs() { + return this.getParameter(TouchEvent.KEY_TS); + } + /** + * @param {TouchCoord[]} c + * @return {TouchEvent} + */ + + + setC(c) { + this.validateType(TouchCoord, c, true); + this.setParameter(TouchEvent.KEY_C, c); + return this; + } + /** + * @return {TouchCoord[]} + */ + + + getC() { + return this.getObject(TouchCoord, TouchEvent.KEY_C); + } + + } + + TouchEvent.KEY_ID = 'id'; + TouchEvent.KEY_TS = 'ts'; + TouchEvent.KEY_C = 'c'; + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} TouchType + * @property {Object} _MAP + */ + + class TouchType extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get BEGIN() { + return TouchType._MAP.BEGIN; + } + /** + * @return {String} + */ + + + static get MOVE() { + return TouchType._MAP.MOVE; + } + /** + * @return {String} + */ + + + static get END() { + return TouchType._MAP.END; + } + /** + * @return {String} + */ + + + static get CANCEL() { + return TouchType._MAP.CANCEL; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return TouchType._valueForKey(key, TouchType._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return TouchType._keyForValue(value, TouchType._MAP); + } + + } + + TouchType._MAP = Object.freeze({ + 'BEGIN': 'BEGIN', + 'MOVE': 'MOVE', + 'END': 'END', + 'CANCEL': 'CANCEL' + }); + + /* eslint-disable camelcase */ + /** + * Notifies about touch events on the screen's prescribed area + */ + + class OnTouchEvent extends RpcNotification { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnTouchEvent); + } + /** + * @param {TouchType} type - The type of touch event. + * @return {OnTouchEvent} + */ + + + setType(type) { + this.validateType(TouchType, type); + this.setParameter(OnTouchEvent.KEY_TYPE, type); + return this; + } + /** + * @return {TouchType} + */ + + + getType() { + return this.getObject(TouchType, OnTouchEvent.KEY_TYPE); + } + /** + * @param {TouchEvent[]} event - List of all individual touches involved in this event. + * @return {OnTouchEvent} + */ + + + setEvent(event) { + this.validateType(TouchEvent, event, true); + this.setParameter(OnTouchEvent.KEY_EVENT, event); + return this; + } + /** + * @return {TouchEvent[]} + */ + + + getEvent() { + return this.getObject(TouchEvent, OnTouchEvent.KEY_EVENT); + } + + } + + OnTouchEvent.KEY_TYPE = 'type'; + OnTouchEvent.KEY_EVENT = 'event'; + + /* eslint-disable camelcase */ + /** + * An asynchronous request from the system for specific data from the device or the cloud or response to a request from + * the device or cloud Binary data can be included in hybrid part of message for some requests (such as Authentication + * request responses) + */ + + class OnSystemRequest extends RpcNotification { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnSystemRequest); + } + /** + * @param {RequestType} type - The type of system request. + * @return {OnSystemRequest} + */ + + + setRequestType(type) { + this.validateType(RequestType, type); + this.setParameter(OnSystemRequest.KEY_REQUEST_TYPE, type); + return this; + } + /** + * @return {RequestType} + */ + + + getRequestType() { + return this.getObject(RequestType, OnSystemRequest.KEY_REQUEST_TYPE); + } + /** + * @param {String} type - This parameter is filled for supporting OEM proprietary data exchanges. + * @return {OnSystemRequest} + */ + + + setRequestSubType(type) { + this.setParameter(OnSystemRequest.KEY_REQUEST_SUB_TYPE, type); + return this; + } + /** + * @return {String} + */ + + + getRequestSubType() { + return this.getParameter(OnSystemRequest.KEY_REQUEST_SUB_TYPE); + } + /** + * @param {String} url - Optional URL for HTTP requests. If blank, the binary data shall be forwarded to the app. If + * not blank, the binary data shall be forwarded to the url with a provided timeout in + * seconds. + * @return {OnSystemRequest} + */ + + + setUrl(url) { + this.setParameter(OnSystemRequest.KEY_URL, url); + return this; + } + /** + * @return {String} + */ + + + getUrl() { + return this.getParameter(OnSystemRequest.KEY_URL); + } + /** + * @param {Number} timeout - Optional timeout for HTTP requests Required if a URL is provided + * @return {OnSystemRequest} + */ + + + setTimeout(timeout) { + this.setParameter(OnSystemRequest.KEY_TIMEOUT, timeout); + return this; + } + /** + * @return {Number} + */ + + + getTimeout() { + return this.getParameter(OnSystemRequest.KEY_TIMEOUT); + } + /** + * @param {FileType} type - Optional file type (meant for HTTP file requests). + * @return {OnSystemRequest} + */ + + + setFileType(type) { + this.validateType(FileType, type); + this.setParameter(OnSystemRequest.KEY_FILE_TYPE, type); + return this; + } + /** + * @return {FileType} + */ + + + getFileType() { + return this.getObject(FileType, OnSystemRequest.KEY_FILE_TYPE); + } + /** + * @param {Number} offset - Optional offset in bytes for resuming partial data chunks + * @return {OnSystemRequest} + */ + + + setOffset(offset) { + this.setParameter(OnSystemRequest.KEY_OFFSET, offset); + return this; + } + /** + * @return {Number} + */ + + + getOffset() { + return this.getParameter(OnSystemRequest.KEY_OFFSET); + } + /** + * @param {Number} length - Optional length in bytes for resuming partial data chunks + * @return {OnSystemRequest} + */ + + + setLength(length) { + this.setParameter(OnSystemRequest.KEY_LENGTH, length); + return this; + } + /** + * @return {Number} + */ + + + getLength() { + return this.getParameter(OnSystemRequest.KEY_LENGTH); + } + + } + + OnSystemRequest.KEY_REQUEST_TYPE = 'requestType'; + OnSystemRequest.KEY_REQUEST_SUB_TYPE = 'requestSubType'; + OnSystemRequest.KEY_URL = 'url'; + OnSystemRequest.KEY_TIMEOUT = 'timeout'; + OnSystemRequest.KEY_FILE_TYPE = 'fileType'; + OnSystemRequest.KEY_OFFSET = 'offset'; + OnSystemRequest.KEY_LENGTH = 'length'; + + /* eslint-disable camelcase */ + /** + * Notification containing an updated hashID which can be used over connection cycles (i.e. loss of connection, + * ignition cycles, etc.). Sent after initial registration and subsequently after any change in the calculated hash of + * all persisted app data. + */ + + class OnHashChange extends RpcNotification { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnHashChange); + } + /** + * @param {String} id - Calculated hash ID to be referenced during RegisterAppInterface. + * @return {OnHashChange} + */ + + + setHashID(id) { + this.setParameter(OnHashChange.KEY_HASH_ID, id); + return this; + } + /** + * @return {String} + */ + + + getHashID() { + return this.getParameter(OnHashChange.KEY_HASH_ID); + } + + } + + OnHashChange.KEY_HASH_ID = 'hashID'; + + /* eslint-disable camelcase */ + /** + * Notification which provides the entire LocationDetails when there is a change to any waypoints or destination. + */ + + class OnWayPointChange extends RpcNotification { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnWayPointChange); + } + /** + * @param {LocationDetails[]} points - See LocationDetails + * @return {OnWayPointChange} + */ + + + setWayPoints(points) { + this.validateType(LocationDetails, points, true); + this.setParameter(OnWayPointChange.KEY_WAY_POINTS, points); + return this; + } + /** + * @return {LocationDetails[]} + */ + + + getWayPoints() { + return this.getObject(LocationDetails, OnWayPointChange.KEY_WAY_POINTS); + } + + } + + OnWayPointChange.KEY_WAY_POINTS = 'wayPoints'; + + /* eslint-disable camelcase */ + + class OnInteriorVehicleData extends RpcNotification { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnInteriorVehicleData); + } + /** + * @param {ModuleData} data - The moduleType indicates which type of data should be changed and identifies which + * data object exists in this struct. For example, if the moduleType is CLIMATE then a + * "climateControlData" should exist + * @return {OnInteriorVehicleData} + */ + + + setModuleData(data) { + this.validateType(ModuleData, data); + this.setParameter(OnInteriorVehicleData.KEY_MODULE_DATA, data); + return this; + } + /** + * @return {ModuleData} + */ + + + getModuleData() { + return this.getObject(ModuleData, OnInteriorVehicleData.KEY_MODULE_DATA); + } + + } + + OnInteriorVehicleData.KEY_MODULE_DATA = 'moduleData'; + + /* eslint-disable camelcase */ + /** + * Issued by SDL to notify the application about remote control status change on SDL + */ + + class OnRCStatus extends RpcNotification { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnRCStatus); + } + /** + * @param {Boolean} allowed - If "true" - RC is allowed; if "false" - RC is disallowed. + * @return {OnRCStatus} + */ + + + setAllowed(allowed) { + this.setParameter(OnRCStatus.KEY_ALLOWED, allowed); + return this; + } + /** + * @return {Boolean} + */ + + + getAllowed() { + return this.getParameter(OnRCStatus.KEY_ALLOWED); + } + /** + * @param {ModuleData[]} modules - Contains a list (zero or more) of module types that are allocated to the + * application. + * @return {OnRCStatus} + */ + + + setAllocatedModules(modules) { + this.validateType(ModuleData, modules, true); + this.setParameter(OnRCStatus.KEY_ALLOCATED_MODULES, modules); + return this; + } + /** + * @return {ModuleData[]} + */ + + + getAllocatedModules() { + return this.getObject(ModuleData, OnRCStatus.KEY_ALLOCATED_MODULES); + } + /** + * @param {ModuleData[]} modules - Contains a list (zero or more) of module types that are free to access for the + * application. + * @return {OnRCStatus} + */ + + + setFreeModules(modules) { + this.validateType(ModuleData, modules, true); + this.setParameter(OnRCStatus.KEY_FREE_MODULES, modules); + return this; + } + /** + * @return {ModuleData[]} + */ + + + getFreeModules() { + return this.getObject(ModuleData, OnRCStatus.KEY_FREE_MODULES); + } + + } + + OnRCStatus.KEY_ALLOWED = 'allowed'; + OnRCStatus.KEY_ALLOCATED_MODULES = 'allocatedModules'; + OnRCStatus.KEY_FREE_MODULES = 'freeModules'; + + /* eslint-disable camelcase */ + /** + * This notification includes the data that is updated from the specific service + */ + + class OnAppServiceData extends RpcNotification { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnAppServiceData); + } + /** + * @param {AppServiceData} data - Contains all the current data of the app service. The serviceType will link to + * which of the service data objects are included in this object (e.g. if the service + * type is MEDIA, the mediaServiceData param should be included). + * @return {OnAppServiceData} + */ + + + setServiceData(data) { + this.validateType(AppServiceData, data); + this.setParameter(OnAppServiceData.KEY_SERVICE_DATA, data); + return this; + } + /** + * @return {AppServiceData} + */ + + + getServiceData() { + return this.getObject(AppServiceData, OnAppServiceData.KEY_SERVICE_DATA); + } + + } + + OnAppServiceData.KEY_SERVICE_DATA = 'serviceData'; + + /* eslint-disable camelcase */ + /** + * A notification to inform the connected device that a specific system capability has changed. + */ + + class OnSystemCapabilityUpdated extends RpcNotification { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnSystemCapabilityUpdated); + } + /** + * @param {SystemCapability} capability - The system capability that has been updated + * @return {OnSystemCapabilityUpdated} + */ + + + setSystemCapability(capability) { + this.validateType(SystemCapability, capability); + this.setParameter(OnSystemCapabilityUpdated.KEY_SYSTEM_CAPABILITY, capability); + return this; + } + /** + * @return {SystemCapability} + */ + + + getSystemCapability() { + return this.getObject(SystemCapability, OnSystemCapabilityUpdated.KEY_SYSTEM_CAPABILITY); + } + + } + + OnSystemCapabilityUpdated.KEY_SYSTEM_CAPABILITY = 'systemCapability'; + + /* eslint-disable camelcase */ + /** + * Allows encoded data in the form of SyncP packets to be sent to the SYNC module. Legacy / v1 Protocol implementation; + * use SyncPData instead. *** DEPRECATED *** + */ + + class EncodedSyncPData extends RpcRequest { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.EncodedSyncPData); + } + /** + * @param {String[]} data - Contains base64 encoded string of SyncP packets. + * @return {EncodedSyncPData} + */ + + + setData(data) { + this.setParameter(EncodedSyncPData.KEY_DATA, data); + return this; + } + /** + * @return {String[]} + */ + + + getData() { + return this.getParameter(EncodedSyncPData.KEY_DATA); + } + + } + + EncodedSyncPData.KEY_DATA = 'data'; + + /* eslint-disable camelcase */ + + class EncodedSyncPDataResponse extends RpcResponse { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.EncodedSyncPData); + } + + } + + /* eslint-disable camelcase */ + /** + * Callback including encoded data of any SyncP packets that SYNC needs to send back to the mobile device. Legacy / v1 + * Protocol implementation; responds to EncodedSyncPData. *** DEPRECATED *** + */ + + class OnEncodedSyncPData extends RpcNotification { + /** + * @constructor + */ + constructor(store) { + super(store); + this.setFunctionName(FunctionID.OnEncodedSyncPData); + } + /** + * @param {String[]} data - Contains base64 encoded string of SyncP packets. + * @return {OnEncodedSyncPData} + */ + + + setData(data) { + this.setParameter(OnEncodedSyncPData.KEY_DATA, data); + return this; + } + /** + * @return {String[]} + */ + + + getData() { + return this.getParameter(OnEncodedSyncPData.KEY_DATA); + } + /** + * @param {String} url - If blank, the SyncP data shall be forwarded to the app. If not blank, the SyncP data shall + * be forwarded to the provided URL. + * @return {OnEncodedSyncPData} + */ + + + setURL(url) { + this.setParameter(OnEncodedSyncPData.KEY_URL, url); + return this; + } + /** + * @return {String} + */ + + + getURL() { + return this.getParameter(OnEncodedSyncPData.KEY_URL); + } + /** + * @param {Number} timeout - If blank, the SyncP data shall be forwarded to the app. If not blank, the SyncP data + * shall be forwarded with the provided timeout in seconds. + * @return {OnEncodedSyncPData} + */ + + + setTimeout(timeout) { + this.setParameter(OnEncodedSyncPData.KEY_TIMEOUT, timeout); + return this; + } + /** + * @return {Number} + */ + + + getTimeout() { + return this.getParameter(OnEncodedSyncPData.KEY_TIMEOUT); + } + + } + + OnEncodedSyncPData.KEY_DATA = 'data'; + OnEncodedSyncPData.KEY_URL = 'URL'; + OnEncodedSyncPData.KEY_TIMEOUT = 'Timeout'; + + /* eslint-disable camelcase */ + + class RpcCreator { + /** + * Converts an SdlPacket to an RpcMessage + * @param {SdlPacket} sdlPacket + * @return {RpcMessage} + */ + static construct(sdlPacket) { + const payload = sdlPacket.getPayload(); + const binaryFrameHeader = BinaryFrameHeader.fromBinaryHeader(payload); + let message; + const rpcType = binaryFrameHeader.getRpcType(); + const rpcName = RpcType.keyForValue(rpcType); + const correlationId = binaryFrameHeader.getCorrelationId(); + const functionId = binaryFrameHeader.getFunctionId(); + const functionName = FunctionID.keyForValue(functionId); + const bulkData = binaryFrameHeader.getBulkData(); + const jsonData = binaryFrameHeader.getJsonData(); + const params = { + parameters: JsonRpcMarshaller.unmarshall(jsonData) + }; + + switch (functionId) { + case FunctionID.RegisterAppInterface: + if (rpcType === RpcType.REQUEST) { + message = new RegisterAppInterface(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new RegisterAppInterfaceResponse(params); + } + + break; + + case FunctionID.UnregisterAppInterface: + if (rpcType === RpcType.REQUEST) { + message = new UnregisterAppInterface(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new UnregisterAppInterfaceResponse(params); + } + + break; + + case FunctionID.CreateWindow: + if (rpcType === RpcType.REQUEST) { + message = new CreateWindow(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new CreateWindowResponse(params); + } + + break; + + case FunctionID.DeleteWindow: + if (rpcType === RpcType.REQUEST) { + message = new DeleteWindow(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new DeleteWindowResponse(params); + } + + break; + + case FunctionID.SetGlobalProperties: + if (rpcType === RpcType.REQUEST) { + message = new SetGlobalProperties(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new SetGlobalPropertiesResponse(params); + } + + break; + + case FunctionID.ResetGlobalProperties: + if (rpcType === RpcType.REQUEST) { + message = new ResetGlobalProperties(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new ResetGlobalPropertiesResponse(params); + } + + break; + + case FunctionID.AddCommand: + if (rpcType === RpcType.REQUEST) { + message = new AddCommand(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new AddCommandResponse(params); + } + + break; + + case FunctionID.DeleteCommand: + if (rpcType === RpcType.REQUEST) { + message = new DeleteCommand(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new DeleteCommandResponse(params); + } + + break; + + case FunctionID.AddSubMenu: + if (rpcType === RpcType.REQUEST) { + message = new AddSubMenu(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new AddSubMenuResponse(params); + } + + break; + + case FunctionID.DeleteSubMenu: + if (rpcType === RpcType.REQUEST) { + message = new DeleteSubMenu(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new DeleteSubMenuResponse(params); + } + + break; + + case FunctionID.ShowAppMenu: + if (rpcType === RpcType.REQUEST) { + message = new ShowAppMenu(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new ShowAppMenuResponse(params); + } + + break; + + case FunctionID.CreateInteractionChoiceSet: + if (rpcType === RpcType.REQUEST) { + message = new CreateInteractionChoiceSet(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new CreateInteractionChoiceSetResponse(params); + } + + break; + + case FunctionID.PerformInteraction: + if (rpcType === RpcType.REQUEST) { + message = new PerformInteraction(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new PerformInteractionResponse(params); + } + + break; + + case FunctionID.DeleteInteractionChoiceSet: + if (rpcType === RpcType.REQUEST) { + message = new DeleteInteractionChoiceSet(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new DeleteInteractionChoiceSetResponse(params); + } + + break; + + case FunctionID.Alert: + if (rpcType === RpcType.REQUEST) { + message = new Alert(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new AlertResponse(params); + } + + break; + + case FunctionID.Show: + if (rpcType === RpcType.REQUEST) { + message = new Show(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new ShowResponse(params); + } + + break; + + case FunctionID.Speak: + if (rpcType === RpcType.REQUEST) { + message = new Speak(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new SpeakResponse(params); + } + + break; + + case FunctionID.SetMediaClockTimer: + if (rpcType === RpcType.REQUEST) { + message = new SetMediaClockTimer(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new SetMediaClockTimerResponse(params); + } + + break; + + case FunctionID.PerformAudioPassThru: + if (rpcType === RpcType.REQUEST) { + message = new PerformAudioPassThru(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new PerformAudioPassThruResponse(params); + } + + break; + + case FunctionID.EndAudioPassThru: + if (rpcType === RpcType.REQUEST) { + message = new EndAudioPassThru(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new EndAudioPassThruResponse(params); + } + + break; + + case FunctionID.SubscribeButton: + if (rpcType === RpcType.REQUEST) { + message = new SubscribeButton(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new SubscribeButtonResponse(params); + } + + break; + + case FunctionID.UnsubscribeButton: + if (rpcType === RpcType.REQUEST) { + message = new UnsubscribeButton(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new UnsubscribeButtonResponse(params); + } + + break; + + case FunctionID.SubscribeVehicleData: + if (rpcType === RpcType.REQUEST) { + message = new SubscribeVehicleData(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new SubscribeVehicleDataResponse(params); + } + + break; + + case FunctionID.UnsubscribeVehicleData: + if (rpcType === RpcType.REQUEST) { + message = new UnsubscribeVehicleData(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new UnsubscribeVehicleDataResponse(params); + } + + break; + + case FunctionID.GetVehicleData: + if (rpcType === RpcType.REQUEST) { + message = new GetVehicleData(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new GetVehicleDataResponse(params); + } + + break; + + case FunctionID.ReadDID: + if (rpcType === RpcType.REQUEST) { + message = new ReadDID(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new ReadDIDResponse(params); + } + + break; + + case FunctionID.GetDTCs: + if (rpcType === RpcType.REQUEST) { + message = new GetDTCs(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new GetDTCsResponse(params); + } + + break; + + case FunctionID.DiagnosticMessage: + if (rpcType === RpcType.REQUEST) { + message = new DiagnosticMessage(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new DiagnosticMessageResponse(params); + } + + break; + + case FunctionID.ScrollableMessage: + if (rpcType === RpcType.REQUEST) { + message = new ScrollableMessage(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new ScrollableMessageResponse(params); + } + + break; + + case FunctionID.Slider: + if (rpcType === RpcType.REQUEST) { + message = new Slider(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new SliderResponse(params); + } + + break; + + case FunctionID.ShowConstantTBT: + if (rpcType === RpcType.REQUEST) { + message = new ShowConstantTBT(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new ShowConstantTBTResponse(params); + } + + break; + + case FunctionID.AlertManeuver: + if (rpcType === RpcType.REQUEST) { + message = new AlertManeuver(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new AlertManeuverResponse(params); + } + + break; + + case FunctionID.UpdateTurnList: + if (rpcType === RpcType.REQUEST) { + message = new UpdateTurnList(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new UpdateTurnListResponse(params); + } + + break; + + case FunctionID.ChangeRegistration: + if (rpcType === RpcType.REQUEST) { + message = new ChangeRegistration(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new ChangeRegistrationResponse(params); + } + + break; + + case FunctionID.GenericResponse: + if (rpcType === RpcType.RESPONSE) { + message = new GenericResponseResponse(params); + } + + break; + + case FunctionID.PutFile: + if (rpcType === RpcType.REQUEST) { + message = new PutFile(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new PutFileResponse(params); + } + + break; + + case FunctionID.GetFile: + if (rpcType === RpcType.REQUEST) { + message = new GetFile(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new GetFileResponse(params); + } + + break; + + case FunctionID.DeleteFile: + if (rpcType === RpcType.REQUEST) { + message = new DeleteFile(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new DeleteFileResponse(params); + } + + break; + + case FunctionID.ListFiles: + if (rpcType === RpcType.REQUEST) { + message = new ListFiles(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new ListFilesResponse(params); + } + + break; + + case FunctionID.SetAppIcon: + if (rpcType === RpcType.REQUEST) { + message = new SetAppIcon(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new SetAppIconResponse(params); + } + + break; + + case FunctionID.SetDisplayLayout: + if (rpcType === RpcType.REQUEST) { + message = new SetDisplayLayout(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new SetDisplayLayoutResponse(params); + } + + break; + + case FunctionID.SystemRequest: + if (rpcType === RpcType.REQUEST) { + message = new SystemRequest(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new SystemRequestResponse(params); + } + + break; + + case FunctionID.SendLocation: + if (rpcType === RpcType.REQUEST) { + message = new SendLocation(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new SendLocationResponse(params); + } + + break; + + case FunctionID.DialNumber: + if (rpcType === RpcType.REQUEST) { + message = new DialNumber(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new DialNumberResponse(params); + } + + break; + + case FunctionID.ButtonPress: + if (rpcType === RpcType.REQUEST) { + message = new ButtonPress(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new ButtonPressResponse(params); + } + + break; + + case FunctionID.GetInteriorVehicleData: + if (rpcType === RpcType.REQUEST) { + message = new GetInteriorVehicleData(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new GetInteriorVehicleDataResponse(params); + } + + break; + + case FunctionID.GetInteriorVehicleDataConsent: + if (rpcType === RpcType.REQUEST) { + message = new GetInteriorVehicleDataConsent(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new GetInteriorVehicleDataConsentResponse(params); + } + + break; + + case FunctionID.ReleaseInteriorVehicleDataModule: + if (rpcType === RpcType.REQUEST) { + message = new ReleaseInteriorVehicleDataModule(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new ReleaseInteriorVehicleDataModuleResponse(params); + } + + break; + + case FunctionID.SetInteriorVehicleData: + if (rpcType === RpcType.REQUEST) { + message = new SetInteriorVehicleData(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new SetInteriorVehicleDataResponse(params); + } + + break; + + case FunctionID.SubscribeWayPoints: + if (rpcType === RpcType.REQUEST) { + message = new SubscribeWayPoints(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new SubscribeWayPointsResponse(params); + } + + break; + + case FunctionID.GetWayPoints: + if (rpcType === RpcType.REQUEST) { + message = new GetWayPoints(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new GetWayPointsResponse(params); + } + + break; + + case FunctionID.UnsubscribeWayPoints: + if (rpcType === RpcType.REQUEST) { + message = new UnsubscribeWayPoints(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new UnsubscribeWayPointsResponse(params); + } + + break; + + case FunctionID.GetSystemCapability: + if (rpcType === RpcType.REQUEST) { + message = new GetSystemCapability(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new GetSystemCapabilityResponse(params); + } + + break; + + case FunctionID.SendHapticData: + if (rpcType === RpcType.REQUEST) { + message = new SendHapticData(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new SendHapticDataResponse(params); + } + + break; + + case FunctionID.SetCloudAppProperties: + if (rpcType === RpcType.REQUEST) { + message = new SetCloudAppProperties(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new SetCloudAppPropertiesResponse(params); + } + + break; + + case FunctionID.GetCloudAppProperties: + if (rpcType === RpcType.REQUEST) { + message = new GetCloudAppProperties(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new GetCloudAppPropertiesResponse(params); + } + + break; + + case FunctionID.PublishAppService: + if (rpcType === RpcType.REQUEST) { + message = new PublishAppService(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new PublishAppServiceResponse(params); + } + + break; + + case FunctionID.UnpublishAppService: + if (rpcType === RpcType.REQUEST) { + message = new UnpublishAppService(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new UnpublishAppServiceResponse(params); + } + + break; + + case FunctionID.GetAppServiceData: + if (rpcType === RpcType.REQUEST) { + message = new GetAppServiceData(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new GetAppServiceDataResponse(params); + } + + break; + + case FunctionID.PerformAppServiceInteraction: + if (rpcType === RpcType.REQUEST) { + message = new PerformAppServiceInteraction(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new PerformAppServiceInteractionResponse(params); + } + + break; + + case FunctionID.CancelInteraction: + if (rpcType === RpcType.REQUEST) { + message = new CancelInteraction(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new CancelInteractionResponse(params); + } + + break; + + case FunctionID.CloseApplication: + if (rpcType === RpcType.REQUEST) { + message = new CloseApplication(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new CloseApplicationResponse(params); + } + + break; + + case FunctionID.OnHMIStatus: + if (rpcType === RpcType.NOTIFICATION) { + message = new OnHMIStatus(params); + } + + break; + + case FunctionID.OnAppInterfaceUnregistered: + if (rpcType === RpcType.NOTIFICATION) { + message = new OnAppInterfaceUnregistered(params); + } + + break; + + case FunctionID.OnButtonEvent: + if (rpcType === RpcType.NOTIFICATION) { + message = new OnButtonEvent(params); + } + + break; + + case FunctionID.OnButtonPress: + if (rpcType === RpcType.NOTIFICATION) { + message = new OnButtonPress(params); + } + + break; + + case FunctionID.OnVehicleData: + if (rpcType === RpcType.NOTIFICATION) { + message = new OnVehicleData(params); + } + + break; + + case FunctionID.OnCommand: + if (rpcType === RpcType.NOTIFICATION) { + message = new OnCommand(params); + } + + break; + + case FunctionID.OnTBTClientState: + if (rpcType === RpcType.NOTIFICATION) { + message = new OnTBTClientState(params); + } + + break; + + case FunctionID.OnDriverDistraction: + if (rpcType === RpcType.NOTIFICATION) { + message = new OnDriverDistraction(params); + } + + break; + + case FunctionID.OnPermissionsChange: + if (rpcType === RpcType.NOTIFICATION) { + message = new OnPermissionsChange(params); + } + + break; + + case FunctionID.OnAudioPassThru: + if (rpcType === RpcType.NOTIFICATION) { + message = new OnAudioPassThru(params); + } + + break; + + case FunctionID.OnLanguageChange: + if (rpcType === RpcType.NOTIFICATION) { + message = new OnLanguageChange(params); + } + + break; + + case FunctionID.OnKeyboardInput: + if (rpcType === RpcType.NOTIFICATION) { + message = new OnKeyboardInput(params); + } + + break; + + case FunctionID.OnTouchEvent: + if (rpcType === RpcType.NOTIFICATION) { + message = new OnTouchEvent(params); + } + + break; + + case FunctionID.OnSystemRequest: + if (rpcType === RpcType.NOTIFICATION) { + message = new OnSystemRequest(params); + } + + break; + + case FunctionID.OnHashChange: + if (rpcType === RpcType.NOTIFICATION) { + message = new OnHashChange(params); + } + + break; + + case FunctionID.OnWayPointChange: + if (rpcType === RpcType.NOTIFICATION) { + message = new OnWayPointChange(params); + } + + break; + + case FunctionID.OnInteriorVehicleData: + if (rpcType === RpcType.NOTIFICATION) { + message = new OnInteriorVehicleData(params); + } + + break; + + case FunctionID.OnRCStatus: + if (rpcType === RpcType.NOTIFICATION) { + message = new OnRCStatus(params); + } + + break; + + case FunctionID.OnAppServiceData: + if (rpcType === RpcType.NOTIFICATION) { + message = new OnAppServiceData(params); + } + + break; + + case FunctionID.OnSystemCapabilityUpdated: + if (rpcType === RpcType.NOTIFICATION) { + message = new OnSystemCapabilityUpdated(params); + } + + break; + + case FunctionID.EncodedSyncPData: + if (rpcType === RpcType.REQUEST) { + message = new EncodedSyncPData(params); + } else if (rpcType === RpcType.RESPONSE) { + message = new EncodedSyncPDataResponse(params); + } + + break; + + case FunctionID.OnEncodedSyncPData: + if (rpcType === RpcType.NOTIFICATION) { + message = new OnEncodedSyncPData(params); + } + + break; + + default: + message = null; + } + + if (message === null || message === undefined) { + // informs of missing classes + console.warn(`RpcCreator couldn't construct an RPC for the ${functionName} ${rpcName}`); + return null; + } + + if (rpcType === RpcType.REQUEST || rpcType === RpcType.RESPONSE) { + message.setCorrelationId(correlationId); + } + + if (bulkData) { + message.setBulkData(bulkData); + } + + return message; + } + + } + /* * Copyright (c) 2019, Livio, Inc. * All rights reserved. @@ -28173,7 +54925,7 @@ _createRegisterAppInterface() { const registerAppInterface = new RegisterAppInterface(); - registerAppInterface.setSdlMsgVersion(new SdlMsgVersion().setMajorVersion(LifecycleManager.MAX_RPC_VERSION.getMajor()).setMinorVersion(LifecycleManager.MAX_RPC_VERSION.getMinor()).setPatchVersion(LifecycleManager.MAX_RPC_VERSION.getPatch())).setAppName(this._appConfig.getAppName()).setFullAppId(this._appConfig.getAppId()).setNgnMediaScreenAppName(this._appConfig.getShortAppName()).setAppHmiType(this._appConfig.getAppTypes()).setLanguageDesired(this._appConfig.getLanguageDesired()).setHmiDisplayLanguageDesired(this._appConfig.getHmiDisplayLanguageDesired()).setIsMediaApplication(this._appConfig.isMediaApp()).setDayColorScheme(this._appConfig.getDayColorScheme()).setNightColorScheme(this._appConfig.getNightColorScheme()).setCorrelationId(LifecycleManager.REGISTER_APP_INTERFACE_CORRELATION_ID); // TODO Add all possible items + registerAppInterface.setSdlMsgVersion(new SdlMsgVersion().setMajorVersion(LifecycleManager.MAX_RPC_VERSION.getMajor()).setMinorVersion(LifecycleManager.MAX_RPC_VERSION.getMinor()).setPatchVersion(LifecycleManager.MAX_RPC_VERSION.getPatch())).setAppName(this._appConfig.getAppName()).setFullAppId(this._appConfig.getAppId()).setNgnMediaScreenAppName(this._appConfig.getShortAppName()).setAppHMIType(this._appConfig.getAppTypes()).setLanguageDesired(this._appConfig.getLanguageDesired()).setHmiDisplayLanguageDesired(this._appConfig.getHmiDisplayLanguageDesired()).setIsMediaApplication(this._appConfig.isMediaApp()).setDayColorScheme(this._appConfig.getDayColorScheme()).setNightColorScheme(this._appConfig.getNightColorScheme()).setCorrelationId(LifecycleManager.REGISTER_APP_INTERFACE_CORRELATION_ID); // TODO Add all possible items return registerAppInterface; } @@ -28195,8 +54947,8 @@ case FunctionID.OnHMIStatus: { // send a single onProxyConnected, when we go from a null HMI level to a defined HMI level - const shouldInit = rpcMessage.getHMILevel() !== null && rpcMessage.getHMILevel() !== undefined && this._currentHMIStatus === null; - this._currentHMIStatus = rpcMessage.getHMILevel(); + const shouldInit = rpcMessage.getHmiLevel() !== null && rpcMessage.getHmiLevel() !== undefined && this._currentHMIStatus === null; + this._currentHMIStatus = rpcMessage.getHmiLevel(); if (this._lifecycleListener !== null && this._lifecycleListener !== undefined && shouldInit) { this._lifecycleListener.onProxyConnected(this); @@ -28239,182 +54991,747 @@ LifecycleManager.REGISTER_APP_INTERFACE_CORRELATION_ID = 65529; LifecycleManager.UNREGISTER_APP_INTERFACE_CORRELATION_ID = 65530; - /* - * Copyright (c) 2019, Livio, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the Livio Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ + /* eslint-disable camelcase */ + /** + * @typedef {Enum} AppServiceType + * @property {Object} _MAP + */ - class VideoStreamingCapability extends RpcStruct { + class AppServiceType extends Enum { /** - * @constructor - */ + * @constructor + */ constructor() { super(); } /** - * @param {ImageResolution} val - * @return {VideoStreamingCapability} - */ + * @return {String} + */ - setPreferredResolution(val) { - this.validateType(ImageResolution, val); - this.setParameter(VideoStreamingCapability.KEY_PREFERRED_RESOLUTION, val); - return this; + static get MEDIA() { + return AppServiceType._MAP.MEDIA; } /** - * @return {ImageResolution} - */ + * @return {String} + */ - getPreferredResolution() { - return this.getObject(ImageResolution, VideoStreamingCapability.KEY_PREFERRED_RESOLUTION); + static get WEATHER() { + return AppServiceType._MAP.WEATHER; } /** - * @param {number} val - * @return {VideoStreamingCapability} - */ + * @return {String} + */ - setMaxBitrate(val) { - this.setParameter(VideoStreamingCapability.KEY_MAX_BITRATE, val); - return this; + static get NAVIGATION() { + return AppServiceType._MAP.NAVIGATION; } /** - * @return {number} - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ - getMaxBitrate() { - return this.getParameter(VideoStreamingCapability.KEY_MAX_BITRATE); + static valueForKey(key) { + return AppServiceType._valueForKey(key, AppServiceType._MAP); } /** - * @param {VideoStreamingFormat[]} val - * @return {VideoStreamingCapability} - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ - setSupportedFormats(val) { - this.validateType(VideoStreamingFormat, val, true); - this.setParameter(VideoStreamingCapability.KEY_SUPPORTED_FORMATS, val); + static keyForValue(value) { + return AppServiceType._keyForValue(value, AppServiceType._MAP); } + + } + + AppServiceType._MAP = Object.freeze({ + 'MEDIA': 'MEDIA', + 'WEATHER': 'WEATHER', + 'NAVIGATION': 'NAVIGATION' + }); + + /* eslint-disable camelcase */ + /** + * Reflects the status of a vehicle maintenance mode. + * @typedef {Enum} MaintenanceModeStatus + * @property {Object} _MAP + */ + + class MaintenanceModeStatus extends Enum { /** - * @return {VideoStreamingFormat[]} - */ + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ - getSupportedFormats() { - return this.getObject(VideoStreamingFormat, VideoStreamingCapability.KEY_SUPPORTED_FORMATS); + static get MMS_NORMAL() { + return MaintenanceModeStatus._MAP.MMS_NORMAL; } /** - * @param {Boolean} val - * @return {VideoStreamingCapability} - */ + * @return {String} + */ - setHapticSpatialDataSupported(val) { - this.setParameter(VideoStreamingCapability.KEY_HAPTIC_SPATIAL_DATA_SUPPORTED, val); - return this; + static get MMS_NEAR() { + return MaintenanceModeStatus._MAP.MMS_NEAR; } /** - * @return {Boolean} - */ + * @return {String} + */ - getHapticSpatialDataSupported() { - return this.getParameter(VideoStreamingCapability.KEY_HAPTIC_SPATIAL_DATA_SUPPORTED); + static get MMS_ACTIVE() { + return MaintenanceModeStatus._MAP.MMS_ACTIVE; } /** - * @param {number} val - * @return {VideoStreamingCapability} - */ + * @return {String} + */ - setDiagonalScreenSize(val) { - this.setParameter(VideoStreamingCapability.KEY_DIAGONAL_SCREEN_SIZE, val); - return this; + static get MMS_FEATURE_NOT_PRESENT() { + return MaintenanceModeStatus._MAP.MMS_FEATURE_NOT_PRESENT; } /** - * @return {number} - */ + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ - getDiagonalScreenSize() { - return this.getParameter(VideoStreamingCapability.KEY_DIAGONAL_SCREEN_SIZE); + static valueForKey(key) { + return MaintenanceModeStatus._valueForKey(key, MaintenanceModeStatus._MAP); } /** - * @param {number} val - * @return {VideoStreamingCapability} - */ + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ - setPixelPerInch(val) { - this.setParameter(VideoStreamingCapability.KEY_PIXEL_PER_INCH, val); - return this; + static keyForValue(value) { + return MaintenanceModeStatus._keyForValue(value, MaintenanceModeStatus._MAP); } + + } + + MaintenanceModeStatus._MAP = Object.freeze({ + 'MMS_NORMAL': 'NORMAL', + 'MMS_NEAR': 'NEAR', + 'MMS_ACTIVE': 'ACTIVE', + 'MMS_FEATURE_NOT_PRESENT': 'FEATURE_NOT_PRESENT' + }); + + /* eslint-disable camelcase */ + /** + * Enumeration that describes possible permission states of a policy table entry. + * @typedef {Enum} PermissionStatus + * @property {Object} _MAP + */ + + class PermissionStatus extends Enum { /** - * @return {number} - */ + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ - getPixelPerInch() { - return this.getParameter(VideoStreamingCapability.KEY_PIXEL_PER_INCH); + static get PS_ALLOWED() { + return PermissionStatus._MAP.PS_ALLOWED; } /** - * @param {number} val - * @return {VideoStreamingCapability} - */ + * @return {String} + */ - setScale(val) { - this.setParameter(VideoStreamingCapability.KEY_SCALE, val); - return this; + static get PS_DISALLOWED() { + return PermissionStatus._MAP.PS_DISALLOWED; } /** - * @return {number} - */ + * @return {String} + */ - getScale() { - return this.getParameter(VideoStreamingCapability.KEY_SCALE); + static get PS_USER_DISALLOWED() { + return PermissionStatus._MAP.PS_USER_DISALLOWED; + } + /** + * @return {String} + */ + + + static get PS_USER_CONSENT_PENDING() { + return PermissionStatus._MAP.PS_USER_CONSENT_PENDING; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return PermissionStatus._valueForKey(key, PermissionStatus._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return PermissionStatus._keyForValue(value, PermissionStatus._MAP); } } - VideoStreamingCapability.KEY_PREFERRED_RESOLUTION = 'preferredResolution'; - VideoStreamingCapability.KEY_MAX_BITRATE = 'maxBitrate'; - VideoStreamingCapability.KEY_SUPPORTED_FORMATS = 'supportedFormats'; - VideoStreamingCapability.KEY_HAPTIC_SPATIAL_DATA_SUPPORTED = 'hapticSpatialDataSupported'; - VideoStreamingCapability.KEY_DIAGONAL_SCREEN_SIZE = 'diagonalScreenSize'; - VideoStreamingCapability.KEY_PIXEL_PER_INCH = 'pixelPerInch'; - VideoStreamingCapability.KEY_SCALE = 'scale'; + PermissionStatus._MAP = Object.freeze({ + 'PS_ALLOWED': 'ALLOWED', + 'PS_DISALLOWED': 'DISALLOWED', + 'PS_USER_DISALLOWED': 'USER_DISALLOWED', + 'PS_USER_CONSENT_PENDING': 'USER_CONSENT_PENDING' + }); + + /* eslint-disable camelcase */ + /** + * Predefined screen layout. + * @typedef {Enum} PredefinedLayout + * @property {Object} _MAP + */ + + class PredefinedLayout extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * Default media / non-media screen. Can be set as a root screen. + * @return {String} + */ + + + static get DEFAULT() { + return PredefinedLayout._MAP.DEFAULT; + } + /** + * Default Media screen. Can be set as a root screen. + * @return {String} + */ + + + static get MEDIA() { + return PredefinedLayout._MAP.MEDIA; + } + /** + * Default Non-media screen. Can be set as a root screen. + * @return {String} + */ + + + static get NON_MEDIA() { + return PredefinedLayout._MAP.NON_MEDIA; + } + /** + * Custom root media screen containing app-defined onscreen presets. Can be set as a root screen. + * @return {String} + */ + + + static get ONSCREEN_PRESETS() { + return PredefinedLayout._MAP.ONSCREEN_PRESETS; + } + /** + * Custom root template screen containing full screen map with navigation controls. Can be set as a root screen. + * @return {String} + */ + + + static get NAV_FULLSCREEN_MAP() { + return PredefinedLayout._MAP.NAV_FULLSCREEN_MAP; + } + /** + * Custom root template screen containing video represented list. Can be set as a root screen. + * @return {String} + */ + + + static get NAV_LIST() { + return PredefinedLayout._MAP.NAV_LIST; + } + /** + * Custom root template screen containing video represented keyboard. Can be set as a root screen. + * @return {String} + */ + + + static get NAV_KEYBOARD() { + return PredefinedLayout._MAP.NAV_KEYBOARD; + } + /** + * Custom root template screen containing half-screen graphic with lines of text. Can be set as a root screen. + * @return {String} + */ + + + static get GRAPHIC_WITH_TEXT() { + return PredefinedLayout._MAP.GRAPHIC_WITH_TEXT; + } + /** + * Custom root template screen containing lines of text with half-screen graphic. Can be set as a root screen. + * @return {String} + */ + + + static get TEXT_WITH_GRAPHIC() { + return PredefinedLayout._MAP.TEXT_WITH_GRAPHIC; + } + /** + * Custom root template screen containing only tiled SoftButtons. Can be set as a root screen. + * @return {String} + */ + + + static get TILES_ONLY() { + return PredefinedLayout._MAP.TILES_ONLY; + } + /** + * Custom root template screen containing only text SoftButtons. Can be set as a root screen. + * @return {String} + */ + + + static get TEXTBUTTONS_ONLY() { + return PredefinedLayout._MAP.TEXTBUTTONS_ONLY; + } + /** + * Custom root template screen containing half-screen graphic with tiled SoftButtons. Can be set as a root screen. + * @return {String} + */ + + + static get GRAPHIC_WITH_TILES() { + return PredefinedLayout._MAP.GRAPHIC_WITH_TILES; + } + /** + * Custom root template screen containing tiled SoftButtons with half-screen graphic. Can be set as a root screen. + * @return {String} + */ + + + static get TILES_WITH_GRAPHIC() { + return PredefinedLayout._MAP.TILES_WITH_GRAPHIC; + } + /** + * Custom root template screen containing half-screen graphic with text and SoftButtons. Can be set as a root + * screen. + * @return {String} + */ + + + static get GRAPHIC_WITH_TEXT_AND_SOFTBUTTONS() { + return PredefinedLayout._MAP.GRAPHIC_WITH_TEXT_AND_SOFTBUTTONS; + } + /** + * Custom root template screen containing text and SoftButtons with half-screen graphic. Can be set as a root + * screen. + * @return {String} + */ + + + static get TEXT_AND_SOFTBUTTONS_WITH_GRAPHIC() { + return PredefinedLayout._MAP.TEXT_AND_SOFTBUTTONS_WITH_GRAPHIC; + } + /** + * Custom root template screen containing half-screen graphic with text only SoftButtons. Can be set as a root + * screen. + * @return {String} + */ + + + static get GRAPHIC_WITH_TEXTBUTTONS() { + return PredefinedLayout._MAP.GRAPHIC_WITH_TEXTBUTTONS; + } + /** + * Custom root template screen containing text only SoftButtons with half-screen graphic. Can be set as a root + * screen. + * @return {String} + */ + + + static get TEXTBUTTONS_WITH_GRAPHIC() { + return PredefinedLayout._MAP.TEXTBUTTONS_WITH_GRAPHIC; + } + /** + * Custom root template screen containing a large graphic and SoftButtons. Can be set as a root screen. + * @return {String} + */ + + + static get LARGE_GRAPHIC_WITH_SOFTBUTTONS() { + return PredefinedLayout._MAP.LARGE_GRAPHIC_WITH_SOFTBUTTONS; + } + /** + * Custom root template screen containing two graphics and SoftButtons. Can be set as a root screen. + * @return {String} + */ + + + static get DOUBLE_GRAPHIC_WITH_SOFTBUTTONS() { + return PredefinedLayout._MAP.DOUBLE_GRAPHIC_WITH_SOFTBUTTONS; + } + /** + * Custom root template screen containing only a large graphic. Can be set as a root screen. + * @return {String} + */ + + + static get LARGE_GRAPHIC_ONLY() { + return PredefinedLayout._MAP.LARGE_GRAPHIC_ONLY; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return PredefinedLayout._valueForKey(key, PredefinedLayout._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return PredefinedLayout._keyForValue(value, PredefinedLayout._MAP); + } + + } + + PredefinedLayout._MAP = Object.freeze({ + 'DEFAULT': 'DEFAULT', + 'MEDIA': 'MEDIA', + 'NON_MEDIA': 'NON-MEDIA', + 'ONSCREEN_PRESETS': 'ONSCREEN_PRESETS', + 'NAV_FULLSCREEN_MAP': 'NAV_FULLSCREEN_MAP', + 'NAV_LIST': 'NAV_LIST', + 'NAV_KEYBOARD': 'NAV_KEYBOARD', + 'GRAPHIC_WITH_TEXT': 'GRAPHIC_WITH_TEXT', + 'TEXT_WITH_GRAPHIC': 'TEXT_WITH_GRAPHIC', + 'TILES_ONLY': 'TILES_ONLY', + 'TEXTBUTTONS_ONLY': 'TEXTBUTTONS_ONLY', + 'GRAPHIC_WITH_TILES': 'GRAPHIC_WITH_TILES', + 'TILES_WITH_GRAPHIC': 'TILES_WITH_GRAPHIC', + 'GRAPHIC_WITH_TEXT_AND_SOFTBUTTONS': 'GRAPHIC_WITH_TEXT_AND_SOFTBUTTONS', + 'TEXT_AND_SOFTBUTTONS_WITH_GRAPHIC': 'TEXT_AND_SOFTBUTTONS_WITH_GRAPHIC', + 'GRAPHIC_WITH_TEXTBUTTONS': 'GRAPHIC_WITH_TEXTBUTTONS', + 'TEXTBUTTONS_WITH_GRAPHIC': 'TEXTBUTTONS_WITH_GRAPHIC', + 'LARGE_GRAPHIC_WITH_SOFTBUTTONS': 'LARGE_GRAPHIC_WITH_SOFTBUTTONS', + 'DOUBLE_GRAPHIC_WITH_SOFTBUTTONS': 'DOUBLE_GRAPHIC_WITH_SOFTBUTTONS', + 'LARGE_GRAPHIC_ONLY': 'LARGE_GRAPHIC_ONLY' + }); + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} PredefinedWindows + * @property {Object} _MAP + */ + + class PredefinedWindows extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * The default window is a main window pre-created on behalf of the app. + * @return {Number} + */ + + + static get DEFAULT_WINDOW() { + return PredefinedWindows._MAP.DEFAULT_WINDOW; + } + /** + * The primary widget of the app. + * @return {Number} + */ + + + static get PRIMARY_WIDGET() { + return PredefinedWindows._MAP.PRIMARY_WIDGET; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return PredefinedWindows._valueForKey(key, PredefinedWindows._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return PredefinedWindows._keyForValue(value, PredefinedWindows._MAP); + } + + } + + PredefinedWindows._MAP = Object.freeze({ + 'DEFAULT_WINDOW': 0, + 'PRIMARY_WIDGET': 1 + }); + + /* eslint-disable camelcase */ + /** + * @typedef {Enum} TimerMode + * @property {Object} _MAP + */ + + class TimerMode extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * Causes the media clock timer to update from 0:00 to a specified time + * @return {String} + */ + + + static get UP() { + return TimerMode._MAP.UP; + } + /** + * Causes the media clock timer to update from a specified time to 0:00 + * @return {String} + */ + + + static get DOWN() { + return TimerMode._MAP.DOWN; + } + /** + * Indicates to not use the media clock timer + * @return {String} + */ + + + static get NONE() { + return TimerMode._MAP.NONE; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return TimerMode._valueForKey(key, TimerMode._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return TimerMode._keyForValue(value, TimerMode._MAP); + } + + } + + TimerMode._MAP = Object.freeze({ + 'UP': 'UP', + 'DOWN': 'DOWN', + 'NONE': 'NONE' + }); + + /* eslint-disable camelcase */ + /** + * Reflects the status of given vehicle component. + * @typedef {Enum} VehicleDataActiveStatus + * @property {Object} _MAP + */ + + class VehicleDataActiveStatus extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {String} + */ + + + static get VDAS_INACTIVE_NOT_CONFIRMED() { + return VehicleDataActiveStatus._MAP.VDAS_INACTIVE_NOT_CONFIRMED; + } + /** + * @return {String} + */ + + + static get VDAS_INACTIVE_CONFIRMED() { + return VehicleDataActiveStatus._MAP.VDAS_INACTIVE_CONFIRMED; + } + /** + * @return {String} + */ + + + static get VDAS_ACTIVE_NOT_CONFIRMED() { + return VehicleDataActiveStatus._MAP.VDAS_ACTIVE_NOT_CONFIRMED; + } + /** + * @return {String} + */ + + + static get VDAS_ACTIVE_CONFIRMED() { + return VehicleDataActiveStatus._MAP.VDAS_ACTIVE_CONFIRMED; + } + /** + * @return {String} + */ + + + static get VDAS_FAULT() { + return VehicleDataActiveStatus._MAP.VDAS_FAULT; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return VehicleDataActiveStatus._valueForKey(key, VehicleDataActiveStatus._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return VehicleDataActiveStatus._keyForValue(value, VehicleDataActiveStatus._MAP); + } + + } + + VehicleDataActiveStatus._MAP = Object.freeze({ + 'VDAS_INACTIVE_NOT_CONFIRMED': 'INACTIVE_NOT_CONFIRMED', + 'VDAS_INACTIVE_CONFIRMED': 'INACTIVE_CONFIRMED', + 'VDAS_ACTIVE_NOT_CONFIRMED': 'ACTIVE_NOT_CONFIRMED', + 'VDAS_ACTIVE_CONFIRMED': 'ACTIVE_CONFIRMED', + 'VDAS_FAULT': 'FAULT' + }); + + /* eslint-disable camelcase */ + /** + * Enumeration linking message types with function types in WiPro protocol. Assumes enumeration starts at value 0. + * @typedef {Enum} messageType + * @property {Object} _MAP + */ + + class messageType extends Enum { + /** + * @constructor + */ + constructor() { + super(); + } + /** + * @return {Number} + */ + + + static get request() { + return messageType._MAP.request; + } + /** + * @return {Number} + */ + + + static get response() { + return messageType._MAP.response; + } + /** + * @return {Number} + */ + + + static get notification() { + return messageType._MAP.notification; + } + /** + * Get the value for the given enum key + * @param key - A key to find in the map of the subclass + * @return {*} - Returns a value if found, or null if not found + */ + + + static valueForKey(key) { + return messageType._valueForKey(key, messageType._MAP); + } + /** + * Get the key for the given enum value + * @param value - A primitive value to find the matching key for in the map of the subclass + * @return {*} - Returns a key if found, or null if not found + */ + + + static keyForValue(value) { + return messageType._keyForValue(value, messageType._MAP); + } + + } + + messageType._MAP = Object.freeze({ + 'request': 0, + 'response': 1, + 'notification': 2 + }); /* * Copyright (c) 2019, Livio, Inc. @@ -29070,80 +56387,367 @@ RpcResponse, RpcStruct, enums: { + AmbientLightStatus, AppHMIType, + AppInterfaceUnregisteredReason, + AppServiceType, + AudioStreamingIndicator, AudioStreamingState, AudioType, BitsPerSample, + ButtonEventMode, ButtonName, + ButtonPressMode, + CarModeStatus, CharacterSet, + CompassDirection, + ComponentVolumeStatus, + DefrostZone, + DeliveryMode, + DeviceLevelStatus, + Dimension, + Direction, + DisplayMode, DisplayType, + DistanceUnit, + DriverDistractionState, + ECallConfirmationStatus, + ElectronicParkBrakeStatus, + EmergencyEventType, FileType, + FuelCutoffStatus, + FuelType, FunctionID, + GlobalProperty, HMILevel, HmiZoneCapabilities, + HybridAppPreference, + IgnitionStableStatus, + IgnitionStatus, ImageFieldName, ImageType, + InteractionMode, + KeyboardEvent, + KeyboardLayout, + KeypressMode, Language, + LayoutMode, + LightName, + LightStatus, + MaintenanceModeStatus, + MassageCushion, + MassageMode, + MassageZone, MediaClockFormat, + MediaType, + MenuLayout, MetadataType, + ModuleType, + NavigationAction, + NavigationJunction, + PRNDL, + PermissionStatus, + PowerModeQualificationStatus, + PowerModeStatus, + PredefinedLayout, + PredefinedWindows, PrerecordedSpeech, + PrimaryAudioSource, + RadioBand, + RadioState, + RequestType, Result, RpcType, SamplingRate, + SeatMemoryActionType, + ServiceUpdateReason, SoftButtonType, SpeechCapabilities, + SupportedSeat, SystemAction, + SystemCapabilityType, SystemContext, + TBTState, + TPMS, + TemperatureUnit, TextAlignment, TextFieldName, + TimerMode, + TouchType, + TriggerSource, + TurnSignal, + UpdateMode, + VehicleDataActiveStatus, + VehicleDataEventStatus, + VehicleDataNotificationStatus, + VehicleDataResultCode, + VehicleDataStatus, + VehicleDataType, + VentilationMode, VideoStreamingCodec, VideoStreamingProtocol, VideoStreamingState, - VrCapabilities + VrCapabilities, + WarningLightStatus, + WayPointType, + WindowType, + WiperStatus, + messageType }, messages: { AddCommand, AddCommandResponse, - OnHmiStatus, + AddSubMenu, + AddSubMenuResponse, + Alert, + AlertManeuver, + AlertManeuverResponse, + AlertResponse, + ButtonPress, + ButtonPressResponse, + CancelInteraction, + CancelInteractionResponse, + ChangeRegistration, + ChangeRegistrationResponse, + CloseApplication, + CloseApplicationResponse, + CreateInteractionChoiceSet, + CreateInteractionChoiceSetResponse, + CreateWindow, + CreateWindowResponse, + DeleteCommand, + DeleteCommandResponse, + DeleteFile, + DeleteFileResponse, + DeleteInteractionChoiceSet, + DeleteInteractionChoiceSetResponse, + DeleteSubMenu, + DeleteSubMenuResponse, + DeleteWindow, + DeleteWindowResponse, + DiagnosticMessage, + DiagnosticMessageResponse, + DialNumber, + DialNumberResponse, + EncodedSyncPData, + EncodedSyncPDataResponse, + EndAudioPassThru, + EndAudioPassThruResponse, + GenericResponseResponse, + GetAppServiceData, + GetAppServiceDataResponse, + GetCloudAppProperties, + GetCloudAppPropertiesResponse, + GetDTCs, + GetDTCsResponse, + GetFile, + GetFileResponse, + GetInteriorVehicleData, + GetInteriorVehicleDataConsent, + GetInteriorVehicleDataConsentResponse, + GetInteriorVehicleDataResponse, + GetSystemCapability, + GetSystemCapabilityResponse, + GetVehicleData, + GetVehicleDataResponse, + GetWayPoints, + GetWayPointsResponse, + ListFiles, + ListFilesResponse, + OnAppInterfaceUnregistered, + OnAppServiceData, + OnAudioPassThru, + OnButtonEvent, + OnButtonPress, + OnCommand, + OnDriverDistraction, + OnEncodedSyncPData, + OnHMIStatus, + OnHashChange, + OnInteriorVehicleData, + OnKeyboardInput, OnLanguageChange, + OnPermissionsChange, + OnRCStatus, + OnSystemCapabilityUpdated, + OnSystemRequest, + OnTBTClientState, + OnTouchEvent, + OnVehicleData, + OnWayPointChange, + PerformAppServiceInteraction, + PerformAppServiceInteractionResponse, + PerformAudioPassThru, + PerformAudioPassThruResponse, + PerformInteraction, + PerformInteractionResponse, + PublishAppService, + PublishAppServiceResponse, PutFile, PutFileResponse, + ReadDID, + ReadDIDResponse, RegisterAppInterface, RegisterAppInterfaceResponse, + ReleaseInteriorVehicleDataModule, + ReleaseInteriorVehicleDataModuleResponse, + ResetGlobalProperties, + ResetGlobalPropertiesResponse, + ScrollableMessage, + ScrollableMessageResponse, + SendHapticData, + SendHapticDataResponse, + SendLocation, + SendLocationResponse, SetAppIcon, SetAppIconResponse, + SetCloudAppProperties, + SetCloudAppPropertiesResponse, + SetDisplayLayout, + SetDisplayLayoutResponse, + SetGlobalProperties, + SetGlobalPropertiesResponse, + SetInteriorVehicleData, + SetInteriorVehicleDataResponse, + SetMediaClockTimer, + SetMediaClockTimerResponse, Show, + ShowAppMenu, + ShowAppMenuResponse, + ShowConstantTBT, + ShowConstantTBTResponse, ShowResponse, + Slider, + SliderResponse, + Speak, + SpeakResponse, + SubscribeButton, + SubscribeButtonResponse, + SubscribeVehicleData, + SubscribeVehicleDataResponse, + SubscribeWayPoints, + SubscribeWayPointsResponse, + SystemRequest, + SystemRequestResponse, + UnpublishAppService, + UnpublishAppServiceResponse, UnregisterAppInterface, - UnregisterAppInterfaceResponse + UnregisterAppInterfaceResponse, + UnsubscribeButton, + UnsubscribeButtonResponse, + UnsubscribeVehicleData, + UnsubscribeVehicleDataResponse, + UnsubscribeWayPoints, + UnsubscribeWayPointsResponse, + UpdateTurnList, + UpdateTurnListResponse }, structs: { + AirbagStatus, AppInfo, + AppServiceCapability, + AppServiceData, + AppServiceManifest, + AppServiceRecord, + AppServicesCapabilities, + AudioControlCapabilities, + AudioControlData, AudioPassThruCapabilities, + BeltStatus, + BodyInformation, ButtonCapabilities, + Choice, + ClimateControlCapabilities, + ClimateControlData, + CloudAppProperties, + ClusterModeStatus, + Coordinate, + DIDResult, + DateTime, DeviceInfo, + DeviceStatus, DisplayCapabilities, + DisplayCapability, + ECallInfo, + EmergencyEvent, + EqualizerSettings, + FuelRange, + GPSData, Grid, HMICapabilities, + HMIPermissions, + HMISettingsControlCapabilities, + HMISettingsControlData, + HapticRect, + HeadLampStatus, Image, ImageField, ImageResolution, + KeyboardProperties, + LightCapabilities, + LightControlCapabilities, + LightControlData, + LightState, + LocationDetails, + MassageCushionFirmness, + MassageModeData, + MediaServiceData, + MediaServiceManifest, MenuParams, MetadataTags, + ModuleData, ModuleInfo, + MyKey, + NavigationCapability, + NavigationInstruction, + NavigationServiceData, + NavigationServiceManifest, + OASISAddress, + ParameterPermissions, + PermissionItem, + PhoneCapability, PresetBankCapabilities, RGBColor, + RadioControlCapabilities, + RadioControlData, + RdsData, + Rectangle, + RemoteControlCapabilities, ScreenParams, SdlMsgVersion, + SeatControlCapabilities, + SeatControlData, + SeatLocation, + SeatLocationCapability, + SeatMemoryAction, + SingleTireStatus, + SisData, SoftButton, SoftButtonCapabilities, + StartTime, + StationIDNumber, + SystemCapability, TTSChunk, + Temperature, TemplateColorScheme, + TemplateConfiguration, TextField, + TireStatus, + TouchCoord, + TouchEvent, TouchEventCapabilities, + Turn, + VehicleDataResult, VehicleType, VideoStreamingCapability, - VideoStreamingFormat + VideoStreamingFormat, + VrHelpItem, + WeatherAlert, + WeatherData, + WeatherServiceData, + WeatherServiceManifest, + WindowCapability, + WindowTypeCapabilities } }, session: { @@ -29193,4 +56797,4 @@ return SDL; }))); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzIjpbIi4uL3RtcC9tYW5hZ2VyL0FwcENvbmZpZy5qcyIsIi4uL3RtcC9tYW5hZ2VyL2xpZmVjeWNsZS9MaWZlY3ljbGVMaXN0ZW5lci5qcyIsIi4uL3RtcC91dGlsL0VudW0uanMiLCIuLi90bXAvcnBjL1JwY1N0cnVjdC5qcyIsIi4uL3RtcC9ycGMvZW51bXMvRnVuY3Rpb25JRC5qcyIsIi4uL3RtcC9ycGMvUnBjTWVzc2FnZS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvUnBjVHlwZS5qcyIsIi4uL3RtcC9ycGMvUnBjUmVxdWVzdC5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9TZGxNc2dWZXJzaW9uLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9TcGVlY2hDYXBhYmlsaXRpZXMuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvVFRTQ2h1bmsuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvRGV2aWNlSW5mby5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9BcHBJbmZvLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1JHQkNvbG9yLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1RlbXBsYXRlQ29sb3JTY2hlbWUuanMiLCIuLi90bXAvcnBjL2VudW1zL0xhbmd1YWdlLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9BcHBITUlUeXBlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9SZWdpc3RlckFwcEludGVyZmFjZS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvUmVzdWx0LmpzIiwiLi4vdG1wL3JwYy9ScGNSZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvUnBjTGlzdGVuZXIuanMiLCIuLi90bXAvcHJvdG9jb2wvU2RsUHJvdG9jb2xMaXN0ZW5lci5qcyIsIi4uL3RtcC9wcm90b2NvbC9lbnVtcy9GcmFtZVR5cGUuanMiLCIuLi8uLi8uLi90aGlyZF9wYXJ0eS9ic29uLmNvbW1vbi5qcyIsIi4uL3RtcC91dGlsL0Jzb24uanMiLCIuLi90bXAvcHJvdG9jb2wvU2RsUGFja2V0LmpzIiwiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3JvbGx1cC1wbHVnaW4tbm9kZS1nbG9iYWxzL3NyYy9nbG9iYWwuanMiLCIuLi8uLi8uLi9ub2RlX21vZHVsZXMvYnVmZmVyLWVzNi9iYXNlNjQuanMiLCIuLi8uLi8uLi9ub2RlX21vZHVsZXMvYnVmZmVyLWVzNi9pZWVlNzU0LmpzIiwiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2J1ZmZlci1lczYvaXNBcnJheS5qcyIsIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9idWZmZXItZXM2L2luZGV4LmpzIiwiLi4vdG1wL3V0aWwvVGV4dEVuY29kZXIuanMiLCIuLi90bXAvdXRpbC9Kc29uUnBjTWFyc2hhbGxlci5qcyIsIi4uL3RtcC9wcm90b2NvbC9CaW5hcnlGcmFtZUhlYWRlci5qcyIsIi4uL3RtcC9wcm90b2NvbC9NZXNzYWdlRnJhbWVEaXNhc3NlbWJsZXIuanMiLCIuLi90bXAvdHJhbnNwb3J0L1RyYW5zcG9ydExpc3RlbmVyLmpzIiwiLi4vdG1wL3V0aWwvVmVyc2lvbi5qcyIsIi4uL3RtcC9wcm90b2NvbC9lbnVtcy9TZXJ2aWNlVHlwZS5qcyIsIi4uL3RtcC9wcm90b2NvbC9NZXNzYWdlRnJhbWVBc3NlbWJsZXIuanMiLCIuLi90bXAvcHJvdG9jb2wvZW51bXMvQ29udHJvbEZyYW1lVGFncy5qcyIsIi4uL3RtcC91dGlsL0JpdENvbnZlcnRlci5qcyIsIi4uL3RtcC9wcm90b2NvbC9TZGxQYWNrZXRGYWN0b3J5LmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9JbWFnZVR5cGUuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvSW1hZ2UuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvTWVudVBhcmFtcy5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvQWRkQ29tbWFuZC5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvQWRkQ29tbWFuZFJlc3BvbnNlLmpzIiwiLi4vdG1wL3JwYy9ScGNOb3RpZmljYXRpb24uanMiLCIuLi90bXAvcnBjL2VudW1zL0hNSUxldmVsLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9BdWRpb1N0cmVhbWluZ1N0YXRlLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9WaWRlb1N0cmVhbWluZ1N0YXRlLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9TeXN0ZW1Db250ZXh0LmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9PbkhtaVN0YXR1cy5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvT25MYW5ndWFnZUNoYW5nZS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvRmlsZVR5cGUuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1B1dEZpbGUuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1B1dEZpbGVSZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvVGV4dEZpZWxkTmFtZS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvQ2hhcmFjdGVyU2V0LmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1RleHRGaWVsZC5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9JbWFnZVJlc29sdXRpb24uanMiLCIuLi90bXAvcnBjL2VudW1zL0ltYWdlRmllbGROYW1lLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL0ltYWdlRmllbGQuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvVG91Y2hFdmVudENhcGFiaWxpdGllcy5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9TY3JlZW5QYXJhbXMuanMiLCIuLi90bXAvcnBjL2VudW1zL0Rpc3BsYXlUeXBlLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9NZWRpYUNsb2NrRm9ybWF0LmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL0Rpc3BsYXlDYXBhYmlsaXRpZXMuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvR3JpZC5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9Nb2R1bGVJbmZvLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9CdXR0b25OYW1lLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL0J1dHRvbkNhcGFiaWxpdGllcy5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9Tb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1ByZXNldEJhbmtDYXBhYmlsaXRpZXMuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvVmVoaWNsZVR5cGUuanMiLCIuLi90bXAvcnBjL2VudW1zL0htaVpvbmVDYXBhYmlsaXRpZXMuanMiLCIuLi90bXAvcnBjL2VudW1zL1ByZXJlY29yZGVkU3BlZWNoLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9TYW1wbGluZ1JhdGUuanMiLCIuLi90bXAvcnBjL2VudW1zL0JpdHNQZXJTYW1wbGUuanMiLCIuLi90bXAvcnBjL2VudW1zL0F1ZGlvVHlwZS5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9BdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9WckNhcGFiaWxpdGllcy5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9ITUlDYXBhYmlsaXRpZXMuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1JlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1NldEFwcEljb24uanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1NldEFwcEljb25SZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvU29mdEJ1dHRvblR5cGUuanMiLCIuLi90bXAvcnBjL2VudW1zL1N5c3RlbUFjdGlvbi5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9Tb2Z0QnV0dG9uLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9NZXRhZGF0YVR5cGUuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvTWV0YWRhdGFUYWdzLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9UZXh0QWxpZ25tZW50LmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9TaG93LmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9TaG93UmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1VucmVnaXN0ZXJBcHBJbnRlcmZhY2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1VucmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvUnBjQ3JlYXRvci5qcyIsIi4uL3RtcC9ycGMvZW51bXMvVmlkZW9TdHJlYW1pbmdQcm90b2NvbC5qcyIsIi4uL3RtcC9ycGMvZW51bXMvVmlkZW9TdHJlYW1pbmdDb2RlYy5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9WaWRlb1N0cmVhbWluZ0Zvcm1hdC5qcyIsIi4uL3RtcC9wcm90b2NvbC9TZGxQcm90b2NvbEJhc2UuanMiLCIuLi90bXAvdHJhbnNwb3J0L2VudW1zL1RyYW5zcG9ydFR5cGUuanMiLCIuLi90bXAvdHJhbnNwb3J0L1NkbFBzbS5qcyIsIi4uL3RtcC90cmFuc3BvcnQvVHJhbnNwb3J0QmFzZS5qcyIsIi4uL3RtcC90cmFuc3BvcnQvV2ViU29ja2V0Q2xpZW50LmpzIiwiLi4vdG1wL3RyYW5zcG9ydC9UcmFuc3BvcnRDYWxsYmFjay5qcyIsIi4uL3RtcC90cmFuc3BvcnQvVHJhbnNwb3J0TWFuYWdlckJhc2UuanMiLCIuLi90bXAvdHJhbnNwb3J0L1NzbENvbmZpZy5qcyIsIi4uL3RtcC90cmFuc3BvcnQvV2ViU29ja2V0U2VydmVyLmpzIiwiLi4vdG1wL3RyYW5zcG9ydC9UcmFuc3BvcnRNYW5hZ2VyLmpzIiwiLi4vdG1wL3Byb3RvY29sL1NkbFByb3RvY29sLmpzIiwiLi4vdG1wL3Nlc3Npb24vU2VydmljZUxpc3RlbmVyTWFwLmpzIiwiLi4vdG1wL3N0cmVhbWluZy92aWRlby9WaWRlb1N0cmVhbWluZ1BhcmFtZXRlcnMuanMiLCIuLi90bXAvc2Vzc2lvbi9TZGxTZXNzaW9uLmpzIiwiLi4vdG1wL3Nlc3Npb24vU2RsU2Vzc2lvbkxpc3RlbmVyLmpzIiwiLi4vdG1wL3V0aWwvQXJyYXlUb29scy5qcyIsIi4uL3RtcC9tYW5hZ2VyL2xpZmVjeWNsZS9MaWZlY3ljbGVNYW5hZ2VyLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1ZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eS5qcyIsIi4uL3RtcC9zZXNzaW9uL1NkbFNlcnZpY2VMaXN0ZW5lci5qcyIsIi4uL3RtcC90cmFuc3BvcnQvQ3VzdG9tVHJhbnNwb3J0LmpzIiwiLi4vdG1wL3RyYW5zcG9ydC9UcmFuc3BvcnRDb25maWdCYXNlLmpzIiwiLi4vdG1wL3RyYW5zcG9ydC9DdXN0b21UcmFuc3BvcnRDb25maWcuanMiLCIuLi90bXAvdHJhbnNwb3J0L1dlYlNvY2tldENsaWVudENvbmZpZy5qcyIsIi4uL3RtcC90cmFuc3BvcnQvdXRpbC9UcmFuc3BvcnRSZWNvcmQuanMiLCIuLi90bXAvdHJhbnNwb3J0L1dlYlNvY2tldFNlcnZlckNvbmZpZy5qcyIsIi4uL2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG4vLyBUT0RPIFRoaXMgY2xhc3MgbWF5IG9yIG1heSBub3QgYmUgaW5jbHVkZWQgaW4gdGhlIHJlbGVhc2UuIFdlIHNob3VsZCBkZXRlcm1pbmUgaWZcbi8vIHRoZXJlIGlzIGEgYmV0dGVyIGNvZGluZyBwYXR0ZXJuIGZvciB0aGlzIGZvciBqYXZhc2NyaXB0LlxuXG5jbGFzcyBBcHBDb25maWcge1xuICAgIC8qKlxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHRoaXMuX3RyYW5zcG9ydENvbmZpZyA9IG51bGw7XG4gICAgICAgIHRoaXMuX2FwcElkID0gbnVsbDtcbiAgICAgICAgdGhpcy5fYXBwTmFtZSA9IG51bGw7XG4gICAgICAgIHRoaXMuX2ljb25OYW1lID0gbnVsbDtcbiAgICAgICAgdGhpcy5faWNvbkZpbGUgPSBudWxsO1xuICAgICAgICB0aGlzLl9zaG9ydEFwcE5hbWUgPSBudWxsO1xuICAgICAgICB0aGlzLl90dHNOYW1lID0gbnVsbDtcbiAgICAgICAgdGhpcy5fdnJTeW5vbnltcyA9IG51bGw7XG4gICAgICAgIHRoaXMuX2lzTWVkaWFBcHAgPSBudWxsO1xuICAgICAgICB0aGlzLl9sYW5ndWFnZURlc2lyZWQgPSBudWxsO1xuICAgICAgICB0aGlzLl9obWlEaXNwbGF5TGFuZ3VhZ2VEZXNpcmVkID0gbnVsbDtcbiAgICAgICAgdGhpcy5fYXBwVHlwZXMgPSBudWxsO1xuICAgICAgICB0aGlzLl9kYXlDb2xvclNjaGVtZSA9IG51bGw7XG4gICAgICAgIHRoaXMuX25pZ2h0Q29sb3JTY2hlbWUgPSBudWxsO1xuICAgICAgICB0aGlzLl9taW5pbXVtUlBDVmVyc2lvbiA9IG51bGw7XG4gICAgICAgIHRoaXMuX21pbmltdW1Qcm90b2NvbFZlcnNpb24gPSBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtUcmFuc3BvcnRDb25maWdCYXNlfSB0cmFuc3BvcnRDb25maWdcbiAgICAqIEByZXR1cm4ge0FwcENvbmZpZ31cbiAgICAqL1xuICAgIHNldFRyYW5zcG9ydENvbmZpZyAodHJhbnNwb3J0Q29uZmlnKSB7XG4gICAgICAgIHRoaXMuX3RyYW5zcG9ydENvbmZpZyA9IHRyYW5zcG9ydENvbmZpZztcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtUcmFuc3BvcnRDb25maWdCYXNlfVxuICAgICovXG4gICAgZ2V0VHJhbnNwb3J0Q29uZmlnICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RyYW5zcG9ydENvbmZpZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBhcHBJZFxuICAgICogQHJldHVybiB7QXBwQ29uZmlnfVxuICAgICovXG4gICAgc2V0QXBwSWQgKGFwcElkKSB7XG4gICAgICAgIHRoaXMuX2FwcElkID0gYXBwSWQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgZ2V0QXBwSWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYXBwSWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gYXBwTmFtZVxuICAgICogQHJldHVybiB7QXBwQ29uZmlnfVxuICAgICovXG4gICAgc2V0QXBwTmFtZSAoYXBwTmFtZSkge1xuICAgICAgICB0aGlzLl9hcHBOYW1lID0gYXBwTmFtZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBnZXRBcHBOYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcE5hbWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gaWNvbk5hbWVcbiAgICAqIEBwYXJhbSB7VWludDhBcnJheX0gZmlsZURhdGFcbiAgICAqIEByZXR1cm4ge0FwcENvbmZpZ31cbiAgICAqL1xuICAgIHNldEFwcEljb24gKGljb25OYW1lID0gJ2ljb24ucG5nJywgZmlsZURhdGEpIHtcbiAgICAgICAgLy8gVE9ETyBjcmVhdGUgU2RsQXJ0d29ya1xuICAgICAgICB0aGlzLl9pY29uTmFtZSA9IGljb25OYW1lO1xuICAgICAgICB0aGlzLl9pY29uRmlsZSA9IGZpbGVEYXRhO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgZ2V0QXBwSWNvbk5hbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faWNvbk5hbWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtVaW50OEFycmF5fVxuICAgICovXG4gICAgZ2V0QXBwSWNvbkZpbGVEYXRhICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ljb25GaWxlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IHNob3J0QXBwTmFtZVxuICAgICogQHJldHVybiB7QXBwQ29uZmlnfVxuICAgICovXG4gICAgc2V0U2hvcnRBcHBOYW1lIChzaG9ydEFwcE5hbWUpIHtcbiAgICAgICAgdGhpcy5fc2hvcnRBcHBOYW1lID0gc2hvcnRBcHBOYW1lO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIGdldFNob3J0QXBwTmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zaG9ydEFwcE5hbWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0FycmF5PFRUU0NodW5rPn0gdHRzTmFtZVxuICAgICogQHJldHVybiB7QXBwQ29uZmlnfVxuICAgICovXG4gICAgc2V0VHRzTmFtZSAodHRzTmFtZSkge1xuICAgICAgICB0aGlzLl90dHNOYW1lID0gdHRzTmFtZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtBcnJheTxUVFNDaHVuaz59XG4gICAgKi9cbiAgICBnZXRUdHNOYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3R0c05hbWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0FycmF5PFN0cmluZz59IHZyU3lub255bXNcbiAgICAqIEByZXR1cm4ge0FwcENvbmZpZ31cbiAgICAqL1xuICAgIHNldFZyU3lub255bXMgKHZyU3lub255bXMpIHtcbiAgICAgICAgdGhpcy5fdnJTeW5vbnltcyA9IHZyU3lub255bXM7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7QXJyYXk8U3RyaW5nPn1cbiAgICAqL1xuICAgIGdldFZyU3lub255bXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdnJTeW5vbnltcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNNZWRpYUFwcFxuICAgICogQHJldHVybiB7QXBwQ29uZmlnfVxuICAgICovXG4gICAgc2V0SXNNZWRpYUFwcCAoaXNNZWRpYUFwcCkge1xuICAgICAgICB0aGlzLl9pc01lZGlhQXBwID0gaXNNZWRpYUFwcDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICovXG4gICAgaXNNZWRpYUFwcCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc01lZGlhQXBwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtMYW5ndWFnZX0gbGFuZ3VhZ2VEZXNpcmVkXG4gICAgKiBAcmV0dXJuIHtBcHBDb25maWd9XG4gICAgKi9cbiAgICBzZXRMYW5ndWFnZURlc2lyZWQgKGxhbmd1YWdlRGVzaXJlZCkge1xuICAgICAgICB0aGlzLl9sYW5ndWFnZURlc2lyZWQgPSBsYW5ndWFnZURlc2lyZWQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TGFuZ3VhZ2V9XG4gICAgKi9cbiAgICBnZXRMYW5ndWFnZURlc2lyZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGFuZ3VhZ2VEZXNpcmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtMYW5ndWFnZX0gaG1pRGlzcGxheUxhbmd1YWdlRGVzaXJlZFxuICAgICogQHJldHVybiB7QXBwQ29uZmlnfVxuICAgICovXG4gICAgc2V0SG1pRGlzcGxheUxhbmd1YWdlRGVzaXJlZCAoaG1pRGlzcGxheUxhbmd1YWdlRGVzaXJlZCkge1xuICAgICAgICB0aGlzLl9obWlEaXNwbGF5TGFuZ3VhZ2VEZXNpcmVkID0gaG1pRGlzcGxheUxhbmd1YWdlRGVzaXJlZDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtMYW5ndWFnZX1cbiAgICAqL1xuICAgIGdldEhtaURpc3BsYXlMYW5ndWFnZURlc2lyZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faG1pRGlzcGxheUxhbmd1YWdlRGVzaXJlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7QXJyYXk8QXBwSE1JVHlwZT59IGFwcFR5cGVzIGFuIGFycmF5IG9mIG9yZGVyZWQgYXBwIHR5cGVzXG4gICAgKiBAcmV0dXJuIHtBcHBDb25maWd9XG4gICAgKi9cbiAgICBzZXRBcHBUeXBlcyAoYXBwVHlwZXMpIHtcbiAgICAgICAgdGhpcy5fYXBwVHlwZXMgPSBhcHBUeXBlcztcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtBcnJheTxBcHBITUlUeXBlPn1cbiAgICAqL1xuICAgIGdldEFwcFR5cGVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcFR5cGVzO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1RlbXBsYXRlQ29sb3JTY2hlbWV9IGRheUNvbG9yU2NoZW1lXG4gICAgKiBAcmV0dXJuIHtBcHBDb25maWd9XG4gICAgKi9cbiAgICBzZXREYXlDb2xvclNjaGVtZSAoZGF5Q29sb3JTY2hlbWUpIHtcbiAgICAgICAgdGhpcy5fZGF5Q29sb3JTY2hlbWUgPSBkYXlDb2xvclNjaGVtZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtUZW1wbGF0ZUNvbG9yU2NoZW1lfVxuICAgICovXG4gICAgZ2V0RGF5Q29sb3JTY2hlbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGF5Q29sb3JTY2hlbWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1RlbXBsYXRlQ29sb3JTY2hlbWV9IG5pZ2h0Q29sb3JTY2hlbWVcbiAgICAqIEByZXR1cm4ge0FwcENvbmZpZ31cbiAgICAqL1xuICAgIHNldE5pZ2h0Q29sb3JTY2hlbWUgKG5pZ2h0Q29sb3JTY2hlbWUpIHtcbiAgICAgICAgdGhpcy5fbmlnaHRDb2xvclNjaGVtZSA9IG5pZ2h0Q29sb3JTY2hlbWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7VGVtcGxhdGVDb2xvclNjaGVtZX1cbiAgICAqL1xuICAgIGdldE5pZ2h0Q29sb3JTY2hlbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbmlnaHRDb2xvclNjaGVtZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIFRoZSBtaW5pbXVtIFJQQyB2ZXJzaW9uIHRoYXQgd2lsbCBiZSBwZXJtaXR0ZWQgdG8gY29ubmVjdC5cbiAgICAqIElmIHRoZSBSUEMgdmVyc2lvbiBvZiB0aGUgaGVhZCB1bml0IGNvbm5lY3RlZCBpcyBiZWxvdyB0aGlzIHZlcnNpb24sIGFuIFVucmVnaXN0ZXJBcHBJbnRlcmZhY2Ugd2lsbCBiZSBzZW50LlxuICAgICpcbiAgICAqIEBwYXJhbSB7VmVyc2lvbn0gbWluaW11bVJQQ1ZlcnNpb25cbiAgICAqIEByZXR1cm4ge0FwcENvbmZpZ31cbiAgICAqL1xuICAgIHNldE1pbmltdW1SUENWZXJzaW9uIChtaW5pbXVtUlBDVmVyc2lvbikge1xuICAgICAgICB0aGlzLl9taW5pbXVtUlBDVmVyc2lvbiA9IG1pbmltdW1SUENWZXJzaW9uO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICogQHJldHVybiB7VmVyc2lvbn1cbiAgICAqL1xuICAgIGdldE1pbmltdW1SUENWZXJzaW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21pbmltdW1SUENWZXJzaW9uO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBTZXRzIHRoZSBtaW5pbXVtIHByb3RvY29sIHZlcnNpb24gdGhhdCB3aWxsIGJlIHBlcm1pdHRlZCB0byBjb25uZWN0LlxuICAgICogSWYgdGhlIHByb3RvY29sIHZlcnNpb24gb2YgdGhlIGhlYWQgdW5pdCBjb25uZWN0ZWQgaXMgYmVsb3cgdGhpcyB2ZXJzaW9uLFxuICAgICogdGhlIGFwcCB3aWxsIGRpc2Nvbm5lY3Qgd2l0aCBhbiBFbmRTZXJ2aWNlIHByb3RvY29sIG1lc3NhZ2UgYW5kIHdpbGwgbm90IHJlZ2lzdGVyLlxuICAgICogQHBhcmFtIHtWZXJzaW9ufSBtaW5pbXVtUHJvdG9jb2xWZXJzaW9uXG4gICAgKiBAcmV0dXJuIHtBcHBDb25maWd9XG4gICAgKi9cbiAgICBzZXRNaW5pbXVtUHJvdG9jb2xWZXJzaW9uIChtaW5pbXVtUHJvdG9jb2xWZXJzaW9uKSB7XG4gICAgICAgIHRoaXMuX21pbmltdW1Qcm90b2NvbFZlcnNpb24gPSBtaW5pbXVtUHJvdG9jb2xWZXJzaW9uO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1ZlcnNpb259XG4gICAgKi9cbiAgICBnZXRNaW5pbXVtUHJvdG9jb2xWZXJzaW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21pbmltdW1Qcm90b2NvbFZlcnNpb247XG4gICAgfVxufVxuXG5leHBvcnQgeyBBcHBDb25maWcgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBMaWZlY3ljbGVMaXN0ZW5lclxuICovXG5jbGFzcyBMaWZlY3ljbGVMaXN0ZW5lciB7XG4gICAgLyoqXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHRoaXMuX29uUHJveHlDb25uZWN0ZWQgPSBudWxsO1xuICAgICAgICB0aGlzLl9vblByb3h5Q2xvc2VkID0gbnVsbDtcbiAgICAgICAgdGhpcy5fb25TZXJ2aWNlU3RhcnRlZCA9IG51bGw7XG4gICAgICAgIHRoaXMuX29uU2VydmljZUVuZGVkID0gbnVsbDtcbiAgICAgICAgdGhpcy5fb25FcnJvciA9IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBzZXRPblByb3h5Q29ubmVjdGVkIChsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLl9vblByb3h5Q29ubmVjdGVkID0gbGlzdGVuZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBzZXRPblByb3h5Q2xvc2VkIChsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLl9vblByb3h5Q2xvc2VkID0gbGlzdGVuZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBzZXRPblNlcnZpY2VTdGFydGVkIChsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLl9vblNlcnZpY2VTdGFydGVkID0gbGlzdGVuZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBzZXRPblNlcnZpY2VFbmRlZCAobGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5fb25TZXJ2aWNlRW5kZWQgPSBsaXN0ZW5lcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBsaXN0ZW5lclxuICAgICAqL1xuICAgIHNldE9uRXJyb3IgKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMuX29uRXJyb3IgPSBsaXN0ZW5lcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0xpZmVjeWNsZU1hbmFnZXJ9IGxpZmVjeWNsZU1hbmFnZXJcblxuICAgICAqL1xuICAgIG9uUHJveHlDb25uZWN0ZWQgKGxpZmVjeWNsZU1hbmFnZXIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9vblByb3h5Q29ubmVjdGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9vblByb3h5Q29ubmVjdGVkKGxpZmVjeWNsZU1hbmFnZXIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtMaWZlY3ljbGVNYW5hZ2VyfSBsaWZlY3ljbGVNYW5hZ2VyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGluZm9cbiAgICAgKiBAcGFyYW0ge1NkbERpc2Nvbm5lY3RlZFJlYXNvbn0gcmVhc29uXG4gICAgICovXG4gICAgb25Qcm94eUNsb3NlZCAobGlmZWN5Y2xlTWFuYWdlciwgaW5mbywgcmVhc29uKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fb25Qcm94eUNsb3NlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5fb25Qcm94eUNsb3NlZChsaWZlY3ljbGVNYW5hZ2VyLCBpbmZvLCByZWFzb24pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTZXJ2aWNlVHlwZX0gc2VydmljZVR5cGVcbiAgICAgKi9cbiAgICBvblNlcnZpY2VTdGFydGVkIChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklELCBjb3JyZWxhdGlvbklEKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fb25Qcm90b2NvbFNlc3Npb25FbmRlZE5BQ0tlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5fb25TZXJ2aWNlU3RhcnRlZChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklELCBjb3JyZWxhdGlvbklEKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICovXG4gICAgb25TZXJ2aWNlRW5kZWQgKHNlcnZpY2VUeXBlKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fb25TZXJ2aWNlRW5kZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuX29uU2VydmljZUVuZGVkKHNlcnZpY2VUeXBlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TGlmZWN5Y2xlTWFuYWdlcn0gbGlmZWN5Y2xlTWFuYWdlclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBpbmZvXG4gICAgICovXG4gICAgb25FcnJvciAobGlmZWN5Y2xlTWFuYWdlciwgaW5mbykge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX29uRXJyb3IgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuX29uRXJyb3IobGlmZWN5Y2xlTWFuYWdlciwgaW5mbyk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCB7IExpZmVjeWNsZUxpc3RlbmVyIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmNsYXNzIEVudW0ge1xuICAgIC8qKlxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIC8vIGludGVudGlvbmFsbHkgZW1wdHlcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIFJldHVybnMgdGhlIGtleSBmb3IgYSBnaXZlbiB2YWx1ZSBpZiB0aGUgdmFsdWUgaXMgZm91bmQgd2l0aGluIHRoZSBrZXk6dmFsdWUgbWFwXG4gICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIGluIHRoZSBtYXBcbiAgICAqIEBwYXJhbSBtYXAge09iamVjdH0gLSBBbiBtYXAgb2Ygc3RyaW5nIHByb3BlcnRpZXMgdG8gcHJpbWl0aXZlIHZhbHVlc1xuICAgICogQHJldHVybiB7bnVsbHxTdHJpbmd9IC0gUmV0dXJucyBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIF9rZXlGb3JWYWx1ZSAodmFsdWUsIG1hcCkge1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBtYXApIHtcbiAgICAgICAgICAgIGlmIChtYXBba2V5XSA9PT0gdmFsdWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ga2V5O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBBIG1ldGhvZCBmb3Igc3ViY2xhc3NlcyB0byBpbXBsZW1lbnQgdGhhdCBkb2VzIHdoYXQgX2tleUZvclZhbHVlIGRvZXNcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAqL1xuICAgIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ21ldGhvZCBtdXN0IGJlIG92ZXJyaWRkZW4nKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIFJldHVybnMgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4ga2V5IGlmIHRoZSBrZXkgaXMgZm91bmQgd2l0aGluIHRoZSBrZXk6dmFsdWUgbWFwXG4gICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIGluIHRoZSBtYXBcbiAgICAqIEBwYXJhbSBtYXAge09iamVjdH0gLSBBbiBtYXAgb2Ygc3RyaW5nIHByb3BlcnRpZXMgdG8gcHJpbWl0aXZlIHZhbHVlc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMgX3ZhbHVlRm9yS2V5IChrZXksIG1hcCkge1xuICAgICAgICByZXR1cm4gbWFwW2tleV0gfHwgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEEgbWV0aG9kIGZvciBzdWJjbGFzc2VzIHRvIGltcGxlbWVudCB0aGF0IGRvZXMgd2hhdCBfdmFsdWVGb3JLZXkgZG9lc1xuICAgICogQHBhcmFtIHZhbHVlIC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbWV0aG9kIG11c3QgYmUgb3ZlcnJpZGRlbicpO1xuICAgIH1cbn1cblxuZXhwb3J0IHsgRW51bSB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vdXRpbC9FbnVtLmpzJztcblxuY2xhc3MgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMgPSB7fSkge1xuICAgICAgICB0aGlzLl9pc0Zvcm1hdFJlcXVlc3RlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9ycGNTcGVjVmVyc2lvbiA9IG51bGw7XG4gICAgICAgIHRoaXMuX3BhcmFtZXRlcnMgPSBwYXJhbWV0ZXJzIHx8IHt9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7T2JqZWN0fVxuICAgICovXG4gICAgZ2V0UGFyYW1ldGVycyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbWV0ZXJzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICAgICogQHJldHVybiB7Kn1cbiAgICAqL1xuICAgIGdldFBhcmFtZXRlciAoa2V5KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbWV0ZXJzW2tleV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5XG4gICAgKiBAcGFyYW0geyp9IHZhbHVlXG4gICAgKiBAcmV0dXJuIHtScGNTdHJ1Y3R9XG4gICAgKi9cbiAgICBzZXRQYXJhbWV0ZXIgKGtleSwgdmFsdWUpIHtcbiAgICAgICAgaWYgKHZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5fcGFyYW1ldGVyc1trZXldO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fcGFyYW1ldGVyc1trZXldID0gdmFsdWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHRDbGFzc1xuICAgICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICAgICogQHJldHVybiB7T2JqZWN0fVxuICAgICovXG4gICAgZ2V0T2JqZWN0ICh0Q2xhc3MsIGtleSkge1xuICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXRPYmplY3QodENsYXNzLCB0aGlzLmdldFBhcmFtZXRlcihrZXkpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHRDbGFzc1xuICAgICogQHBhcmFtIHtPYmplY3R9IG9ialxuICAgICogQHJldHVybiB7bnVsbHxPYmplY3R9XG4gICAgKi9cbiAgICBmb3JtYXRPYmplY3QgKHRDbGFzcywgb2JqKSB7XG4gICAgICAgIGlmIChvYmogPT09IG51bGwgfHwgb2JqID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9IGVsc2UgaWYgKG9iai5jb25zdHJ1Y3RvciA9PT0gdENsYXNzKSB7XG4gICAgICAgICAgICAvLyBpZiB0Q2xhc3MgaXMgU3RyaW5nIGFuZCBvYmogaXMgYSBTdHJpbmcsIHRoaXMgc2hvdWxkIGV4ZWN1dGVcbiAgICAgICAgICAgIHJldHVybiBvYmo7XG4gICAgICAgIH0gZWxzZSBpZiAob2JqLmNvbnN0cnVjdG9yID09PSBTdHJpbmcpIHsgLy8gdGhpcyBjb3ZlcnMgdGhlIEVudW0gY2FzZSB0b29cbiAgICAgICAgICAgIHJldHVybiBvYmo7XG4gICAgICAgIH0gZWxzZSBpZiAob2JqLmNvbnN0cnVjdG9yID09PSBPYmplY3QpIHtcbiAgICAgICAgICAgIGlmICh0Q2xhc3MucHJvdG90eXBlIGluc3RhbmNlb2YgUnBjU3RydWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyB0Q2xhc3Mob2JqKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9IGVsc2UgaWYgKG9iai5jb25zdHJ1Y3RvciA9PT0gQXJyYXkpIHtcbiAgICAgICAgICAgIGlmIChvYmoubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG91dEFycmF5ID0gW107XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIG9iaikge1xuICAgICAgICAgICAgICAgICAgICBvdXRBcnJheS5wdXNoKHRoaXMuZm9ybWF0T2JqZWN0KHRDbGFzcywgaXRlbSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gb3V0QXJyYXk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSB0Q2xhc3NcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNBcnJheSAoZmFsc2UpXG4gICAgKi9cbiAgICB2YWxpZGF0ZVR5cGUgKHRDbGFzcywgb2JqLCBpc0FycmF5ID0gZmFsc2UpIHtcbiAgICAgICAgaWYgKGlzQXJyYXkpIHtcbiAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iai5uYW1lfSBtdXN0IGJlIGFuIGFycmF5IGNvbnRhaW5pbmcgaXRlbXMgb2YgdHlwZSAke3RDbGFzcy5uYW1lfWApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2Ygb2JqKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKHRDbGFzcywgaXRlbSwgZmFsc2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgICh0Q2xhc3MucHJvdG90eXBlIGluc3RhbmNlb2YgRW51bSAmJiB0Q2xhc3Mua2V5Rm9yVmFsdWUob2JqKSA9PT0gbnVsbClcbiAgICAgICAgICAgIHx8ICh0Q2xhc3MucHJvdG90eXBlIGluc3RhbmNlb2YgUnBjU3RydWN0ICYmIG9iaiAhPT0gbnVsbCAmJiBvYmouY29uc3RydWN0b3IgIT09IHRDbGFzcylcbiAgICAgICAgKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7b2JqLm5hbWV9IG11c3QgYmUgb2YgdHlwZSAke3RDbGFzcy5uYW1lfWApO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgeyBScGNTdHJ1Y3QgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYge0VudW19IEZ1bmN0aW9uSURcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIEZ1bmN0aW9uSUQgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJlZ2lzdGVyQXBwSW50ZXJmYWNlICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5SZWdpc3RlckFwcEludGVyZmFjZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgVW5yZWdpc3RlckFwcEludGVyZmFjZSAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuVW5yZWdpc3RlckFwcEludGVyZmFjZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgU2V0R2xvYmFsUHJvcGVydGllcyAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuU2V0R2xvYmFsUHJvcGVydGllcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgUmVzZXRHbG9iYWxQcm9wZXJ0aWVzICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5SZXNldEdsb2JhbFByb3BlcnRpZXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFkZENvbW1hbmQgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkFkZENvbW1hbmQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IERlbGV0ZUNvbW1hbmQgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkRlbGV0ZUNvbW1hbmQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFkZFN1Yk1lbnUgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkFkZFN1Yk1lbnU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IERlbGV0ZVN1Yk1lbnUgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkRlbGV0ZVN1Yk1lbnU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IENyZWF0ZUludGVyYWN0aW9uQ2hvaWNlU2V0ICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5DcmVhdGVJbnRlcmFjdGlvbkNob2ljZVNldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgUGVyZm9ybUludGVyYWN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5QZXJmb3JtSW50ZXJhY3Rpb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IERlbGV0ZUludGVyYWN0aW9uQ2hvaWNlU2V0ICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5EZWxldGVJbnRlcmFjdGlvbkNob2ljZVNldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgQWxlcnQgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkFsZXJ0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBTaG93ICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5TaG93O1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBTcGVhayAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuU3BlYWs7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNldE1lZGlhQ2xvY2tUaW1lciAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuU2V0TWVkaWFDbG9ja1RpbWVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBQZXJmb3JtQXVkaW9QYXNzVGhydSAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuUGVyZm9ybUF1ZGlvUGFzc1RocnU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IEVuZEF1ZGlvUGFzc1RocnUgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkVuZEF1ZGlvUGFzc1RocnU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IFN1YnNjcmliZUJ1dHRvbiAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuU3Vic2NyaWJlQnV0dG9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBVbnN1YnNjcmliZUJ1dHRvbiAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuVW5zdWJzY3JpYmVCdXR0b247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IFN1YnNjcmliZVZlaGljbGVEYXRhICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5TdWJzY3JpYmVWZWhpY2xlRGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgVW5zdWJzY3JpYmVWZWhpY2xlRGF0YSAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgR2V0VmVoaWNsZURhdGEgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkdldFZlaGljbGVEYXRhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBSZWFkRElEICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5SZWFkRElEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBHZXREVENzICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5HZXREVENzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBTY3JvbGxhYmxlTWVzc2FnZSAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuU2Nyb2xsYWJsZU1lc3NhZ2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNsaWRlciAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuU2xpZGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBTaG93Q29uc3RhbnRUQlQgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlNob3dDb25zdGFudFRCVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgQWxlcnRNYW5ldXZlciAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuQWxlcnRNYW5ldXZlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgVXBkYXRlVHVybkxpc3QgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlVwZGF0ZVR1cm5MaXN0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBDaGFuZ2VSZWdpc3RyYXRpb24gKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkNoYW5nZVJlZ2lzdHJhdGlvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgR2VuZXJpY1Jlc3BvbnNlICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5HZW5lcmljUmVzcG9uc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IFB1dEZpbGUgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlB1dEZpbGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IERlbGV0ZUZpbGUgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkRlbGV0ZUZpbGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IExpc3RGaWxlcyAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuTGlzdEZpbGVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBTZXRBcHBJY29uICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5TZXRBcHBJY29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBTZXREaXNwbGF5TGF5b3V0ICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5TZXREaXNwbGF5TGF5b3V0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBEaWFnbm9zdGljTWVzc2FnZSAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuRGlhZ25vc3RpY01lc3NhZ2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IFN5c3RlbVJlcXVlc3QgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlN5c3RlbVJlcXVlc3Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNlbmRMb2NhdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuU2VuZExvY2F0aW9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBEaWFsTnVtYmVyICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5EaWFsTnVtYmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBCdXR0b25QcmVzcyAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuQnV0dG9uUHJlc3M7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IEdldEludGVyaW9yVmVoaWNsZURhdGEgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkdldEludGVyaW9yVmVoaWNsZURhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNldEludGVyaW9yVmVoaWNsZURhdGEgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlNldEludGVyaW9yVmVoaWNsZURhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IEdldFdheVBvaW50cyAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuR2V0V2F5UG9pbnRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBTdWJzY3JpYmVXYXlQb2ludHMgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlN1YnNjcmliZVdheVBvaW50cztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgVW5zdWJzY3JpYmVXYXlQb2ludHMgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlVuc3Vic2NyaWJlV2F5UG9pbnRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBHZXRTeXN0ZW1DYXBhYmlsaXR5ICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5HZXRTeXN0ZW1DYXBhYmlsaXR5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBTZW5kSGFwdGljRGF0YSAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuU2VuZEhhcHRpY0RhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNldENsb3VkQXBwUHJvcGVydGllcyAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuU2V0Q2xvdWRBcHBQcm9wZXJ0aWVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBHZXRDbG91ZEFwcFByb3BlcnRpZXMgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkdldENsb3VkQXBwUHJvcGVydGllcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgUHVibGlzaEFwcFNlcnZpY2UgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlB1Ymxpc2hBcHBTZXJ2aWNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBHZXRBcHBTZXJ2aWNlRGF0YSAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuR2V0QXBwU2VydmljZURhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IEdldEZpbGUgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkdldEZpbGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IFBlcmZvcm1BcHBTZXJ2aWNlSW50ZXJhY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlBlcmZvcm1BcHBTZXJ2aWNlSW50ZXJhY3Rpb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IFVucHVibGlzaEFwcFNlcnZpY2UgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlVucHVibGlzaEFwcFNlcnZpY2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IENhbmNlbEludGVyYWN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5DYW5jZWxJbnRlcmFjdGlvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ2xvc2VBcHBsaWNhdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuQ2xvc2VBcHBsaWNhdGlvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgU2hvd0FwcE1lbnUgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlNob3dBcHBNZW51O1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBDcmVhdGVXaW5kb3cgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkNyZWF0ZVdpbmRvdztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgRGVsZXRlV2luZG93ICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5EZWxldGVXaW5kb3c7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IEdldEludGVyaW9yVmVoaWNsZURhdGFDb25zZW50ICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5HZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgUmVsZWFzZUludGVyaW9yVmVoaWNsZURhdGFNb2R1bGUgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlJlbGVhc2VJbnRlcmlvclZlaGljbGVEYXRhTW9kdWxlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBPbkhNSVN0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuT25ITUlTdGF0dXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IE9uQXBwSW50ZXJmYWNlVW5yZWdpc3RlcmVkICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5PbkFwcEludGVyZmFjZVVucmVnaXN0ZXJlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgT25CdXR0b25FdmVudCAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuT25CdXR0b25FdmVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgT25CdXR0b25QcmVzcyAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuT25CdXR0b25QcmVzcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgT25WZWhpY2xlRGF0YSAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuT25WZWhpY2xlRGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgT25Db21tYW5kICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5PbkNvbW1hbmQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IE9uVEJUQ2xpZW50U3RhdGUgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLk9uVEJUQ2xpZW50U3RhdGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IE9uRHJpdmVyRGlzdHJhY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLk9uRHJpdmVyRGlzdHJhY3Rpb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IE9uUGVybWlzc2lvbnNDaGFuZ2UgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLk9uUGVybWlzc2lvbnNDaGFuZ2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IE9uQXVkaW9QYXNzVGhydSAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuT25BdWRpb1Bhc3NUaHJ1O1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBPbkxhbmd1YWdlQ2hhbmdlICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5Pbkxhbmd1YWdlQ2hhbmdlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBPbktleWJvYXJkSW5wdXQgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLk9uS2V5Ym9hcmRJbnB1dDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgT25Ub3VjaEV2ZW50ICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5PblRvdWNoRXZlbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IE9uU3lzdGVtUmVxdWVzdCAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuT25TeXN0ZW1SZXF1ZXN0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBPbkhhc2hDaGFuZ2UgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLk9uSGFzaENoYW5nZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgT25JbnRlcmlvclZlaGljbGVEYXRhICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5PbkludGVyaW9yVmVoaWNsZURhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IE9uV2F5UG9pbnRDaGFuZ2UgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLk9uV2F5UG9pbnRDaGFuZ2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IE9uUkNTdGF0dXMgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLk9uUkNTdGF0dXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IE9uQXBwU2VydmljZURhdGEgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLk9uQXBwU2VydmljZURhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IE9uU3lzdGVtQ2FwYWJpbGl0eVVwZGF0ZWQgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLk9uU3lzdGVtQ2FwYWJpbGl0eVVwZGF0ZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX3ZhbHVlRm9yS2V5KGtleSwgRnVuY3Rpb25JRC5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fa2V5Rm9yVmFsdWUodmFsdWUsIEZ1bmN0aW9uSUQuX01BUCk7XG4gICAgfVxufVxuXG5GdW5jdGlvbklELl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnUmVnaXN0ZXJBcHBJbnRlcmZhY2UnOiAgICAgICAgICAgICAgICAweDAxLFxuICAgICdVbnJlZ2lzdGVyQXBwSW50ZXJmYWNlJzogICAgICAgICAgICAgIDB4MDIsXG4gICAgJ1NldEdsb2JhbFByb3BlcnRpZXMnOiAgICAgICAgICAgICAgICAgMHgwMyxcbiAgICAnUmVzZXRHbG9iYWxQcm9wZXJ0aWVzJzogICAgICAgICAgICAgICAweDA0LFxuICAgICdBZGRDb21tYW5kJzogICAgICAgICAgICAgICAgICAgICAgICAgIDB4MDUsXG4gICAgJ0RlbGV0ZUNvbW1hbmQnOiAgICAgICAgICAgICAgICAgICAgICAgMHgwNixcbiAgICAnQWRkU3ViTWVudSc6ICAgICAgICAgICAgICAgICAgICAgICAgICAweDA3LFxuICAgICdEZWxldGVTdWJNZW51JzogICAgICAgICAgICAgICAgICAgICAgIDB4MDgsXG4gICAgJ0NyZWF0ZUludGVyYWN0aW9uQ2hvaWNlU2V0JzogICAgICAgICAgMHgwOSxcbiAgICAnUGVyZm9ybUludGVyYWN0aW9uJzogICAgICAgICAgICAgICAgICAweDBBLFxuICAgICdEZWxldGVJbnRlcmFjdGlvbkNob2ljZVNldCc6ICAgICAgICAgIDB4MEIsXG4gICAgJ0FsZXJ0JzogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwQyxcbiAgICAnU2hvdyc6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDBELFxuICAgICdTcGVhayc6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MEUsXG4gICAgJ1NldE1lZGlhQ2xvY2tUaW1lcic6ICAgICAgICAgICAgICAgICAgMHgwRixcbiAgICAnUGVyZm9ybUF1ZGlvUGFzc1RocnUnOiAgICAgICAgICAgICAgICAweDEwLFxuICAgICdFbmRBdWRpb1Bhc3NUaHJ1JzogICAgICAgICAgICAgICAgICAgIDB4MTEsXG4gICAgJ1N1YnNjcmliZUJ1dHRvbic6ICAgICAgICAgICAgICAgICAgICAgMHgxMixcbiAgICAnVW5zdWJzY3JpYmVCdXR0b24nOiAgICAgICAgICAgICAgICAgICAweDEzLFxuICAgICdTdWJzY3JpYmVWZWhpY2xlRGF0YSc6ICAgICAgICAgICAgICAgIDB4MTQsXG4gICAgJ1Vuc3Vic2NyaWJlVmVoaWNsZURhdGEnOiAgICAgICAgICAgICAgMHgxNSxcbiAgICAnR2V0VmVoaWNsZURhdGEnOiAgICAgICAgICAgICAgICAgICAgICAweDE2LFxuICAgICdSZWFkRElEJzogICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MTcsXG4gICAgJ0dldERUQ3MnOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxOCxcbiAgICAnU2Nyb2xsYWJsZU1lc3NhZ2UnOiAgICAgICAgICAgICAgICAgICAweDE5LFxuICAgICdTbGlkZXInOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MUEsXG4gICAgJ1Nob3dDb25zdGFudFRCVCc6ICAgICAgICAgICAgICAgICAgICAgMHgxQixcbiAgICAnQWxlcnRNYW5ldXZlcic6ICAgICAgICAgICAgICAgICAgICAgICAweDFDLFxuICAgICdVcGRhdGVUdXJuTGlzdCc6ICAgICAgICAgICAgICAgICAgICAgIDB4MUQsXG4gICAgJ0NoYW5nZVJlZ2lzdHJhdGlvbic6ICAgICAgICAgICAgICAgICAgMHgxRSxcbiAgICAnR2VuZXJpY1Jlc3BvbnNlJzogICAgICAgICAgICAgICAgICAgICAweDFGLFxuICAgICdQdXRGaWxlJzogICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MjAsXG4gICAgJ0RlbGV0ZUZpbGUnOiAgICAgICAgICAgICAgICAgICAgICAgICAgMHgyMSxcbiAgICAnTGlzdEZpbGVzJzogICAgICAgICAgICAgICAgICAgICAgICAgICAweDIyLFxuICAgICdTZXRBcHBJY29uJzogICAgICAgICAgICAgICAgICAgICAgICAgIDB4MjMsXG4gICAgJ1NldERpc3BsYXlMYXlvdXQnOiAgICAgICAgICAgICAgICAgICAgMHgyNCxcbiAgICAnRGlhZ25vc3RpY01lc3NhZ2UnOiAgICAgICAgICAgICAgICAgICAweDI1LFxuICAgICdTeXN0ZW1SZXF1ZXN0JzogICAgICAgICAgICAgICAgICAgICAgIDB4MjYsXG4gICAgJ1NlbmRMb2NhdGlvbic6ICAgICAgICAgICAgICAgICAgICAgICAgMHgyNyxcbiAgICAnRGlhbE51bWJlcic6ICAgICAgICAgICAgICAgICAgICAgICAgICAweDI4LFxuICAgICdCdXR0b25QcmVzcyc6ICAgICAgICAgICAgICAgICAgICAgICAgIDB4MjksXG4gICAgJ0dldEludGVyaW9yVmVoaWNsZURhdGEnOiAgICAgICAgICAgICAgMHgyQixcbiAgICAnU2V0SW50ZXJpb3JWZWhpY2xlRGF0YSc6ICAgICAgICAgICAgICAweDJDLFxuICAgICdHZXRXYXlQb2ludHMnOiAgICAgICAgICAgICAgICAgICAgICAgIDB4MkQsXG4gICAgJ1N1YnNjcmliZVdheVBvaW50cyc6ICAgICAgICAgICAgICAgICAgMHgyRSxcbiAgICAnVW5zdWJzY3JpYmVXYXlQb2ludHMnOiAgICAgICAgICAgICAgICAweDJGLFxuICAgICdHZXRTeXN0ZW1DYXBhYmlsaXR5JzogICAgICAgICAgICAgICAgIDB4MzAsXG4gICAgJ1NlbmRIYXB0aWNEYXRhJzogICAgICAgICAgICAgICAgICAgICAgMHgzMSxcbiAgICAnU2V0Q2xvdWRBcHBQcm9wZXJ0aWVzJzogICAgICAgICAgICAgICAweDMyLFxuICAgICdHZXRDbG91ZEFwcFByb3BlcnRpZXMnOiAgICAgICAgICAgICAgIDB4MzMsXG4gICAgJ1B1Ymxpc2hBcHBTZXJ2aWNlJzogICAgICAgICAgICAgICAgICAgMHgzNCxcbiAgICAnR2V0QXBwU2VydmljZURhdGEnOiAgICAgICAgICAgICAgICAgICAweDM1LFxuICAgICdHZXRGaWxlJzogICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MzYsXG4gICAgJ1BlcmZvcm1BcHBTZXJ2aWNlSW50ZXJhY3Rpb24nOiAgICAgICAgMHgzNyxcbiAgICAnVW5wdWJsaXNoQXBwU2VydmljZSc6ICAgICAgICAgICAgICAgICAweDM4LFxuICAgICdDYW5jZWxJbnRlcmFjdGlvbic6ICAgICAgICAgICAgICAgICAgIDB4MzksXG4gICAgJ0Nsb3NlQXBwbGljYXRpb24nOiAgICAgICAgICAgICAgICAgICAgMHgzQSxcbiAgICAnU2hvd0FwcE1lbnUnOiAgICAgICAgICAgICAgICAgICAgICAgICAweDNCLFxuICAgICdDcmVhdGVXaW5kb3cnOiAgICAgICAgICAgICAgICAgICAgICAgIDB4M0MsXG4gICAgJ0RlbGV0ZVdpbmRvdyc6ICAgICAgICAgICAgICAgICAgICAgICAgMHgzRCxcbiAgICAnR2V0SW50ZXJpb3JWZWhpY2xlRGF0YUNvbnNlbnQnOiAgICAgICAweDNFLFxuICAgICdSZWxlYXNlSW50ZXJpb3JWZWhpY2xlRGF0YU1vZHVsZSc6ICAgIDB4M0YsXG4gICAgJ09uSE1JU3RhdHVzJzogICAgICAgICAgICAgICAgICAgICAgICAgMHg4MDAwLFxuICAgICdPbkFwcEludGVyZmFjZVVucmVnaXN0ZXJlZCc6ICAgICAgICAgIDB4ODAwMSxcbiAgICAnT25CdXR0b25FdmVudCc6ICAgICAgICAgICAgICAgICAgICAgICAweDgwMDIsXG4gICAgJ09uQnV0dG9uUHJlc3MnOiAgICAgICAgICAgICAgICAgICAgICAgMHg4MDAzLFxuICAgICdPblZlaGljbGVEYXRhJzogICAgICAgICAgICAgICAgICAgICAgIDB4ODAwNCxcbiAgICAnT25Db21tYW5kJzogICAgICAgICAgICAgICAgICAgICAgICAgICAweDgwMDUsXG4gICAgJ09uVEJUQ2xpZW50U3RhdGUnOiAgICAgICAgICAgICAgICAgICAgMHg4MDA2LFxuICAgICdPbkRyaXZlckRpc3RyYWN0aW9uJzogICAgICAgICAgICAgICAgIDB4ODAwNyxcbiAgICAnT25QZXJtaXNzaW9uc0NoYW5nZSc6ICAgICAgICAgICAgICAgICAweDgwMDgsXG4gICAgJ09uQXVkaW9QYXNzVGhydSc6ICAgICAgICAgICAgICAgICAgICAgMHg4MDA5LFxuICAgICdPbkxhbmd1YWdlQ2hhbmdlJzogICAgICAgICAgICAgICAgICAgIDB4ODAwQSxcbiAgICAnT25LZXlib2FyZElucHV0JzogICAgICAgICAgICAgICAgICAgICAweDgwMEIsXG4gICAgJ09uVG91Y2hFdmVudCc6ICAgICAgICAgICAgICAgICAgICAgICAgMHg4MDBDLFxuICAgICdPblN5c3RlbVJlcXVlc3QnOiAgICAgICAgICAgICAgICAgICAgIDB4ODAwRCxcbiAgICAnT25IYXNoQ2hhbmdlJzogICAgICAgICAgICAgICAgICAgICAgICAweDgwMEUsXG4gICAgJ09uSW50ZXJpb3JWZWhpY2xlRGF0YSc6ICAgICAgICAgICAgICAgMHg4MDBGLFxuICAgICdPbldheVBvaW50Q2hhbmdlJzogICAgICAgICAgICAgICAgICAgIDB4ODAxMCxcbiAgICAnT25SQ1N0YXR1cyc6ICAgICAgICAgICAgICAgICAgICAgICAgICAweDgwMTEsXG4gICAgJ09uQXBwU2VydmljZURhdGEnOiAgICAgICAgICAgICAgICAgICAgMHg4MDEyLFxuICAgICdPblN5c3RlbUNhcGFiaWxpdHlVcGRhdGVkJzogICAgICAgICAgIDB4ODAxMyxcbn0pO1xuXG5leHBvcnQgeyBGdW5jdGlvbklEIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFJwY01lc3NhZ2VcbiAqIEBwcm9wZXJ0eSB7UnBjVHlwZX0gcnBjVHlwZVxuICovXG5jbGFzcyBScGNNZXNzYWdlIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKlxuICAgIHtcbiAgICAgICAgXCJycGNUeXBlXCI6IFwiUmVxdWVzdFwiLFxuICAgICAgICBcImZ1bmN0aW9uTmFtZVwiOiBcIlJlZ2lzdGVyQXBwSW50ZXJmYWNlXCIsXG4gICAgICAgIFwiY29vcmVsYXRpb25JRFwiOiBcIjMyMDk0OFwiLFxuICAgICAgICBcImlzRW5jcnlwdGVkXCI6IGZhbHNlLFxuICAgICAgICBcInBhcmFtZXRlcnNcIjoge1xuICAgICAgICAgICAgXCJhcHBOYW1lXCI6IFwiSGVsbG9cIlxuICAgICAgICB9LFxuICAgICAgICBcImJ1bGtEYXRhXCI6IFwiLi4uXCIsXG4gICAgfVxuICAgICovXG5cbiAgICAvKipcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlID0ge30pIHtcbiAgICAgICAgc3VwZXIoc3RvcmUucGFyYW1ldGVycyk7XG4gICAgICAgIHRoaXMuX2lzRW5jcnlwdGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3JwY1R5cGUgPSBzdG9yZS5ycGNUeXBlO1xuICAgICAgICB0aGlzLl9mdW5jdGlvbk5hbWUgPSBzdG9yZS5mdW5jdGlvbk5hbWU7XG4gICAgICAgIHRoaXMuX2NvcnJlbGF0aW9uSUQgPSBzdG9yZS5jb3JyZWxhdGlvbklEO1xuICAgICAgICB0aGlzLnNldEJ1bGtEYXRhKHN0b3JlLmJ1bGtEYXRhKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1JwY1R5cGV9XG4gICAgKi9cbiAgICBnZXRSUENUeXBlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JwY1R5cGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1JwY1R5cGV9IHR5cGVcbiAgICAqIEByZXR1cm4ge1JwY01lc3NhZ2V9XG4gICAgKi9cbiAgICBzZXRSUENUeXBlICh0eXBlKSB7XG4gICAgICAgIHRoaXMuX3JwY1R5cGUgPSB0eXBlO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7RnVuY3Rpb25JRH0gdHlwZVxuICAgICovXG4gICAgZ2V0RnVuY3Rpb25OYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Z1bmN0aW9uTmFtZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7RnVuY3Rpb25JRH0gbmFtZVxuICAgICogQHJldHVybiB7UnBjTWVzc2FnZX1cbiAgICAqL1xuICAgIHNldEZ1bmN0aW9uTmFtZSAobmFtZSkge1xuICAgICAgICBpZiAodHlwZW9mIG5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLl9mdW5jdGlvbk5hbWUgPSBGdW5jdGlvbklELmtleUZvclZhbHVlKG5hbWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fZnVuY3Rpb25OYW1lID0gbmFtZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfSB0eXBlXG4gICAgKi9cbiAgICBnZXRDb3JyZWxhdGlvbklkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvcnJlbGF0aW9uSUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICAgICogQHJldHVybiB7UnBjTWVzc2FnZX1cbiAgICAqL1xuICAgIHNldENvcnJlbGF0aW9uSWQgKGlkKSB7XG4gICAgICAgIHRoaXMuX2NvcnJlbGF0aW9uSUQgPSBpZDtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1VpbnQ4QXJyYXl9IGRhdGFcbiAgICAqL1xuICAgIGdldEJ1bGtEYXRhICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1bGtEYXRhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtVSW50OEFycmF5fSBkYXRhXG4gICAgKiBAcmV0dXJuIHtScGNNZXNzYWdlfVxuICAgICovXG4gICAgc2V0QnVsa0RhdGEgKGRhdGEgPSBudWxsKSB7XG4gICAgICAgIGlmIChkYXRhICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl9idWxrRGF0YSA9IGRhdGEuc2xpY2UoMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9idWxrRGF0YSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgKi9cbiAgICBnZXRJc0VuY3J5cHRlZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc0VuY3J5cHRlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYm9vbFxuICAgICogQHJldHVybiB7UnBjTWVzc2FnZX1cbiAgICAqL1xuICAgIHNldElzRW5jcnlwdGVkIChib29sKSB7XG4gICAgICAgIHRoaXMuX2lzRW5jcnlwdGVkID0gYm9vbDtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5cbmV4cG9ydCB7IFJwY01lc3NhZ2UgfTtcbiIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gUnBjVHlwZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgUnBjVHlwZSBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTk9USUZJQ0FUSU9OICgpIHtcbiAgICAgICAgcmV0dXJuIFJwY1R5cGUuX01BUC5OT1RJRklDQVRJT047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUkVTUE9OU0UgKCkge1xuICAgICAgICByZXR1cm4gUnBjVHlwZS5fTUFQLlJFU1BPTlNFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJFUVVFU1QgKCkge1xuICAgICAgICByZXR1cm4gUnBjVHlwZS5fTUFQLlJFUVVFU1Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFJwY1R5cGUuX3ZhbHVlRm9yS2V5KGtleSwgUnBjVHlwZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gUnBjVHlwZS5fa2V5Rm9yVmFsdWUodmFsdWUsIFJwY1R5cGUuX01BUCk7XG4gICAgfVxufVxuXG5ScGNUeXBlLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnTk9USUZJQ0FUSU9OJzogMHgyLFxuICAgICdSRVNQT05TRSc6IDB4MSxcbiAgICAnUkVRVUVTVCc6IDB4MCxcbn0pO1xuXG5leHBvcnQgeyBScGNUeXBlIH07XG4iLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuXG5pbXBvcnQgeyBScGNNZXNzYWdlIH0gZnJvbSAnLi9ScGNNZXNzYWdlLmpzJztcbmltcG9ydCB7IFJwY1R5cGUgfSBmcm9tICcuL2VudW1zL1JwY1R5cGUuanMnO1xuXG5jbGFzcyBScGNSZXF1ZXN0IGV4dGVuZHMgUnBjTWVzc2FnZSB7XG4gICAgLyoqXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0UlBDVHlwZShScGNUeXBlLlJFUVVFU1QpO1xuICAgICAgICB0aGlzLl9wcm9taXNlID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAgKi9cbiAgICBnZXRPblJQQ1Jlc3BvbnNlUHJvbWlzZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wcm9taXNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtQcm9taXNlfSBwcm9taXNlXG4gICAgKiBAcmV0dXJuIHtScGNNZXNzYWdlfVxuICAgICovXG4gICAgc2V0T25SUENSZXNwb25zZVByb21pc2UgKHByb21pc2UpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoUHJvbWlzZSwgcHJvbWlzZSk7XG5cbiAgICAgICAgdGhpcy5fcHJvbWlzZSA9IHByb21pc2U7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cblxuZXhwb3J0IHsgUnBjUmVxdWVzdCB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuXG5jbGFzcyBTZGxNc2dWZXJzaW9uIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSB0aGUgbWFqb3IgdmVyc2lvbiBvZiB0aGlzIG9iamVjdFxuICAgICogQHJldHVybiB7U2RsTXNnVmVyc2lvbn1cbiAgICAqL1xuICAgIHNldE1ham9yVmVyc2lvbiAodmFsdWUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2RsTXNnVmVyc2lvbi5LRVlfTUFKT1JfVkVSU0lPTiwgdmFsdWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn0gdGhlIG1ham9yIHZlcnNpb24gb2YgdGhpcyBvYmplY3RcbiAgICAqL1xuICAgIGdldE1ham9yVmVyc2lvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTZGxNc2dWZXJzaW9uLktFWV9NQUpPUl9WRVJTSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSB0aGUgbWlub3IgdmVyc2lvbiBvZiB0aGlzIG9iamVjdFxuICAgICogQHJldHVybiB7U2RsTXNnVmVyc2lvbn1cbiAgICAqL1xuICAgIHNldE1pbm9yVmVyc2lvbiAodmFsdWUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2RsTXNnVmVyc2lvbi5LRVlfTUlOT1JfVkVSU0lPTiwgdmFsdWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn0gdGhlIG1pbm9yIHZlcnNpb24gb2YgdGhpcyBvYmplY3RcbiAgICAqL1xuICAgIGdldE1pbm9yVmVyc2lvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTZGxNc2dWZXJzaW9uLktFWV9NSU5PUl9WRVJTSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSB0aGUgcGF0Y2ggdmVyc2lvbiBvZiB0aGlzIG9iamVjdFxuICAgICogQHJldHVybiB7U2RsTXNnVmVyc2lvbn1cbiAgICAqL1xuICAgIHNldFBhdGNoVmVyc2lvbiAodmFsdWUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2RsTXNnVmVyc2lvbi5LRVlfUEFUQ0hfVkVSU0lPTiwgdmFsdWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn0gdGhlIHBhdGNoIHZlcnNpb24gb2YgdGhpcyBvYmplY3RzXG4gICAgKi9cbiAgICBnZXRQYXRjaFZlcnNpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2RsTXNnVmVyc2lvbi5LRVlfUEFUQ0hfVkVSU0lPTik7XG4gICAgfVxufVxuXG5TZGxNc2dWZXJzaW9uLktFWV9NQUpPUl9WRVJTSU9OID0gJ21ham9yVmVyc2lvbic7XG5TZGxNc2dWZXJzaW9uLktFWV9NSU5PUl9WRVJTSU9OID0gJ21pbm9yVmVyc2lvbic7XG5TZGxNc2dWZXJzaW9uLktFWV9QQVRDSF9WRVJTSU9OID0gJ3BhdGNoVmVyc2lvbic7XG5cbmV4cG9ydCB7IFNkbE1zZ1ZlcnNpb24gfTtcbiIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gU3BlZWNoQ2FwYWJpbGl0aWVzXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBTcGVlY2hDYXBhYmlsaXRpZXMgZXh0ZW5kcyBFbnVtIHtcbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0NfVEVYVCAoKSB7XG4gICAgICAgIHJldHVybiBTcGVlY2hDYXBhYmlsaXRpZXMuX01BUC5TQ19URVhUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNBUElfUEhPTkVNRVMgKCkge1xuICAgICAgICByZXR1cm4gU3BlZWNoQ2FwYWJpbGl0aWVzLl9NQVAuU0FQSV9QSE9ORU1FUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBMSFBMVVNfUEhPTkVNRVMgKCkge1xuICAgICAgICByZXR1cm4gU3BlZWNoQ2FwYWJpbGl0aWVzLl9NQVAuTEhQTFVTX1BIT05FTUVTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFBSRV9SRUNPUkRFRCAoKSB7XG4gICAgICAgIHJldHVybiBTcGVlY2hDYXBhYmlsaXRpZXMuX01BUC5QUkVfUkVDT1JERUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0lMRU5DRSAoKSB7XG4gICAgICAgIHJldHVybiBTcGVlY2hDYXBhYmlsaXRpZXMuX01BUC5TSUxFTkNFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEZJTEUgKCkge1xuICAgICAgICByZXR1cm4gU3BlZWNoQ2FwYWJpbGl0aWVzLl9NQVAuRklMRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gU3BlZWNoQ2FwYWJpbGl0aWVzLl92YWx1ZUZvcktleShrZXksIFNwZWVjaENhcGFiaWxpdGllcy5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gU3BlZWNoQ2FwYWJpbGl0aWVzLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgU3BlZWNoQ2FwYWJpbGl0aWVzLl9NQVApO1xuICAgIH1cbn1cblxuU3BlZWNoQ2FwYWJpbGl0aWVzLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnU0NfVEVYVCc6ICdURVhUJyxcbiAgICAnU0FQSV9QSE9ORU1FUyc6ICdTQVBJX1BIT05FTUVTJyxcbiAgICAnTEhQTFVTX1BIT05FTUVTJzogJ0xIUExVU19QSE9ORU1FUycsXG4gICAgJ1BSRV9SRUNPUkRFRCc6ICdQUkVfUkVDT1JERUQnLFxuICAgICdTSUxFTkNFJzogJ1NJTEVOQ0UnLFxuICAgICdGSUxFJzogJ0ZJTEUnLFxufSk7XG5cbmV4cG9ydCB7IFNwZWVjaENhcGFiaWxpdGllcyB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgU3BlZWNoQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi4vZW51bXMvU3BlZWNoQ2FwYWJpbGl0aWVzLmpzJztcblxuY2xhc3MgVFRTQ2h1bmsgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IHRleHRcbiAgICAqIEByZXR1cm4ge1RUU0NodW5rfVxuICAgICovXG4gICAgc2V0VGV4dCAodGV4dCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihUVFNDaHVuay5LRVlfVEVYVCwgdGV4dCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgZ2V0VGV4dCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihUVFNDaHVuay5LRVlfVEVYVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1NwZWVjaENhcGFiaWxpdGllc30gdHlwZVxuICAgICogQHJldHVybiB7VFRTQ2h1bmt9XG4gICAgKi9cbiAgICBzZXRUeXBlICh0eXBlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFNwZWVjaENhcGFiaWxpdGllcywgdHlwZSk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVFRTQ2h1bmsuS0VZX1RZUEUsIHR5cGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1NwZWVjaENhcGFiaWxpdGllc31cbiAgICAqL1xuICAgIGdldFR5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoU3BlZWNoQ2FwYWJpbGl0aWVzLCBUVFNDaHVuay5LRVlfVFlQRSk7XG4gICAgfVxufVxuXG5UVFNDaHVuay5LRVlfVEVYVCA9ICd0ZXh0JztcblRUU0NodW5rLktFWV9UWVBFID0gJ3R5cGUnO1xuXG5leHBvcnQgeyBUVFNDaHVuayB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5cbmNsYXNzIERldmljZUluZm8gZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IGhhcmR3YXJlXG4gICAgKiBAcmV0dXJuIHtEZXZpY2VJbmZvfVxuICAgICovXG4gICAgc2V0SGFyZHdhcmUgKGhhcmR3YXJlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFN0cmluZywgaGFyZHdhcmUpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKERldmljZUluZm8uS0VZX0hBUkRXQVJFLCBoYXJkd2FyZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgZ2V0SGFyZHdhcmUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoRGV2aWNlSW5mby5LRVlfSEFSRFdBUkUpO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gZmlybXdhcmVSZXZcbiAgICAqIEByZXR1cm4ge0RldmljZUluZm99XG4gICAgKi9cbiAgICBzZXRGaXJtd2FyZVJldiAoZmlybXdhcmVSZXYpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoU3RyaW5nLCBmaXJtd2FyZVJldik7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGV2aWNlSW5mby5LRVlfRklSTVdBUkVfUkVWLCBmaXJtd2FyZVJldik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgZ2V0RmlybXdhcmVSZXYgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoRGV2aWNlSW5mby5LRVlfRklSTVdBUkVfUkVWKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IG9zXG4gICAgKiBAcmV0dXJuIHtEZXZpY2VJbmZvfVxuICAgICovXG4gICAgc2V0T3MgKG9zKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFN0cmluZywgb3MpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKERldmljZUluZm8uS0VZX09TLCBvcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgZ2V0T3MgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoRGV2aWNlSW5mby5LRVlfT1MpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IG9zVmVyc2lvblxuICAgICogQHJldHVybiB7RGV2aWNlSW5mb31cbiAgICAqL1xuICAgIHNldE9zVmVyc2lvbiAob3NWZXJzaW9uKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFN0cmluZywgb3NWZXJzaW9uKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihEZXZpY2VJbmZvLktFWV9PU19WRVJTSU9OLCBvc1ZlcnNpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIGdldE9zVmVyc2lvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihEZXZpY2VJbmZvLktFWV9PU19WRVJTSU9OKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IGNhcnJpZXJcbiAgICAqIEByZXR1cm4ge0RldmljZUluZm99XG4gICAgKi9cbiAgICBzZXRDYXJyaWVyIChjYXJyaWVyKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFN0cmluZywgY2Fycmllcik7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGV2aWNlSW5mby5LRVlfQ0FSUklFUiwgY2Fycmllcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgZ2V0Q2FycmllciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihEZXZpY2VJbmZvLktFWV9DQVJSSUVSKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtOdW1iZXJ9IG1heE51bWJlclJGQ09NTVBvcnRzXG4gICAgKiBAcmV0dXJuIHtEZXZpY2VJbmZvfVxuICAgICovXG4gICAgc2V0TWF4TnVtYmVyUkZDT01NUG9ydHMgKG1heE51bWJlclJGQ09NTVBvcnRzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKE51bWJlciwgbWF4TnVtYmVyUkZDT01NUG9ydHMpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKERldmljZUluZm8uS0VZX01BWF9OVU1CRVJfUkZDT01NX1BPUlRTLCBtYXhOdW1iZXJSRkNPTU1Qb3J0cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgZ2V0TWF4TnVtYmVyUkZDT01NUG9ydHMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoRGV2aWNlSW5mby5LRVlfTUFYX05VTUJFUl9SRkNPTU1fUE9SVFMpO1xuICAgIH1cbn1cblxuRGV2aWNlSW5mby5LRVlfSEFSRFdBUkUgPSAnaGFyZHdhcmUnO1xuRGV2aWNlSW5mby5LRVlfRklSTVdBUkVfUkVWID0gJ2Zpcm13YXJlUmV2JztcbkRldmljZUluZm8uS0VZX09TID0gJ29zJztcbkRldmljZUluZm8uS0VZX09TX1ZFUlNJT04gPSAnb3NWZXJzaW9uJztcbkRldmljZUluZm8uS0VZX0NBUlJJRVIgPSAnY2Fycmllcic7XG5EZXZpY2VJbmZvLktFWV9NQVhfTlVNQkVSX1JGQ09NTV9QT1JUUyA9ICdtYXhOdW1iZXJSRkNPTU1Qb3J0cyc7XG5cbmV4cG9ydCB7IERldmljZUluZm8gfTtcbiIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuXG5jbGFzcyBBcHBJbmZvIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBhcHBEaXNwbGF5TmFtZVxuICAgICogQHJldHVybiB7QXBwSW5mb31cbiAgICAqL1xuICAgIHNldEFwcERpc3BsYXlOYW1lIChhcHBEaXNwbGF5TmFtZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBcHBJbmZvLktFWV9BUFBfRElTUExBWV9OQU1FLCBhcHBEaXNwbGF5TmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgZ2V0QXBwRGlzcGxheU5hbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQXBwSW5mby5LRVlfQVBQX0RJU1BMQVlfTkFNRSk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBhcHBCdW5kbGVJRFxuICAgICogQHJldHVybiB7QXBwSW5mb31cbiAgICAqL1xuICAgIHNldEFwcEJ1bmRsZUlEIChhcHBCdW5kbGVJRCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBcHBJbmZvLktFWV9BUFBfQlVORExFX0lELCBhcHBCdW5kbGVJRCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgZ2V0QXBwQnVuZGxlSUQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQXBwSW5mby5LRVlfQVBQX0JVTkRMRV9JRCk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBhcHBWZXJzaW9uXG4gICAgKiBAcmV0dXJuIHtBcHBJbmZvfVxuICAgICovXG4gICAgc2V0QXBwVmVyc2lvbiAoYXBwVmVyc2lvbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBcHBJbmZvLktFWV9BUFBfVkVSU0lPTiwgYXBwVmVyc2lvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgZ2V0QXBwVmVyc2lvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihBcHBJbmZvLktFWV9BUFBfVkVSU0lPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gYXBwSWNvbiBzdHJpbmcgb2YgdGhlIGFwcCBpY29uIGZpbGUgbmFtZVxuICAgICogQHJldHVybiB7QXBwSW5mb31cbiAgICAqL1xuICAgIHNldEFwcEljb24gKGFwcEljb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQXBwSW5mby5LRVlfQVBQX0lDT04sIGFwcEljb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIGdldEFwcEljb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQXBwSW5mby5LRVlfQVBQX0lDT04pO1xuICAgIH1cbn1cblxuQXBwSW5mby5LRVlfQVBQX0RJU1BMQVlfTkFNRSA9ICdhcHBEaXNwbGF5TmFtZSc7XG5BcHBJbmZvLktFWV9BUFBfQlVORExFX0lEID0gJ2FwcEJ1bmRsZUlEJztcbkFwcEluZm8uS0VZX0FQUF9WRVJTSU9OID0gJ2FwcFZlcnNpb24nO1xuQXBwSW5mby5LRVlfQVBQX0lDT04gPSAnYXBwSWNvbic7XG5cbmV4cG9ydCB7IEFwcEluZm8gfTtcbiIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuXG5jbGFzcyBSR0JDb2xvciBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge051bWJlcn0gcmVkVmFsdWVcbiAgICAqIEByZXR1cm4ge1JHQkNvbG9yfVxuICAgICovXG4gICAgc2V0UmVkVmFsdWUgKHJlZFZhbHVlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJHQkNvbG9yLktFWV9SRUQsIHJlZFZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBnZXRSZWRWYWx1ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSR0JDb2xvci5LRVlfUkVEKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtOdW1iZXJ9IGdyZWVuVmFsdWVcbiAgICAqIEByZXR1cm4ge1JHQkNvbG9yfVxuICAgICovXG4gICAgc2V0R3JlZW5WYWx1ZSAoZ3JlZW5WYWx1ZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSR0JDb2xvci5LRVlfR1JFRU4sIGdyZWVuVmFsdWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIGdldEdyZWVuVmFsdWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUkdCQ29sb3IuS0VZX0dSRUVOKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtOdW1iZXJ9IGJsdWVWYWx1ZVxuICAgICogQHJldHVybiB7UkdCQ29sb3J9XG4gICAgKi9cbiAgICBzZXRCbHVlVmFsdWUgKGJsdWVWYWx1ZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSR0JDb2xvci5LRVlfQkxVRSwgYmx1ZVZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBnZXRCbHVlVmFsdWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUkdCQ29sb3IuS0VZX0JMVUUpO1xuICAgIH1cbn1cblxuUkdCQ29sb3IuS0VZX1JFRCA9ICdyZWQnO1xuUkdCQ29sb3IuS0VZX0dSRUVOID0gJ2dyZWVuJztcblJHQkNvbG9yLktFWV9CTFVFID0gJ2JsdWUnO1xuXG5leHBvcnQgeyBSR0JDb2xvciB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBSR0JDb2xvciB9IGZyb20gJy4vUkdCQ29sb3IuanMnO1xuXG5jbGFzcyBUZW1wbGF0ZUNvbG9yU2NoZW1lIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7UkdCQ29sb3J9IHByaW1hcnlDb2xvclxuICAgICogQHJldHVybiB7VGVtcGxhdGVDb2xvclNjaGVtZX1cbiAgICAqL1xuICAgIHNldFByaW1hcnlDb2xvciAocHJpbWFyeUNvbG9yKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFJHQkNvbG9yLCBwcmltYXJ5Q29sb3IpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFRlbXBsYXRlQ29sb3JTY2hlbWUuS0VZX1BSSU1BUllfQ09MT1IsIHByaW1hcnlDb2xvcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7UkdCQ29sb3J9XG4gICAgKi9cbiAgICBnZXRQcmltYXJ5Q29sb3IgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoUkdCQ29sb3IsIFRlbXBsYXRlQ29sb3JTY2hlbWUuS0VZX1BSSU1BUllfQ09MT1IpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtSR0JDb2xvcn0gc2Vjb25kYXJ5Q29sb3JcbiAgICAqIEByZXR1cm4ge1RlbXBsYXRlQ29sb3JTY2hlbWV9XG4gICAgKi9cbiAgICBzZXRTZWNvbmRhcnlDb2xvciAoc2Vjb25kYXJ5Q29sb3IpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoUkdCQ29sb3IsIHNlY29uZGFyeUNvbG9yKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihUZW1wbGF0ZUNvbG9yU2NoZW1lLktFWV9TRUNPTkRBUllfQ09MT1IsIHNlY29uZGFyeUNvbG9yKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtSR0JDb2xvcn1cbiAgICAqL1xuICAgIGdldFNlY29uZGFyeUNvbG9yICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFJHQkNvbG9yLCBUZW1wbGF0ZUNvbG9yU2NoZW1lLktFWV9TRUNPTkRBUllfQ09MT1IpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtSR0JDb2xvcn0gYmFja2dyb3VuZENvbG9yXG4gICAgKiBAcmV0dXJuIHtUZW1wbGF0ZUNvbG9yU2NoZW1lfVxuICAgICovXG4gICAgc2V0QmFja2dyb3VuZENvbG9yIChiYWNrZ3JvdW5kQ29sb3IpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoUkdCQ29sb3IsIGJhY2tncm91bmRDb2xvcik7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVGVtcGxhdGVDb2xvclNjaGVtZS5LRVlfQkFDS0dST1VORF9DT0xPUiwgYmFja2dyb3VuZENvbG9yKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtSR0JDb2xvcn1cbiAgICAqL1xuICAgIGdldEJhY2tncm91bmRDb2xvciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChSR0JDb2xvciwgVGVtcGxhdGVDb2xvclNjaGVtZS5LRVlfQkFDS0dST1VORF9DT0xPUik7XG4gICAgfVxufVxuXG5UZW1wbGF0ZUNvbG9yU2NoZW1lLktFWV9QUklNQVJZX0NPTE9SID0gJ3ByaW1hcnlDb2xvcic7XG5UZW1wbGF0ZUNvbG9yU2NoZW1lLktFWV9TRUNPTkRBUllfQ09MT1IgPSAnc2Vjb25kYXJ5Q29sb3InO1xuVGVtcGxhdGVDb2xvclNjaGVtZS5LRVlfQkFDS0dST1VORF9DT0xPUiA9ICdiYWNrZ3JvdW5kQ29sb3InO1xuXG5leHBvcnQgeyBUZW1wbGF0ZUNvbG9yU2NoZW1lIH07XG4iLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYge0VudW19IExhbmd1YWdlXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBMYW5ndWFnZSBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFTl9TQSAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLkVOX1NBO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEhFX0lMICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuSEVfSUw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUk9fUk8gKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5ST19STztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBVS19VQSAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLlVLX1VBO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IElEX0lEICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuSURfSUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVklfVk4gKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5WSV9WTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBNU19NWSAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLk1TX01ZO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEhJX0lOICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuSElfSU47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTkxfQkUgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5OTF9CRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFTF9HUiAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLkVMX0dSO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEhVX0hVICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuSFVfSFU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRklfRkkgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5GSV9GSTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTS19TSyAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLlNLX1NLO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEVOX1VTICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuRU5fVVM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRVNfTVggKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5FU19NWDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBGUl9DQSAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLkZSX0NBO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IERFX0RFICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuREVfREU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRVNfRVMgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5FU19FUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFTl9HQiAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLkVOX0dCO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJVX1JVICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuUlVfUlU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVFJfVFIgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5UUl9UUjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBQTF9QTCAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLlBMX1BMO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEZSX0ZSICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuRlJfRlI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSVRfSVQgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5JVF9JVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTVl9TRSAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLlNWX1NFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFBUX1BUICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuUFRfUFQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTkxfTkwgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5OTF9OTDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFTl9BVSAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLkVOX0FVO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFpIX0NOICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuWkhfQ047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgWkhfVFcgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5aSF9UVztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBKQV9KUCAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLkpBX0pQO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFSX1NBICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuQVJfU0E7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgS09fS1IgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5LT19LUjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBQVF9CUiAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLlBUX0JSO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENTX0NaICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuQ1NfQ1o7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgREFfREsgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5EQV9ESztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOT19OTyAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLk5PX05PO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEVOX0lOICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuRU5fSU47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVEhfVEggKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5USF9USDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX3ZhbHVlRm9yS2V5KGtleSwgTGFuZ3VhZ2UuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgTGFuZ3VhZ2UuX01BUCk7XG4gICAgfVxufVxuXG5MYW5ndWFnZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0VOX1NBJzogJ0VOLVNBJyxcbiAgICAnSEVfSUwnOiAnSEUtSUwnLFxuICAgICdST19STyc6ICdSTy1STycsXG4gICAgJ1VLX1VBJzogJ1VLLVVBJyxcbiAgICAnSURfSUQnOiAnSUQtSUQnLFxuICAgICdWSV9WTic6ICdWSS1WTicsXG4gICAgJ01TX01ZJzogJ01TLU1ZJyxcbiAgICAnSElfSU4nOiAnSEktSU4nLFxuICAgICdOTF9CRSc6ICdOTC1CRScsXG4gICAgJ0VMX0dSJzogJ0VMLUdSJyxcbiAgICAnSFVfSFUnOiAnSFUtSFUnLFxuICAgICdGSV9GSSc6ICdGSS1GSScsXG4gICAgJ1NLX1NLJzogJ1NLLVNLJyxcbiAgICAnRU5fVVMnOiAnRU4tVVMnLFxuICAgICdFU19NWCc6ICdFUy1NWCcsXG4gICAgJ0ZSX0NBJzogJ0ZSLUNBJyxcbiAgICAnREVfREUnOiAnREUtREUnLFxuICAgICdFU19FUyc6ICdFUy1FUycsXG4gICAgJ0VOX0dCJzogJ0VOLUdCJyxcbiAgICAnUlVfUlUnOiAnUlUtUlUnLFxuICAgICdUUl9UUic6ICdUUi1UUicsXG4gICAgJ1BMX1BMJzogJ1BMLVBMJyxcbiAgICAnRlJfRlInOiAnRlItRlInLFxuICAgICdJVF9JVCc6ICdJVC1JVCcsXG4gICAgJ1NWX1NFJzogJ1NWLVNFJyxcbiAgICAnUFRfUFQnOiAnUFQtUFQnLFxuICAgICdOTF9OTCc6ICdOTC1OTCcsXG4gICAgJ0VOX0FVJzogJ0VOLUFVJyxcbiAgICAnWkhfQ04nOiAnWkgtQ04nLFxuICAgICdaSF9UVyc6ICdaSC1UVycsXG4gICAgJ0pBX0pQJzogJ0pBLUpQJyxcbiAgICAnQVJfU0EnOiAnQVItU0EnLFxuICAgICdLT19LUic6ICdLTy1LUicsXG4gICAgJ1BUX0JSJzogJ1BULUJSJyxcbiAgICAnQ1NfQ1onOiAnQ1MtQ1onLFxuICAgICdEQV9ESyc6ICdEQS1ESycsXG4gICAgJ05PX05PJzogJ05PLU5PJyxcbiAgICAnRU5fSU4nOiAnRU4tSU4nLFxuICAgICdUSF9USCc6ICdUSC1USCcsXG59KTtcblxuXG5leHBvcnQgeyBMYW5ndWFnZSB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gQXBwSE1JVHlwZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgQXBwSE1JVHlwZSBleHRlbmRzIEVudW0ge1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBERUZBVUxUICgpIHtcbiAgICAgICAgcmV0dXJuIEFwcEhNSVR5cGUuX01BUC5ERUZBVUxUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENPTU1VTklDQVRJT04gKCkge1xuICAgICAgICByZXR1cm4gQXBwSE1JVHlwZS5fTUFQLkNPTU1VTklDQVRJT047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTUVESUEgKCkge1xuICAgICAgICByZXR1cm4gQXBwSE1JVHlwZS5fTUFQLk1FRElBO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE1FU1NBR0lORyAoKSB7XG4gICAgICAgIHJldHVybiBBcHBITUlUeXBlLl9NQVAuTUVTU0FHSU5HO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5BVklHQVRJT04gKCkge1xuICAgICAgICByZXR1cm4gQXBwSE1JVHlwZS5fTUFQLk5BVklHQVRJT047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSU5GT1JNQVRJT04gKCkge1xuICAgICAgICByZXR1cm4gQXBwSE1JVHlwZS5fTUFQLklORk9STUFUSU9OO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNPQ0lBTCAoKSB7XG4gICAgICAgIHJldHVybiBBcHBITUlUeXBlLl9NQVAuU09DSUFMO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEJBQ0tHUk9VTkRfUFJPQ0VTUyAoKSB7XG4gICAgICAgIHJldHVybiBBcHBITUlUeXBlLl9NQVAuQkFDS0dST1VORF9QUk9DRVNTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFRFU1RJTkcgKCkge1xuICAgICAgICByZXR1cm4gQXBwSE1JVHlwZS5fTUFQLlRFU1RJTkc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU1lTVEVNICgpIHtcbiAgICAgICAgcmV0dXJuIEFwcEhNSVR5cGUuX01BUC5TWVNURU07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUFJPSkVDVElPTiAoKSB7XG4gICAgICAgIHJldHVybiBBcHBITUlUeXBlLl9NQVAuUFJPSkVDVElPTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSRU1PVEVfQ09OVFJPTCAoKSB7XG4gICAgICAgIHJldHVybiBBcHBITUlUeXBlLl9NQVAuUkVNT1RFX0NPTlRST0w7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIEFwcEhNSVR5cGUuX3ZhbHVlRm9yS2V5KGtleSwgQXBwSE1JVHlwZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gQXBwSE1JVHlwZS5fa2V5Rm9yVmFsdWUodmFsdWUsIEFwcEhNSVR5cGUuX01BUCk7XG4gICAgfVxufVxuXG5BcHBITUlUeXBlLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnREVGQVVMVCc6ICdERUZBVUxUJyxcbiAgICAnQ09NTVVOSUNBVElPTic6ICdDT01NVU5JQ0FUSU9OJyxcbiAgICAnTUVESUEnOiAnTUVESUEnLFxuICAgICdNRVNTQUdJTkcnOiAnTUVTU0FHSU5HJyxcbiAgICAnTkFWSUdBVElPTic6ICdOQVZJR0FUSU9OJyxcbiAgICAnSU5GT1JNQVRJT04nOiAnSU5GT1JNQVRJT04nLFxuICAgICdTT0NJQUwnOiAnU09DSUFMJyxcbiAgICAnQkFDS0dST1VORF9QUk9DRVNTJzogJ0JBQ0tHUk9VTkRfUFJPQ0VTUycsXG4gICAgJ1RFU1RJTkcnOiAnVEVTVElORycsXG4gICAgJ1NZU1RFTSc6ICdTWVNURU0nLFxuICAgICdQUk9KRUNUSU9OJzogJ1BST0pFQ1RJT04nLFxuICAgICdSRU1PVEVfQ09OVFJPTCc6ICdSRU1PVEVfQ09OVFJPTCcsXG59KTtcblxuZXhwb3J0IHsgQXBwSE1JVHlwZSB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBTZGxNc2dWZXJzaW9uIH0gZnJvbSAnLi4vc3RydWN0cy9TZGxNc2dWZXJzaW9uLmpzJztcbmltcG9ydCB7IFRUU0NodW5rIH0gZnJvbSAnLi4vc3RydWN0cy9UVFNDaHVuay5qcyc7XG5pbXBvcnQgeyBEZXZpY2VJbmZvIH0gZnJvbSAnLi4vc3RydWN0cy9EZXZpY2VJbmZvLmpzJztcbmltcG9ydCB7IEFwcEluZm8gfSBmcm9tICcuLi9zdHJ1Y3RzL0FwcEluZm8uanMnO1xuaW1wb3J0IHsgVGVtcGxhdGVDb2xvclNjaGVtZSB9IGZyb20gJy4uL3N0cnVjdHMvVGVtcGxhdGVDb2xvclNjaGVtZS5qcyc7XG5cbmltcG9ydCB7IExhbmd1YWdlIH0gZnJvbSAnLi4vZW51bXMvTGFuZ3VhZ2UuanMnO1xuaW1wb3J0IHsgQXBwSE1JVHlwZSB9IGZyb20gJy4uL2VudW1zL0FwcEhNSVR5cGUuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG5jbGFzcyBSZWdpc3RlckFwcEludGVyZmFjZSBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuUmVnaXN0ZXJBcHBJbnRlcmZhY2UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTZGxNc2dWZXJzaW9ufSBUaGUgbWF4IFJQQyBTcGVjIHZlcnNpb24gc3VwcG9ydGVkIGJ5IHRoaXMgbGlicmFyeVxuICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2V9XG4gICAgKi9cbiAgICBzZXRTZGxNc2dWZXJzaW9uIChzZGxNc2dWZXJzaW9uKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFNkbE1zZ1ZlcnNpb24sIHNkbE1zZ1ZlcnNpb24pO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9TRExfTVNHX1ZFUlNJT04sIHNkbE1zZ1ZlcnNpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1NkbE1zZ1ZlcnNpb259XG4gICAgKi9cbiAgICBnZXRTZGxNc2dWZXJzaW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFNkbE1zZ1ZlcnNpb24sIFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9TRExfTVNHX1ZFUlNJT04pO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gYXBwTmFtZSB0aGUgbmFtZSBvZiB0aGUgYXBwIHRoYXQgaXMgcmVnaXN0ZXJpbmdcbiAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlfVxuICAgICovXG4gICAgc2V0QXBwTmFtZSAoYXBwTmFtZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShTdHJpbmcsIGFwcE5hbWUpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9BUFBfTkFNRSwgYXBwTmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfSB0aGUgYXBwIG5hbWVcbiAgICAqL1xuICAgIGdldEFwcE5hbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0FQUF9OQU1FKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICogQHBhcmFtIHtBcnJheTxUVFNDaHVuaz59IHR0c05hbWVzIFRUUyBzdHJpbmcgZm9yIFZSIHJlY29nbml0aW9uIG9mIHRoZSBtb2JpbGUgYXBwbGljYXRpb24gbmFtZSwgZS5nLiBcIk15IFMgRCBMIEFwcFwiLlxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVhbnQgdG8gb3ZlcmNvbWUgYW55IGZhaWxpbmcgb24gc3BlZWNoIGVuZ2luZSBpbiBwcm9wZXJseSBwcm9ub3VuY2luZyAvIHVuZGVyc3RhbmRpbmdcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcCBuYW1lLiBOZWVkcyB0byBiZSB1bmlxdWUgb3ZlciBhbGwgYXBwbGljYXRpb25zIGZyb20gdGhlIHNhbWUgZGV2aWNlLiBNYXkgbm90IGJlXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbXB0eS4gTWF5IG5vdCBzdGFydCB3aXRoIGEgbmV3IGxpbmUgY2hhcmFjdGVyLiBPbmx5IGNoYXJhY3RlcnMgZnJvbSBjaGFyIHNldFxuICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZX1cbiAgICovXG4gICAgc2V0VHRzTmFtZSAodHRzTmFtZXMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX1RUU19OQU1FLCB0dHNOYW1lcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7QXJyYXk8VFRTQ2h1bms+fVxuICAgICovXG4gICAgZ2V0VHRzTmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChUVFNDaHVuaywgUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX1RUU19OQU1FKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSAgbmducHBOYW1lIFByb3ZpZGVzIGFuIGFiYnJldmlhdGVkIHZlcnNpb24gb2YgdGhlIGFwcCBuYW1lIChpZiBuZWVkZWQpLCB0aGF0IHdpbGwgYmUgZGlzcGxheWVkXG4gICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbiB0aGUgTkdOIG1lZGlhIHNjcmVlbi4gSWYgbm90IHByb3ZpZGVkLCB0aGUgYXBwTmFtZSBpcyB1c2VkIGluc3RlYWQgKGFuZFxuICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lsbCBiZSB0cnVuY2F0ZWQgaWYgdG9vIGxvbmcpT25seSBjaGFyYWN0ZXJzIGZyb20gY2hhciBzZXQuXG4gICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZX1cbiAgICAqL1xuICAgIHNldE5nbk1lZGlhU2NyZWVuQXBwTmFtZSAobmducHBOYW1lKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFN0cmluZywgbmducHBOYW1lKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZS5LRVlfTkdOX01FRElBX1NDUkVFTl9BUFBfTkFNRSwgbmducHBOYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9IGFuIGFiYnJldmlhdGVkIHZlcnNpb24gb2YgdGhlIGFwcCBuYW1lXG4gICAgKi9cbiAgICBnZXROZ25NZWRpYVNjcmVlbkFwcE5hbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX05HTl9NRURJQV9TQ1JFRU5fQVBQX05BTUUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtBcnJheTxTdHJpbmc+fSB2clN5bm9ueW1zIERlZmluZXMgYW4gYWRkaXRpb25hbCB2b2ljZSByZWNvZ25pdGlvbiBjb21tYW5kLiBNYXkgbm90XG4gICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJmZXJlIHdpdGggYW55IGFwcCBuYW1lIG9mIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCBhcHBsaWNhdGlvbnNcbiAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tIHRoZSBzYW1lIGRldmljZSBhbmQgYW55IHByZWRlZmluZWQgYmxhY2tsaXN0IG9mIHdvcmRzIChnbG9iYWxcbiAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kcylPbmx5IGNoYXJhY3RlcnMgZnJvbSBjaGFyIHNldFxuICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2V9XG4gICAgKi9cbiAgICBzZXRWclN5bm9ueW1zICh2clN5bm9ueW1zKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9WUl9TWU5PTllNUywgdnJTeW5vbnltcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7QXJyYXk8U3RyaW5nPn1cbiAgICAqL1xuICAgIGdldFZyU3lub255bXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX1ZSX1NZTk9OWU1TKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNNZWRpYUFwcGxpY2F0aW9uIEluZGljYXRlcyBpZiB0aGUgYXBwbGljYXRpb24gaXMgYSBtZWRpYSBvciBhIG5vbi1tZWRpYSBhcHBsaWNhdGlvbi5cbiAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9ubHkgbWVkaWEgYXBwbGljYXRpb25zIHdpbGwgYmUgYWJsZSB0byBzdHJlYW0gYXVkaW8gdG8gdGhlIG1vZHVsZVxuICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdCBpcyBhdWRpYmxlIG91dHNpZGUgb2YgdGhlIEJUIG1lZGlhIHNvdXJjZS5cbiAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlfVxuICAgICovXG4gICAgc2V0SXNNZWRpYUFwcGxpY2F0aW9uIChpc01lZGlhQXBwbGljYXRpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0lTX01FRElBX0FQUExJQ0FUSU9OLCBpc01lZGlhQXBwbGljYXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgKi9cbiAgICBnZXRJc01lZGlhQXBwbGljYXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0lTX01FRElBX0FQUExJQ0FUSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7TGFuZ3VhZ2V9IGxhbmd1YWdlRGVzaXJlZFxuICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2V9XG4gICAgKi9cbiAgICBzZXRMYW5ndWFnZURlc2lyZWQgKGxhbmd1YWdlRGVzaXJlZCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShMYW5ndWFnZSwgbGFuZ3VhZ2VEZXNpcmVkKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZS5LRVlfTEFOR1VBR0VfREVTSVJFRCwgbGFuZ3VhZ2VEZXNpcmVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtMYW5ndWFnZX1cbiAgICAqL1xuICAgIGdldExhbmd1YWdlRGVzaXJlZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChMYW5ndWFnZSwgUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0xBTkdVQUdFX0RFU0lSRUQpO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0xhbmd1YWdlfSBobWlEaXNwbGF5TGFuZ3VhZ2VEZXNpcmVkXG4gICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZX1cbiAgICAqL1xuICAgIHNldEhtaURpc3BsYXlMYW5ndWFnZURlc2lyZWQgKGhtaURpc3BsYXlMYW5ndWFnZURlc2lyZWQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTGFuZ3VhZ2UsIGhtaURpc3BsYXlMYW5ndWFnZURlc2lyZWQpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9ITUlfRElTUExBWV9MQU5HVUFHRV9ERVNJUkVELCBobWlEaXNwbGF5TGFuZ3VhZ2VEZXNpcmVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtMYW5ndWFnZX1cbiAgICAqL1xuICAgIGdldEhtaURpc3BsYXlMYW5ndWFnZURlc2lyZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTGFuZ3VhZ2UsIFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9ITUlfRElTUExBWV9MQU5HVUFHRV9ERVNJUkVEKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtBcnJheTxBcHBITUlUeXBlPn0gYXBwSE1JVHlwZVxuICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2V9XG4gICAgKi9cbiAgICBzZXRBcHBIbWlUeXBlIChhcHBITUlUeXBlKSB7XG4gICAgICAgIC8vIFRPRE8gbWFrZSB2YWxpZGF0ZSB0eXBlIGFjY2VwdCBhcnJheXNcbiAgICAgICAgLy8gdGhpcy52YWxpZGF0ZVR5cGUoQXBwSE1JVHlwZSwgYXBwSE1JVHlwZSk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0FQUF9ITUlfVFlQRSwgYXBwSE1JVHlwZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7QXJyYXk8QXBwSE1JVHlwZT59XG4gICAgKi9cbiAgICBnZXRBcHBIbWlUeXBlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEFwcEhNSVR5cGUsIFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9BUFBfSE1JX1RZUEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IGhhc2hJRCB0aGUgaGFzaCBJRFxuICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2V9XG4gICAgKi9cbiAgICBzZXRIYXNoSUQgKGhhc2hJRCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShTdHJpbmcsIGhhc2hJRCk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0hBU0hfSUQsIGhhc2hJRCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfSB0aGUgaGFzaCBJRFxuICAgICovXG4gICAgZ2V0SGFzaElEICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9IQVNIX0lEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0RldmljZUluZm99IGRldmljZUluZm9cbiAgICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZX1cbiAgICAgKi9cbiAgICBzZXREZXZpY2VJbmZvIChkZXZpY2VJbmZvKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKERldmljZUluZm8sIGRldmljZUluZm8pO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9ERVZJQ0VfSU5GTywgZGV2aWNlSW5mbyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7RGV2aWNlSW5mb31cbiAgICAqL1xuICAgIGdldERldmljZUluZm8gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoRGV2aWNlSW5mbywgUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0RFVklDRV9JTkZPKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IGFwcE5hbWUgVGhpcyBtZXRob2Qgc2hvdWxkIG5vdCBiZSBhY2Nlc3NlZCBkaXJlY3RseSBieSBkZXZlbG9wZXJzLiBPbmx5IHNldCB0aGUgZnVsbCBJRCBhbmQgdGhpcyBwYXJhbSB3aWxsIGJlIHNldC5cbiAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlfVxuICAgICovXG4gICAgX3NldEFwcElkIChhcHBJZCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShTdHJpbmcsIGFwcElkKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZS5LRVlfQVBQX0lELCBhcHBJZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfSB0aGUgYXBwIGlkXG4gICAgKi9cbiAgICBnZXRBcHBJZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZS5LRVlfQVBQX0lEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBmdWxsQXBwSWRcbiAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlfVxuICAgICovXG4gICAgc2V0RnVsbEFwcElkIChmdWxsQXBwSWQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoU3RyaW5nLCBmdWxsQXBwSWQpO1xuXG4gICAgICAgIGlmIChmdWxsQXBwSWQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGZ1bGxBcHBJZCA9IGZ1bGxBcHBJZC50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0ZVTExfQVBQX0lELCBmdWxsQXBwSWQpO1xuICAgICAgICAgICAgbGV0IGFwcElkO1xuICAgICAgICAgICAgaWYgKGZ1bGxBcHBJZC5sZW5ndGggPD0gUmVnaXN0ZXJBcHBJbnRlcmZhY2UuQVBQX0lEX01BWF9MRU5HVEgpIHtcbiAgICAgICAgICAgICAgICBhcHBJZCA9IGZ1bGxBcHBJZDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYXBwSWQgPSBmdWxsQXBwSWQucmVwbGFjZSgnLScsICcnKS5zdWJzdHJpbmcoMCwgUmVnaXN0ZXJBcHBJbnRlcmZhY2UuQVBQX0lEX01BWF9MRU5HVEgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fc2V0QXBwSWQoYXBwSWQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0ZVTExfQVBQX0lELCBudWxsKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfSB0aGUgYXBwIGlkXG4gICAgKi9cbiAgICBnZXRGdWxsQXBwSWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0ZVTExfQVBQX0lEKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7QXBwSW5mb30gYXBwSW5mb1xuICAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlfVxuICAgICAqL1xuICAgIHNldEFwcEluZm8gKGFwcEluZm8pIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQXBwSW5mbywgYXBwSW5mbyk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0FQUF9JTkZPLCBhcHBJbmZvKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtBcHBJbmZvfVxuICAgICovXG4gICAgZ2V0QXBwSW5mbyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChBcHBJbmZvLCBSZWdpc3RlckFwcEludGVyZmFjZS5LRVlfQVBQX0lORk8pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VGVtcGxhdGVDb2xvclNjaGVtZX0gZGF5Q29sb3JTY2hlbWVcbiAgICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZX1cbiAgICAgKi9cbiAgICBzZXREYXlDb2xvclNjaGVtZSAoZGF5Q29sb3JTY2hlbWUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVGVtcGxhdGVDb2xvclNjaGVtZSwgZGF5Q29sb3JTY2hlbWUpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9EQVlfQ09MT1JfU0NIRU1FLCBkYXlDb2xvclNjaGVtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7VGVtcGxhdGVDb2xvclNjaGVtZX1cbiAgICAqL1xuICAgIGdldERheUNvbG9yU2NoZW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFRlbXBsYXRlQ29sb3JTY2hlbWUsIFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9EQVlfQ09MT1JfU0NIRU1FKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1RlbXBsYXRlQ29sb3JTY2hlbWV9IG5pZ2h0Q29sb3JTY2hlbWVcbiAgICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZX1cbiAgICAgKi9cbiAgICBzZXROaWdodENvbG9yU2NoZW1lIChuaWdodENvbG9yU2NoZW1lKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFRlbXBsYXRlQ29sb3JTY2hlbWUsIG5pZ2h0Q29sb3JTY2hlbWUpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9OSUdIVF9DT0xPUl9TQ0hFTUUsIG5pZ2h0Q29sb3JTY2hlbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1RlbXBsYXRlQ29sb3JTY2hlbWV9XG4gICAgKi9cbiAgICBnZXROaWdodENvbG9yU2NoZW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFRlbXBsYXRlQ29sb3JTY2hlbWUsIFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9OSUdIVF9DT0xPUl9TQ0hFTUUpO1xuICAgIH1cbn1cblxuUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX1NZTkNfTVNHX1ZFUlNJT04gPSAnc3luY01zZ1ZlcnNpb24nO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX1NETF9NU0dfVkVSU0lPTiA9ICdzeW5jTXNnVmVyc2lvbic7XG5SZWdpc3RlckFwcEludGVyZmFjZS5LRVlfQVBQX05BTUUgPSAnYXBwTmFtZSc7XG5SZWdpc3RlckFwcEludGVyZmFjZS5LRVlfVFRTX05BTUUgPSAndHRzTmFtZSc7XG5SZWdpc3RlckFwcEludGVyZmFjZS5LRVlfTkdOX01FRElBX1NDUkVFTl9BUFBfTkFNRSA9ICduZ25NZWRpYVNjcmVlbkFwcE5hbWUnO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX1ZSX1NZTk9OWU1TID0gJ3ZyU3lub255bXMnO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0lTX01FRElBX0FQUExJQ0FUSU9OID0gJ2lzTWVkaWFBcHBsaWNhdGlvbic7XG5SZWdpc3RlckFwcEludGVyZmFjZS5LRVlfTEFOR1VBR0VfREVTSVJFRCA9ICdsYW5ndWFnZURlc2lyZWQnO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0hNSV9ESVNQTEFZX0xBTkdVQUdFX0RFU0lSRUQgPSAnaG1pRGlzcGxheUxhbmd1YWdlRGVzaXJlZCc7XG5SZWdpc3RlckFwcEludGVyZmFjZS5LRVlfQVBQX0hNSV9UWVBFID0gJ2FwcEhNSVR5cGUnO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0hBU0hfSUQgPSAnaGFzaElEJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9ERVZJQ0VfSU5GTyA9ICdkZXZpY2VJbmZvJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9BUFBfSUQgPSAnYXBwSUQnO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0ZVTExfQVBQX0lEID0gJ2Z1bGxBcHBJRCc7XG5SZWdpc3RlckFwcEludGVyZmFjZS5LRVlfQVBQX0lORk8gPSAnYXBwSW5mbyc7XG5SZWdpc3RlckFwcEludGVyZmFjZS5LRVlfREFZX0NPTE9SX1NDSEVNRSA9ICdkYXlDb2xvclNjaGVtZSc7XG5SZWdpc3RlckFwcEludGVyZmFjZS5LRVlfTklHSFRfQ09MT1JfU0NIRU1FID0gJ25pZ2h0Q29sb3JTY2hlbWUnO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2UuQVBQX0lEX01BWF9MRU5HVEggPSAxMDtcblxuZXhwb3J0IHsgUmVnaXN0ZXJBcHBJbnRlcmZhY2UgfTtcbiIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gUmVzdWx0XG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBSZXN1bHQgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU1VDQ0VTUyAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5TVUNDRVNTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFVOU1VQUE9SVEVEX1JFUVVFU1QgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuVU5TVVBQT1JURURfUkVRVUVTVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBVTlNVUFBPUlRFRF9SRVNPVVJDRSAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5VTlNVUFBPUlRFRF9SRVFVRVNUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IERJU0FMTE9XRUQgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuRElTQUxMT1dFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSRUpFQ1RFRCAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5SRUpFQ1RFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBBQk9SVEVEICgpIHtcbiAgICAgICAgcmV0dXJuIFJlc3VsdC5fTUFQLkFCT1JURUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSUdOT1JFRCAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5JR05PUkVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJFVFJZICgpIHtcbiAgICAgICAgcmV0dXJuIFJlc3VsdC5fTUFQLlJFVFJZO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IElOX1VTRSAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5JTl9VU0U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVkVISUNMRV9EQVRBX05PVF9BVkFJTEFCTEUgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuVkVISUNMRV9EQVRBX05PVF9BVkFJTEFCTEU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVElNRURfT1VUICgpIHtcbiAgICAgICAgcmV0dXJuIFJlc3VsdC5fTUFQLlRJTUVEX09VVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBJTlZBTElEX0RBVEEgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuSU5WQUxJRF9EQVRBO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENIQVJfTElNSVRfRVhDRUVERUQgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuQ0hBUl9MSU1JVF9FWENFRURFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBJTlZBTElEX0lEICgpIHtcbiAgICAgICAgcmV0dXJuIFJlc3VsdC5fTUFQLklOVkFMSURfSUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRFVQTElDQVRFX05BTUUgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuRFVQTElDQVRFX05BTUU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQVBQTElDQVRJT05fTk9UX1JFR0lTVEVSRUQgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuQVBQTElDQVRJT05fTk9UX1JFR0lTVEVSRUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgV1JPTkdfTEFOR1VBR0UgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuV1JPTkdfTEFOR1VBR0U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgT1VUX09GX01FTU9SWSAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5PVVRfT0ZfTUVNT1JZO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFRPT19NQU5ZX1BFTkRJTkdfUkVRVUVTVFMgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuVE9PX01BTllfUEVORElOR19SRVFVRVNUUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBUT09fTUFOWV9BUFBMSUNBVElPTlMgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuVE9PX01BTllfQVBQTElDQVRJT05TO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFQUExJQ0FUSU9OX1JFR0lTVEVSRURfQUxSRUFEWSAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5BUFBMSUNBVElPTl9SRUdJU1RFUkVEX0FMUkVBRFk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgV0FSTklOR1MgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuV0FSTklOR1M7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgR0VORVJJQ19FUlJPUiAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5HRU5FUklDX0VSUk9SO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFVTRVJfRElTQUxMT1dFRCAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5VU0VSX0RJU0FMTE9XRUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVFJVTkNBVEVEX0RBVEEgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuVFJVTkNBVEVEX0RBVEE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVU5TVVBQT1JURURfVkVSU0lPTiAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5VTlNVUFBPUlRFRF9WRVJTSU9OO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZFSElDTEVfREFUQV9OT1RfQUxMT1dFRCAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5WRUhJQ0xFX0RBVEFfTk9UX0FMTE9XRUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRklMRV9OT1RfRk9VTkQgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuRklMRV9OT1RfRk9VTkQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ0FOQ0VMX1JPVVRFICgpIHtcbiAgICAgICAgcmV0dXJuIFJlc3VsdC5fTUFQLkNBTkNFTF9ST1VURTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTQVZFRCAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5TQVZFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBJTlZBTElEX0NFUlQgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuSU5WQUxJRF9DRVJUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEVYUElSRURfQ0VSVCAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5FWFBJUkVEX0NFUlQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUkVTVU1FX0ZBSUxFRCAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5SRVNVTUVfRkFJTEVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IERBVEFfTk9UX0FWQUlMQUJMRSAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5EQVRBX05PVF9BVkFJTEFCTEU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUkVBRF9PTkxZICgpIHtcbiAgICAgICAgcmV0dXJuIFJlc3VsdC5fTUFQLlJFQURfT05MWTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDT1JSVVBURURfREFUQSAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5DT1JSVVBURURfREFUQTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll92YWx1ZUZvcktleShrZXksIFJlc3VsdC5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9rZXlGb3JWYWx1ZSh2YWx1ZSwgUmVzdWx0Ll9NQVApO1xuICAgIH1cbn1cblxuUmVzdWx0Ll9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnU1VDQ0VTUyc6ICdTVUNDRVNTJyxcbiAgICAnVU5TVVBQT1JURURfUkVRVUVTVCc6ICdVTlNVUFBPUlRFRF9SRVFVRVNUJyxcbiAgICAnVU5TVVBQT1JURURfUkVTT1VSQ0UnOiAnVU5TVVBQT1JURURfUkVTT1VSQ0UnLFxuICAgICdESVNBTExPV0VEJzogJ0RJU0FMTE9XRUQnLFxuICAgICdSRUpFQ1RFRCc6ICdSRUpFQ1RFRCcsXG4gICAgJ0FCT1JURUQnOiAnQUJPUlRFRCcsXG4gICAgJ0lHTk9SRUQnOiAnSUdOT1JFRCcsXG4gICAgJ1JFVFJZJzogJ1JFVFJZJyxcbiAgICAnSU5fVVNFJzogJ0lOX1VTRScsXG4gICAgJ1ZFSElDTEVfREFUQV9OT1RfQVZBSUxBQkxFJzogJ1ZFSElDTEVfREFUQV9OT1RfQVZBSUxBQkxFJyxcbiAgICAnVElNRURfT1VUJzogJ1RJTUVEX09VVCcsXG4gICAgJ0lOVkFMSURfREFUQSc6ICdJTlZBTElEX0RBVEEnLFxuICAgICdDSEFSX0xJTUlUX0VYQ0VFREVEJzogJ0NIQVJfTElNSVRfRVhDRUVERUQnLFxuICAgICdJTlZBTElEX0lEJzogJ0lOVkFMSURfSUQnLFxuICAgICdEVVBMSUNBVEVfTkFNRSc6ICdEVVBMSUNBVEVfTkFNRScsXG4gICAgJ0FQUExJQ0FUSU9OX05PVF9SRUdJU1RFUkVEJzogJ0FQUExJQ0FUSU9OX05PVF9SRUdJU1RFUkVEJyxcbiAgICAnV1JPTkdfTEFOR1VBR0UnOiAnV1JPTkdfTEFOR1VBR0UnLFxuICAgICdPVVRfT0ZfTUVNT1JZJzogJ09VVF9PRl9NRU1PUlknLFxuICAgICdUT09fTUFOWV9QRU5ESU5HX1JFUVVFU1RTJzogJ1RPT19NQU5ZX1BFTkRJTkdfUkVRVUVTVFMnLFxuICAgICdUT09fTUFOWV9BUFBMSUNBVElPTlMnOiAnVE9PX01BTllfQVBQTElDQVRJT05TJyxcbiAgICAnQVBQTElDQVRJT05fUkVHSVNURVJFRF9BTFJFQURZJzogJ0FQUExJQ0FUSU9OX1JFR0lTVEVSRURfQUxSRUFEWScsXG4gICAgJ1dBUk5JTkdTJzogJ1dBUk5JTkdTJyxcbiAgICAnR0VORVJJQ19FUlJPUic6ICdHRU5FUklDX0VSUk9SJyxcbiAgICAnVVNFUl9ESVNBTExPV0VEJzogJ1VTRVJfRElTQUxMT1dFRCcsXG4gICAgJ1RSVU5DQVRFRF9EQVRBJzogJ1RSVU5DQVRFRF9EQVRBJyxcbiAgICAnVU5TVVBQT1JURURfVkVSU0lPTic6ICdVTlNVUFBPUlRFRF9WRVJTSU9OJyxcbiAgICAnVkVISUNMRV9EQVRBX05PVF9BTExPV0VEJzogJ1ZFSElDTEVfREFUQV9OT1RfQUxMT1dFRCcsXG4gICAgJ0ZJTEVfTk9UX0ZPVU5EJzogJ0ZJTEVfTk9UX0ZPVU5EJyxcbiAgICAnQ0FOQ0VMX1JPVVRFJzogJ0NBTkNFTF9ST1VURScsXG4gICAgJ1NBVkVEJzogJ1NBVkVEJyxcbiAgICAnSU5WQUxJRF9DRVJUJzogJ0lOVkFMSURfQ0VSVCcsXG4gICAgJ0VYUElSRURfQ0VSVCc6ICdFWFBJUkVEX0NFUlQnLFxuICAgICdSRVNVTUVfRkFJTEVEJzogJ1JFU1VNRV9GQUlMRUQnLFxuICAgICdEQVRBX05PVF9BVkFJTEFCTEUnOiAnREFUQV9OT1RfQVZBSUxBQkxFJyxcbiAgICAnUkVBRF9PTkxZJzogJ1JFQURfT05MWScsXG4gICAgJ0NPUlJVUFRFRF9EQVRBJzogJ0NPUlJVUFRFRF9EQVRBJyxcbn0pO1xuXG5leHBvcnQgeyBSZXN1bHQgfTtcbiIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNNZXNzYWdlIH0gZnJvbSAnLi9ScGNNZXNzYWdlLmpzJztcbmltcG9ydCB7IFJwY1R5cGUgfSBmcm9tICcuL2VudW1zL1JwY1R5cGUuanMnO1xuaW1wb3J0IHsgUmVzdWx0IH0gZnJvbSAnLi9lbnVtcy9SZXN1bHQuanMnO1xuXG5jbGFzcyBScGNSZXNwb25zZSBleHRlbmRzIFJwY01lc3NhZ2Uge1xuICAgIC8qKlxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldFJQQ1R5cGUoUnBjVHlwZS5SRVNQT05TRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICovXG4gICAgZ2V0U3VjY2VzcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihScGNSZXNwb25zZS5LRVlfU1VDQ0VTUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtScGNSZXNwb25zZX1cbiAgICAqL1xuICAgIHNldFN1Y2Nlc3MgKHN1Y2Nlc3MpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUnBjUmVzcG9uc2UuS0VZX1NVQ0NFU1MsIHN1Y2Nlc3MpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIGdldEluZm8gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUnBjUmVzcG9uc2UuS0VZX0lORk8pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7UnBjUmVzcG9uc2V9XG4gICAgKi9cbiAgICBzZXRJbmZvIChpbmZvKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJwY1Jlc3BvbnNlLktFWV9JTkZPLCBpbmZvKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtSZXN1bHR9XG4gICAgKi9cbiAgICBnZXRSZXN1bHRDb2RlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFJlc3VsdCwgUnBjUmVzcG9uc2UuS0VZX1JFU1VMVF9DT0RFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1JwY1Jlc3BvbnNlfVxuICAgICovXG4gICAgc2V0UmVzdWx0Q29kZSAocmVzdWx0Q29kZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShSZXN1bHQsIHJlc3VsdENvZGUpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJwY1Jlc3BvbnNlLktFWV9SRVNVTFRfQ09ERSwgcmVzdWx0Q29kZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cblxuUnBjUmVzcG9uc2UuS0VZX1NVQ0NFU1MgICAgID0gJ3N1Y2Nlc3MnO1xuUnBjUmVzcG9uc2UuS0VZX0lORk8gICAgICAgID0gJ2luZm8nO1xuUnBjUmVzcG9uc2UuS0VZX1JFU1VMVF9DT0RFID0gJ3Jlc3VsdENvZGUnO1xuXG5leHBvcnQgeyBScGNSZXNwb25zZSB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmNsYXNzIFJwY0xpc3RlbmVyIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHRoaXMuX29uUnBjTWVzc2FnZSA9IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuY1xuICAgICAqIEByZXR1cm4ge1JwY0xpc3RlbmVyfVxuICAgICAqL1xuICAgIHNldE9uUnBjTWVzc2FnZSAoZnVuYykge1xuICAgICAgICB0aGlzLl9vblJwY01lc3NhZ2UgPSBmdW5jO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtScGNNZXNzYWdlfSBycGNNZXNzYWdlXG4gICAgICovXG4gICAgb25ScGNNZXNzYWdlIChycGNNZXNzYWdlKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fb25ScGNNZXNzYWdlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9vblJwY01lc3NhZ2UocnBjTWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCB7IFJwY0xpc3RlbmVyIH07XG4iLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBTZGxQcm90b2NvbExpc3RlbmVyXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBzZXRPblJwY01lc3NhZ2VSZWNlaXZlZFxuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gb25ScGNNZXNzYWdlUmVjZWl2ZWRcbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IHNldE9uUHJvdG9jb2xTZXNzaW9uU3RhcnRlZFxuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gb25Qcm90b2NvbFNlc3Npb25TdGFydGVkXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBzZXRPblByb3RvY29sU2Vzc2lvbkVuZGVkXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBvblByb3RvY29sU2Vzc2lvbkVuZGVkXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBzZXRPblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBvblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBzZXRHZXRTZXNzaW9uSWRcbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IGdldFNlc3Npb25JZFxuICovXG5jbGFzcyBTZGxQcm90b2NvbExpc3RlbmVyIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHRoaXMuX29uUnBjTWVzc2FnZVJlY2VpdmVkID0gbnVsbDtcbiAgICAgICAgdGhpcy5fb25Qcm90b2NvbFNlc3Npb25TdGFydGVkID0gbnVsbDtcbiAgICAgICAgdGhpcy5fb25Qcm90b2NvbFNlc3Npb25FbmRlZCA9IG51bGw7XG4gICAgICAgIHRoaXMuX29uUHJvdG9jb2xTZXNzaW9uRW5kZWROQUNLZWQgPSBudWxsO1xuICAgICAgICB0aGlzLl9nZXRTZXNzaW9uSWQgPSBudWxsO1xuICAgICAgICB0aGlzLl9vblRyYW5zcG9ydENvbm5lY3RlZCA9IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBzZXRPblRyYW5zcG9ydENvbm5lY3RlZCAobGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5fb25UcmFuc3BvcnRDb25uZWN0ZWQgPSBsaXN0ZW5lcjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBzZXRPblJwY01lc3NhZ2VSZWNlaXZlZCAobGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5fb25ScGNNZXNzYWdlUmVjZWl2ZWQgPSBsaXN0ZW5lcjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtScGNNZXNzYWdlfSBycGNNZXNzYWdlXG4gICAgICovXG4gICAgb25ScGNNZXNzYWdlUmVjZWl2ZWQgKHJwY01lc3NhZ2UpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9vblJwY01lc3NhZ2VSZWNlaXZlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5fb25ScGNNZXNzYWdlUmVjZWl2ZWQocnBjTWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBsaXN0ZW5lclxuICAgICAqL1xuICAgIHNldE9uUHJvdG9jb2xTZXNzaW9uU3RhcnRlZCAobGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5fb25Qcm90b2NvbFNlc3Npb25TdGFydGVkID0gbGlzdGVuZXI7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgb25UcmFuc3BvcnRDb25uZWN0ZWQgKCkge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX29uVHJhbnNwb3J0Q29ubmVjdGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9vblRyYW5zcG9ydENvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW52b2tlIHRoZSBvblByb3RvY29sU2Vzc2lvblN0YXJ0ZWQgbGlzdGVuZXIgd2l0aCB0aGUgZXZlbnQgZGF0YVxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlc3Npb25JZFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB2ZXJzaW9uXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGNvcnJlbGF0aW9uSWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaGFzaElkXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBpc0VuY3J5cHRlZFxuICAgICAqL1xuICAgIG9uUHJvdG9jb2xTZXNzaW9uU3RhcnRlZCAoc2VydmljZVR5cGUsIHNlc3Npb25JZCwgdmVyc2lvbiwgY29ycmVsYXRpb25JZCwgaGFzaElkLCBpc0VuY3J5cHRlZCkge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX29uUHJvdG9jb2xTZXNzaW9uU3RhcnRlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5fb25Qcm90b2NvbFNlc3Npb25TdGFydGVkKHNlcnZpY2VUeXBlLCBzZXNzaW9uSWQsIHZlcnNpb24sIGNvcnJlbGF0aW9uSWQsIGhhc2hJZCwgaXNFbmNyeXB0ZWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBzZXRPblByb3RvY29sU2Vzc2lvbkVuZGVkIChsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLl9vblByb3RvY29sU2Vzc2lvbkVuZGVkID0gbGlzdGVuZXI7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEludm9rZSB0aGUgb25Qcm90b2NvbFNlc3Npb25FbmRlZCBsaXN0ZW5lciB3aXRoIHRoZSBldmVudCBkYXRhXG4gICAgICogQHBhcmFtIHtTZXJ2aWNlVHlwZX0gc2VydmljZVR5cGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc2Vzc2lvbklkXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGNvcnJlbGF0aW9uSWRcbiAgICAgKi9cbiAgICBvblByb3RvY29sU2Vzc2lvbkVuZGVkIChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklkLCBjb3JyZWxhdGlvbklkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fb25Qcm90b2NvbFNlc3Npb25FbmRlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5fb25Qcm90b2NvbFNlc3Npb25FbmRlZChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklkLCBjb3JyZWxhdGlvbklkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyXG4gICAgICovXG4gICAgc2V0T25Qcm90b2NvbFNlc3Npb25FbmRlZE5BQ0tlZCAobGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5fb25Qcm90b2NvbFNlc3Npb25FbmRlZE5BQ0tlZCA9IGxpc3RlbmVyO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbnZva2UgdGhlIG9uUHJvdG9jb2xTZXNzaW9uRW5kZWROQUNLZWQgbGlzdGVuZXIgd2l0aCB0aGUgZXZlbnQgZGF0YVxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlc3Npb25JZFxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBjb3JyZWxhdGlvbklkXG4gICAgICovXG4gICAgb25Qcm90b2NvbFNlc3Npb25FbmRlZE5BQ0tlZCAoc2VydmljZVR5cGUsIHNlc3Npb25JZCwgY29ycmVsYXRpb25JZCkge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX29uUHJvdG9jb2xTZXNzaW9uRW5kZWROQUNLZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuX29uUHJvdG9jb2xTZXNzaW9uRW5kZWROQUNLZWQoc2VydmljZVR5cGUsIHNlc3Npb25JZCwgY29ycmVsYXRpb25JZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBnZXR0ZXJcbiAgICAgKi9cbiAgICBzZXRHZXRTZXNzaW9uSWQgKGdldHRlcikge1xuICAgICAgICB0aGlzLl9nZXRTZXNzaW9uSWQgPSBnZXR0ZXI7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEludm9rZSB0aGUgZ2V0U2Vzc2lvbklkIGdldHRlclxuICAgICAqIEByZXR1cm5zIHtOdW1iZXJ9IHNlc3Npb25JZFxuICAgICAqL1xuICAgIGdldFNlc3Npb25JZCAoKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fZ2V0U2Vzc2lvbklkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0U2Vzc2lvbklkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGdldERlc2lyZWRWaWRlb1BhcmFtcyBnZXR0ZXJcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBnZXR0ZXJcbiAgICAgKi9cbiAgICBzZXRHZXREZXNpcmVkVmlkZW9QYXJhbXMgKGdldHRlcikge1xuICAgICAgICB0aGlzLl9nZXREZXNpcmVkVmlkZW9QYXJhbXMgPSBnZXR0ZXI7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEludm9rZSB0aGUgZ2V0RGVzaXJlZFZpZGVvUGFyYW1zIGdldHRlclxuICAgICAqIEByZXR1cm5zIHtWaWRlb1N0cmVhbWluZ1BhcmFtZXRlcnN9XG4gICAgICovXG4gICAgZ2V0RGVzaXJlZFZpZGVvUGFyYW1zICgpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9nZXREZXNpcmVkVmlkZW9QYXJhbXMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXREZXNpcmVkVmlkZW9QYXJhbXMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHNldFNldEFjY2VwdGVkVmlkZW9QYXJhbXMgc2V0dGVyXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gc2V0dGVyXG4gICAgICovXG4gICAgc2V0U2V0QWNjZXB0ZWRWaWRlb1BhcmFtcyAoc2V0dGVyKSB7XG4gICAgICAgIHRoaXMuX3NldEFjY2VwdGVkVmlkZW9QYXJhbXMgPSBzZXR0ZXI7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogSW52b2tlIHRoZSBzZXRBY2NlcHRlZFZpZGVvUGFyYW1zIHNldHRlclxuICAgICAqIEBwYXJhbSB7VmlkZW9TdHJlYW1pbmdQYXJhbWV0ZXJzfSBwYXJhbXNcbiAgICAgKi9cbiAgICBzZXRBY2NlcHRlZFZpZGVvUGFyYW1zIChwYXJhbXMpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9zZXRBY2NlcHRlZFZpZGVvUGFyYW1zID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9zZXRBY2NlcHRlZFZpZGVvUGFyYW1zKHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuXG5leHBvcnQgeyBTZGxQcm90b2NvbExpc3RlbmVyIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBGcmFtZVR5cGVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIEZyYW1lVHlwZSBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IENPTlRST0wgKCkge1xuICAgICAgICByZXR1cm4gRnJhbWVUeXBlLl9NQVAuQ09OVFJPTDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgRklSU1QgKCkge1xuICAgICAgICByZXR1cm4gRnJhbWVUeXBlLl9NQVAuRklSU1Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IENPTlNFQ1VUSVZFICgpIHtcbiAgICAgICAgcmV0dXJuIEZyYW1lVHlwZS5fTUFQLkNPTlNFQ1VUSVZFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBTSU5HTEUgKCkge1xuICAgICAgICByZXR1cm4gRnJhbWVUeXBlLl9NQVAuU0lOR0xFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgKiBAcGFyYW0gdmFsdWUgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBGcmFtZVR5cGUuX3ZhbHVlRm9yS2V5KGtleSwgRnJhbWVUeXBlLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBGcmFtZVR5cGUuX2tleUZvclZhbHVlKHZhbHVlLCBGcmFtZVR5cGUuX01BUCk7XG4gICAgfVxufVxuXG5GcmFtZVR5cGUuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdDT05UUk9MJzogMHgwMCxcbiAgICAnRklSU1QnOiAweDAyLFxuICAgICdDT05TRUNVVElWRSc6IDB4MDMsXG4gICAgJ1NJTkdMRSc6IDB4MDEsXG59KTtcblxuZXhwb3J0IHsgRnJhbWVUeXBlIH07XG4iLCJleHBvcnRzW1wiYnNvblwiXSA9XG4vKioqKioqLyAoZnVuY3Rpb24obW9kdWxlcykgeyAvLyB3ZWJwYWNrQm9vdHN0cmFwXG4vKioqKioqLyBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbi8qKioqKiovIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG4vKioqKioqLyBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcbi8qKioqKiovXG4vKioqKioqLyBcdFx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG4vKioqKioqLyBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pIHtcbi8qKioqKiovIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuLyoqKioqKi8gXHRcdH1cbi8qKioqKiovIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuLyoqKioqKi8gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbi8qKioqKiovIFx0XHRcdGk6IG1vZHVsZUlkLFxuLyoqKioqKi8gXHRcdFx0bDogZmFsc2UsXG4vKioqKioqLyBcdFx0XHRleHBvcnRzOiB7fVxuLyoqKioqKi8gXHRcdH07XG4vKioqKioqL1xuLyoqKioqKi8gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuLyoqKioqKi8gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuLyoqKioqKi9cbi8qKioqKiovIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4vKioqKioqLyBcdFx0bW9kdWxlLmwgPSB0cnVlO1xuLyoqKioqKi9cbi8qKioqKiovIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuLyoqKioqKi8gXHRcdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbi8qKioqKiovIFx0fVxuLyoqKioqKi9cbi8qKioqKiovXG4vKioqKioqLyBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG4vKioqKioqL1xuLyoqKioqKi8gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gZGVmaW5lIGdldHRlciBmdW5jdGlvbiBmb3IgaGFybW9ueSBleHBvcnRzXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuLyoqKioqKi8gXHRcdGlmKCFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywgbmFtZSkpIHtcbi8qKioqKiovIFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBuYW1lLCB7XG4vKioqKioqLyBcdFx0XHRcdGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4vKioqKioqLyBcdFx0XHRcdGVudW1lcmFibGU6IHRydWUsXG4vKioqKioqLyBcdFx0XHRcdGdldDogZ2V0dGVyXG4vKioqKioqLyBcdFx0XHR9KTtcbi8qKioqKiovIFx0XHR9XG4vKioqKioqLyBcdH07XG4vKioqKioqL1xuLyoqKioqKi8gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSBmdW5jdGlvbihtb2R1bGUpIHtcbi8qKioqKiovIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cbi8qKioqKiovIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4vKioqKioqLyBcdFx0XHRmdW5jdGlvbiBnZXRNb2R1bGVFeHBvcnRzKCkgeyByZXR1cm4gbW9kdWxlOyB9O1xuLyoqKioqKi8gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcbi8qKioqKiovIFx0XHRyZXR1cm4gZ2V0dGVyO1xuLyoqKioqKi8gXHR9O1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18ubyA9IGZ1bmN0aW9uKG9iamVjdCwgcHJvcGVydHkpIHsgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KTsgfTtcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18ucCA9IFwiXCI7XG4vKioqKioqL1xuLyoqKioqKi8gXHQvLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbi8qKioqKiovIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gMik7XG4vKioqKioqLyB9KVxuLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qKioqKiovIChbXG4vKiAwICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbnZhciBnO1xuXG4vLyBUaGlzIHdvcmtzIGluIG5vbi1zdHJpY3QgbW9kZVxuZyA9IChmdW5jdGlvbigpIHtcblx0cmV0dXJuIHRoaXM7XG59KSgpO1xuXG50cnkge1xuXHQvLyBUaGlzIHdvcmtzIGlmIGV2YWwgaXMgYWxsb3dlZCAoc2VlIENTUClcblx0ZyA9IGcgfHwgRnVuY3Rpb24oXCJyZXR1cm4gdGhpc1wiKSgpIHx8ICgxLGV2YWwpKFwidGhpc1wiKTtcbn0gY2F0Y2goZSkge1xuXHQvLyBUaGlzIHdvcmtzIGlmIHRoZSB3aW5kb3cgcmVmZXJlbmNlIGlzIGF2YWlsYWJsZVxuXHRpZih0eXBlb2Ygd2luZG93ID09PSBcIm9iamVjdFwiKVxuXHRcdGcgPSB3aW5kb3c7XG59XG5cbi8vIGcgY2FuIHN0aWxsIGJlIHVuZGVmaW5lZCwgYnV0IG5vdGhpbmcgdG8gZG8gYWJvdXQgaXQuLi5cbi8vIFdlIHJldHVybiB1bmRlZmluZWQsIGluc3RlYWQgb2Ygbm90aGluZyBoZXJlLCBzbyBpdCdzXG4vLyBlYXNpZXIgdG8gaGFuZGxlIHRoaXMgY2FzZS4gaWYoIWdsb2JhbCkgeyAuLi59XG5cbm1vZHVsZS5leHBvcnRzID0gZztcblxuXG4vKioqLyB9KSxcbi8qIDEgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXCJ1c2Ugc3RyaWN0XCI7XG4vKiBXRUJQQUNLIFZBUiBJTkpFQ1RJT04gKi8oZnVuY3Rpb24oZ2xvYmFsKSB7LyohXG4gKiBUaGUgYnVmZmVyIG1vZHVsZSBmcm9tIG5vZGUuanMsIGZvciB0aGUgYnJvd3Nlci5cbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8aHR0cDovL2Zlcm9zcy5vcmc+XG4gKiBAbGljZW5zZSAgTUlUXG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIG5vLXByb3RvICovXG5cblxuXG52YXIgYmFzZTY0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygzKVxudmFyIGllZWU3NTQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQpXG52YXIgaXNBcnJheSA9IF9fd2VicGFja19yZXF1aXJlX18oNSlcblxuZXhwb3J0cy5CdWZmZXIgPSBCdWZmZXJcbmV4cG9ydHMuU2xvd0J1ZmZlciA9IFNsb3dCdWZmZXJcbmV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVMgPSA1MFxuXG4vKipcbiAqIElmIGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGA6XG4gKiAgID09PSB0cnVlICAgIFVzZSBVaW50OEFycmF5IGltcGxlbWVudGF0aW9uIChmYXN0ZXN0KVxuICogICA9PT0gZmFsc2UgICBVc2UgT2JqZWN0IGltcGxlbWVudGF0aW9uIChtb3N0IGNvbXBhdGlibGUsIGV2ZW4gSUU2KVxuICpcbiAqIEJyb3dzZXJzIHRoYXQgc3VwcG9ydCB0eXBlZCBhcnJheXMgYXJlIElFIDEwKywgRmlyZWZveCA0KywgQ2hyb21lIDcrLCBTYWZhcmkgNS4xKyxcbiAqIE9wZXJhIDExLjYrLCBpT1MgNC4yKy5cbiAqXG4gKiBEdWUgdG8gdmFyaW91cyBicm93c2VyIGJ1Z3MsIHNvbWV0aW1lcyB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uIHdpbGwgYmUgdXNlZCBldmVuXG4gKiB3aGVuIHRoZSBicm93c2VyIHN1cHBvcnRzIHR5cGVkIGFycmF5cy5cbiAqXG4gKiBOb3RlOlxuICpcbiAqICAgLSBGaXJlZm94IDQtMjkgbGFja3Mgc3VwcG9ydCBmb3IgYWRkaW5nIG5ldyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YCBpbnN0YW5jZXMsXG4gKiAgICAgU2VlOiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02OTU0MzguXG4gKlxuICogICAtIENocm9tZSA5LTEwIGlzIG1pc3NpbmcgdGhlIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24uXG4gKlxuICogICAtIElFMTAgaGFzIGEgYnJva2VuIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhcnJheXMgb2ZcbiAqICAgICBpbmNvcnJlY3QgbGVuZ3RoIGluIHNvbWUgc2l0dWF0aW9ucy5cblxuICogV2UgZGV0ZWN0IHRoZXNlIGJ1Z2d5IGJyb3dzZXJzIGFuZCBzZXQgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYCB0byBgZmFsc2VgIHNvIHRoZXlcbiAqIGdldCB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uLCB3aGljaCBpcyBzbG93ZXIgYnV0IGJlaGF2ZXMgY29ycmVjdGx5LlxuICovXG5CdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCA9IGdsb2JhbC5UWVBFRF9BUlJBWV9TVVBQT1JUICE9PSB1bmRlZmluZWRcbiAgPyBnbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVFxuICA6IHR5cGVkQXJyYXlTdXBwb3J0KClcblxuLypcbiAqIEV4cG9ydCBrTWF4TGVuZ3RoIGFmdGVyIHR5cGVkIGFycmF5IHN1cHBvcnQgaXMgZGV0ZXJtaW5lZC5cbiAqL1xuZXhwb3J0cy5rTWF4TGVuZ3RoID0ga01heExlbmd0aCgpXG5cbmZ1bmN0aW9uIHR5cGVkQXJyYXlTdXBwb3J0ICgpIHtcbiAgdHJ5IHtcbiAgICB2YXIgYXJyID0gbmV3IFVpbnQ4QXJyYXkoMSlcbiAgICBhcnIuX19wcm90b19fID0ge19fcHJvdG9fXzogVWludDhBcnJheS5wcm90b3R5cGUsIGZvbzogZnVuY3Rpb24gKCkgeyByZXR1cm4gNDIgfX1cbiAgICByZXR1cm4gYXJyLmZvbygpID09PSA0MiAmJiAvLyB0eXBlZCBhcnJheSBpbnN0YW5jZXMgY2FuIGJlIGF1Z21lbnRlZFxuICAgICAgICB0eXBlb2YgYXJyLnN1YmFycmF5ID09PSAnZnVuY3Rpb24nICYmIC8vIGNocm9tZSA5LTEwIGxhY2sgYHN1YmFycmF5YFxuICAgICAgICBhcnIuc3ViYXJyYXkoMSwgMSkuYnl0ZUxlbmd0aCA9PT0gMCAvLyBpZTEwIGhhcyBicm9rZW4gYHN1YmFycmF5YFxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuZnVuY3Rpb24ga01heExlbmd0aCAoKSB7XG4gIHJldHVybiBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVFxuICAgID8gMHg3ZmZmZmZmZlxuICAgIDogMHgzZmZmZmZmZlxufVxuXG5mdW5jdGlvbiBjcmVhdGVCdWZmZXIgKHRoYXQsIGxlbmd0aCkge1xuICBpZiAoa01heExlbmd0aCgpIDwgbGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0ludmFsaWQgdHlwZWQgYXJyYXkgbGVuZ3RoJylcbiAgfVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICB0aGF0ID0gbmV3IFVpbnQ4QXJyYXkobGVuZ3RoKVxuICAgIHRoYXQuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICBpZiAodGhhdCA9PT0gbnVsbCkge1xuICAgICAgdGhhdCA9IG5ldyBCdWZmZXIobGVuZ3RoKVxuICAgIH1cbiAgICB0aGF0Lmxlbmd0aCA9IGxlbmd0aFxuICB9XG5cbiAgcmV0dXJuIHRoYXRcbn1cblxuLyoqXG4gKiBUaGUgQnVmZmVyIGNvbnN0cnVjdG9yIHJldHVybnMgaW5zdGFuY2VzIG9mIGBVaW50OEFycmF5YCB0aGF0IGhhdmUgdGhlaXJcbiAqIHByb3RvdHlwZSBjaGFuZ2VkIHRvIGBCdWZmZXIucHJvdG90eXBlYC4gRnVydGhlcm1vcmUsIGBCdWZmZXJgIGlzIGEgc3ViY2xhc3Mgb2ZcbiAqIGBVaW50OEFycmF5YCwgc28gdGhlIHJldHVybmVkIGluc3RhbmNlcyB3aWxsIGhhdmUgYWxsIHRoZSBub2RlIGBCdWZmZXJgIG1ldGhvZHNcbiAqIGFuZCB0aGUgYFVpbnQ4QXJyYXlgIG1ldGhvZHMuIFNxdWFyZSBicmFja2V0IG5vdGF0aW9uIHdvcmtzIGFzIGV4cGVjdGVkIC0tIGl0XG4gKiByZXR1cm5zIGEgc2luZ2xlIG9jdGV0LlxuICpcbiAqIFRoZSBgVWludDhBcnJheWAgcHJvdG90eXBlIHJlbWFpbnMgdW5tb2RpZmllZC5cbiAqL1xuXG5mdW5jdGlvbiBCdWZmZXIgKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiYgISh0aGlzIGluc3RhbmNlb2YgQnVmZmVyKSkge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgLy8gQ29tbW9uIGNhc2UuXG4gIGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykge1xuICAgIGlmICh0eXBlb2YgZW5jb2RpbmdPck9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0lmIGVuY29kaW5nIGlzIHNwZWNpZmllZCB0aGVuIHRoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nJ1xuICAgICAgKVxuICAgIH1cbiAgICByZXR1cm4gYWxsb2NVbnNhZmUodGhpcywgYXJnKVxuICB9XG4gIHJldHVybiBmcm9tKHRoaXMsIGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxuLy8gVE9ETzogTGVnYWN5LCBub3QgbmVlZGVkIGFueW1vcmUuIFJlbW92ZSBpbiBuZXh0IG1ham9yIHZlcnNpb24uXG5CdWZmZXIuX2F1Z21lbnQgPSBmdW5jdGlvbiAoYXJyKSB7XG4gIGFyci5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIHJldHVybiBhcnJcbn1cblxuZnVuY3Rpb24gZnJvbSAodGhhdCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBtdXN0IG5vdCBiZSBhIG51bWJlcicpXG4gIH1cblxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB2YWx1ZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgcmV0dXJuIGZyb21BcnJheUJ1ZmZlcih0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyh0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldClcbiAgfVxuXG4gIHJldHVybiBmcm9tT2JqZWN0KHRoYXQsIHZhbHVlKVxufVxuXG4vKipcbiAqIEZ1bmN0aW9uYWxseSBlcXVpdmFsZW50IHRvIEJ1ZmZlcihhcmcsIGVuY29kaW5nKSBidXQgdGhyb3dzIGEgVHlwZUVycm9yXG4gKiBpZiB2YWx1ZSBpcyBhIG51bWJlci5cbiAqIEJ1ZmZlci5mcm9tKHN0clssIGVuY29kaW5nXSlcbiAqIEJ1ZmZlci5mcm9tKGFycmF5KVxuICogQnVmZmVyLmZyb20oYnVmZmVyKVxuICogQnVmZmVyLmZyb20oYXJyYXlCdWZmZXJbLCBieXRlT2Zmc2V0WywgbGVuZ3RoXV0pXG4gKiovXG5CdWZmZXIuZnJvbSA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBmcm9tKG51bGwsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbmlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICBCdWZmZXIucHJvdG90eXBlLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXkucHJvdG90eXBlXG4gIEJ1ZmZlci5fX3Byb3RvX18gPSBVaW50OEFycmF5XG4gIGlmICh0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wuc3BlY2llcyAmJlxuICAgICAgQnVmZmVyW1N5bWJvbC5zcGVjaWVzXSA9PT0gQnVmZmVyKSB7XG4gICAgLy8gRml4IHN1YmFycmF5KCkgaW4gRVMyMDE2LiBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL3B1bGwvOTdcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQnVmZmVyLCBTeW1ib2wuc3BlY2llcywge1xuICAgICAgdmFsdWU6IG51bGwsXG4gICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KVxuICB9XG59XG5cbmZ1bmN0aW9uIGFzc2VydFNpemUgKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3QgYmUgYSBudW1iZXInKVxuICB9IGVsc2UgaWYgKHNpemUgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIG5lZ2F0aXZlJylcbiAgfVxufVxuXG5mdW5jdGlvbiBhbGxvYyAodGhhdCwgc2l6ZSwgZmlsbCwgZW5jb2RpbmcpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICBpZiAoc2l6ZSA8PSAwKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKVxuICB9XG4gIGlmIChmaWxsICE9PSB1bmRlZmluZWQpIHtcbiAgICAvLyBPbmx5IHBheSBhdHRlbnRpb24gdG8gZW5jb2RpbmcgaWYgaXQncyBhIHN0cmluZy4gVGhpc1xuICAgIC8vIHByZXZlbnRzIGFjY2lkZW50YWxseSBzZW5kaW5nIGluIGEgbnVtYmVyIHRoYXQgd291bGRcbiAgICAvLyBiZSBpbnRlcnByZXR0ZWQgYXMgYSBzdGFydCBvZmZzZXQuXG4gICAgcmV0dXJuIHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZydcbiAgICAgID8gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpLmZpbGwoZmlsbCwgZW5jb2RpbmcpXG4gICAgICA6IGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKS5maWxsKGZpbGwpXG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqIGFsbG9jKHNpemVbLCBmaWxsWywgZW5jb2RpbmddXSlcbiAqKi9cbkJ1ZmZlci5hbGxvYyA9IGZ1bmN0aW9uIChzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICByZXR1cm4gYWxsb2MobnVsbCwgc2l6ZSwgZmlsbCwgZW5jb2RpbmcpXG59XG5cbmZ1bmN0aW9uIGFsbG9jVW5zYWZlICh0aGF0LCBzaXplKSB7XG4gIGFzc2VydFNpemUoc2l6ZSlcbiAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplIDwgMCA/IDAgOiBjaGVja2VkKHNpemUpIHwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2l6ZTsgKytpKSB7XG4gICAgICB0aGF0W2ldID0gMFxuICAgIH1cbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG4vKipcbiAqIEVxdWl2YWxlbnQgdG8gQnVmZmVyKG51bSksIGJ5IGRlZmF1bHQgY3JlYXRlcyBhIG5vbi16ZXJvLWZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKiAqL1xuQnVmZmVyLmFsbG9jVW5zYWZlID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgcmV0dXJuIGFsbG9jVW5zYWZlKG51bGwsIHNpemUpXG59XG4vKipcbiAqIEVxdWl2YWxlbnQgdG8gU2xvd0J1ZmZlcihudW0pLCBieSBkZWZhdWx0IGNyZWF0ZXMgYSBub24temVyby1maWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICovXG5CdWZmZXIuYWxsb2NVbnNhZmVTbG93ID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgcmV0dXJuIGFsbG9jVW5zYWZlKG51bGwsIHNpemUpXG59XG5cbmZ1bmN0aW9uIGZyb21TdHJpbmcgKHRoYXQsIHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycgfHwgZW5jb2RpbmcgPT09ICcnKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgfVxuXG4gIGlmICghQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJlbmNvZGluZ1wiIG11c3QgYmUgYSB2YWxpZCBzdHJpbmcgZW5jb2RpbmcnKVxuICB9XG5cbiAgdmFyIGxlbmd0aCA9IGJ5dGVMZW5ndGgoc3RyaW5nLCBlbmNvZGluZykgfCAwXG4gIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgbGVuZ3RoKVxuXG4gIHZhciBhY3R1YWwgPSB0aGF0LndyaXRlKHN0cmluZywgZW5jb2RpbmcpXG5cbiAgaWYgKGFjdHVhbCAhPT0gbGVuZ3RoKSB7XG4gICAgLy8gV3JpdGluZyBhIGhleCBzdHJpbmcsIGZvciBleGFtcGxlLCB0aGF0IGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVycyB3aWxsXG4gICAgLy8gY2F1c2UgZXZlcnl0aGluZyBhZnRlciB0aGUgZmlyc3QgaW52YWxpZCBjaGFyYWN0ZXIgdG8gYmUgaWdub3JlZC4gKGUuZy5cbiAgICAvLyAnYWJ4eGNkJyB3aWxsIGJlIHRyZWF0ZWQgYXMgJ2FiJylcbiAgICB0aGF0ID0gdGhhdC5zbGljZSgwLCBhY3R1YWwpXG4gIH1cblxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tQXJyYXlMaWtlICh0aGF0LCBhcnJheSkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoIDwgMCA/IDAgOiBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgbGVuZ3RoKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhhdFtpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5QnVmZmVyICh0aGF0LCBhcnJheSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gIGFycmF5LmJ5dGVMZW5ndGggLy8gdGhpcyB0aHJvd3MgaWYgYGFycmF5YCBpcyBub3QgYSB2YWxpZCBBcnJheUJ1ZmZlclxuXG4gIGlmIChieXRlT2Zmc2V0IDwgMCB8fCBhcnJheS5ieXRlTGVuZ3RoIDwgYnl0ZU9mZnNldCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcXCdvZmZzZXRcXCcgaXMgb3V0IG9mIGJvdW5kcycpXG4gIH1cblxuICBpZiAoYXJyYXkuYnl0ZUxlbmd0aCA8IGJ5dGVPZmZzZXQgKyAobGVuZ3RoIHx8IDApKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1xcJ2xlbmd0aFxcJyBpcyBvdXQgb2YgYm91bmRzJylcbiAgfVxuXG4gIGlmIChieXRlT2Zmc2V0ID09PSB1bmRlZmluZWQgJiYgbGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBhcnJheSA9IG5ldyBVaW50OEFycmF5KGFycmF5KVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgYXJyYXkgPSBuZXcgVWludDhBcnJheShhcnJheSwgYnl0ZU9mZnNldClcbiAgfSBlbHNlIHtcbiAgICBhcnJheSA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICB0aGF0ID0gYXJyYXlcbiAgICB0aGF0Ll9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgfSBlbHNlIHtcbiAgICAvLyBGYWxsYmFjazogUmV0dXJuIGFuIG9iamVjdCBpbnN0YW5jZSBvZiB0aGUgQnVmZmVyIGNsYXNzXG4gICAgdGhhdCA9IGZyb21BcnJheUxpa2UodGhhdCwgYXJyYXkpXG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbU9iamVjdCAodGhhdCwgb2JqKSB7XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIob2JqKSkge1xuICAgIHZhciBsZW4gPSBjaGVja2VkKG9iai5sZW5ndGgpIHwgMFxuICAgIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgbGVuKVxuXG4gICAgaWYgKHRoYXQubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gdGhhdFxuICAgIH1cblxuICAgIG9iai5jb3B5KHRoYXQsIDAsIDAsIGxlbilcbiAgICByZXR1cm4gdGhhdFxuICB9XG5cbiAgaWYgKG9iaikge1xuICAgIGlmICgodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICBvYmouYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHx8ICdsZW5ndGgnIGluIG9iaikge1xuICAgICAgaWYgKHR5cGVvZiBvYmoubGVuZ3RoICE9PSAnbnVtYmVyJyB8fCBpc25hbihvYmoubGVuZ3RoKSkge1xuICAgICAgICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIDApXG4gICAgICB9XG4gICAgICByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmopXG4gICAgfVxuXG4gICAgaWYgKG9iai50eXBlID09PSAnQnVmZmVyJyAmJiBpc0FycmF5KG9iai5kYXRhKSkge1xuICAgICAgcmV0dXJuIGZyb21BcnJheUxpa2UodGhhdCwgb2JqLmRhdGEpXG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcignRmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZywgQnVmZmVyLCBBcnJheUJ1ZmZlciwgQXJyYXksIG9yIGFycmF5LWxpa2Ugb2JqZWN0LicpXG59XG5cbmZ1bmN0aW9uIGNoZWNrZWQgKGxlbmd0aCkge1xuICAvLyBOb3RlOiBjYW5ub3QgdXNlIGBsZW5ndGggPCBrTWF4TGVuZ3RoKClgIGhlcmUgYmVjYXVzZSB0aGF0IGZhaWxzIHdoZW5cbiAgLy8gbGVuZ3RoIGlzIE5hTiAod2hpY2ggaXMgb3RoZXJ3aXNlIGNvZXJjZWQgdG8gemVyby4pXG4gIGlmIChsZW5ndGggPj0ga01heExlbmd0aCgpKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gYWxsb2NhdGUgQnVmZmVyIGxhcmdlciB0aGFuIG1heGltdW0gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgJ3NpemU6IDB4JyArIGtNYXhMZW5ndGgoKS50b1N0cmluZygxNikgKyAnIGJ5dGVzJylcbiAgfVxuICByZXR1cm4gbGVuZ3RoIHwgMFxufVxuXG5mdW5jdGlvbiBTbG93QnVmZmVyIChsZW5ndGgpIHtcbiAgaWYgKCtsZW5ndGggIT0gbGVuZ3RoKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZXFlcWVxXG4gICAgbGVuZ3RoID0gMFxuICB9XG4gIHJldHVybiBCdWZmZXIuYWxsb2MoK2xlbmd0aClcbn1cblxuQnVmZmVyLmlzQnVmZmVyID0gZnVuY3Rpb24gaXNCdWZmZXIgKGIpIHtcbiAgcmV0dXJuICEhKGIgIT0gbnVsbCAmJiBiLl9pc0J1ZmZlcilcbn1cblxuQnVmZmVyLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChhLCBiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGEpIHx8ICFCdWZmZXIuaXNCdWZmZXIoYikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudHMgbXVzdCBiZSBCdWZmZXJzJylcbiAgfVxuXG4gIGlmIChhID09PSBiKSByZXR1cm4gMFxuXG4gIHZhciB4ID0gYS5sZW5ndGhcbiAgdmFyIHkgPSBiLmxlbmd0aFxuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBNYXRoLm1pbih4LCB5KTsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKGFbaV0gIT09IGJbaV0pIHtcbiAgICAgIHggPSBhW2ldXG4gICAgICB5ID0gYltpXVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbkJ1ZmZlci5pc0VuY29kaW5nID0gZnVuY3Rpb24gaXNFbmNvZGluZyAoZW5jb2RpbmcpIHtcbiAgc3dpdGNoIChTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKCkpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICBjYXNlICdhc2NpaSc6XG4gICAgY2FzZSAnbGF0aW4xJzpcbiAgICBjYXNlICdiaW5hcnknOlxuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgIHJldHVybiB0cnVlXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbkJ1ZmZlci5jb25jYXQgPSBmdW5jdGlvbiBjb25jYXQgKGxpc3QsIGxlbmd0aCkge1xuICBpZiAoIWlzQXJyYXkobGlzdCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RcIiBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMnKVxuICB9XG5cbiAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5hbGxvYygwKVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbGVuZ3RoID0gMFxuICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgICBsZW5ndGggKz0gbGlzdFtpXS5sZW5ndGhcbiAgICB9XG4gIH1cblxuICB2YXIgYnVmZmVyID0gQnVmZmVyLmFsbG9jVW5zYWZlKGxlbmd0aClcbiAgdmFyIHBvcyA9IDBcbiAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgYnVmID0gbGlzdFtpXVxuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpXG4gICAgfVxuICAgIGJ1Zi5jb3B5KGJ1ZmZlciwgcG9zKVxuICAgIHBvcyArPSBidWYubGVuZ3RoXG4gIH1cbiAgcmV0dXJuIGJ1ZmZlclxufVxuXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChzdHJpbmcsIGVuY29kaW5nKSB7XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIoc3RyaW5nKSkge1xuICAgIHJldHVybiBzdHJpbmcubGVuZ3RoXG4gIH1cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIEFycmF5QnVmZmVyLmlzVmlldyA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgKEFycmF5QnVmZmVyLmlzVmlldyhzdHJpbmcpIHx8IHN0cmluZyBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSkge1xuICAgIHJldHVybiBzdHJpbmcuYnl0ZUxlbmd0aFxuICB9XG4gIGlmICh0eXBlb2Ygc3RyaW5nICE9PSAnc3RyaW5nJykge1xuICAgIHN0cmluZyA9ICcnICsgc3RyaW5nXG4gIH1cblxuICB2YXIgbGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAobGVuID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIFVzZSBhIGZvciBsb29wIHRvIGF2b2lkIHJlY3Vyc2lvblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsZW5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgY2FzZSB1bmRlZmluZWQ6XG4gICAgICAgIHJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIGxlbiAqIDJcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBsZW4gPj4+IDFcbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aCAvLyBhc3N1bWUgdXRmOFxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuQnVmZmVyLmJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoXG5cbmZ1bmN0aW9uIHNsb3dUb1N0cmluZyAoZW5jb2RpbmcsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcblxuICAvLyBObyBuZWVkIHRvIHZlcmlmeSB0aGF0IFwidGhpcy5sZW5ndGggPD0gTUFYX1VJTlQzMlwiIHNpbmNlIGl0J3MgYSByZWFkLW9ubHlcbiAgLy8gcHJvcGVydHkgb2YgYSB0eXBlZCBhcnJheS5cblxuICAvLyBUaGlzIGJlaGF2ZXMgbmVpdGhlciBsaWtlIFN0cmluZyBub3IgVWludDhBcnJheSBpbiB0aGF0IHdlIHNldCBzdGFydC9lbmRcbiAgLy8gdG8gdGhlaXIgdXBwZXIvbG93ZXIgYm91bmRzIGlmIHRoZSB2YWx1ZSBwYXNzZWQgaXMgb3V0IG9mIHJhbmdlLlxuICAvLyB1bmRlZmluZWQgaXMgaGFuZGxlZCBzcGVjaWFsbHkgYXMgcGVyIEVDTUEtMjYyIDZ0aCBFZGl0aW9uLFxuICAvLyBTZWN0aW9uIDEzLjMuMy43IFJ1bnRpbWUgU2VtYW50aWNzOiBLZXllZEJpbmRpbmdJbml0aWFsaXphdGlvbi5cbiAgaWYgKHN0YXJ0ID09PSB1bmRlZmluZWQgfHwgc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgPSAwXG4gIH1cbiAgLy8gUmV0dXJuIGVhcmx5IGlmIHN0YXJ0ID4gdGhpcy5sZW5ndGguIERvbmUgaGVyZSB0byBwcmV2ZW50IHBvdGVudGlhbCB1aW50MzJcbiAgLy8gY29lcmNpb24gZmFpbCBiZWxvdy5cbiAgaWYgKHN0YXJ0ID4gdGhpcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIGlmIChlbmQgPT09IHVuZGVmaW5lZCB8fCBlbmQgPiB0aGlzLmxlbmd0aCkge1xuICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gIH1cblxuICBpZiAoZW5kIDw9IDApIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIC8vIEZvcmNlIGNvZXJzaW9uIHRvIHVpbnQzMi4gVGhpcyB3aWxsIGFsc28gY29lcmNlIGZhbHNleS9OYU4gdmFsdWVzIHRvIDAuXG4gIGVuZCA+Pj49IDBcbiAgc3RhcnQgPj4+PSAwXG5cbiAgaWYgKGVuZCA8PSBzdGFydCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGF0aW4xU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1dGYxNmxlU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbi8vIFRoZSBwcm9wZXJ0eSBpcyB1c2VkIGJ5IGBCdWZmZXIuaXNCdWZmZXJgIGFuZCBgaXMtYnVmZmVyYCAoaW4gU2FmYXJpIDUtNykgdG8gZGV0ZWN0XG4vLyBCdWZmZXIgaW5zdGFuY2VzLlxuQnVmZmVyLnByb3RvdHlwZS5faXNCdWZmZXIgPSB0cnVlXG5cbmZ1bmN0aW9uIHN3YXAgKGIsIG4sIG0pIHtcbiAgdmFyIGkgPSBiW25dXG4gIGJbbl0gPSBiW21dXG4gIGJbbV0gPSBpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDE2ID0gZnVuY3Rpb24gc3dhcDE2ICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSAyICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAxNi1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSAyKSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgMSlcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXAzMiA9IGZ1bmN0aW9uIHN3YXAzMiAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgNCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgMzItYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gNCkge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDMpXG4gICAgc3dhcCh0aGlzLCBpICsgMSwgaSArIDIpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwNjQgPSBmdW5jdGlvbiBzd2FwNjQgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDggIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDY0LWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDgpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyA3KVxuICAgIHN3YXAodGhpcywgaSArIDEsIGkgKyA2KVxuICAgIHN3YXAodGhpcywgaSArIDIsIGkgKyA1KVxuICAgIHN3YXAodGhpcywgaSArIDMsIGkgKyA0KVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyAoKSB7XG4gIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aCB8IDBcbiAgaWYgKGxlbmd0aCA9PT0gMCkgcmV0dXJuICcnXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIDAsIGxlbmd0aClcbiAgcmV0dXJuIHNsb3dUb1N0cmluZy5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gZXF1YWxzIChiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiB0cnVlXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKSA9PT0gMFxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0ICgpIHtcbiAgdmFyIHN0ciA9ICcnXG4gIHZhciBtYXggPSBleHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTXG4gIGlmICh0aGlzLmxlbmd0aCA+IDApIHtcbiAgICBzdHIgPSB0aGlzLnRvU3RyaW5nKCdoZXgnLCAwLCBtYXgpLm1hdGNoKC8uezJ9L2cpLmpvaW4oJyAnKVxuICAgIGlmICh0aGlzLmxlbmd0aCA+IG1heCkgc3RyICs9ICcgLi4uICdcbiAgfVxuICByZXR1cm4gJzxCdWZmZXIgJyArIHN0ciArICc+J1xufVxuXG5CdWZmZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlICh0YXJnZXQsIHN0YXJ0LCBlbmQsIHRoaXNTdGFydCwgdGhpc0VuZCkge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcih0YXJnZXQpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlcicpXG4gIH1cblxuICBpZiAoc3RhcnQgPT09IHVuZGVmaW5lZCkge1xuICAgIHN0YXJ0ID0gMFxuICB9XG4gIGlmIChlbmQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuZCA9IHRhcmdldCA/IHRhcmdldC5sZW5ndGggOiAwXG4gIH1cbiAgaWYgKHRoaXNTdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhpc1N0YXJ0ID0gMFxuICB9XG4gIGlmICh0aGlzRW5kID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzRW5kID0gdGhpcy5sZW5ndGhcbiAgfVxuXG4gIGlmIChzdGFydCA8IDAgfHwgZW5kID4gdGFyZ2V0Lmxlbmd0aCB8fCB0aGlzU3RhcnQgPCAwIHx8IHRoaXNFbmQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdvdXQgb2YgcmFuZ2UgaW5kZXgnKVxuICB9XG5cbiAgaWYgKHRoaXNTdGFydCA+PSB0aGlzRW5kICYmIHN0YXJ0ID49IGVuZCkge1xuICAgIHJldHVybiAwXG4gIH1cbiAgaWYgKHRoaXNTdGFydCA+PSB0aGlzRW5kKSB7XG4gICAgcmV0dXJuIC0xXG4gIH1cbiAgaWYgKHN0YXJ0ID49IGVuZCkge1xuICAgIHJldHVybiAxXG4gIH1cblxuICBzdGFydCA+Pj49IDBcbiAgZW5kID4+Pj0gMFxuICB0aGlzU3RhcnQgPj4+PSAwXG4gIHRoaXNFbmQgPj4+PSAwXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCkgcmV0dXJuIDBcblxuICB2YXIgeCA9IHRoaXNFbmQgLSB0aGlzU3RhcnRcbiAgdmFyIHkgPSBlbmQgLSBzdGFydFxuICB2YXIgbGVuID0gTWF0aC5taW4oeCwgeSlcblxuICB2YXIgdGhpc0NvcHkgPSB0aGlzLnNsaWNlKHRoaXNTdGFydCwgdGhpc0VuZClcbiAgdmFyIHRhcmdldENvcHkgPSB0YXJnZXQuc2xpY2Uoc3RhcnQsIGVuZClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKHRoaXNDb3B5W2ldICE9PSB0YXJnZXRDb3B5W2ldKSB7XG4gICAgICB4ID0gdGhpc0NvcHlbaV1cbiAgICAgIHkgPSB0YXJnZXRDb3B5W2ldXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuLy8gRmluZHMgZWl0aGVyIHRoZSBmaXJzdCBpbmRleCBvZiBgdmFsYCBpbiBgYnVmZmVyYCBhdCBvZmZzZXQgPj0gYGJ5dGVPZmZzZXRgLFxuLy8gT1IgdGhlIGxhc3QgaW5kZXggb2YgYHZhbGAgaW4gYGJ1ZmZlcmAgYXQgb2Zmc2V0IDw9IGBieXRlT2Zmc2V0YC5cbi8vXG4vLyBBcmd1bWVudHM6XG4vLyAtIGJ1ZmZlciAtIGEgQnVmZmVyIHRvIHNlYXJjaFxuLy8gLSB2YWwgLSBhIHN0cmluZywgQnVmZmVyLCBvciBudW1iZXJcbi8vIC0gYnl0ZU9mZnNldCAtIGFuIGluZGV4IGludG8gYGJ1ZmZlcmA7IHdpbGwgYmUgY2xhbXBlZCB0byBhbiBpbnQzMlxuLy8gLSBlbmNvZGluZyAtIGFuIG9wdGlvbmFsIGVuY29kaW5nLCByZWxldmFudCBpcyB2YWwgaXMgYSBzdHJpbmdcbi8vIC0gZGlyIC0gdHJ1ZSBmb3IgaW5kZXhPZiwgZmFsc2UgZm9yIGxhc3RJbmRleE9mXG5mdW5jdGlvbiBiaWRpcmVjdGlvbmFsSW5kZXhPZiAoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpIHtcbiAgLy8gRW1wdHkgYnVmZmVyIG1lYW5zIG5vIG1hdGNoXG4gIGlmIChidWZmZXIubGVuZ3RoID09PSAwKSByZXR1cm4gLTFcblxuICAvLyBOb3JtYWxpemUgYnl0ZU9mZnNldFxuICBpZiAodHlwZW9mIGJ5dGVPZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBieXRlT2Zmc2V0XG4gICAgYnl0ZU9mZnNldCA9IDBcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0ID4gMHg3ZmZmZmZmZikge1xuICAgIGJ5dGVPZmZzZXQgPSAweDdmZmZmZmZmXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA8IC0weDgwMDAwMDAwKSB7XG4gICAgYnl0ZU9mZnNldCA9IC0weDgwMDAwMDAwXG4gIH1cbiAgYnl0ZU9mZnNldCA9ICtieXRlT2Zmc2V0ICAvLyBDb2VyY2UgdG8gTnVtYmVyLlxuICBpZiAoaXNOYU4oYnl0ZU9mZnNldCkpIHtcbiAgICAvLyBieXRlT2Zmc2V0OiBpdCBpdCdzIHVuZGVmaW5lZCwgbnVsbCwgTmFOLCBcImZvb1wiLCBldGMsIHNlYXJjaCB3aG9sZSBidWZmZXJcbiAgICBieXRlT2Zmc2V0ID0gZGlyID8gMCA6IChidWZmZXIubGVuZ3RoIC0gMSlcbiAgfVxuXG4gIC8vIE5vcm1hbGl6ZSBieXRlT2Zmc2V0OiBuZWdhdGl2ZSBvZmZzZXRzIHN0YXJ0IGZyb20gdGhlIGVuZCBvZiB0aGUgYnVmZmVyXG4gIGlmIChieXRlT2Zmc2V0IDwgMCkgYnl0ZU9mZnNldCA9IGJ1ZmZlci5sZW5ndGggKyBieXRlT2Zmc2V0XG4gIGlmIChieXRlT2Zmc2V0ID49IGJ1ZmZlci5sZW5ndGgpIHtcbiAgICBpZiAoZGlyKSByZXR1cm4gLTFcbiAgICBlbHNlIGJ5dGVPZmZzZXQgPSBidWZmZXIubGVuZ3RoIC0gMVxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAwKSB7XG4gICAgaWYgKGRpcikgYnl0ZU9mZnNldCA9IDBcbiAgICBlbHNlIHJldHVybiAtMVxuICB9XG5cbiAgLy8gTm9ybWFsaXplIHZhbFxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHtcbiAgICB2YWwgPSBCdWZmZXIuZnJvbSh2YWwsIGVuY29kaW5nKVxuICB9XG5cbiAgLy8gRmluYWxseSwgc2VhcmNoIGVpdGhlciBpbmRleE9mIChpZiBkaXIgaXMgdHJ1ZSkgb3IgbGFzdEluZGV4T2ZcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcih2YWwpKSB7XG4gICAgLy8gU3BlY2lhbCBjYXNlOiBsb29raW5nIGZvciBlbXB0eSBzdHJpbmcvYnVmZmVyIGFsd2F5cyBmYWlsc1xuICAgIGlmICh2YWwubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gLTFcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZihidWZmZXIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcilcbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIHZhbCA9IHZhbCAmIDB4RkYgLy8gU2VhcmNoIGZvciBhIGJ5dGUgdmFsdWUgWzAtMjU1XVxuICAgIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJlxuICAgICAgICB0eXBlb2YgVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaWYgKGRpcikge1xuICAgICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmxhc3RJbmRleE9mLmNhbGwoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YoYnVmZmVyLCBbIHZhbCBdLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmFsIG11c3QgYmUgc3RyaW5nLCBudW1iZXIgb3IgQnVmZmVyJylcbn1cblxuZnVuY3Rpb24gYXJyYXlJbmRleE9mIChhcnIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcikge1xuICB2YXIgaW5kZXhTaXplID0gMVxuICB2YXIgYXJyTGVuZ3RoID0gYXJyLmxlbmd0aFxuICB2YXIgdmFsTGVuZ3RoID0gdmFsLmxlbmd0aFxuXG4gIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSBTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICBpZiAoZW5jb2RpbmcgPT09ICd1Y3MyJyB8fCBlbmNvZGluZyA9PT0gJ3Vjcy0yJyB8fFxuICAgICAgICBlbmNvZGluZyA9PT0gJ3V0ZjE2bGUnIHx8IGVuY29kaW5nID09PSAndXRmLTE2bGUnKSB7XG4gICAgICBpZiAoYXJyLmxlbmd0aCA8IDIgfHwgdmFsLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgcmV0dXJuIC0xXG4gICAgICB9XG4gICAgICBpbmRleFNpemUgPSAyXG4gICAgICBhcnJMZW5ndGggLz0gMlxuICAgICAgdmFsTGVuZ3RoIC89IDJcbiAgICAgIGJ5dGVPZmZzZXQgLz0gMlxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlYWQgKGJ1ZiwgaSkge1xuICAgIGlmIChpbmRleFNpemUgPT09IDEpIHtcbiAgICAgIHJldHVybiBidWZbaV1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGJ1Zi5yZWFkVUludDE2QkUoaSAqIGluZGV4U2l6ZSlcbiAgICB9XG4gIH1cblxuICB2YXIgaVxuICBpZiAoZGlyKSB7XG4gICAgdmFyIGZvdW5kSW5kZXggPSAtMVxuICAgIGZvciAoaSA9IGJ5dGVPZmZzZXQ7IGkgPCBhcnJMZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHJlYWQoYXJyLCBpKSA9PT0gcmVhZCh2YWwsIGZvdW5kSW5kZXggPT09IC0xID8gMCA6IGkgLSBmb3VuZEluZGV4KSkge1xuICAgICAgICBpZiAoZm91bmRJbmRleCA9PT0gLTEpIGZvdW5kSW5kZXggPSBpXG4gICAgICAgIGlmIChpIC0gZm91bmRJbmRleCArIDEgPT09IHZhbExlbmd0aCkgcmV0dXJuIGZvdW5kSW5kZXggKiBpbmRleFNpemVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ICE9PSAtMSkgaSAtPSBpIC0gZm91bmRJbmRleFxuICAgICAgICBmb3VuZEluZGV4ID0gLTFcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGJ5dGVPZmZzZXQgKyB2YWxMZW5ndGggPiBhcnJMZW5ndGgpIGJ5dGVPZmZzZXQgPSBhcnJMZW5ndGggLSB2YWxMZW5ndGhcbiAgICBmb3IgKGkgPSBieXRlT2Zmc2V0OyBpID49IDA7IGktLSkge1xuICAgICAgdmFyIGZvdW5kID0gdHJ1ZVxuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCB2YWxMZW5ndGg7IGorKykge1xuICAgICAgICBpZiAocmVhZChhcnIsIGkgKyBqKSAhPT0gcmVhZCh2YWwsIGopKSB7XG4gICAgICAgICAgZm91bmQgPSBmYWxzZVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChmb3VuZCkgcmV0dXJuIGlcbiAgICB9XG4gIH1cblxuICByZXR1cm4gLTFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbmNsdWRlcyA9IGZ1bmN0aW9uIGluY2x1ZGVzICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiB0aGlzLmluZGV4T2YodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykgIT09IC0xXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uIGluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGJpZGlyZWN0aW9uYWxJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIHRydWUpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUubGFzdEluZGV4T2YgPSBmdW5jdGlvbiBsYXN0SW5kZXhPZiAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZmFsc2UpXG59XG5cbmZ1bmN0aW9uIGhleFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gYnVmLmxlbmd0aCAtIG9mZnNldFxuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9IE51bWJlcihsZW5ndGgpXG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gICAgfVxuICB9XG5cbiAgLy8gbXVzdCBiZSBhbiBldmVuIG51bWJlciBvZiBkaWdpdHNcbiAgdmFyIHN0ckxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKHN0ckxlbiAlIDIgIT09IDApIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgaGV4IHN0cmluZycpXG5cbiAgaWYgKGxlbmd0aCA+IHN0ckxlbiAvIDIpIHtcbiAgICBsZW5ndGggPSBzdHJMZW4gLyAyXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIHZhciBwYXJzZWQgPSBwYXJzZUludChzdHJpbmcuc3Vic3RyKGkgKiAyLCAyKSwgMTYpXG4gICAgaWYgKGlzTmFOKHBhcnNlZCkpIHJldHVybiBpXG4gICAgYnVmW29mZnNldCArIGldID0gcGFyc2VkXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gdXRmOFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmOFRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYXNjaWlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGFzY2lpVG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBsYXRpbjFXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBhc2NpaVdyaXRlKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYmFzZTY0V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihiYXNlNjRUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIHVjczJXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjE2bGVUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiB3cml0ZSAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpIHtcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZylcbiAgaWYgKG9mZnNldCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgZW5jb2RpbmcpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIG9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IG9mZnNldFxuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBvZmZzZXRbLCBsZW5ndGhdWywgZW5jb2RpbmddKVxuICB9IGVsc2UgaWYgKGlzRmluaXRlKG9mZnNldCkpIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gICAgaWYgKGlzRmluaXRlKGxlbmd0aCkpIHtcbiAgICAgIGxlbmd0aCA9IGxlbmd0aCB8IDBcbiAgICAgIGlmIChlbmNvZGluZyA9PT0gdW5kZWZpbmVkKSBlbmNvZGluZyA9ICd1dGY4J1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmNvZGluZyA9IGxlbmd0aFxuICAgICAgbGVuZ3RoID0gdW5kZWZpbmVkXG4gICAgfVxuICAvLyBsZWdhY3kgd3JpdGUoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0LCBsZW5ndGgpIC0gcmVtb3ZlIGluIHYwLjEzXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ0J1ZmZlci53cml0ZShzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXRbLCBsZW5ndGhdKSBpcyBubyBsb25nZXIgc3VwcG9ydGVkJ1xuICAgIClcbiAgfVxuXG4gIHZhciByZW1haW5pbmcgPSB0aGlzLmxlbmd0aCAtIG9mZnNldFxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgfHwgbGVuZ3RoID4gcmVtYWluaW5nKSBsZW5ndGggPSByZW1haW5pbmdcblxuICBpZiAoKHN0cmluZy5sZW5ndGggPiAwICYmIChsZW5ndGggPCAwIHx8IG9mZnNldCA8IDApKSB8fCBvZmZzZXQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIHdyaXRlIG91dHNpZGUgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxhdGluMVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIC8vIFdhcm5pbmc6IG1heExlbmd0aCBub3QgdGFrZW4gaW50byBhY2NvdW50IGluIGJhc2U2NFdyaXRlXG4gICAgICAgIHJldHVybiBiYXNlNjRXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdWNzMldyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTiAoKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ0J1ZmZlcicsXG4gICAgZGF0YTogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy5fYXJyIHx8IHRoaXMsIDApXG4gIH1cbn1cblxuZnVuY3Rpb24gYmFzZTY0U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBpZiAoc3RhcnQgPT09IDAgJiYgZW5kID09PSBidWYubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1ZilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmLnNsaWNlKHN0YXJ0LCBlbmQpKVxuICB9XG59XG5cbmZ1bmN0aW9uIHV0ZjhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcbiAgdmFyIHJlcyA9IFtdXG5cbiAgdmFyIGkgPSBzdGFydFxuICB3aGlsZSAoaSA8IGVuZCkge1xuICAgIHZhciBmaXJzdEJ5dGUgPSBidWZbaV1cbiAgICB2YXIgY29kZVBvaW50ID0gbnVsbFxuICAgIHZhciBieXRlc1BlclNlcXVlbmNlID0gKGZpcnN0Qnl0ZSA+IDB4RUYpID8gNFxuICAgICAgOiAoZmlyc3RCeXRlID4gMHhERikgPyAzXG4gICAgICA6IChmaXJzdEJ5dGUgPiAweEJGKSA/IDJcbiAgICAgIDogMVxuXG4gICAgaWYgKGkgKyBieXRlc1BlclNlcXVlbmNlIDw9IGVuZCkge1xuICAgICAgdmFyIHNlY29uZEJ5dGUsIHRoaXJkQnl0ZSwgZm91cnRoQnl0ZSwgdGVtcENvZGVQb2ludFxuXG4gICAgICBzd2l0Y2ggKGJ5dGVzUGVyU2VxdWVuY2UpIHtcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIGlmIChmaXJzdEJ5dGUgPCAweDgwKSB7XG4gICAgICAgICAgICBjb2RlUG9pbnQgPSBmaXJzdEJ5dGVcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHgxRikgPDwgMHg2IHwgKHNlY29uZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4QyB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKHRoaXJkQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0ZGICYmICh0ZW1wQ29kZVBvaW50IDwgMHhEODAwIHx8IHRlbXBDb2RlUG9pbnQgPiAweERGRkYpKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGZvdXJ0aEJ5dGUgPSBidWZbaSArIDNdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwICYmIChmb3VydGhCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweDEyIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweEMgfCAodGhpcmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKGZvdXJ0aEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweEZGRkYgJiYgdGVtcENvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvZGVQb2ludCA9PT0gbnVsbCkge1xuICAgICAgLy8gd2UgZGlkIG5vdCBnZW5lcmF0ZSBhIHZhbGlkIGNvZGVQb2ludCBzbyBpbnNlcnQgYVxuICAgICAgLy8gcmVwbGFjZW1lbnQgY2hhciAoVStGRkZEKSBhbmQgYWR2YW5jZSBvbmx5IDEgYnl0ZVxuICAgICAgY29kZVBvaW50ID0gMHhGRkZEXG4gICAgICBieXRlc1BlclNlcXVlbmNlID0gMVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50ID4gMHhGRkZGKSB7XG4gICAgICAvLyBlbmNvZGUgdG8gdXRmMTYgKHN1cnJvZ2F0ZSBwYWlyIGRhbmNlKVxuICAgICAgY29kZVBvaW50IC09IDB4MTAwMDBcbiAgICAgIHJlcy5wdXNoKGNvZGVQb2ludCA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMClcbiAgICAgIGNvZGVQb2ludCA9IDB4REMwMCB8IGNvZGVQb2ludCAmIDB4M0ZGXG4gICAgfVxuXG4gICAgcmVzLnB1c2goY29kZVBvaW50KVxuICAgIGkgKz0gYnl0ZXNQZXJTZXF1ZW5jZVxuICB9XG5cbiAgcmV0dXJuIGRlY29kZUNvZGVQb2ludHNBcnJheShyZXMpXG59XG5cbi8vIEJhc2VkIG9uIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIyNzQ3MjcyLzY4MDc0MiwgdGhlIGJyb3dzZXIgd2l0aFxuLy8gdGhlIGxvd2VzdCBsaW1pdCBpcyBDaHJvbWUsIHdpdGggMHgxMDAwMCBhcmdzLlxuLy8gV2UgZ28gMSBtYWduaXR1ZGUgbGVzcywgZm9yIHNhZmV0eVxudmFyIE1BWF9BUkdVTUVOVFNfTEVOR1RIID0gMHgxMDAwXG5cbmZ1bmN0aW9uIGRlY29kZUNvZGVQb2ludHNBcnJheSAoY29kZVBvaW50cykge1xuICB2YXIgbGVuID0gY29kZVBvaW50cy5sZW5ndGhcbiAgaWYgKGxlbiA8PSBNQVhfQVJHVU1FTlRTX0xFTkdUSCkge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY29kZVBvaW50cykgLy8gYXZvaWQgZXh0cmEgc2xpY2UoKVxuICB9XG5cbiAgLy8gRGVjb2RlIGluIGNodW5rcyB0byBhdm9pZCBcImNhbGwgc3RhY2sgc2l6ZSBleGNlZWRlZFwiLlxuICB2YXIgcmVzID0gJydcbiAgdmFyIGkgPSAwXG4gIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoXG4gICAgICBTdHJpbmcsXG4gICAgICBjb2RlUG9pbnRzLnNsaWNlKGksIGkgKz0gTUFYX0FSR1VNRU5UU19MRU5HVEgpXG4gICAgKVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0gJiAweDdGKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gbGF0aW4xU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gaGV4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuXG4gIGlmICghc3RhcnQgfHwgc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgfHwgZW5kIDwgMCB8fCBlbmQgPiBsZW4pIGVuZCA9IGxlblxuXG4gIHZhciBvdXQgPSAnJ1xuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIG91dCArPSB0b0hleChidWZbaV0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuXG5mdW5jdGlvbiB1dGYxNmxlU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgYnl0ZXMgPSBidWYuc2xpY2Uoc3RhcnQsIGVuZClcbiAgdmFyIHJlcyA9ICcnXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSArIGJ5dGVzW2kgKyAxXSAqIDI1NilcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbiBzbGljZSAoc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgc3RhcnQgPSB+fnN0YXJ0XG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuIDogfn5lbmRcblxuICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgKz0gbGVuXG4gICAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIH0gZWxzZSBpZiAoc3RhcnQgPiBsZW4pIHtcbiAgICBzdGFydCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IDApIHtcbiAgICBlbmQgKz0gbGVuXG4gICAgaWYgKGVuZCA8IDApIGVuZCA9IDBcbiAgfSBlbHNlIGlmIChlbmQgPiBsZW4pIHtcbiAgICBlbmQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICB2YXIgbmV3QnVmXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIG5ld0J1ZiA9IHRoaXMuc3ViYXJyYXkoc3RhcnQsIGVuZClcbiAgICBuZXdCdWYuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIHZhciBzbGljZUxlbiA9IGVuZCAtIHN0YXJ0XG4gICAgbmV3QnVmID0gbmV3IEJ1ZmZlcihzbGljZUxlbiwgdW5kZWZpbmVkKVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2xpY2VMZW47ICsraSkge1xuICAgICAgbmV3QnVmW2ldID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ld0J1ZlxufVxuXG4vKlxuICogTmVlZCB0byBtYWtlIHN1cmUgdGhhdCBidWZmZXIgaXNuJ3QgdHJ5aW5nIHRvIHdyaXRlIG91dCBvZiBib3VuZHMuXG4gKi9cbmZ1bmN0aW9uIGNoZWNrT2Zmc2V0IChvZmZzZXQsIGV4dCwgbGVuZ3RoKSB7XG4gIGlmICgob2Zmc2V0ICUgMSkgIT09IDAgfHwgb2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ29mZnNldCBpcyBub3QgdWludCcpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBsZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdUcnlpbmcgdG8gYWNjZXNzIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludExFID0gZnVuY3Rpb24gcmVhZFVJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludEJFID0gZnVuY3Rpb24gcmVhZFVJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcbiAgfVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF1cbiAgdmFyIG11bCA9IDFcbiAgd2hpbGUgKGJ5dGVMZW5ndGggPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50OCA9IGZ1bmN0aW9uIHJlYWRVSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkxFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCA4KSB8IHRoaXNbb2Zmc2V0ICsgMV1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyTEUgPSBmdW5jdGlvbiByZWFkVUludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKCh0aGlzW29mZnNldF0pIHxcbiAgICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSkgK1xuICAgICAgKHRoaXNbb2Zmc2V0ICsgM10gKiAweDEwMDAwMDApXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gKiAweDEwMDAwMDApICtcbiAgICAoKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgdGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50TEUgPSBmdW5jdGlvbiByZWFkSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50QkUgPSBmdW5jdGlvbiByZWFkSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgaSA9IGJ5dGVMZW5ndGhcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1pXVxuICB3aGlsZSAoaSA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uIHJlYWRJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIGlmICghKHRoaXNbb2Zmc2V0XSAmIDB4ODApKSByZXR1cm4gKHRoaXNbb2Zmc2V0XSlcbiAgcmV0dXJuICgoMHhmZiAtIHRoaXNbb2Zmc2V0XSArIDEpICogLTEpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2TEUgPSBmdW5jdGlvbiByZWFkSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkJFID0gZnVuY3Rpb24gcmVhZEludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgMV0gfCAodGhpc1tvZmZzZXRdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0pIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSA8PCAyNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgMjQpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRMRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdExFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRCRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdEJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFID0gZnVuY3Rpb24gcmVhZERvdWJsZUxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCA1MiwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlQkUgPSBmdW5jdGlvbiByZWFkRG91YmxlQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCA1MiwgOClcbn1cblxuZnVuY3Rpb24gY2hlY2tJbnQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImJ1ZmZlclwiIGFyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXIgaW5zdGFuY2UnKVxuICBpZiAodmFsdWUgPiBtYXggfHwgdmFsdWUgPCBtaW4pIHRocm93IG5ldyBSYW5nZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgaXMgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlVUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIG1heEJ5dGVzID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpIC0gMVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG1heEJ5dGVzLCAwKVxuICB9XG5cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlVUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIG1heEJ5dGVzID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpIC0gMVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG1heEJ5dGVzLCAwKVxuICB9XG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVVSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweGZmLCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDE2IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZiArIHZhbHVlICsgMVxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGJ1Zi5sZW5ndGggLSBvZmZzZXQsIDIpOyBpIDwgajsgKytpKSB7XG4gICAgYnVmW29mZnNldCArIGldID0gKHZhbHVlICYgKDB4ZmYgPDwgKDggKiAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSkpKSA+Pj5cbiAgICAgIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpICogOFxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDMyIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCA0KTsgaSA8IGo7ICsraSkge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSA+Pj4gKGxpdHRsZUVuZGlhbiA/IGkgOiAzIC0gaSkgKiA4KSAmIDB4ZmZcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSAwXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIGlmICh2YWx1ZSA8IDAgJiYgc3ViID09PSAwICYmIHRoaXNbb2Zmc2V0ICsgaSAtIDFdICE9PSAwKSB7XG4gICAgICBzdWIgPSAxXG4gICAgfVxuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlSW50QkUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gMFxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIGlmICh2YWx1ZSA8IDAgJiYgc3ViID09PSAwICYmIHRoaXNbb2Zmc2V0ICsgaSArIDFdICE9PSAwKSB7XG4gICAgICBzdWIgPSAxXG4gICAgfVxuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4N2YsIC0weDgwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZiArIHZhbHVlICsgMVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5mdW5jdGlvbiBjaGVja0lFRUU3NTQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG4gIGlmIChvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuZnVuY3Rpb24gd3JpdGVGbG9hdCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA0LCAzLjQwMjgyMzQ2NjM4NTI4ODZlKzM4LCAtMy40MDI4MjM0NjYzODUyODg2ZSszOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCAyMywgNClcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0TEUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRCRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiB3cml0ZURvdWJsZSAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA4LCAxLjc5NzY5MzEzNDg2MjMxNTdFKzMwOCwgLTEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDUyLCA4KVxuICByZXR1cm4gb2Zmc2V0ICsgOFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlTEUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVCRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbi8vIGNvcHkodGFyZ2V0QnVmZmVyLCB0YXJnZXRTdGFydD0wLCBzb3VyY2VTdGFydD0wLCBzb3VyY2VFbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uIGNvcHkgKHRhcmdldCwgdGFyZ2V0U3RhcnQsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kICYmIGVuZCAhPT0gMCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldFN0YXJ0ID49IHRhcmdldC5sZW5ndGgpIHRhcmdldFN0YXJ0ID0gdGFyZ2V0Lmxlbmd0aFxuICBpZiAoIXRhcmdldFN0YXJ0KSB0YXJnZXRTdGFydCA9IDBcbiAgaWYgKGVuZCA+IDAgJiYgZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgLy8gQ29weSAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm4gMFxuICBpZiAodGFyZ2V0Lmxlbmd0aCA9PT0gMCB8fCB0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBGYXRhbCBlcnJvciBjb25kaXRpb25zXG4gIGlmICh0YXJnZXRTdGFydCA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigndGFyZ2V0U3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIH1cbiAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+PSB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZVN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICBpZiAoZW5kIDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZUVuZCBvdXQgb2YgYm91bmRzJylcblxuICAvLyBBcmUgd2Ugb29iP1xuICBpZiAoZW5kID4gdGhpcy5sZW5ndGgpIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgPCBlbmQgLSBzdGFydCkge1xuICAgIGVuZCA9IHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCArIHN0YXJ0XG4gIH1cblxuICB2YXIgbGVuID0gZW5kIC0gc3RhcnRcbiAgdmFyIGlcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0ICYmIHN0YXJ0IDwgdGFyZ2V0U3RhcnQgJiYgdGFyZ2V0U3RhcnQgPCBlbmQpIHtcbiAgICAvLyBkZXNjZW5kaW5nIGNvcHkgZnJvbSBlbmRcbiAgICBmb3IgKGkgPSBsZW4gLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSBpZiAobGVuIDwgMTAwMCB8fCAhQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBhc2NlbmRpbmcgY29weSBmcm9tIHN0YXJ0XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICB0YXJnZXRbaSArIHRhcmdldFN0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBVaW50OEFycmF5LnByb3RvdHlwZS5zZXQuY2FsbChcbiAgICAgIHRhcmdldCxcbiAgICAgIHRoaXMuc3ViYXJyYXkoc3RhcnQsIHN0YXJ0ICsgbGVuKSxcbiAgICAgIHRhcmdldFN0YXJ0XG4gICAgKVxuICB9XG5cbiAgcmV0dXJuIGxlblxufVxuXG4vLyBVc2FnZTpcbi8vICAgIGJ1ZmZlci5maWxsKG51bWJlclssIG9mZnNldFssIGVuZF1dKVxuLy8gICAgYnVmZmVyLmZpbGwoYnVmZmVyWywgb2Zmc2V0WywgZW5kXV0pXG4vLyAgICBidWZmZXIuZmlsbChzdHJpbmdbLCBvZmZzZXRbLCBlbmRdXVssIGVuY29kaW5nXSlcbkJ1ZmZlci5wcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uIGZpbGwgKHZhbCwgc3RhcnQsIGVuZCwgZW5jb2RpbmcpIHtcbiAgLy8gSGFuZGxlIHN0cmluZyBjYXNlczpcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKHR5cGVvZiBzdGFydCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVuY29kaW5nID0gc3RhcnRcbiAgICAgIHN0YXJ0ID0gMFxuICAgICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBlbmQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IGVuZFxuICAgICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgICB9XG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDEpIHtcbiAgICAgIHZhciBjb2RlID0gdmFsLmNoYXJDb2RlQXQoMClcbiAgICAgIGlmIChjb2RlIDwgMjU2KSB7XG4gICAgICAgIHZhbCA9IGNvZGVcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVuY29kaW5nICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZW5jb2RpbmcgbXVzdCBiZSBhIHN0cmluZycpXG4gICAgfVxuICAgIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnICYmICFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICB2YWwgPSB2YWwgJiAyNTVcbiAgfVxuXG4gIC8vIEludmFsaWQgcmFuZ2VzIGFyZSBub3Qgc2V0IHRvIGEgZGVmYXVsdCwgc28gY2FuIHJhbmdlIGNoZWNrIGVhcmx5LlxuICBpZiAoc3RhcnQgPCAwIHx8IHRoaXMubGVuZ3RoIDwgc3RhcnQgfHwgdGhpcy5sZW5ndGggPCBlbmQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignT3V0IG9mIHJhbmdlIGluZGV4JylcbiAgfVxuXG4gIGlmIChlbmQgPD0gc3RhcnQpIHtcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgc3RhcnQgPSBzdGFydCA+Pj4gMFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IHRoaXMubGVuZ3RoIDogZW5kID4+PiAwXG5cbiAgaWYgKCF2YWwpIHZhbCA9IDBcblxuICB2YXIgaVxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgICB0aGlzW2ldID0gdmFsXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciBieXRlcyA9IEJ1ZmZlci5pc0J1ZmZlcih2YWwpXG4gICAgICA/IHZhbFxuICAgICAgOiB1dGY4VG9CeXRlcyhuZXcgQnVmZmVyKHZhbCwgZW5jb2RpbmcpLnRvU3RyaW5nKCkpXG4gICAgdmFyIGxlbiA9IGJ5dGVzLmxlbmd0aFxuICAgIGZvciAoaSA9IDA7IGkgPCBlbmQgLSBzdGFydDsgKytpKSB7XG4gICAgICB0aGlzW2kgKyBzdGFydF0gPSBieXRlc1tpICUgbGVuXVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzXG59XG5cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT1cblxudmFyIElOVkFMSURfQkFTRTY0X1JFID0gL1teK1xcLzAtOUEtWmEtei1fXS9nXG5cbmZ1bmN0aW9uIGJhc2U2NGNsZWFuIChzdHIpIHtcbiAgLy8gTm9kZSBzdHJpcHMgb3V0IGludmFsaWQgY2hhcmFjdGVycyBsaWtlIFxcbiBhbmQgXFx0IGZyb20gdGhlIHN0cmluZywgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHN0ciA9IHN0cmluZ3RyaW0oc3RyKS5yZXBsYWNlKElOVkFMSURfQkFTRTY0X1JFLCAnJylcbiAgLy8gTm9kZSBjb252ZXJ0cyBzdHJpbmdzIHdpdGggbGVuZ3RoIDwgMiB0byAnJ1xuICBpZiAoc3RyLmxlbmd0aCA8IDIpIHJldHVybiAnJ1xuICAvLyBOb2RlIGFsbG93cyBmb3Igbm9uLXBhZGRlZCBiYXNlNjQgc3RyaW5ncyAobWlzc2luZyB0cmFpbGluZyA9PT0pLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgd2hpbGUgKHN0ci5sZW5ndGggJSA0ICE9PSAwKSB7XG4gICAgc3RyID0gc3RyICsgJz0nXG4gIH1cbiAgcmV0dXJuIHN0clxufVxuXG5mdW5jdGlvbiBzdHJpbmd0cmltIChzdHIpIHtcbiAgaWYgKHN0ci50cmltKSByZXR1cm4gc3RyLnRyaW0oKVxuICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKVxufVxuXG5mdW5jdGlvbiB0b0hleCAobikge1xuICBpZiAobiA8IDE2KSByZXR1cm4gJzAnICsgbi50b1N0cmluZygxNilcbiAgcmV0dXJuIG4udG9TdHJpbmcoMTYpXG59XG5cbmZ1bmN0aW9uIHV0ZjhUb0J5dGVzIChzdHJpbmcsIHVuaXRzKSB7XG4gIHVuaXRzID0gdW5pdHMgfHwgSW5maW5pdHlcbiAgdmFyIGNvZGVQb2ludFxuICB2YXIgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aFxuICB2YXIgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcbiAgdmFyIGJ5dGVzID0gW11cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgY29kZVBvaW50ID0gc3RyaW5nLmNoYXJDb2RlQXQoaSlcblxuICAgIC8vIGlzIHN1cnJvZ2F0ZSBjb21wb25lbnRcbiAgICBpZiAoY29kZVBvaW50ID4gMHhEN0ZGICYmIGNvZGVQb2ludCA8IDB4RTAwMCkge1xuICAgICAgLy8gbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICghbGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgICAvLyBubyBsZWFkIHlldFxuICAgICAgICBpZiAoY29kZVBvaW50ID4gMHhEQkZGKSB7XG4gICAgICAgICAgLy8gdW5leHBlY3RlZCB0cmFpbFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH0gZWxzZSBpZiAoaSArIDEgPT09IGxlbmd0aCkge1xuICAgICAgICAgIC8vIHVucGFpcmVkIGxlYWRcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gdmFsaWQgbGVhZFxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG5cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gMiBsZWFkcyBpbiBhIHJvd1xuICAgICAgaWYgKGNvZGVQb2ludCA8IDB4REMwMCkge1xuICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyB2YWxpZCBzdXJyb2dhdGUgcGFpclxuICAgICAgY29kZVBvaW50ID0gKGxlYWRTdXJyb2dhdGUgLSAweEQ4MDAgPDwgMTAgfCBjb2RlUG9pbnQgLSAweERDMDApICsgMHgxMDAwMFxuICAgIH0gZWxzZSBpZiAobGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgLy8gdmFsaWQgYm1wIGNoYXIsIGJ1dCBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgfVxuXG4gICAgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcblxuICAgIC8vIGVuY29kZSB1dGY4XG4gICAgaWYgKGNvZGVQb2ludCA8IDB4ODApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMSkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChjb2RlUG9pbnQpXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDgwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2IHwgMHhDMCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyB8IDB4RTAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDQpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDEyIHwgMHhGMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjb2RlIHBvaW50JylcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnl0ZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlUb0J5dGVzIChzdHIpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7XG4gICAgLy8gTm9kZSdzIGNvZGUgc2VlbXMgdG8gYmUgZG9pbmcgdGhpcyBhbmQgbm90ICYgMHg3Ri4uXG4gICAgYnl0ZUFycmF5LnB1c2goc3RyLmNoYXJDb2RlQXQoaSkgJiAweEZGKVxuICB9XG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVRvQnl0ZXMgKHN0ciwgdW5pdHMpIHtcbiAgdmFyIGMsIGhpLCBsb1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcblxuICAgIGMgPSBzdHIuY2hhckNvZGVBdChpKVxuICAgIGhpID0gYyA+PiA4XG4gICAgbG8gPSBjICUgMjU2XG4gICAgYnl0ZUFycmF5LnB1c2gobG8pXG4gICAgYnl0ZUFycmF5LnB1c2goaGkpXG4gIH1cblxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFRvQnl0ZXMgKHN0cikge1xuICByZXR1cm4gYmFzZTY0LnRvQnl0ZUFycmF5KGJhc2U2NGNsZWFuKHN0cikpXG59XG5cbmZ1bmN0aW9uIGJsaXRCdWZmZXIgKHNyYywgZHN0LCBvZmZzZXQsIGxlbmd0aCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgaWYgKChpICsgb2Zmc2V0ID49IGRzdC5sZW5ndGgpIHx8IChpID49IHNyYy5sZW5ndGgpKSBicmVha1xuICAgIGRzdFtpICsgb2Zmc2V0XSA9IHNyY1tpXVxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIGlzbmFuICh2YWwpIHtcbiAgcmV0dXJuIHZhbCAhPT0gdmFsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlXG59XG5cbi8qIFdFQlBBQ0sgVkFSIElOSkVDVElPTiAqL30uY2FsbChleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKDApKSlcblxuLyoqKi8gfSksXG4vKiAyICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbi8qIFdFQlBBQ0sgVkFSIElOSkVDVElPTiAqLyhmdW5jdGlvbihnbG9iYWwsIEJ1ZmZlcikgeyhmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7XG5cdCB0cnVlID8gZmFjdG9yeShleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKDYpLCBfX3dlYnBhY2tfcmVxdWlyZV9fKDEpKSA6XG5cdHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShbJ2V4cG9ydHMnLCAnbG9uZycsICdidWZmZXInXSwgZmFjdG9yeSkgOlxuXHQoZmFjdG9yeSgoZ2xvYmFsLkJTT04gPSB7fSksZ2xvYmFsLmxvbmcsZ2xvYmFsLkJ1ZmZlcikpO1xufSh0aGlzLCAoZnVuY3Rpb24gKGV4cG9ydHMsbG9uZyxidWZmZXIpIHsgJ3VzZSBzdHJpY3QnO1xuXG5cdGxvbmcgPSBsb25nICYmIGxvbmcuaGFzT3duUHJvcGVydHkoJ2RlZmF1bHQnKSA/IGxvbmdbJ2RlZmF1bHQnXSA6IGxvbmc7XG5cdGJ1ZmZlciA9IGJ1ZmZlciAmJiBidWZmZXIuaGFzT3duUHJvcGVydHkoJ2RlZmF1bHQnKSA/IGJ1ZmZlclsnZGVmYXVsdCddIDogYnVmZmVyO1xuXG5cdHZhciBjb21tb25qc0dsb2JhbCA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogdHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcgPyBzZWxmIDoge307XG5cblx0ZnVuY3Rpb24gY3JlYXRlQ29tbW9uanNNb2R1bGUoZm4sIG1vZHVsZSkge1xuXHRcdHJldHVybiBtb2R1bGUgPSB7IGV4cG9ydHM6IHt9IH0sIGZuKG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMpLCBtb2R1bGUuZXhwb3J0cztcblx0fVxuXG5cdGZ1bmN0aW9uIGdldENqc0V4cG9ydEZyb21OYW1lc3BhY2UgKG4pIHtcblx0XHRyZXR1cm4gbiAmJiBuLmRlZmF1bHQgfHwgbjtcblx0fVxuXG5cdHZhciBtYXAgPSBjcmVhdGVDb21tb25qc01vZHVsZShmdW5jdGlvbiAobW9kdWxlKSB7XG5cblx0ICBpZiAodHlwZW9mIGNvbW1vbmpzR2xvYmFsLk1hcCAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0ICAgIG1vZHVsZS5leHBvcnRzID0gY29tbW9uanNHbG9iYWwuTWFwO1xuXHQgICAgbW9kdWxlLmV4cG9ydHMuTWFwID0gY29tbW9uanNHbG9iYWwuTWFwO1xuXHQgIH0gZWxzZSB7XG5cdCAgICAvLyBXZSB3aWxsIHJldHVybiBhIHBvbHlmaWxsXG5cdCAgICB2YXIgTWFwID0gZnVuY3Rpb24gTWFwKGFycmF5KSB7XG5cdCAgICAgIHRoaXMuX2tleXMgPSBbXTtcblx0ICAgICAgdGhpcy5fdmFsdWVzID0ge307XG5cblx0ICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgIGlmIChhcnJheVtpXSA9PSBudWxsKSBjb250aW51ZTsgLy8gc2tpcCBudWxsIGFuZCB1bmRlZmluZWRcblxuXHQgICAgICAgIHZhciBlbnRyeSA9IGFycmF5W2ldO1xuXHQgICAgICAgIHZhciBrZXkgPSBlbnRyeVswXTtcblx0ICAgICAgICB2YXIgdmFsdWUgPSBlbnRyeVsxXTsgLy8gQWRkIHRoZSBrZXkgdG8gdGhlIGxpc3Qgb2Yga2V5cyBpbiBvcmRlclxuXG5cdCAgICAgICAgdGhpcy5fa2V5cy5wdXNoKGtleSk7IC8vIEFkZCB0aGUga2V5IGFuZCB2YWx1ZSB0byB0aGUgdmFsdWVzIGRpY3Rpb25hcnkgd2l0aCBhIHBvaW50XG5cdCAgICAgICAgLy8gdG8gdGhlIGxvY2F0aW9uIGluIHRoZSBvcmRlcmVkIGtleXMgbGlzdFxuXG5cblx0ICAgICAgICB0aGlzLl92YWx1ZXNba2V5XSA9IHtcblx0ICAgICAgICAgIHY6IHZhbHVlLFxuXHQgICAgICAgICAgaTogdGhpcy5fa2V5cy5sZW5ndGggLSAxXG5cdCAgICAgICAgfTtcblx0ICAgICAgfVxuXHQgICAgfTtcblxuXHQgICAgTWFwLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgdGhpcy5fa2V5cyA9IFtdO1xuXHQgICAgICB0aGlzLl92YWx1ZXMgPSB7fTtcblx0ICAgIH07XG5cblx0ICAgIE1hcC5wcm90b3R5cGUuZGVsZXRlID0gZnVuY3Rpb24gKGtleSkge1xuXHQgICAgICB2YXIgdmFsdWUgPSB0aGlzLl92YWx1ZXNba2V5XTtcblx0ICAgICAgaWYgKHZhbHVlID09IG51bGwpIHJldHVybiBmYWxzZTsgLy8gRGVsZXRlIGVudHJ5XG5cblx0ICAgICAgZGVsZXRlIHRoaXMuX3ZhbHVlc1trZXldOyAvLyBSZW1vdmUgdGhlIGtleSBmcm9tIHRoZSBvcmRlcmVkIGtleXMgbGlzdFxuXG5cdCAgICAgIHRoaXMuX2tleXMuc3BsaWNlKHZhbHVlLmksIDEpO1xuXG5cdCAgICAgIHJldHVybiB0cnVlO1xuXHQgICAgfTtcblxuXHQgICAgTWFwLnByb3RvdHlwZS5lbnRyaWVzID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICB2YXIgc2VsZiA9IHRoaXM7XG5cdCAgICAgIHZhciBpbmRleCA9IDA7XG5cdCAgICAgIHJldHVybiB7XG5cdCAgICAgICAgbmV4dDogZnVuY3Rpb24gbmV4dCgpIHtcblx0ICAgICAgICAgIHZhciBrZXkgPSBzZWxmLl9rZXlzW2luZGV4KytdO1xuXHQgICAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgdmFsdWU6IGtleSAhPT0gdW5kZWZpbmVkID8gW2tleSwgc2VsZi5fdmFsdWVzW2tleV0udl0gOiB1bmRlZmluZWQsXG5cdCAgICAgICAgICAgIGRvbmU6IGtleSAhPT0gdW5kZWZpbmVkID8gZmFsc2UgOiB0cnVlXG5cdCAgICAgICAgICB9O1xuXHQgICAgICAgIH1cblx0ICAgICAgfTtcblx0ICAgIH07XG5cblx0ICAgIE1hcC5wcm90b3R5cGUuZm9yRWFjaCA9IGZ1bmN0aW9uIChjYWxsYmFjaywgc2VsZikge1xuXHQgICAgICBzZWxmID0gc2VsZiB8fCB0aGlzO1xuXG5cdCAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5fa2V5cy5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgIHZhciBrZXkgPSB0aGlzLl9rZXlzW2ldOyAvLyBDYWxsIHRoZSBmb3JFYWNoIGNhbGxiYWNrXG5cblx0ICAgICAgICBjYWxsYmFjay5jYWxsKHNlbGYsIHRoaXMuX3ZhbHVlc1trZXldLnYsIGtleSwgc2VsZik7XG5cdCAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIE1hcC5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGtleSkge1xuXHQgICAgICByZXR1cm4gdGhpcy5fdmFsdWVzW2tleV0gPyB0aGlzLl92YWx1ZXNba2V5XS52IDogdW5kZWZpbmVkO1xuXHQgICAgfTtcblxuXHQgICAgTWFwLnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbiAoa2V5KSB7XG5cdCAgICAgIHJldHVybiB0aGlzLl92YWx1ZXNba2V5XSAhPSBudWxsO1xuXHQgICAgfTtcblxuXHQgICAgTWFwLnByb3RvdHlwZS5rZXlzID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICB2YXIgc2VsZiA9IHRoaXM7XG5cdCAgICAgIHZhciBpbmRleCA9IDA7XG5cdCAgICAgIHJldHVybiB7XG5cdCAgICAgICAgbmV4dDogZnVuY3Rpb24gbmV4dCgpIHtcblx0ICAgICAgICAgIHZhciBrZXkgPSBzZWxmLl9rZXlzW2luZGV4KytdO1xuXHQgICAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgdmFsdWU6IGtleSAhPT0gdW5kZWZpbmVkID8ga2V5IDogdW5kZWZpbmVkLFxuXHQgICAgICAgICAgICBkb25lOiBrZXkgIT09IHVuZGVmaW5lZCA/IGZhbHNlIDogdHJ1ZVxuXHQgICAgICAgICAgfTtcblx0ICAgICAgICB9XG5cdCAgICAgIH07XG5cdCAgICB9O1xuXG5cdCAgICBNYXAucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG5cdCAgICAgIGlmICh0aGlzLl92YWx1ZXNba2V5XSkge1xuXHQgICAgICAgIHRoaXMuX3ZhbHVlc1trZXldLnYgPSB2YWx1ZTtcblx0ICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgICAgfSAvLyBBZGQgdGhlIGtleSB0byB0aGUgbGlzdCBvZiBrZXlzIGluIG9yZGVyXG5cblxuXHQgICAgICB0aGlzLl9rZXlzLnB1c2goa2V5KTsgLy8gQWRkIHRoZSBrZXkgYW5kIHZhbHVlIHRvIHRoZSB2YWx1ZXMgZGljdGlvbmFyeSB3aXRoIGEgcG9pbnRcblx0ICAgICAgLy8gdG8gdGhlIGxvY2F0aW9uIGluIHRoZSBvcmRlcmVkIGtleXMgbGlzdFxuXG5cblx0ICAgICAgdGhpcy5fdmFsdWVzW2tleV0gPSB7XG5cdCAgICAgICAgdjogdmFsdWUsXG5cdCAgICAgICAgaTogdGhpcy5fa2V5cy5sZW5ndGggLSAxXG5cdCAgICAgIH07XG5cdCAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgfTtcblxuXHQgICAgTWFwLnByb3RvdHlwZS52YWx1ZXMgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgIHZhciBzZWxmID0gdGhpcztcblx0ICAgICAgdmFyIGluZGV4ID0gMDtcblx0ICAgICAgcmV0dXJuIHtcblx0ICAgICAgICBuZXh0OiBmdW5jdGlvbiBuZXh0KCkge1xuXHQgICAgICAgICAgdmFyIGtleSA9IHNlbGYuX2tleXNbaW5kZXgrK107XG5cdCAgICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICB2YWx1ZToga2V5ICE9PSB1bmRlZmluZWQgPyBzZWxmLl92YWx1ZXNba2V5XS52IDogdW5kZWZpbmVkLFxuXHQgICAgICAgICAgICBkb25lOiBrZXkgIT09IHVuZGVmaW5lZCA/IGZhbHNlIDogdHJ1ZVxuXHQgICAgICAgICAgfTtcblx0ICAgICAgICB9XG5cdCAgICAgIH07XG5cdCAgICB9OyAvLyBMYXN0IGlzbWFzdGVyXG5cblxuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KE1hcC5wcm90b3R5cGUsICdzaXplJywge1xuXHQgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuXHQgICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fa2V5cy5sZW5ndGg7XG5cdCAgICAgIH1cblx0ICAgIH0pO1xuXHQgICAgbW9kdWxlLmV4cG9ydHMgPSBNYXA7XG5cdCAgfVxuXHR9KTtcblx0dmFyIG1hcF8xID0gbWFwLk1hcDtcblxuXHQvKipcblx0ICogQGlnbm9yZVxuXHQgKi9cblxuXG5cdGxvbmcucHJvdG90eXBlLnRvRXh0ZW5kZWRKU09OID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcblx0ICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLnJlbGF4ZWQpIHJldHVybiB0aGlzLnRvTnVtYmVyKCk7XG5cdCAgcmV0dXJuIHtcblx0ICAgICRudW1iZXJMb25nOiB0aGlzLnRvU3RyaW5nKClcblx0ICB9O1xuXHR9O1xuXHQvKipcblx0ICogQGlnbm9yZVxuXHQgKi9cblxuXG5cdGxvbmcuZnJvbUV4dGVuZGVkSlNPTiA9IGZ1bmN0aW9uIChkb2MsIG9wdGlvbnMpIHtcblx0ICB2YXIgcmVzdWx0ID0gbG9uZy5mcm9tU3RyaW5nKGRvYy4kbnVtYmVyTG9uZyk7XG5cdCAgcmV0dXJuIG9wdGlvbnMgJiYgb3B0aW9ucy5yZWxheGVkID8gcmVzdWx0LnRvTnVtYmVyKCkgOiByZXN1bHQ7XG5cdH07XG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGxvbmcucHJvdG90eXBlLCAnX2Jzb250eXBlJywge1xuXHQgIHZhbHVlOiAnTG9uZydcblx0fSk7XG5cdHZhciBsb25nXzEgPSBsb25nO1xuXG5cdC8qKlxuXHQgKiBBIGNsYXNzIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBCU09OIERvdWJsZSB0eXBlLlxuXHQgKi9cblxuXHRmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG5cdGZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH1cblxuXHRmdW5jdGlvbiBfY3JlYXRlQ2xhc3MoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfVxuXG5cdHZhciBEb3VibGUgPVxuXHQvKiNfX1BVUkVfXyovXG5cdGZ1bmN0aW9uICgpIHtcblx0ICAvKipcblx0ICAgKiBDcmVhdGUgYSBEb3VibGUgdHlwZVxuXHQgICAqXG5cdCAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIHRoZSBudW1iZXIgd2Ugd2FudCB0byByZXByZXNlbnQgYXMgYSBkb3VibGUuXG5cdCAgICogQHJldHVybiB7RG91YmxlfVxuXHQgICAqL1xuXHQgIGZ1bmN0aW9uIERvdWJsZSh2YWx1ZSkge1xuXHQgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIERvdWJsZSk7XG5cblx0ICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcblx0ICB9XG5cdCAgLyoqXG5cdCAgICogQWNjZXNzIHRoZSBudW1iZXIgdmFsdWUuXG5cdCAgICpcblx0ICAgKiBAbWV0aG9kXG5cdCAgICogQHJldHVybiB7bnVtYmVyfSByZXR1cm5zIHRoZSB3cmFwcGVkIGRvdWJsZSBudW1iZXIuXG5cdCAgICovXG5cblxuXHQgIF9jcmVhdGVDbGFzcyhEb3VibGUsIFt7XG5cdCAgICBrZXk6IFwidmFsdWVPZlwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHZhbHVlT2YoKSB7XG5cdCAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBAaWdub3JlXG5cdCAgICAgKi9cblxuXHQgIH0sIHtcblx0ICAgIGtleTogXCJ0b0pTT05cIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB0b0pTT04oKSB7XG5cdCAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBAaWdub3JlXG5cdCAgICAgKi9cblxuXHQgIH0sIHtcblx0ICAgIGtleTogXCJ0b0V4dGVuZGVkSlNPTlwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHRvRXh0ZW5kZWRKU09OKG9wdGlvbnMpIHtcblx0ICAgICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5yZWxheGVkICYmIGlzRmluaXRlKHRoaXMudmFsdWUpKSByZXR1cm4gdGhpcy52YWx1ZTtcblx0ICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAkbnVtYmVyRG91YmxlOiB0aGlzLnZhbHVlLnRvU3RyaW5nKClcblx0ICAgICAgfTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9XSwgW3tcblx0ICAgIGtleTogXCJmcm9tRXh0ZW5kZWRKU09OXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gZnJvbUV4dGVuZGVkSlNPTihkb2MsIG9wdGlvbnMpIHtcblx0ICAgICAgcmV0dXJuIG9wdGlvbnMgJiYgb3B0aW9ucy5yZWxheGVkID8gcGFyc2VGbG9hdChkb2MuJG51bWJlckRvdWJsZSkgOiBuZXcgRG91YmxlKHBhcnNlRmxvYXQoZG9jLiRudW1iZXJEb3VibGUpKTtcblx0ICAgIH1cblx0ICB9XSk7XG5cblx0ICByZXR1cm4gRG91YmxlO1xuXHR9KCk7XG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KERvdWJsZS5wcm90b3R5cGUsICdfYnNvbnR5cGUnLCB7XG5cdCAgdmFsdWU6ICdEb3VibGUnXG5cdH0pO1xuXHR2YXIgZG91YmxlXzEgPSBEb3VibGU7XG5cblx0ZnVuY3Rpb24gX3R5cGVvZihvYmopIHsgaWYgKHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSBcInN5bWJvbFwiKSB7IF90eXBlb2YgPSBmdW5jdGlvbiBfdHlwZW9mKG9iaikgeyByZXR1cm4gdHlwZW9mIG9iajsgfTsgfSBlbHNlIHsgX3R5cGVvZiA9IGZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqOyB9OyB9IHJldHVybiBfdHlwZW9mKG9iaik7IH1cblxuXHRmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2skMShpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cblx0ZnVuY3Rpb24gX2RlZmluZVByb3BlcnRpZXMkMSh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9XG5cblx0ZnVuY3Rpb24gX2NyZWF0ZUNsYXNzJDEoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyQxKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgX2RlZmluZVByb3BlcnRpZXMkMShDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH1cblxuXHRmdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7IGlmIChjYWxsICYmIChfdHlwZW9mKGNhbGwpID09PSBcIm9iamVjdFwiIHx8IHR5cGVvZiBjYWxsID09PSBcImZ1bmN0aW9uXCIpKSB7IHJldHVybiBjYWxsOyB9IHJldHVybiBfYXNzZXJ0VGhpc0luaXRpYWxpemVkKHNlbGYpOyB9XG5cblx0ZnVuY3Rpb24gX2Fzc2VydFRoaXNJbml0aWFsaXplZChzZWxmKSB7IGlmIChzZWxmID09PSB2b2lkIDApIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKFwidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkXCIpOyB9IHJldHVybiBzZWxmOyB9XG5cblx0ZnVuY3Rpb24gX2dldFByb3RvdHlwZU9mKG8pIHsgX2dldFByb3RvdHlwZU9mID0gT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LmdldFByb3RvdHlwZU9mIDogZnVuY3Rpb24gX2dldFByb3RvdHlwZU9mKG8pIHsgcmV0dXJuIG8uX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihvKTsgfTsgcmV0dXJuIF9nZXRQcm90b3R5cGVPZihvKTsgfVxuXG5cdGZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09IFwiZnVuY3Rpb25cIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvblwiKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBfc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpOyB9XG5cblx0ZnVuY3Rpb24gX3NldFByb3RvdHlwZU9mKG8sIHApIHsgX3NldFByb3RvdHlwZU9mID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IGZ1bmN0aW9uIF9zZXRQcm90b3R5cGVPZihvLCBwKSB7IG8uX19wcm90b19fID0gcDsgcmV0dXJuIG87IH07IHJldHVybiBfc2V0UHJvdG90eXBlT2YobywgcCk7IH1cblx0LyoqXG5cdCAqIEBjbGFzc1xuXHQgKiBAcGFyYW0ge251bWJlcn0gbG93ICB0aGUgbG93IChzaWduZWQpIDMyIGJpdHMgb2YgdGhlIFRpbWVzdGFtcC5cblx0ICogQHBhcmFtIHtudW1iZXJ9IGhpZ2ggdGhlIGhpZ2ggKHNpZ25lZCkgMzIgYml0cyBvZiB0aGUgVGltZXN0YW1wLlxuXHQgKiBAcmV0dXJuIHtUaW1lc3RhbXB9XG5cdCAqL1xuXG5cblx0dmFyIFRpbWVzdGFtcCA9XG5cdC8qI19fUFVSRV9fKi9cblx0ZnVuY3Rpb24gKF9Mb25nKSB7XG5cdCAgX2luaGVyaXRzKFRpbWVzdGFtcCwgX0xvbmcpO1xuXG5cdCAgZnVuY3Rpb24gVGltZXN0YW1wKGxvdywgaGlnaCkge1xuXHQgICAgdmFyIF90aGlzO1xuXG5cdCAgICBfY2xhc3NDYWxsQ2hlY2skMSh0aGlzLCBUaW1lc3RhbXApO1xuXG5cdCAgICBpZiAobG9uZ18xLmlzTG9uZyhsb3cpKSB7XG5cdCAgICAgIF90aGlzID0gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgX2dldFByb3RvdHlwZU9mKFRpbWVzdGFtcCkuY2FsbCh0aGlzLCBsb3cubG93LCBsb3cuaGlnaCkpO1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgX3RoaXMgPSBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCBfZ2V0UHJvdG90eXBlT2YoVGltZXN0YW1wKS5jYWxsKHRoaXMsIGxvdywgaGlnaCkpO1xuXHQgICAgfVxuXG5cdCAgICByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oX3RoaXMpO1xuXHQgIH1cblx0ICAvKipcblx0ICAgKiBSZXR1cm4gdGhlIEpTT04gdmFsdWUuXG5cdCAgICpcblx0ICAgKiBAbWV0aG9kXG5cdCAgICogQHJldHVybiB7U3RyaW5nfSB0aGUgSlNPTiByZXByZXNlbnRhdGlvbi5cblx0ICAgKi9cblxuXG5cdCAgX2NyZWF0ZUNsYXNzJDEoVGltZXN0YW1wLCBbe1xuXHQgICAga2V5OiBcInRvSlNPTlwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHRvSlNPTigpIHtcblx0ICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAkdGltZXN0YW1wOiB0aGlzLnRvU3RyaW5nKClcblx0ICAgICAgfTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0dXJucyBhIFRpbWVzdGFtcCByZXByZXNlbnRlZCBieSB0aGUgZ2l2ZW4gKDMyLWJpdCkgaW50ZWdlciB2YWx1ZS5cblx0ICAgICAqXG5cdCAgICAgKiBAbWV0aG9kXG5cdCAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgdGhlIDMyLWJpdCBpbnRlZ2VyIGluIHF1ZXN0aW9uLlxuXHQgICAgICogQHJldHVybiB7VGltZXN0YW1wfSB0aGUgdGltZXN0YW1wLlxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwidG9FeHRlbmRlZEpTT05cIixcblxuXHQgICAgLyoqXG5cdCAgICAgKiBAaWdub3JlXG5cdCAgICAgKi9cblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB0b0V4dGVuZGVkSlNPTigpIHtcblx0ICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAkdGltZXN0YW1wOiB7XG5cdCAgICAgICAgICB0OiB0aGlzLmhpZ2gsXG5cdCAgICAgICAgICBpOiB0aGlzLmxvd1xuXHQgICAgICAgIH1cblx0ICAgICAgfTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9XSwgW3tcblx0ICAgIGtleTogXCJmcm9tSW50XCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gZnJvbUludCh2YWx1ZSkge1xuXHQgICAgICByZXR1cm4gbmV3IFRpbWVzdGFtcChsb25nXzEuZnJvbUludCh2YWx1ZSkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXR1cm5zIGEgVGltZXN0YW1wIHJlcHJlc2VudGluZyB0aGUgZ2l2ZW4gbnVtYmVyIHZhbHVlLCBwcm92aWRlZCB0aGF0IGl0IGlzIGEgZmluaXRlIG51bWJlci4gT3RoZXJ3aXNlLCB6ZXJvIGlzIHJldHVybmVkLlxuXHQgICAgICpcblx0ICAgICAqIEBtZXRob2Rcblx0ICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSB0aGUgbnVtYmVyIGluIHF1ZXN0aW9uLlxuXHQgICAgICogQHJldHVybiB7VGltZXN0YW1wfSB0aGUgdGltZXN0YW1wLlxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwiZnJvbU51bWJlclwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIGZyb21OdW1iZXIodmFsdWUpIHtcblx0ICAgICAgcmV0dXJuIG5ldyBUaW1lc3RhbXAobG9uZ18xLmZyb21OdW1iZXIodmFsdWUpKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0dXJucyBhIFRpbWVzdGFtcCBmb3IgdGhlIGdpdmVuIGhpZ2ggYW5kIGxvdyBiaXRzLiBFYWNoIGlzIGFzc3VtZWQgdG8gdXNlIDMyIGJpdHMuXG5cdCAgICAgKlxuXHQgICAgICogQG1ldGhvZFxuXHQgICAgICogQHBhcmFtIHtudW1iZXJ9IGxvd0JpdHMgdGhlIGxvdyAzMi1iaXRzLlxuXHQgICAgICogQHBhcmFtIHtudW1iZXJ9IGhpZ2hCaXRzIHRoZSBoaWdoIDMyLWJpdHMuXG5cdCAgICAgKiBAcmV0dXJuIHtUaW1lc3RhbXB9IHRoZSB0aW1lc3RhbXAuXG5cdCAgICAgKi9cblxuXHQgIH0sIHtcblx0ICAgIGtleTogXCJmcm9tQml0c1wiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIGZyb21CaXRzKGxvd0JpdHMsIGhpZ2hCaXRzKSB7XG5cdCAgICAgIHJldHVybiBuZXcgVGltZXN0YW1wKGxvd0JpdHMsIGhpZ2hCaXRzKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0dXJucyBhIFRpbWVzdGFtcCBmcm9tIHRoZSBnaXZlbiBzdHJpbmcsIG9wdGlvbmFsbHkgdXNpbmcgdGhlIGdpdmVuIHJhZGl4LlxuXHQgICAgICpcblx0ICAgICAqIEBtZXRob2Rcblx0ICAgICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgdGhlIHRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIFRpbWVzdGFtcC5cblx0ICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0X3JhZGl4XSB0aGUgcmFkaXggaW4gd2hpY2ggdGhlIHRleHQgaXMgd3JpdHRlbi5cblx0ICAgICAqIEByZXR1cm4ge1RpbWVzdGFtcH0gdGhlIHRpbWVzdGFtcC5cblx0ICAgICAqL1xuXG5cdCAgfSwge1xuXHQgICAga2V5OiBcImZyb21TdHJpbmdcIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tU3RyaW5nKHN0ciwgb3B0X3JhZGl4KSB7XG5cdCAgICAgIHJldHVybiBuZXcgVGltZXN0YW1wKGxvbmdfMS5mcm9tU3RyaW5nKHN0ciwgb3B0X3JhZGl4KSk7XG5cdCAgICB9XG5cdCAgfSwge1xuXHQgICAga2V5OiBcImZyb21FeHRlbmRlZEpTT05cIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tRXh0ZW5kZWRKU09OKGRvYykge1xuXHQgICAgICByZXR1cm4gbmV3IFRpbWVzdGFtcChkb2MuJHRpbWVzdGFtcC5pLCBkb2MuJHRpbWVzdGFtcC50KTtcblx0ICAgIH1cblx0ICB9XSk7XG5cblx0ICByZXR1cm4gVGltZXN0YW1wO1xuXHR9KGxvbmdfMSk7XG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KFRpbWVzdGFtcC5wcm90b3R5cGUsICdfYnNvbnR5cGUnLCB7XG5cdCAgdmFsdWU6ICdUaW1lc3RhbXAnXG5cdH0pO1xuXHR2YXIgdGltZXN0YW1wID0gVGltZXN0YW1wO1xuXG5cdHZhciBlbXB0eSA9IHt9O1xuXG5cdHZhciBlbXB0eSQxID0gLyojX19QVVJFX18qL09iamVjdC5mcmVlemUoe1xuXHRcdGRlZmF1bHQ6IGVtcHR5XG5cdH0pO1xuXG5cdHZhciByZXF1aXJlJCQwID0gZ2V0Q2pzRXhwb3J0RnJvbU5hbWVzcGFjZShlbXB0eSQxKTtcblxuXHQvKiBnbG9iYWwgd2luZG93ICovXG5cblx0LyoqXG5cdCAqIE5vcm1hbGl6ZXMgb3VyIGV4cGVjdGVkIHN0cmluZ2lmaWVkIGZvcm0gb2YgYSBmdW5jdGlvbiBhY3Jvc3MgdmVyc2lvbnMgb2Ygbm9kZVxuXHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gc3RyaW5naWZ5XG5cdCAqL1xuXG5cblx0ZnVuY3Rpb24gbm9ybWFsaXplZEZ1bmN0aW9uU3RyaW5nKGZuKSB7XG5cdCAgcmV0dXJuIGZuLnRvU3RyaW5nKCkucmVwbGFjZSgnZnVuY3Rpb24oJywgJ2Z1bmN0aW9uICgnKTtcblx0fVxuXG5cdGZ1bmN0aW9uIGluc2VjdXJlUmFuZG9tQnl0ZXMoc2l6ZSkge1xuXHQgIHZhciByZXN1bHQgPSBuZXcgVWludDhBcnJheShzaXplKTtcblxuXHQgIGZvciAodmFyIGkgPSAwOyBpIDwgc2l6ZTsgKytpKSB7XG5cdCAgICByZXN1bHRbaV0gPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAyNTYpO1xuXHQgIH1cblxuXHQgIHJldHVybiByZXN1bHQ7XG5cdH1cblxuXHR2YXIgcmFuZG9tQnl0ZXMgPSBpbnNlY3VyZVJhbmRvbUJ5dGVzO1xuXG5cdGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuY3J5cHRvICYmIHdpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKSB7XG5cdCAgcmFuZG9tQnl0ZXMgPSBmdW5jdGlvbiByYW5kb21CeXRlcyhzaXplKSB7XG5cdCAgICByZXR1cm4gd2luZG93LmNyeXB0by5nZXRSYW5kb21WYWx1ZXMobmV3IFVpbnQ4QXJyYXkoc2l6ZSkpO1xuXHQgIH07XG5cdH0gZWxzZSB7XG5cdCAgdHJ5IHtcblx0ICAgIHJhbmRvbUJ5dGVzID0gcmVxdWlyZSQkMC5yYW5kb21CeXRlcztcblx0ICB9IGNhdGNoIChlKSB7fSAvLyBrZWVwIHRoZSBmYWxsYmFja1xuXHQgIC8vIE5PVEU6IGluIHRyYW5zcGlsZWQgY2FzZXMgdGhlIGFib3ZlIHJlcXVpcmUgbWlnaHQgcmV0dXJuIG51bGwvdW5kZWZpbmVkXG5cblxuXHQgIGlmIChyYW5kb21CeXRlcyA9PSBudWxsKSB7XG5cdCAgICByYW5kb21CeXRlcyA9IGluc2VjdXJlUmFuZG9tQnl0ZXM7XG5cdCAgfVxuXHR9XG5cblx0dmFyIHV0aWxzID0ge1xuXHQgIG5vcm1hbGl6ZWRGdW5jdGlvblN0cmluZzogbm9ybWFsaXplZEZ1bmN0aW9uU3RyaW5nLFxuXHQgIHJhbmRvbUJ5dGVzOiByYW5kb21CeXRlc1xuXHR9O1xuXG5cdC8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxuXHQvLyBiYXNlZCBvZmYgaHR0cHM6Ly9naXRodWIuY29tL2RlZnVuY3R6b21iaWUvbm9kZS1wcm9jZXNzL2Jsb2IvbWFzdGVyL2Jyb3dzZXIuanNcblx0ZnVuY3Rpb24gZGVmYXVsdFNldFRpbW91dCgpIHtcblx0ICB0aHJvdyBuZXcgRXJyb3IoJ3NldFRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcblx0fVxuXG5cdGZ1bmN0aW9uIGRlZmF1bHRDbGVhclRpbWVvdXQoKSB7XG5cdCAgdGhyb3cgbmV3IEVycm9yKCdjbGVhclRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcblx0fVxuXG5cdHZhciBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcblx0dmFyIGNhY2hlZENsZWFyVGltZW91dCA9IGRlZmF1bHRDbGVhclRpbWVvdXQ7XG5cblx0aWYgKHR5cGVvZiBnbG9iYWwuc2V0VGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuXHQgIGNhY2hlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuXHR9XG5cblx0aWYgKHR5cGVvZiBnbG9iYWwuY2xlYXJUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG5cdCAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuXHR9XG5cblx0ZnVuY3Rpb24gcnVuVGltZW91dChmdW4pIHtcblx0ICBpZiAoY2FjaGVkU2V0VGltZW91dCA9PT0gc2V0VGltZW91dCkge1xuXHQgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG5cdCAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuXHQgIH0gLy8gaWYgc2V0VGltZW91dCB3YXNuJ3QgYXZhaWxhYmxlIGJ1dCB3YXMgbGF0dGVyIGRlZmluZWRcblxuXG5cdCAgaWYgKChjYWNoZWRTZXRUaW1lb3V0ID09PSBkZWZhdWx0U2V0VGltb3V0IHx8ICFjYWNoZWRTZXRUaW1lb3V0KSAmJiBzZXRUaW1lb3V0KSB7XG5cdCAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcblx0ICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1biwgMCk7XG5cdCAgfVxuXG5cdCAgdHJ5IHtcblx0ICAgIC8vIHdoZW4gd2hlbiBzb21lYm9keSBoYXMgc2NyZXdlZCB3aXRoIHNldFRpbWVvdXQgYnV0IG5vIEkuRS4gbWFkZG5lc3Ncblx0ICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0KGZ1biwgMCk7XG5cdCAgfSBjYXRjaCAoZSkge1xuXHQgICAgdHJ5IHtcblx0ICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0IHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG5cdCAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwobnVsbCwgZnVuLCAwKTtcblx0ICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgLy8gc2FtZSBhcyBhYm92ZSBidXQgd2hlbiBpdCdzIGEgdmVyc2lvbiBvZiBJLkUuIHRoYXQgbXVzdCBoYXZlIHRoZSBnbG9iYWwgb2JqZWN0IGZvciAndGhpcycsIGhvcGZ1bGx5IG91ciBjb250ZXh0IGNvcnJlY3Qgb3RoZXJ3aXNlIGl0IHdpbGwgdGhyb3cgYSBnbG9iYWwgZXJyb3Jcblx0ICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbCh0aGlzLCBmdW4sIDApO1xuXHQgICAgfVxuXHQgIH1cblx0fVxuXG5cdGZ1bmN0aW9uIHJ1bkNsZWFyVGltZW91dChtYXJrZXIpIHtcblx0ICBpZiAoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBjbGVhclRpbWVvdXQpIHtcblx0ICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuXHQgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuXHQgIH0gLy8gaWYgY2xlYXJUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuXG5cblx0ICBpZiAoKGNhY2hlZENsZWFyVGltZW91dCA9PT0gZGVmYXVsdENsZWFyVGltZW91dCB8fCAhY2FjaGVkQ2xlYXJUaW1lb3V0KSAmJiBjbGVhclRpbWVvdXQpIHtcblx0ICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcblx0ICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcblx0ICB9XG5cblx0ICB0cnkge1xuXHQgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuXHQgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dChtYXJrZXIpO1xuXHQgIH0gY2F0Y2ggKGUpIHtcblx0ICAgIHRyeSB7XG5cdCAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCAgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcblx0ICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKG51bGwsIG1hcmtlcik7XG5cdCAgICB9IGNhdGNoIChlKSB7XG5cdCAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yLlxuXHQgICAgICAvLyBTb21lIHZlcnNpb25zIG9mIEkuRS4gaGF2ZSBkaWZmZXJlbnQgcnVsZXMgZm9yIGNsZWFyVGltZW91dCB2cyBzZXRUaW1lb3V0XG5cdCAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbCh0aGlzLCBtYXJrZXIpO1xuXHQgICAgfVxuXHQgIH1cblx0fVxuXG5cdHZhciBxdWV1ZSA9IFtdO1xuXHR2YXIgZHJhaW5pbmcgPSBmYWxzZTtcblx0dmFyIGN1cnJlbnRRdWV1ZTtcblx0dmFyIHF1ZXVlSW5kZXggPSAtMTtcblxuXHRmdW5jdGlvbiBjbGVhblVwTmV4dFRpY2soKSB7XG5cdCAgaWYgKCFkcmFpbmluZyB8fCAhY3VycmVudFF1ZXVlKSB7XG5cdCAgICByZXR1cm47XG5cdCAgfVxuXG5cdCAgZHJhaW5pbmcgPSBmYWxzZTtcblxuXHQgIGlmIChjdXJyZW50UXVldWUubGVuZ3RoKSB7XG5cdCAgICBxdWV1ZSA9IGN1cnJlbnRRdWV1ZS5jb25jYXQocXVldWUpO1xuXHQgIH0gZWxzZSB7XG5cdCAgICBxdWV1ZUluZGV4ID0gLTE7XG5cdCAgfVxuXG5cdCAgaWYgKHF1ZXVlLmxlbmd0aCkge1xuXHQgICAgZHJhaW5RdWV1ZSgpO1xuXHQgIH1cblx0fVxuXG5cdGZ1bmN0aW9uIGRyYWluUXVldWUoKSB7XG5cdCAgaWYgKGRyYWluaW5nKSB7XG5cdCAgICByZXR1cm47XG5cdCAgfVxuXG5cdCAgdmFyIHRpbWVvdXQgPSBydW5UaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7XG5cdCAgZHJhaW5pbmcgPSB0cnVlO1xuXHQgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG5cblx0ICB3aGlsZSAobGVuKSB7XG5cdCAgICBjdXJyZW50UXVldWUgPSBxdWV1ZTtcblx0ICAgIHF1ZXVlID0gW107XG5cblx0ICAgIHdoaWxlICgrK3F1ZXVlSW5kZXggPCBsZW4pIHtcblx0ICAgICAgaWYgKGN1cnJlbnRRdWV1ZSkge1xuXHQgICAgICAgIGN1cnJlbnRRdWV1ZVtxdWV1ZUluZGV4XS5ydW4oKTtcblx0ICAgICAgfVxuXHQgICAgfVxuXG5cdCAgICBxdWV1ZUluZGV4ID0gLTE7XG5cdCAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG5cdCAgfVxuXG5cdCAgY3VycmVudFF1ZXVlID0gbnVsbDtcblx0ICBkcmFpbmluZyA9IGZhbHNlO1xuXHQgIHJ1bkNsZWFyVGltZW91dCh0aW1lb3V0KTtcblx0fVxuXG5cdGZ1bmN0aW9uIG5leHRUaWNrKGZ1bikge1xuXHQgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKTtcblxuXHQgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuXHQgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG5cdCAgICB9XG5cdCAgfVxuXG5cdCAgcXVldWUucHVzaChuZXcgSXRlbShmdW4sIGFyZ3MpKTtcblxuXHQgIGlmIChxdWV1ZS5sZW5ndGggPT09IDEgJiYgIWRyYWluaW5nKSB7XG5cdCAgICBydW5UaW1lb3V0KGRyYWluUXVldWUpO1xuXHQgIH1cblx0fSAvLyB2OCBsaWtlcyBwcmVkaWN0aWJsZSBvYmplY3RzXG5cblx0ZnVuY3Rpb24gSXRlbShmdW4sIGFycmF5KSB7XG5cdCAgdGhpcy5mdW4gPSBmdW47XG5cdCAgdGhpcy5hcnJheSA9IGFycmF5O1xuXHR9XG5cblx0SXRlbS5wcm90b3R5cGUucnVuID0gZnVuY3Rpb24gKCkge1xuXHQgIHRoaXMuZnVuLmFwcGx5KG51bGwsIHRoaXMuYXJyYXkpO1xuXHR9O1xuXG5cdHZhciB0aXRsZSA9ICdicm93c2VyJztcblx0dmFyIHBsYXRmb3JtID0gJ2Jyb3dzZXInO1xuXHR2YXIgYnJvd3NlciA9IHRydWU7XG5cdHZhciBlbnYgPSB7fTtcblx0dmFyIGFyZ3YgPSBbXTtcblx0dmFyIHZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcblxuXHR2YXIgdmVyc2lvbnMgPSB7fTtcblx0dmFyIHJlbGVhc2UgPSB7fTtcblx0dmFyIGNvbmZpZyA9IHt9O1xuXG5cdGZ1bmN0aW9uIG5vb3AoKSB7fVxuXG5cdHZhciBvbiA9IG5vb3A7XG5cdHZhciBhZGRMaXN0ZW5lciA9IG5vb3A7XG5cdHZhciBvbmNlID0gbm9vcDtcblx0dmFyIG9mZiA9IG5vb3A7XG5cdHZhciByZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5cdHZhciByZW1vdmVBbGxMaXN0ZW5lcnMgPSBub29wO1xuXHR2YXIgZW1pdCA9IG5vb3A7XG5cdGZ1bmN0aW9uIGJpbmRpbmcobmFtZSkge1xuXHQgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcblx0fVxuXHRmdW5jdGlvbiBjd2QoKSB7XG5cdCAgcmV0dXJuICcvJztcblx0fVxuXHRmdW5jdGlvbiBjaGRpcihkaXIpIHtcblx0ICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xuXHR9XG5cdGZ1bmN0aW9uIHVtYXNrKCkge1xuXHQgIHJldHVybiAwO1xuXHR9IC8vIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2t1bWF2aXMvYnJvd3Nlci1wcm9jZXNzLWhydGltZS9ibG9iL21hc3Rlci9pbmRleC5qc1xuXG5cdHZhciBwZXJmb3JtYW5jZSA9IGdsb2JhbC5wZXJmb3JtYW5jZSB8fCB7fTtcblxuXHR2YXIgcGVyZm9ybWFuY2VOb3cgPSBwZXJmb3JtYW5jZS5ub3cgfHwgcGVyZm9ybWFuY2UubW96Tm93IHx8IHBlcmZvcm1hbmNlLm1zTm93IHx8IHBlcmZvcm1hbmNlLm9Ob3cgfHwgcGVyZm9ybWFuY2Uud2Via2l0Tm93IHx8IGZ1bmN0aW9uICgpIHtcblx0ICByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5cdH07IC8vIGdlbmVyYXRlIHRpbWVzdGFtcCBvciBkZWx0YVxuXHQvLyBzZWUgaHR0cDovL25vZGVqcy5vcmcvYXBpL3Byb2Nlc3MuaHRtbCNwcm9jZXNzX3Byb2Nlc3NfaHJ0aW1lXG5cblxuXHRmdW5jdGlvbiBocnRpbWUocHJldmlvdXNUaW1lc3RhbXApIHtcblx0ICB2YXIgY2xvY2t0aW1lID0gcGVyZm9ybWFuY2VOb3cuY2FsbChwZXJmb3JtYW5jZSkgKiAxZS0zO1xuXHQgIHZhciBzZWNvbmRzID0gTWF0aC5mbG9vcihjbG9ja3RpbWUpO1xuXHQgIHZhciBuYW5vc2Vjb25kcyA9IE1hdGguZmxvb3IoY2xvY2t0aW1lICUgMSAqIDFlOSk7XG5cblx0ICBpZiAocHJldmlvdXNUaW1lc3RhbXApIHtcblx0ICAgIHNlY29uZHMgPSBzZWNvbmRzIC0gcHJldmlvdXNUaW1lc3RhbXBbMF07XG5cdCAgICBuYW5vc2Vjb25kcyA9IG5hbm9zZWNvbmRzIC0gcHJldmlvdXNUaW1lc3RhbXBbMV07XG5cblx0ICAgIGlmIChuYW5vc2Vjb25kcyA8IDApIHtcblx0ICAgICAgc2Vjb25kcy0tO1xuXHQgICAgICBuYW5vc2Vjb25kcyArPSAxZTk7XG5cdCAgICB9XG5cdCAgfVxuXG5cdCAgcmV0dXJuIFtzZWNvbmRzLCBuYW5vc2Vjb25kc107XG5cdH1cblx0dmFyIHN0YXJ0VGltZSA9IG5ldyBEYXRlKCk7XG5cdGZ1bmN0aW9uIHVwdGltZSgpIHtcblx0ICB2YXIgY3VycmVudFRpbWUgPSBuZXcgRGF0ZSgpO1xuXHQgIHZhciBkaWYgPSBjdXJyZW50VGltZSAtIHN0YXJ0VGltZTtcblx0ICByZXR1cm4gZGlmIC8gMTAwMDtcblx0fVxuXHR2YXIgcHJvY2VzcyA9IHtcblx0ICBuZXh0VGljazogbmV4dFRpY2ssXG5cdCAgdGl0bGU6IHRpdGxlLFxuXHQgIGJyb3dzZXI6IGJyb3dzZXIsXG5cdCAgZW52OiBlbnYsXG5cdCAgYXJndjogYXJndixcblx0ICB2ZXJzaW9uOiB2ZXJzaW9uLFxuXHQgIHZlcnNpb25zOiB2ZXJzaW9ucyxcblx0ICBvbjogb24sXG5cdCAgYWRkTGlzdGVuZXI6IGFkZExpc3RlbmVyLFxuXHQgIG9uY2U6IG9uY2UsXG5cdCAgb2ZmOiBvZmYsXG5cdCAgcmVtb3ZlTGlzdGVuZXI6IHJlbW92ZUxpc3RlbmVyLFxuXHQgIHJlbW92ZUFsbExpc3RlbmVyczogcmVtb3ZlQWxsTGlzdGVuZXJzLFxuXHQgIGVtaXQ6IGVtaXQsXG5cdCAgYmluZGluZzogYmluZGluZyxcblx0ICBjd2Q6IGN3ZCxcblx0ICBjaGRpcjogY2hkaXIsXG5cdCAgdW1hc2s6IHVtYXNrLFxuXHQgIGhydGltZTogaHJ0aW1lLFxuXHQgIHBsYXRmb3JtOiBwbGF0Zm9ybSxcblx0ICByZWxlYXNlOiByZWxlYXNlLFxuXHQgIGNvbmZpZzogY29uZmlnLFxuXHQgIHVwdGltZTogdXB0aW1lXG5cdH07XG5cblx0dmFyIGluaGVyaXRzO1xuXG5cdGlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuXHQgIGluaGVyaXRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG5cdCAgICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuXHQgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3I7XG5cdCAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuXHQgICAgICBjb25zdHJ1Y3Rvcjoge1xuXHQgICAgICAgIHZhbHVlOiBjdG9yLFxuXHQgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuXHQgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuXHQgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuXHQgICAgICB9XG5cdCAgICB9KTtcblx0ICB9O1xuXHR9IGVsc2Uge1xuXHQgIGluaGVyaXRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG5cdCAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvcjtcblxuXHQgICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gVGVtcEN0b3IoKSB7fTtcblxuXHQgICAgVGVtcEN0b3IucHJvdG90eXBlID0gc3VwZXJDdG9yLnByb3RvdHlwZTtcblx0ICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKCk7XG5cdCAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3I7XG5cdCAgfTtcblx0fVxuXG5cdHZhciBpbmhlcml0cyQxID0gaW5oZXJpdHM7XG5cblx0ZnVuY3Rpb24gX3R5cGVvZiQxKG9iaikgeyBpZiAodHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09IFwic3ltYm9sXCIpIHsgX3R5cGVvZiQxID0gZnVuY3Rpb24gX3R5cGVvZihvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH07IH0gZWxzZSB7IF90eXBlb2YkMSA9IGZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqOyB9OyB9IHJldHVybiBfdHlwZW9mJDEob2JqKTsgfVxuXHR2YXIgZm9ybWF0UmVnRXhwID0gLyVbc2RqJV0vZztcblx0ZnVuY3Rpb24gZm9ybWF0KGYpIHtcblx0ICBpZiAoIWlzU3RyaW5nKGYpKSB7XG5cdCAgICB2YXIgb2JqZWN0cyA9IFtdO1xuXG5cdCAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuXHQgICAgICBvYmplY3RzLnB1c2goaW5zcGVjdChhcmd1bWVudHNbaV0pKTtcblx0ICAgIH1cblxuXHQgICAgcmV0dXJuIG9iamVjdHMuam9pbignICcpO1xuXHQgIH1cblxuXHQgIHZhciBpID0gMTtcblx0ICB2YXIgYXJncyA9IGFyZ3VtZW50cztcblx0ICB2YXIgbGVuID0gYXJncy5sZW5ndGg7XG5cdCAgdmFyIHN0ciA9IFN0cmluZyhmKS5yZXBsYWNlKGZvcm1hdFJlZ0V4cCwgZnVuY3Rpb24gKHgpIHtcblx0ICAgIGlmICh4ID09PSAnJSUnKSByZXR1cm4gJyUnO1xuXHQgICAgaWYgKGkgPj0gbGVuKSByZXR1cm4geDtcblxuXHQgICAgc3dpdGNoICh4KSB7XG5cdCAgICAgIGNhc2UgJyVzJzpcblx0ICAgICAgICByZXR1cm4gU3RyaW5nKGFyZ3NbaSsrXSk7XG5cblx0ICAgICAgY2FzZSAnJWQnOlxuXHQgICAgICAgIHJldHVybiBOdW1iZXIoYXJnc1tpKytdKTtcblxuXHQgICAgICBjYXNlICclaic6XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShhcmdzW2krK10pO1xuXHQgICAgICAgIH0gY2F0Y2ggKF8pIHtcblx0ICAgICAgICAgIHJldHVybiAnW0NpcmN1bGFyXSc7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgIGRlZmF1bHQ6XG5cdCAgICAgICAgcmV0dXJuIHg7XG5cdCAgICB9XG5cdCAgfSk7XG5cblx0ICBmb3IgKHZhciB4ID0gYXJnc1tpXTsgaSA8IGxlbjsgeCA9IGFyZ3NbKytpXSkge1xuXHQgICAgaWYgKGlzTnVsbCh4KSB8fCAhaXNPYmplY3QoeCkpIHtcblx0ICAgICAgc3RyICs9ICcgJyArIHg7XG5cdCAgICB9IGVsc2Uge1xuXHQgICAgICBzdHIgKz0gJyAnICsgaW5zcGVjdCh4KTtcblx0ICAgIH1cblx0ICB9XG5cblx0ICByZXR1cm4gc3RyO1xuXHR9XG5cdC8vIFJldHVybnMgYSBtb2RpZmllZCBmdW5jdGlvbiB3aGljaCB3YXJucyBvbmNlIGJ5IGRlZmF1bHQuXG5cdC8vIElmIC0tbm8tZGVwcmVjYXRpb24gaXMgc2V0LCB0aGVuIGl0IGlzIGEgbm8tb3AuXG5cblx0ZnVuY3Rpb24gZGVwcmVjYXRlKGZuLCBtc2cpIHtcblx0ICAvLyBBbGxvdyBmb3IgZGVwcmVjYXRpbmcgdGhpbmdzIGluIHRoZSBwcm9jZXNzIG9mIHN0YXJ0aW5nIHVwLlxuXHQgIGlmIChpc1VuZGVmaW5lZChnbG9iYWwucHJvY2VzcykpIHtcblx0ICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgIHJldHVybiBkZXByZWNhdGUoZm4sIG1zZykuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblx0ICAgIH07XG5cdCAgfVxuXG5cdCAgdmFyIHdhcm5lZCA9IGZhbHNlO1xuXG5cdCAgZnVuY3Rpb24gZGVwcmVjYXRlZCgpIHtcblx0ICAgIGlmICghd2FybmVkKSB7XG5cdCAgICAgIHtcblx0ICAgICAgICBjb25zb2xlLmVycm9yKG1zZyk7XG5cdCAgICAgIH1cblxuXHQgICAgICB3YXJuZWQgPSB0cnVlO1xuXHQgICAgfVxuXG5cdCAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblx0ICB9XG5cblx0ICByZXR1cm4gZGVwcmVjYXRlZDtcblx0fVxuXHR2YXIgZGVidWdzID0ge307XG5cdHZhciBkZWJ1Z0Vudmlyb247XG5cdGZ1bmN0aW9uIGRlYnVnbG9nKHNldCkge1xuXHQgIGlmIChpc1VuZGVmaW5lZChkZWJ1Z0Vudmlyb24pKSBkZWJ1Z0Vudmlyb24gPSBwcm9jZXNzLmVudi5OT0RFX0RFQlVHIHx8ICcnO1xuXHQgIHNldCA9IHNldC50b1VwcGVyQ2FzZSgpO1xuXG5cdCAgaWYgKCFkZWJ1Z3Nbc2V0XSkge1xuXHQgICAgaWYgKG5ldyBSZWdFeHAoJ1xcXFxiJyArIHNldCArICdcXFxcYicsICdpJykudGVzdChkZWJ1Z0Vudmlyb24pKSB7XG5cdCAgICAgIHZhciBwaWQgPSAwO1xuXG5cdCAgICAgIGRlYnVnc1tzZXRdID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIHZhciBtc2cgPSBmb3JtYXQuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcblx0ICAgICAgICBjb25zb2xlLmVycm9yKCclcyAlZDogJXMnLCBzZXQsIHBpZCwgbXNnKTtcblx0ICAgICAgfTtcblx0ICAgIH0gZWxzZSB7XG5cdCAgICAgIGRlYnVnc1tzZXRdID0gZnVuY3Rpb24gKCkge307XG5cdCAgICB9XG5cdCAgfVxuXG5cdCAgcmV0dXJuIGRlYnVnc1tzZXRdO1xuXHR9XG5cdC8qKlxuXHQgKiBFY2hvcyB0aGUgdmFsdWUgb2YgYSB2YWx1ZS4gVHJ5cyB0byBwcmludCB0aGUgdmFsdWUgb3V0XG5cdCAqIGluIHRoZSBiZXN0IHdheSBwb3NzaWJsZSBnaXZlbiB0aGUgZGlmZmVyZW50IHR5cGVzLlxuXHQgKlxuXHQgKiBAcGFyYW0ge09iamVjdH0gb2JqIFRoZSBvYmplY3QgdG8gcHJpbnQgb3V0LlxuXHQgKiBAcGFyYW0ge09iamVjdH0gb3B0cyBPcHRpb25hbCBvcHRpb25zIG9iamVjdCB0aGF0IGFsdGVycyB0aGUgb3V0cHV0LlxuXHQgKi9cblxuXHQvKiBsZWdhY3k6IG9iaiwgc2hvd0hpZGRlbiwgZGVwdGgsIGNvbG9ycyovXG5cblx0ZnVuY3Rpb24gaW5zcGVjdChvYmosIG9wdHMpIHtcblx0ICAvLyBkZWZhdWx0IG9wdGlvbnNcblx0ICB2YXIgY3R4ID0ge1xuXHQgICAgc2VlbjogW10sXG5cdCAgICBzdHlsaXplOiBzdHlsaXplTm9Db2xvclxuXHQgIH07IC8vIGxlZ2FjeS4uLlxuXG5cdCAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gMykgY3R4LmRlcHRoID0gYXJndW1lbnRzWzJdO1xuXHQgIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDQpIGN0eC5jb2xvcnMgPSBhcmd1bWVudHNbM107XG5cblx0ICBpZiAoaXNCb29sZWFuKG9wdHMpKSB7XG5cdCAgICAvLyBsZWdhY3kuLi5cblx0ICAgIGN0eC5zaG93SGlkZGVuID0gb3B0cztcblx0ICB9IGVsc2UgaWYgKG9wdHMpIHtcblx0ICAgIC8vIGdvdCBhbiBcIm9wdGlvbnNcIiBvYmplY3Rcblx0ICAgIF9leHRlbmQoY3R4LCBvcHRzKTtcblx0ICB9IC8vIHNldCBkZWZhdWx0IG9wdGlvbnNcblxuXG5cdCAgaWYgKGlzVW5kZWZpbmVkKGN0eC5zaG93SGlkZGVuKSkgY3R4LnNob3dIaWRkZW4gPSBmYWxzZTtcblx0ICBpZiAoaXNVbmRlZmluZWQoY3R4LmRlcHRoKSkgY3R4LmRlcHRoID0gMjtcblx0ICBpZiAoaXNVbmRlZmluZWQoY3R4LmNvbG9ycykpIGN0eC5jb2xvcnMgPSBmYWxzZTtcblx0ICBpZiAoaXNVbmRlZmluZWQoY3R4LmN1c3RvbUluc3BlY3QpKSBjdHguY3VzdG9tSW5zcGVjdCA9IHRydWU7XG5cdCAgaWYgKGN0eC5jb2xvcnMpIGN0eC5zdHlsaXplID0gc3R5bGl6ZVdpdGhDb2xvcjtcblx0ICByZXR1cm4gZm9ybWF0VmFsdWUoY3R4LCBvYmosIGN0eC5kZXB0aCk7XG5cdH0gLy8gaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9BTlNJX2VzY2FwZV9jb2RlI2dyYXBoaWNzXG5cblx0aW5zcGVjdC5jb2xvcnMgPSB7XG5cdCAgJ2JvbGQnOiBbMSwgMjJdLFxuXHQgICdpdGFsaWMnOiBbMywgMjNdLFxuXHQgICd1bmRlcmxpbmUnOiBbNCwgMjRdLFxuXHQgICdpbnZlcnNlJzogWzcsIDI3XSxcblx0ICAnd2hpdGUnOiBbMzcsIDM5XSxcblx0ICAnZ3JleSc6IFs5MCwgMzldLFxuXHQgICdibGFjayc6IFszMCwgMzldLFxuXHQgICdibHVlJzogWzM0LCAzOV0sXG5cdCAgJ2N5YW4nOiBbMzYsIDM5XSxcblx0ICAnZ3JlZW4nOiBbMzIsIDM5XSxcblx0ICAnbWFnZW50YSc6IFszNSwgMzldLFxuXHQgICdyZWQnOiBbMzEsIDM5XSxcblx0ICAneWVsbG93JzogWzMzLCAzOV1cblx0fTsgLy8gRG9uJ3QgdXNlICdibHVlJyBub3QgdmlzaWJsZSBvbiBjbWQuZXhlXG5cblx0aW5zcGVjdC5zdHlsZXMgPSB7XG5cdCAgJ3NwZWNpYWwnOiAnY3lhbicsXG5cdCAgJ251bWJlcic6ICd5ZWxsb3cnLFxuXHQgICdib29sZWFuJzogJ3llbGxvdycsXG5cdCAgJ3VuZGVmaW5lZCc6ICdncmV5Jyxcblx0ICAnbnVsbCc6ICdib2xkJyxcblx0ICAnc3RyaW5nJzogJ2dyZWVuJyxcblx0ICAnZGF0ZSc6ICdtYWdlbnRhJyxcblx0ICAvLyBcIm5hbWVcIjogaW50ZW50aW9uYWxseSBub3Qgc3R5bGluZ1xuXHQgICdyZWdleHAnOiAncmVkJ1xuXHR9O1xuXG5cdGZ1bmN0aW9uIHN0eWxpemVXaXRoQ29sb3Ioc3RyLCBzdHlsZVR5cGUpIHtcblx0ICB2YXIgc3R5bGUgPSBpbnNwZWN0LnN0eWxlc1tzdHlsZVR5cGVdO1xuXG5cdCAgaWYgKHN0eWxlKSB7XG5cdCAgICByZXR1cm4gXCJcXHgxQltcIiArIGluc3BlY3QuY29sb3JzW3N0eWxlXVswXSArICdtJyArIHN0ciArIFwiXFx4MUJbXCIgKyBpbnNwZWN0LmNvbG9yc1tzdHlsZV1bMV0gKyAnbSc7XG5cdCAgfSBlbHNlIHtcblx0ICAgIHJldHVybiBzdHI7XG5cdCAgfVxuXHR9XG5cblx0ZnVuY3Rpb24gc3R5bGl6ZU5vQ29sb3Ioc3RyLCBzdHlsZVR5cGUpIHtcblx0ICByZXR1cm4gc3RyO1xuXHR9XG5cblx0ZnVuY3Rpb24gYXJyYXlUb0hhc2goYXJyYXkpIHtcblx0ICB2YXIgaGFzaCA9IHt9O1xuXHQgIGFycmF5LmZvckVhY2goZnVuY3Rpb24gKHZhbCwgaWR4KSB7XG5cdCAgICBoYXNoW3ZhbF0gPSB0cnVlO1xuXHQgIH0pO1xuXHQgIHJldHVybiBoYXNoO1xuXHR9XG5cblx0ZnVuY3Rpb24gZm9ybWF0VmFsdWUoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzKSB7XG5cdCAgLy8gUHJvdmlkZSBhIGhvb2sgZm9yIHVzZXItc3BlY2lmaWVkIGluc3BlY3QgZnVuY3Rpb25zLlxuXHQgIC8vIENoZWNrIHRoYXQgdmFsdWUgaXMgYW4gb2JqZWN0IHdpdGggYW4gaW5zcGVjdCBmdW5jdGlvbiBvbiBpdFxuXHQgIGlmIChjdHguY3VzdG9tSW5zcGVjdCAmJiB2YWx1ZSAmJiBpc0Z1bmN0aW9uKHZhbHVlLmluc3BlY3QpICYmIC8vIEZpbHRlciBvdXQgdGhlIHV0aWwgbW9kdWxlLCBpdCdzIGluc3BlY3QgZnVuY3Rpb24gaXMgc3BlY2lhbFxuXHQgIHZhbHVlLmluc3BlY3QgIT09IGluc3BlY3QgJiYgLy8gQWxzbyBmaWx0ZXIgb3V0IGFueSBwcm90b3R5cGUgb2JqZWN0cyB1c2luZyB0aGUgY2lyY3VsYXIgY2hlY2suXG5cdCAgISh2YWx1ZS5jb25zdHJ1Y3RvciAmJiB2YWx1ZS5jb25zdHJ1Y3Rvci5wcm90b3R5cGUgPT09IHZhbHVlKSkge1xuXHQgICAgdmFyIHJldCA9IHZhbHVlLmluc3BlY3QocmVjdXJzZVRpbWVzLCBjdHgpO1xuXG5cdCAgICBpZiAoIWlzU3RyaW5nKHJldCkpIHtcblx0ICAgICAgcmV0ID0gZm9ybWF0VmFsdWUoY3R4LCByZXQsIHJlY3Vyc2VUaW1lcyk7XG5cdCAgICB9XG5cblx0ICAgIHJldHVybiByZXQ7XG5cdCAgfSAvLyBQcmltaXRpdmUgdHlwZXMgY2Fubm90IGhhdmUgcHJvcGVydGllc1xuXG5cblx0ICB2YXIgcHJpbWl0aXZlID0gZm9ybWF0UHJpbWl0aXZlKGN0eCwgdmFsdWUpO1xuXG5cdCAgaWYgKHByaW1pdGl2ZSkge1xuXHQgICAgcmV0dXJuIHByaW1pdGl2ZTtcblx0ICB9IC8vIExvb2sgdXAgdGhlIGtleXMgb2YgdGhlIG9iamVjdC5cblxuXG5cdCAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh2YWx1ZSk7XG5cdCAgdmFyIHZpc2libGVLZXlzID0gYXJyYXlUb0hhc2goa2V5cyk7XG5cblx0ICBpZiAoY3R4LnNob3dIaWRkZW4pIHtcblx0ICAgIGtleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh2YWx1ZSk7XG5cdCAgfSAvLyBJRSBkb2Vzbid0IG1ha2UgZXJyb3IgZmllbGRzIG5vbi1lbnVtZXJhYmxlXG5cdCAgLy8gaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2llL2R3dzUyc2J0KHY9dnMuOTQpLmFzcHhcblxuXG5cdCAgaWYgKGlzRXJyb3IodmFsdWUpICYmIChrZXlzLmluZGV4T2YoJ21lc3NhZ2UnKSA+PSAwIHx8IGtleXMuaW5kZXhPZignZGVzY3JpcHRpb24nKSA+PSAwKSkge1xuXHQgICAgcmV0dXJuIGZvcm1hdEVycm9yKHZhbHVlKTtcblx0ICB9IC8vIFNvbWUgdHlwZSBvZiBvYmplY3Qgd2l0aG91dCBwcm9wZXJ0aWVzIGNhbiBiZSBzaG9ydGN1dHRlZC5cblxuXG5cdCAgaWYgKGtleXMubGVuZ3RoID09PSAwKSB7XG5cdCAgICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcblx0ICAgICAgdmFyIG5hbWUgPSB2YWx1ZS5uYW1lID8gJzogJyArIHZhbHVlLm5hbWUgOiAnJztcblx0ICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCdbRnVuY3Rpb24nICsgbmFtZSArICddJywgJ3NwZWNpYWwnKTtcblx0ICAgIH1cblxuXHQgICAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuXHQgICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuXHQgICAgfVxuXG5cdCAgICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuXHQgICAgICByZXR1cm4gY3R4LnN0eWxpemUoRGF0ZS5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdkYXRlJyk7XG5cdCAgICB9XG5cblx0ICAgIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuXHQgICAgICByZXR1cm4gZm9ybWF0RXJyb3IodmFsdWUpO1xuXHQgICAgfVxuXHQgIH1cblxuXHQgIHZhciBiYXNlID0gJycsXG5cdCAgICAgIGFycmF5ID0gZmFsc2UsXG5cdCAgICAgIGJyYWNlcyA9IFsneycsICd9J107IC8vIE1ha2UgQXJyYXkgc2F5IHRoYXQgdGhleSBhcmUgQXJyYXlcblxuXHQgIGlmIChpc0FycmF5KHZhbHVlKSkge1xuXHQgICAgYXJyYXkgPSB0cnVlO1xuXHQgICAgYnJhY2VzID0gWydbJywgJ10nXTtcblx0ICB9IC8vIE1ha2UgZnVuY3Rpb25zIHNheSB0aGF0IHRoZXkgYXJlIGZ1bmN0aW9uc1xuXG5cblx0ICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcblx0ICAgIHZhciBuID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG5cdCAgICBiYXNlID0gJyBbRnVuY3Rpb24nICsgbiArICddJztcblx0ICB9IC8vIE1ha2UgUmVnRXhwcyBzYXkgdGhhdCB0aGV5IGFyZSBSZWdFeHBzXG5cblxuXHQgIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcblx0ICAgIGJhc2UgPSAnICcgKyBSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpO1xuXHQgIH0gLy8gTWFrZSBkYXRlcyB3aXRoIHByb3BlcnRpZXMgZmlyc3Qgc2F5IHRoZSBkYXRlXG5cblxuXHQgIGlmIChpc0RhdGUodmFsdWUpKSB7XG5cdCAgICBiYXNlID0gJyAnICsgRGF0ZS5wcm90b3R5cGUudG9VVENTdHJpbmcuY2FsbCh2YWx1ZSk7XG5cdCAgfSAvLyBNYWtlIGVycm9yIHdpdGggbWVzc2FnZSBmaXJzdCBzYXkgdGhlIGVycm9yXG5cblxuXHQgIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuXHQgICAgYmFzZSA9ICcgJyArIGZvcm1hdEVycm9yKHZhbHVlKTtcblx0ICB9XG5cblx0ICBpZiAoa2V5cy5sZW5ndGggPT09IDAgJiYgKCFhcnJheSB8fCB2YWx1ZS5sZW5ndGggPT0gMCkpIHtcblx0ICAgIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgYnJhY2VzWzFdO1xuXHQgIH1cblxuXHQgIGlmIChyZWN1cnNlVGltZXMgPCAwKSB7XG5cdCAgICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG5cdCAgICAgIHJldHVybiBjdHguc3R5bGl6ZShSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAncmVnZXhwJyk7XG5cdCAgICB9IGVsc2Uge1xuXHQgICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ1tPYmplY3RdJywgJ3NwZWNpYWwnKTtcblx0ICAgIH1cblx0ICB9XG5cblx0ICBjdHguc2Vlbi5wdXNoKHZhbHVlKTtcblx0ICB2YXIgb3V0cHV0O1xuXG5cdCAgaWYgKGFycmF5KSB7XG5cdCAgICBvdXRwdXQgPSBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKTtcblx0ICB9IGVsc2Uge1xuXHQgICAgb3V0cHV0ID0ga2V5cy5tYXAoZnVuY3Rpb24gKGtleSkge1xuXHQgICAgICByZXR1cm4gZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5LCBhcnJheSk7XG5cdCAgICB9KTtcblx0ICB9XG5cblx0ICBjdHguc2Vlbi5wb3AoKTtcblx0ICByZXR1cm4gcmVkdWNlVG9TaW5nbGVTdHJpbmcob3V0cHV0LCBiYXNlLCBicmFjZXMpO1xuXHR9XG5cblx0ZnVuY3Rpb24gZm9ybWF0UHJpbWl0aXZlKGN0eCwgdmFsdWUpIHtcblx0ICBpZiAoaXNVbmRlZmluZWQodmFsdWUpKSByZXR1cm4gY3R4LnN0eWxpemUoJ3VuZGVmaW5lZCcsICd1bmRlZmluZWQnKTtcblxuXHQgIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcblx0ICAgIHZhciBzaW1wbGUgPSAnXFwnJyArIEpTT04uc3RyaW5naWZ5KHZhbHVlKS5yZXBsYWNlKC9eXCJ8XCIkL2csICcnKS5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIikucmVwbGFjZSgvXFxcXFwiL2csICdcIicpICsgJ1xcJyc7XG5cdCAgICByZXR1cm4gY3R4LnN0eWxpemUoc2ltcGxlLCAnc3RyaW5nJyk7XG5cdCAgfVxuXG5cdCAgaWYgKGlzTnVtYmVyKHZhbHVlKSkgcmV0dXJuIGN0eC5zdHlsaXplKCcnICsgdmFsdWUsICdudW1iZXInKTtcblx0ICBpZiAoaXNCb29sZWFuKHZhbHVlKSkgcmV0dXJuIGN0eC5zdHlsaXplKCcnICsgdmFsdWUsICdib29sZWFuJyk7IC8vIEZvciBzb21lIHJlYXNvbiB0eXBlb2YgbnVsbCBpcyBcIm9iamVjdFwiLCBzbyBzcGVjaWFsIGNhc2UgaGVyZS5cblxuXHQgIGlmIChpc051bGwodmFsdWUpKSByZXR1cm4gY3R4LnN0eWxpemUoJ251bGwnLCAnbnVsbCcpO1xuXHR9XG5cblx0ZnVuY3Rpb24gZm9ybWF0RXJyb3IodmFsdWUpIHtcblx0ICByZXR1cm4gJ1snICsgRXJyb3IucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpICsgJ10nO1xuXHR9XG5cblx0ZnVuY3Rpb24gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cykge1xuXHQgIHZhciBvdXRwdXQgPSBbXTtcblxuXHQgIGZvciAodmFyIGkgPSAwLCBsID0gdmFsdWUubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG5cdCAgICBpZiAoaGFzT3duUHJvcGVydHkodmFsdWUsIFN0cmluZyhpKSkpIHtcblx0ICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywgU3RyaW5nKGkpLCB0cnVlKSk7XG5cdCAgICB9IGVsc2Uge1xuXHQgICAgICBvdXRwdXQucHVzaCgnJyk7XG5cdCAgICB9XG5cdCAgfVxuXG5cdCAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcblx0ICAgIGlmICgha2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuXHQgICAgICBvdXRwdXQucHVzaChmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXksIHRydWUpKTtcblx0ICAgIH1cblx0ICB9KTtcblx0ICByZXR1cm4gb3V0cHV0O1xuXHR9XG5cblx0ZnVuY3Rpb24gZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5LCBhcnJheSkge1xuXHQgIHZhciBuYW1lLCBzdHIsIGRlc2M7XG5cdCAgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodmFsdWUsIGtleSkgfHwge1xuXHQgICAgdmFsdWU6IHZhbHVlW2tleV1cblx0ICB9O1xuXG5cdCAgaWYgKGRlc2MuZ2V0KSB7XG5cdCAgICBpZiAoZGVzYy5zZXQpIHtcblx0ICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tHZXR0ZXIvU2V0dGVyXScsICdzcGVjaWFsJyk7XG5cdCAgICB9IGVsc2Uge1xuXHQgICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0dldHRlcl0nLCAnc3BlY2lhbCcpO1xuXHQgICAgfVxuXHQgIH0gZWxzZSB7XG5cdCAgICBpZiAoZGVzYy5zZXQpIHtcblx0ICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tTZXR0ZXJdJywgJ3NwZWNpYWwnKTtcblx0ICAgIH1cblx0ICB9XG5cblx0ICBpZiAoIWhhc093blByb3BlcnR5KHZpc2libGVLZXlzLCBrZXkpKSB7XG5cdCAgICBuYW1lID0gJ1snICsga2V5ICsgJ10nO1xuXHQgIH1cblxuXHQgIGlmICghc3RyKSB7XG5cdCAgICBpZiAoY3R4LnNlZW4uaW5kZXhPZihkZXNjLnZhbHVlKSA8IDApIHtcblx0ICAgICAgaWYgKGlzTnVsbChyZWN1cnNlVGltZXMpKSB7XG5cdCAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCBkZXNjLnZhbHVlLCBudWxsKTtcblx0ICAgICAgfSBlbHNlIHtcblx0ICAgICAgICBzdHIgPSBmb3JtYXRWYWx1ZShjdHgsIGRlc2MudmFsdWUsIHJlY3Vyc2VUaW1lcyAtIDEpO1xuXHQgICAgICB9XG5cblx0ICAgICAgaWYgKHN0ci5pbmRleE9mKCdcXG4nKSA+IC0xKSB7XG5cdCAgICAgICAgaWYgKGFycmF5KSB7XG5cdCAgICAgICAgICBzdHIgPSBzdHIuc3BsaXQoJ1xcbicpLm1hcChmdW5jdGlvbiAobGluZSkge1xuXHQgICAgICAgICAgICByZXR1cm4gJyAgJyArIGxpbmU7XG5cdCAgICAgICAgICB9KS5qb2luKCdcXG4nKS5zdWJzdHIoMik7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIHN0ciA9ICdcXG4nICsgc3RyLnNwbGl0KCdcXG4nKS5tYXAoZnVuY3Rpb24gKGxpbmUpIHtcblx0ICAgICAgICAgICAgcmV0dXJuICcgICAnICsgbGluZTtcblx0ICAgICAgICAgIH0pLmpvaW4oJ1xcbicpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tDaXJjdWxhcl0nLCAnc3BlY2lhbCcpO1xuXHQgICAgfVxuXHQgIH1cblxuXHQgIGlmIChpc1VuZGVmaW5lZChuYW1lKSkge1xuXHQgICAgaWYgKGFycmF5ICYmIGtleS5tYXRjaCgvXlxcZCskLykpIHtcblx0ICAgICAgcmV0dXJuIHN0cjtcblx0ICAgIH1cblxuXHQgICAgbmFtZSA9IEpTT04uc3RyaW5naWZ5KCcnICsga2V5KTtcblxuXHQgICAgaWYgKG5hbWUubWF0Y2goL15cIihbYS16QS1aX11bYS16QS1aXzAtOV0qKVwiJC8pKSB7XG5cdCAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cigxLCBuYW1lLmxlbmd0aCAtIDIpO1xuXHQgICAgICBuYW1lID0gY3R4LnN0eWxpemUobmFtZSwgJ25hbWUnKTtcblx0ICAgIH0gZWxzZSB7XG5cdCAgICAgIG5hbWUgPSBuYW1lLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKS5yZXBsYWNlKC9cXFxcXCIvZywgJ1wiJykucmVwbGFjZSgvKF5cInxcIiQpL2csIFwiJ1wiKTtcblx0ICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICdzdHJpbmcnKTtcblx0ICAgIH1cblx0ICB9XG5cblx0ICByZXR1cm4gbmFtZSArICc6ICcgKyBzdHI7XG5cdH1cblxuXHRmdW5jdGlvbiByZWR1Y2VUb1NpbmdsZVN0cmluZyhvdXRwdXQsIGJhc2UsIGJyYWNlcykge1xuXHQgIHZhciBsZW5ndGggPSBvdXRwdXQucmVkdWNlKGZ1bmN0aW9uIChwcmV2LCBjdXIpIHtcblx0ICAgIGlmIChjdXIuaW5kZXhPZignXFxuJykgPj0gMCkgO1xuXHQgICAgcmV0dXJuIHByZXYgKyBjdXIucmVwbGFjZSgvXFx1MDAxYlxcW1xcZFxcZD9tL2csICcnKS5sZW5ndGggKyAxO1xuXHQgIH0sIDApO1xuXG5cdCAgaWYgKGxlbmd0aCA+IDYwKSB7XG5cdCAgICByZXR1cm4gYnJhY2VzWzBdICsgKGJhc2UgPT09ICcnID8gJycgOiBiYXNlICsgJ1xcbiAnKSArICcgJyArIG91dHB1dC5qb2luKCcsXFxuICAnKSArICcgJyArIGJyYWNlc1sxXTtcblx0ICB9XG5cblx0ICByZXR1cm4gYnJhY2VzWzBdICsgYmFzZSArICcgJyArIG91dHB1dC5qb2luKCcsICcpICsgJyAnICsgYnJhY2VzWzFdO1xuXHR9IC8vIE5PVEU6IFRoZXNlIHR5cGUgY2hlY2tpbmcgZnVuY3Rpb25zIGludGVudGlvbmFsbHkgZG9uJ3QgdXNlIGBpbnN0YW5jZW9mYFxuXHQvLyBiZWNhdXNlIGl0IGlzIGZyYWdpbGUgYW5kIGNhbiBiZSBlYXNpbHkgZmFrZWQgd2l0aCBgT2JqZWN0LmNyZWF0ZSgpYC5cblxuXG5cdGZ1bmN0aW9uIGlzQXJyYXkoYXIpIHtcblx0ICByZXR1cm4gQXJyYXkuaXNBcnJheShhcik7XG5cdH1cblx0ZnVuY3Rpb24gaXNCb29sZWFuKGFyZykge1xuXHQgIHJldHVybiB0eXBlb2YgYXJnID09PSAnYm9vbGVhbic7XG5cdH1cblx0ZnVuY3Rpb24gaXNOdWxsKGFyZykge1xuXHQgIHJldHVybiBhcmcgPT09IG51bGw7XG5cdH1cblx0ZnVuY3Rpb24gaXNOdWxsT3JVbmRlZmluZWQoYXJnKSB7XG5cdCAgcmV0dXJuIGFyZyA9PSBudWxsO1xuXHR9XG5cdGZ1bmN0aW9uIGlzTnVtYmVyKGFyZykge1xuXHQgIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcblx0fVxuXHRmdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcblx0ICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ3N0cmluZyc7XG5cdH1cblx0ZnVuY3Rpb24gaXNTeW1ib2woYXJnKSB7XG5cdCAgcmV0dXJuIF90eXBlb2YkMShhcmcpID09PSAnc3ltYm9sJztcblx0fVxuXHRmdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcblx0ICByZXR1cm4gYXJnID09PSB2b2lkIDA7XG5cdH1cblx0ZnVuY3Rpb24gaXNSZWdFeHAocmUpIHtcblx0ICByZXR1cm4gaXNPYmplY3QocmUpICYmIG9iamVjdFRvU3RyaW5nKHJlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG5cdH1cblx0ZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG5cdCAgcmV0dXJuIF90eXBlb2YkMShhcmcpID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG5cdH1cblx0ZnVuY3Rpb24gaXNEYXRlKGQpIHtcblx0ICByZXR1cm4gaXNPYmplY3QoZCkgJiYgb2JqZWN0VG9TdHJpbmcoZCkgPT09ICdbb2JqZWN0IERhdGVdJztcblx0fVxuXHRmdW5jdGlvbiBpc0Vycm9yKGUpIHtcblx0ICByZXR1cm4gaXNPYmplY3QoZSkgJiYgKG9iamVjdFRvU3RyaW5nKGUpID09PSAnW29iamVjdCBFcnJvcl0nIHx8IGUgaW5zdGFuY2VvZiBFcnJvcik7XG5cdH1cblx0ZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpIHtcblx0ICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcblx0fVxuXHRmdW5jdGlvbiBpc1ByaW1pdGl2ZShhcmcpIHtcblx0ICByZXR1cm4gYXJnID09PSBudWxsIHx8IHR5cGVvZiBhcmcgPT09ICdib29sZWFuJyB8fCB0eXBlb2YgYXJnID09PSAnbnVtYmVyJyB8fCB0eXBlb2YgYXJnID09PSAnc3RyaW5nJyB8fCBfdHlwZW9mJDEoYXJnKSA9PT0gJ3N5bWJvbCcgfHwgLy8gRVM2IHN5bWJvbFxuXHQgIHR5cGVvZiBhcmcgPT09ICd1bmRlZmluZWQnO1xuXHR9XG5cdGZ1bmN0aW9uIGlzQnVmZmVyKG1heWJlQnVmKSB7XG5cdCAgcmV0dXJuIEJ1ZmZlci5pc0J1ZmZlcihtYXliZUJ1Zik7XG5cdH1cblxuXHRmdW5jdGlvbiBvYmplY3RUb1N0cmluZyhvKSB7XG5cdCAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTtcblx0fVxuXG5cdGZ1bmN0aW9uIHBhZChuKSB7XG5cdCAgcmV0dXJuIG4gPCAxMCA/ICcwJyArIG4udG9TdHJpbmcoMTApIDogbi50b1N0cmluZygxMCk7XG5cdH1cblxuXHR2YXIgbW9udGhzID0gWydKYW4nLCAnRmViJywgJ01hcicsICdBcHInLCAnTWF5JywgJ0p1bicsICdKdWwnLCAnQXVnJywgJ1NlcCcsICdPY3QnLCAnTm92JywgJ0RlYyddOyAvLyAyNiBGZWIgMTY6MTk6MzRcblxuXHRmdW5jdGlvbiB0aW1lc3RhbXAkMSgpIHtcblx0ICB2YXIgZCA9IG5ldyBEYXRlKCk7XG5cdCAgdmFyIHRpbWUgPSBbcGFkKGQuZ2V0SG91cnMoKSksIHBhZChkLmdldE1pbnV0ZXMoKSksIHBhZChkLmdldFNlY29uZHMoKSldLmpvaW4oJzonKTtcblx0ICByZXR1cm4gW2QuZ2V0RGF0ZSgpLCBtb250aHNbZC5nZXRNb250aCgpXSwgdGltZV0uam9pbignICcpO1xuXHR9IC8vIGxvZyBpcyBqdXN0IGEgdGhpbiB3cmFwcGVyIHRvIGNvbnNvbGUubG9nIHRoYXQgcHJlcGVuZHMgYSB0aW1lc3RhbXBcblxuXG5cdGZ1bmN0aW9uIGxvZygpIHtcblx0ICBjb25zb2xlLmxvZygnJXMgLSAlcycsIHRpbWVzdGFtcCQxKCksIGZvcm1hdC5hcHBseShudWxsLCBhcmd1bWVudHMpKTtcblx0fVxuXHRmdW5jdGlvbiBfZXh0ZW5kKG9yaWdpbiwgYWRkKSB7XG5cdCAgLy8gRG9uJ3QgZG8gYW55dGhpbmcgaWYgYWRkIGlzbid0IGFuIG9iamVjdFxuXHQgIGlmICghYWRkIHx8ICFpc09iamVjdChhZGQpKSByZXR1cm4gb3JpZ2luO1xuXHQgIHZhciBrZXlzID0gT2JqZWN0LmtleXMoYWRkKTtcblx0ICB2YXIgaSA9IGtleXMubGVuZ3RoO1xuXG5cdCAgd2hpbGUgKGktLSkge1xuXHQgICAgb3JpZ2luW2tleXNbaV1dID0gYWRkW2tleXNbaV1dO1xuXHQgIH1cblxuXHQgIHJldHVybiBvcmlnaW47XG5cdH1cblxuXHRmdW5jdGlvbiBoYXNPd25Qcm9wZXJ0eShvYmosIHByb3ApIHtcblx0ICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCk7XG5cdH1cblxuXHR2YXIgdXRpbCA9IHtcblx0ICBpbmhlcml0czogaW5oZXJpdHMkMSxcblx0ICBfZXh0ZW5kOiBfZXh0ZW5kLFxuXHQgIGxvZzogbG9nLFxuXHQgIGlzQnVmZmVyOiBpc0J1ZmZlcixcblx0ICBpc1ByaW1pdGl2ZTogaXNQcmltaXRpdmUsXG5cdCAgaXNGdW5jdGlvbjogaXNGdW5jdGlvbixcblx0ICBpc0Vycm9yOiBpc0Vycm9yLFxuXHQgIGlzRGF0ZTogaXNEYXRlLFxuXHQgIGlzT2JqZWN0OiBpc09iamVjdCxcblx0ICBpc1JlZ0V4cDogaXNSZWdFeHAsXG5cdCAgaXNVbmRlZmluZWQ6IGlzVW5kZWZpbmVkLFxuXHQgIGlzU3ltYm9sOiBpc1N5bWJvbCxcblx0ICBpc1N0cmluZzogaXNTdHJpbmcsXG5cdCAgaXNOdW1iZXI6IGlzTnVtYmVyLFxuXHQgIGlzTnVsbE9yVW5kZWZpbmVkOiBpc051bGxPclVuZGVmaW5lZCxcblx0ICBpc051bGw6IGlzTnVsbCxcblx0ICBpc0Jvb2xlYW46IGlzQm9vbGVhbixcblx0ICBpc0FycmF5OiBpc0FycmF5LFxuXHQgIGluc3BlY3Q6IGluc3BlY3QsXG5cdCAgZGVwcmVjYXRlOiBkZXByZWNhdGUsXG5cdCAgZm9ybWF0OiBmb3JtYXQsXG5cdCAgZGVidWdsb2c6IGRlYnVnbG9nXG5cdH07XG5cblx0dmFyIHV0aWwkMSA9IC8qI19fUFVSRV9fKi9PYmplY3QuZnJlZXplKHtcblx0XHRmb3JtYXQ6IGZvcm1hdCxcblx0XHRkZXByZWNhdGU6IGRlcHJlY2F0ZSxcblx0XHRkZWJ1Z2xvZzogZGVidWdsb2csXG5cdFx0aW5zcGVjdDogaW5zcGVjdCxcblx0XHRpc0FycmF5OiBpc0FycmF5LFxuXHRcdGlzQm9vbGVhbjogaXNCb29sZWFuLFxuXHRcdGlzTnVsbDogaXNOdWxsLFxuXHRcdGlzTnVsbE9yVW5kZWZpbmVkOiBpc051bGxPclVuZGVmaW5lZCxcblx0XHRpc051bWJlcjogaXNOdW1iZXIsXG5cdFx0aXNTdHJpbmc6IGlzU3RyaW5nLFxuXHRcdGlzU3ltYm9sOiBpc1N5bWJvbCxcblx0XHRpc1VuZGVmaW5lZDogaXNVbmRlZmluZWQsXG5cdFx0aXNSZWdFeHA6IGlzUmVnRXhwLFxuXHRcdGlzT2JqZWN0OiBpc09iamVjdCxcblx0XHRpc0RhdGU6IGlzRGF0ZSxcblx0XHRpc0Vycm9yOiBpc0Vycm9yLFxuXHRcdGlzRnVuY3Rpb246IGlzRnVuY3Rpb24sXG5cdFx0aXNQcmltaXRpdmU6IGlzUHJpbWl0aXZlLFxuXHRcdGlzQnVmZmVyOiBpc0J1ZmZlcixcblx0XHRsb2c6IGxvZyxcblx0XHRpbmhlcml0czogaW5oZXJpdHMkMSxcblx0XHRfZXh0ZW5kOiBfZXh0ZW5kLFxuXHRcdGRlZmF1bHQ6IHV0aWxcblx0fSk7XG5cblx0dmFyIHV0aWwkMiA9IGdldENqc0V4cG9ydEZyb21OYW1lc3BhY2UodXRpbCQxKTtcblxuXHRmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2skMihpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cblx0ZnVuY3Rpb24gX2RlZmluZVByb3BlcnRpZXMkMih0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9XG5cblx0ZnVuY3Rpb24gX2NyZWF0ZUNsYXNzJDIoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyQyKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgX2RlZmluZVByb3BlcnRpZXMkMihDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH1cblxuXHR2YXIgQnVmZmVyJDEgPSBidWZmZXIuQnVmZmVyO1xuXHR2YXIgcmFuZG9tQnl0ZXMkMSA9IHV0aWxzLnJhbmRvbUJ5dGVzO1xuXHR2YXIgZGVwcmVjYXRlJDEgPSB1dGlsJDIuZGVwcmVjYXRlOyAvLyBjb25zdGFudHNcblxuXHR2YXIgUFJPQ0VTU19VTklRVUUgPSByYW5kb21CeXRlcyQxKDUpOyAvLyBSZWd1bGFyIGV4cHJlc3Npb24gdGhhdCBjaGVja3MgZm9yIGhleCB2YWx1ZVxuXG5cdHZhciBjaGVja0ZvckhleFJlZ0V4cCA9IG5ldyBSZWdFeHAoJ15bMC05YS1mQS1GXXsyNH0kJyk7XG5cdHZhciBoYXNCdWZmZXJUeXBlID0gZmFsc2U7IC8vIENoZWNrIGlmIGJ1ZmZlciBleGlzdHNcblxuXHR0cnkge1xuXHQgIGlmIChCdWZmZXIkMSAmJiBCdWZmZXIkMS5mcm9tKSBoYXNCdWZmZXJUeXBlID0gdHJ1ZTtcblx0fSBjYXRjaCAoZXJyKSB7XG5cdCAgaGFzQnVmZmVyVHlwZSA9IGZhbHNlO1xuXHR9IC8vIFByZWNvbXB1dGVkIGhleCB0YWJsZSBlbmFibGVzIHNwZWVkeSBoZXggc3RyaW5nIGNvbnZlcnNpb25cblxuXG5cdHZhciBoZXhUYWJsZSA9IFtdO1xuXG5cdGZvciAodmFyIF9pID0gMDsgX2kgPCAyNTY7IF9pKyspIHtcblx0ICBoZXhUYWJsZVtfaV0gPSAoX2kgPD0gMTUgPyAnMCcgOiAnJykgKyBfaS50b1N0cmluZygxNik7XG5cdH0gLy8gTG9va3VwIHRhYmxlc1xuXG5cblx0dmFyIGRlY29kZUxvb2t1cCA9IFtdO1xuXHR2YXIgaSA9IDA7XG5cblx0d2hpbGUgKGkgPCAxMCkge1xuXHQgIGRlY29kZUxvb2t1cFsweDMwICsgaV0gPSBpKys7XG5cdH1cblxuXHR3aGlsZSAoaSA8IDE2KSB7XG5cdCAgZGVjb2RlTG9va3VwWzB4NDEgLSAxMCArIGldID0gZGVjb2RlTG9va3VwWzB4NjEgLSAxMCArIGldID0gaSsrO1xuXHR9XG5cblx0dmFyIF9CdWZmZXIgPSBCdWZmZXIkMTtcblxuXHRmdW5jdGlvbiBjb252ZXJ0VG9IZXgoYnl0ZXMpIHtcblx0ICByZXR1cm4gYnl0ZXMudG9TdHJpbmcoJ2hleCcpO1xuXHR9XG5cblx0ZnVuY3Rpb24gbWFrZU9iamVjdElkRXJyb3IoaW52YWxpZFN0cmluZywgaW5kZXgpIHtcblx0ICB2YXIgaW52YWxpZENoYXJhY3RlciA9IGludmFsaWRTdHJpbmdbaW5kZXhdO1xuXHQgIHJldHVybiBuZXcgVHlwZUVycm9yKFwiT2JqZWN0SWQgc3RyaW5nIFxcXCJcIi5jb25jYXQoaW52YWxpZFN0cmluZywgXCJcXFwiIGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVyIFxcXCJcIikuY29uY2F0KGludmFsaWRDaGFyYWN0ZXIsIFwiXFxcIiB3aXRoIGNoYXJhY3RlciBjb2RlIChcIikuY29uY2F0KGludmFsaWRTdHJpbmcuY2hhckNvZGVBdChpbmRleCksIFwiKS4gQWxsIGNoYXJhY3RlciBjb2RlcyBmb3IgYSBub24taGV4IHN0cmluZyBtdXN0IGJlIGxlc3MgdGhhbiAyNTYuXCIpKTtcblx0fVxuXHQvKipcblx0ICogQSBjbGFzcyByZXByZXNlbnRhdGlvbiBvZiB0aGUgQlNPTiBPYmplY3RJZCB0eXBlLlxuXHQgKi9cblxuXG5cdHZhciBPYmplY3RJZCA9XG5cdC8qI19fUFVSRV9fKi9cblx0ZnVuY3Rpb24gKCkge1xuXHQgIC8qKlxuXHQgICAqIENyZWF0ZSBhbiBPYmplY3RJZCB0eXBlXG5cdCAgICpcblx0ICAgKiBAcGFyYW0geyhzdHJpbmd8QnVmZmVyfG51bWJlcil9IGlkIENhbiBiZSBhIDI0IGJ5dGUgaGV4IHN0cmluZywgMTIgYnl0ZSBiaW5hcnkgQnVmZmVyLCBvciBhIE51bWJlci5cblx0ICAgKiBAcHJvcGVydHkge251bWJlcn0gZ2VuZXJhdGlvblRpbWUgVGhlIGdlbmVyYXRpb24gdGltZSBvZiB0aGlzIE9iamVjdElkIGluc3RhbmNlXG5cdCAgICogQHJldHVybiB7T2JqZWN0SWR9IGluc3RhbmNlIG9mIE9iamVjdElkLlxuXHQgICAqL1xuXHQgIGZ1bmN0aW9uIE9iamVjdElkKGlkKSB7XG5cdCAgICBfY2xhc3NDYWxsQ2hlY2skMih0aGlzLCBPYmplY3RJZCk7XG5cblx0ICAgIC8vIER1Y2stdHlwaW5nIHRvIHN1cHBvcnQgT2JqZWN0SWQgZnJvbSBkaWZmZXJlbnQgbnBtIHBhY2thZ2VzXG5cdCAgICBpZiAoaWQgaW5zdGFuY2VvZiBPYmplY3RJZCkgcmV0dXJuIGlkOyAvLyBUaGUgbW9zdCBjb21tb24gdXNlY2FzZSAoYmxhbmsgaWQsIG5ldyBvYmplY3RJZCBpbnN0YW5jZSlcblxuXHQgICAgaWYgKGlkID09IG51bGwgfHwgdHlwZW9mIGlkID09PSAnbnVtYmVyJykge1xuXHQgICAgICAvLyBHZW5lcmF0ZSBhIG5ldyBpZFxuXHQgICAgICB0aGlzLmlkID0gT2JqZWN0SWQuZ2VuZXJhdGUoaWQpOyAvLyBJZiB3ZSBhcmUgY2FjaGluZyB0aGUgaGV4IHN0cmluZ1xuXG5cdCAgICAgIGlmIChPYmplY3RJZC5jYWNoZUhleFN0cmluZykgdGhpcy5fX2lkID0gdGhpcy50b1N0cmluZygnaGV4Jyk7IC8vIFJldHVybiB0aGUgb2JqZWN0XG5cblx0ICAgICAgcmV0dXJuO1xuXHQgICAgfSAvLyBDaGVjayBpZiB0aGUgcGFzc2VkIGluIGlkIGlzIHZhbGlkXG5cblxuXHQgICAgdmFyIHZhbGlkID0gT2JqZWN0SWQuaXNWYWxpZChpZCk7IC8vIFRocm93IGFuIGVycm9yIGlmIGl0J3Mgbm90IGEgdmFsaWQgc2V0dXBcblxuXHQgICAgaWYgKCF2YWxpZCAmJiBpZCAhPSBudWxsKSB7XG5cdCAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IHBhc3NlZCBpbiBtdXN0IGJlIGEgc2luZ2xlIFN0cmluZyBvZiAxMiBieXRlcyBvciBhIHN0cmluZyBvZiAyNCBoZXggY2hhcmFjdGVycycpO1xuXHQgICAgfSBlbHNlIGlmICh2YWxpZCAmJiB0eXBlb2YgaWQgPT09ICdzdHJpbmcnICYmIGlkLmxlbmd0aCA9PT0gMjQgJiYgaGFzQnVmZmVyVHlwZSkge1xuXHQgICAgICByZXR1cm4gbmV3IE9iamVjdElkKEJ1ZmZlciQxLmZyb20oaWQsICdoZXgnKSk7XG5cdCAgICB9IGVsc2UgaWYgKHZhbGlkICYmIHR5cGVvZiBpZCA9PT0gJ3N0cmluZycgJiYgaWQubGVuZ3RoID09PSAyNCkge1xuXHQgICAgICByZXR1cm4gT2JqZWN0SWQuY3JlYXRlRnJvbUhleFN0cmluZyhpZCk7XG5cdCAgICB9IGVsc2UgaWYgKGlkICE9IG51bGwgJiYgaWQubGVuZ3RoID09PSAxMikge1xuXHQgICAgICAvLyBhc3N1bWUgMTIgYnl0ZSBzdHJpbmdcblx0ICAgICAgdGhpcy5pZCA9IGlkO1xuXHQgICAgfSBlbHNlIGlmIChpZCAhPSBudWxsICYmIGlkLnRvSGV4U3RyaW5nKSB7XG5cdCAgICAgIC8vIER1Y2stdHlwaW5nIHRvIHN1cHBvcnQgT2JqZWN0SWQgZnJvbSBkaWZmZXJlbnQgbnBtIHBhY2thZ2VzXG5cdCAgICAgIHJldHVybiBPYmplY3RJZC5jcmVhdGVGcm9tSGV4U3RyaW5nKGlkLnRvSGV4U3RyaW5nKCkpO1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgcGFzc2VkIGluIG11c3QgYmUgYSBzaW5nbGUgU3RyaW5nIG9mIDEyIGJ5dGVzIG9yIGEgc3RyaW5nIG9mIDI0IGhleCBjaGFyYWN0ZXJzJyk7XG5cdCAgICB9XG5cblx0ICAgIGlmIChPYmplY3RJZC5jYWNoZUhleFN0cmluZykgdGhpcy5fX2lkID0gdGhpcy50b1N0cmluZygnaGV4Jyk7XG5cdCAgfVxuXHQgIC8qKlxuXHQgICAqIFJldHVybiB0aGUgT2JqZWN0SWQgaWQgYXMgYSAyNCBieXRlIGhleCBzdHJpbmcgcmVwcmVzZW50YXRpb25cblx0ICAgKlxuXHQgICAqIEBtZXRob2Rcblx0ICAgKiBAcmV0dXJuIHtzdHJpbmd9IHJldHVybiB0aGUgMjQgYnl0ZSBoZXggc3RyaW5nIHJlcHJlc2VudGF0aW9uLlxuXHQgICAqL1xuXG5cblx0ICBfY3JlYXRlQ2xhc3MkMihPYmplY3RJZCwgW3tcblx0ICAgIGtleTogXCJ0b0hleFN0cmluZ1wiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHRvSGV4U3RyaW5nKCkge1xuXHQgICAgICBpZiAoT2JqZWN0SWQuY2FjaGVIZXhTdHJpbmcgJiYgdGhpcy5fX2lkKSByZXR1cm4gdGhpcy5fX2lkO1xuXHQgICAgICB2YXIgaGV4U3RyaW5nID0gJyc7XG5cblx0ICAgICAgaWYgKCF0aGlzLmlkIHx8ICF0aGlzLmlkLmxlbmd0aCkge1xuXHQgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgT2JqZWN0SWQsIE9iamVjdElkLmlkIG11c3QgYmUgZWl0aGVyIGEgc3RyaW5nIG9yIGEgQnVmZmVyLCBidXQgaXMgWycgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmlkKSArICddJyk7XG5cdCAgICAgIH1cblxuXHQgICAgICBpZiAodGhpcy5pZCBpbnN0YW5jZW9mIF9CdWZmZXIpIHtcblx0ICAgICAgICBoZXhTdHJpbmcgPSBjb252ZXJ0VG9IZXgodGhpcy5pZCk7XG5cdCAgICAgICAgaWYgKE9iamVjdElkLmNhY2hlSGV4U3RyaW5nKSB0aGlzLl9faWQgPSBoZXhTdHJpbmc7XG5cdCAgICAgICAgcmV0dXJuIGhleFN0cmluZztcblx0ICAgICAgfVxuXG5cdCAgICAgIGZvciAodmFyIF9pMiA9IDA7IF9pMiA8IHRoaXMuaWQubGVuZ3RoOyBfaTIrKykge1xuXHQgICAgICAgIHZhciBoZXhDaGFyID0gaGV4VGFibGVbdGhpcy5pZC5jaGFyQ29kZUF0KF9pMildO1xuXG5cdCAgICAgICAgaWYgKHR5cGVvZiBoZXhDaGFyICE9PSAnc3RyaW5nJykge1xuXHQgICAgICAgICAgdGhyb3cgbWFrZU9iamVjdElkRXJyb3IodGhpcy5pZCwgX2kyKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBoZXhTdHJpbmcgKz0gaGV4Q2hhcjtcblx0ICAgICAgfVxuXG5cdCAgICAgIGlmIChPYmplY3RJZC5jYWNoZUhleFN0cmluZykgdGhpcy5fX2lkID0gaGV4U3RyaW5nO1xuXHQgICAgICByZXR1cm4gaGV4U3RyaW5nO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBVcGRhdGUgdGhlIE9iamVjdElkIGluZGV4IHVzZWQgaW4gZ2VuZXJhdGluZyBuZXcgT2JqZWN0SWQncyBvbiB0aGUgZHJpdmVyXG5cdCAgICAgKlxuXHQgICAgICogQG1ldGhvZFxuXHQgICAgICogQHJldHVybiB7bnVtYmVyfSByZXR1cm5zIG5leHQgaW5kZXggdmFsdWUuXG5cdCAgICAgKiBAaWdub3JlXG5cdCAgICAgKi9cblxuXHQgIH0sIHtcblx0ICAgIGtleTogXCJ0b1N0cmluZ1wiLFxuXG5cdCAgICAvKipcblx0ICAgICAqIENvbnZlcnRzIHRoZSBpZCBpbnRvIGEgMjQgYnl0ZSBoZXggc3RyaW5nIGZvciBwcmludGluZ1xuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSB7U3RyaW5nfSBmb3JtYXQgVGhlIEJ1ZmZlciB0b1N0cmluZyBmb3JtYXQgcGFyYW1ldGVyLlxuXHQgICAgICogQHJldHVybiB7U3RyaW5nfSByZXR1cm4gdGhlIDI0IGJ5dGUgaGV4IHN0cmluZyByZXByZXNlbnRhdGlvbi5cblx0ICAgICAqIEBpZ25vcmVcblx0ICAgICAqL1xuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHRvU3RyaW5nKGZvcm1hdCkge1xuXHQgICAgICAvLyBJcyB0aGUgaWQgYSBidWZmZXIgdGhlbiB1c2UgdGhlIGJ1ZmZlciB0b1N0cmluZyBtZXRob2QgdG8gcmV0dXJuIHRoZSBmb3JtYXRcblx0ICAgICAgaWYgKHRoaXMuaWQgJiYgdGhpcy5pZC5jb3B5KSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuaWQudG9TdHJpbmcodHlwZW9mIGZvcm1hdCA9PT0gJ3N0cmluZycgPyBmb3JtYXQgOiAnaGV4Jyk7XG5cdCAgICAgIH1cblxuXHQgICAgICByZXR1cm4gdGhpcy50b0hleFN0cmluZygpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBDb252ZXJ0cyB0byBpdHMgSlNPTiByZXByZXNlbnRhdGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAcmV0dXJuIHtTdHJpbmd9IHJldHVybiB0aGUgMjQgYnl0ZSBoZXggc3RyaW5nIHJlcHJlc2VudGF0aW9uLlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwidG9KU09OXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gdG9KU09OKCkge1xuXHQgICAgICByZXR1cm4gdGhpcy50b0hleFN0cmluZygpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBDb21wYXJlcyB0aGUgZXF1YWxpdHkgb2YgdGhpcyBPYmplY3RJZCB3aXRoIGBvdGhlcklEYC5cblx0ICAgICAqXG5cdCAgICAgKiBAbWV0aG9kXG5cdCAgICAgKiBAcGFyYW0ge29iamVjdH0gb3RoZXJJZCBPYmplY3RJZCBpbnN0YW5jZSB0byBjb21wYXJlIGFnYWluc3QuXG5cdCAgICAgKiBAcmV0dXJuIHtib29sZWFufSB0aGUgcmVzdWx0IG9mIGNvbXBhcmluZyB0d28gT2JqZWN0SWQnc1xuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwiZXF1YWxzXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gZXF1YWxzKG90aGVySWQpIHtcblx0ICAgICAgaWYgKG90aGVySWQgaW5zdGFuY2VvZiBPYmplY3RJZCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLnRvU3RyaW5nKCkgPT09IG90aGVySWQudG9TdHJpbmcoKTtcblx0ICAgICAgfVxuXG5cdCAgICAgIGlmICh0eXBlb2Ygb3RoZXJJZCA9PT0gJ3N0cmluZycgJiYgT2JqZWN0SWQuaXNWYWxpZChvdGhlcklkKSAmJiBvdGhlcklkLmxlbmd0aCA9PT0gMTIgJiYgdGhpcy5pZCBpbnN0YW5jZW9mIF9CdWZmZXIpIHtcblx0ICAgICAgICByZXR1cm4gb3RoZXJJZCA9PT0gdGhpcy5pZC50b1N0cmluZygnYmluYXJ5Jyk7XG5cdCAgICAgIH1cblxuXHQgICAgICBpZiAodHlwZW9mIG90aGVySWQgPT09ICdzdHJpbmcnICYmIE9iamVjdElkLmlzVmFsaWQob3RoZXJJZCkgJiYgb3RoZXJJZC5sZW5ndGggPT09IDI0KSB7XG5cdCAgICAgICAgcmV0dXJuIG90aGVySWQudG9Mb3dlckNhc2UoKSA9PT0gdGhpcy50b0hleFN0cmluZygpO1xuXHQgICAgICB9XG5cblx0ICAgICAgaWYgKHR5cGVvZiBvdGhlcklkID09PSAnc3RyaW5nJyAmJiBPYmplY3RJZC5pc1ZhbGlkKG90aGVySWQpICYmIG90aGVySWQubGVuZ3RoID09PSAxMikge1xuXHQgICAgICAgIHJldHVybiBvdGhlcklkID09PSB0aGlzLmlkO1xuXHQgICAgICB9XG5cblx0ICAgICAgaWYgKG90aGVySWQgIT0gbnVsbCAmJiAob3RoZXJJZCBpbnN0YW5jZW9mIE9iamVjdElkIHx8IG90aGVySWQudG9IZXhTdHJpbmcpKSB7XG5cdCAgICAgICAgcmV0dXJuIG90aGVySWQudG9IZXhTdHJpbmcoKSA9PT0gdGhpcy50b0hleFN0cmluZygpO1xuXHQgICAgICB9XG5cblx0ICAgICAgcmV0dXJuIGZhbHNlO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXR1cm5zIHRoZSBnZW5lcmF0aW9uIGRhdGUgKGFjY3VyYXRlIHVwIHRvIHRoZSBzZWNvbmQpIHRoYXQgdGhpcyBJRCB3YXMgZ2VuZXJhdGVkLlxuXHQgICAgICpcblx0ICAgICAqIEBtZXRob2Rcblx0ICAgICAqIEByZXR1cm4ge0RhdGV9IHRoZSBnZW5lcmF0aW9uIGRhdGVcblx0ICAgICAqL1xuXG5cdCAgfSwge1xuXHQgICAga2V5OiBcImdldFRpbWVzdGFtcFwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIGdldFRpbWVzdGFtcCgpIHtcblx0ICAgICAgdmFyIHRpbWVzdGFtcCA9IG5ldyBEYXRlKCk7XG5cdCAgICAgIHZhciB0aW1lID0gdGhpcy5pZC5yZWFkVUludDMyQkUoMCk7XG5cdCAgICAgIHRpbWVzdGFtcC5zZXRUaW1lKE1hdGguZmxvb3IodGltZSkgKiAxMDAwKTtcblx0ICAgICAgcmV0dXJuIHRpbWVzdGFtcDtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwidG9FeHRlbmRlZEpTT05cIixcblxuXHQgICAgLyoqXG5cdCAgICAgKiBAaWdub3JlXG5cdCAgICAgKi9cblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB0b0V4dGVuZGVkSlNPTigpIHtcblx0ICAgICAgaWYgKHRoaXMudG9IZXhTdHJpbmcpIHJldHVybiB7XG5cdCAgICAgICAgJG9pZDogdGhpcy50b0hleFN0cmluZygpXG5cdCAgICAgIH07XG5cdCAgICAgIHJldHVybiB7XG5cdCAgICAgICAgJG9pZDogdGhpcy50b1N0cmluZygnaGV4Jylcblx0ICAgICAgfTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9XSwgW3tcblx0ICAgIGtleTogXCJnZXRJbmNcIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRJbmMoKSB7XG5cdCAgICAgIHJldHVybiBPYmplY3RJZC5pbmRleCA9IChPYmplY3RJZC5pbmRleCArIDEpICUgMHhmZmZmZmY7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEdlbmVyYXRlIGEgMTIgYnl0ZSBpZCBidWZmZXIgdXNlZCBpbiBPYmplY3RJZCdzXG5cdCAgICAgKlxuXHQgICAgICogQG1ldGhvZFxuXHQgICAgICogQHBhcmFtIHtudW1iZXJ9IFt0aW1lXSBvcHRpb25hbCBwYXJhbWV0ZXIgYWxsb3dpbmcgdG8gcGFzcyBpbiBhIHNlY29uZCBiYXNlZCB0aW1lc3RhbXAuXG5cdCAgICAgKiBAcmV0dXJuIHtCdWZmZXJ9IHJldHVybiB0aGUgMTIgYnl0ZSBpZCBidWZmZXIgc3RyaW5nLlxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwiZ2VuZXJhdGVcIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBnZW5lcmF0ZSh0aW1lKSB7XG5cdCAgICAgIGlmICgnbnVtYmVyJyAhPT0gdHlwZW9mIHRpbWUpIHtcblx0ICAgICAgICB0aW1lID0gfn4oRGF0ZS5ub3coKSAvIDEwMDApO1xuXHQgICAgICB9XG5cblx0ICAgICAgdmFyIGluYyA9IE9iamVjdElkLmdldEluYygpO1xuXHQgICAgICB2YXIgYnVmZmVyJCQxID0gQnVmZmVyJDEuYWxsb2MoMTIpOyAvLyA0LWJ5dGUgdGltZXN0YW1wXG5cblx0ICAgICAgYnVmZmVyJCQxWzNdID0gdGltZSAmIDB4ZmY7XG5cdCAgICAgIGJ1ZmZlciQkMVsyXSA9IHRpbWUgPj4gOCAmIDB4ZmY7XG5cdCAgICAgIGJ1ZmZlciQkMVsxXSA9IHRpbWUgPj4gMTYgJiAweGZmO1xuXHQgICAgICBidWZmZXIkJDFbMF0gPSB0aW1lID4+IDI0ICYgMHhmZjsgLy8gNS1ieXRlIHByb2Nlc3MgdW5pcXVlXG5cblx0ICAgICAgYnVmZmVyJCQxWzRdID0gUFJPQ0VTU19VTklRVUVbMF07XG5cdCAgICAgIGJ1ZmZlciQkMVs1XSA9IFBST0NFU1NfVU5JUVVFWzFdO1xuXHQgICAgICBidWZmZXIkJDFbNl0gPSBQUk9DRVNTX1VOSVFVRVsyXTtcblx0ICAgICAgYnVmZmVyJCQxWzddID0gUFJPQ0VTU19VTklRVUVbM107XG5cdCAgICAgIGJ1ZmZlciQkMVs4XSA9IFBST0NFU1NfVU5JUVVFWzRdOyAvLyAzLWJ5dGUgY291bnRlclxuXG5cdCAgICAgIGJ1ZmZlciQkMVsxMV0gPSBpbmMgJiAweGZmO1xuXHQgICAgICBidWZmZXIkJDFbMTBdID0gaW5jID4+IDggJiAweGZmO1xuXHQgICAgICBidWZmZXIkJDFbOV0gPSBpbmMgPj4gMTYgJiAweGZmO1xuXHQgICAgICByZXR1cm4gYnVmZmVyJCQxO1xuXHQgICAgfVxuXHQgIH0sIHtcblx0ICAgIGtleTogXCJjcmVhdGVQa1wiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIGNyZWF0ZVBrKCkge1xuXHQgICAgICByZXR1cm4gbmV3IE9iamVjdElkKCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIENyZWF0ZXMgYW4gT2JqZWN0SWQgZnJvbSBhIHNlY29uZCBiYXNlZCBudW1iZXIsIHdpdGggdGhlIHJlc3Qgb2YgdGhlIE9iamVjdElkIHplcm9lZCBvdXQuIFVzZWQgZm9yIGNvbXBhcmlzb25zIG9yIHNvcnRpbmcgdGhlIE9iamVjdElkLlxuXHQgICAgICpcblx0ICAgICAqIEBtZXRob2Rcblx0ICAgICAqIEBwYXJhbSB7bnVtYmVyfSB0aW1lIGFuIGludGVnZXIgbnVtYmVyIHJlcHJlc2VudGluZyBhIG51bWJlciBvZiBzZWNvbmRzLlxuXHQgICAgICogQHJldHVybiB7T2JqZWN0SWR9IHJldHVybiB0aGUgY3JlYXRlZCBPYmplY3RJZFxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwiY3JlYXRlRnJvbVRpbWVcIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBjcmVhdGVGcm9tVGltZSh0aW1lKSB7XG5cdCAgICAgIHZhciBidWZmZXIkJDEgPSBCdWZmZXIkMS5mcm9tKFswLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwXSk7IC8vIEVuY29kZSB0aW1lIGludG8gZmlyc3QgNCBieXRlc1xuXG5cdCAgICAgIGJ1ZmZlciQkMVszXSA9IHRpbWUgJiAweGZmO1xuXHQgICAgICBidWZmZXIkJDFbMl0gPSB0aW1lID4+IDggJiAweGZmO1xuXHQgICAgICBidWZmZXIkJDFbMV0gPSB0aW1lID4+IDE2ICYgMHhmZjtcblx0ICAgICAgYnVmZmVyJCQxWzBdID0gdGltZSA+PiAyNCAmIDB4ZmY7IC8vIFJldHVybiB0aGUgbmV3IG9iamVjdElkXG5cblx0ICAgICAgcmV0dXJuIG5ldyBPYmplY3RJZChidWZmZXIkJDEpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBDcmVhdGVzIGFuIE9iamVjdElkIGZyb20gYSBoZXggc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGFuIE9iamVjdElkLlxuXHQgICAgICpcblx0ICAgICAqIEBtZXRob2Rcblx0ICAgICAqIEBwYXJhbSB7c3RyaW5nfSBoZXhTdHJpbmcgY3JlYXRlIGEgT2JqZWN0SWQgZnJvbSBhIHBhc3NlZCBpbiAyNCBieXRlIGhleHN0cmluZy5cblx0ICAgICAqIEByZXR1cm4ge09iamVjdElkfSByZXR1cm4gdGhlIGNyZWF0ZWQgT2JqZWN0SWRcblx0ICAgICAqL1xuXG5cdCAgfSwge1xuXHQgICAga2V5OiBcImNyZWF0ZUZyb21IZXhTdHJpbmdcIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBjcmVhdGVGcm9tSGV4U3RyaW5nKHN0cmluZykge1xuXHQgICAgICAvLyBUaHJvdyBhbiBlcnJvciBpZiBpdCdzIG5vdCBhIHZhbGlkIHNldHVwXG5cdCAgICAgIGlmICh0eXBlb2Ygc3RyaW5nID09PSAndW5kZWZpbmVkJyB8fCBzdHJpbmcgIT0gbnVsbCAmJiBzdHJpbmcubGVuZ3RoICE9PSAyNCkge1xuXHQgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IHBhc3NlZCBpbiBtdXN0IGJlIGEgc2luZ2xlIFN0cmluZyBvZiAxMiBieXRlcyBvciBhIHN0cmluZyBvZiAyNCBoZXggY2hhcmFjdGVycycpO1xuXHQgICAgICB9IC8vIFVzZSBCdWZmZXIuZnJvbSBtZXRob2QgaWYgYXZhaWxhYmxlXG5cblxuXHQgICAgICBpZiAoaGFzQnVmZmVyVHlwZSkgcmV0dXJuIG5ldyBPYmplY3RJZChCdWZmZXIkMS5mcm9tKHN0cmluZywgJ2hleCcpKTsgLy8gQ2FsY3VsYXRlIGxlbmd0aHNcblxuXHQgICAgICB2YXIgYXJyYXkgPSBuZXcgX0J1ZmZlcigxMik7XG5cdCAgICAgIHZhciBuID0gMDtcblx0ICAgICAgdmFyIGkgPSAwO1xuXG5cdCAgICAgIHdoaWxlIChpIDwgMjQpIHtcblx0ICAgICAgICBhcnJheVtuKytdID0gZGVjb2RlTG9va3VwW3N0cmluZy5jaGFyQ29kZUF0KGkrKyldIDw8IDQgfCBkZWNvZGVMb29rdXBbc3RyaW5nLmNoYXJDb2RlQXQoaSsrKV07XG5cdCAgICAgIH1cblxuXHQgICAgICByZXR1cm4gbmV3IE9iamVjdElkKGFycmF5KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQ2hlY2tzIGlmIGEgdmFsdWUgaXMgYSB2YWxpZCBic29uIE9iamVjdElkXG5cdCAgICAgKlxuXHQgICAgICogQG1ldGhvZFxuXHQgICAgICogQHJldHVybiB7Ym9vbGVhbn0gcmV0dXJuIHRydWUgaWYgdGhlIHZhbHVlIGlzIGEgdmFsaWQgYnNvbiBPYmplY3RJZCwgcmV0dXJuIGZhbHNlIG90aGVyd2lzZS5cblx0ICAgICAqL1xuXG5cdCAgfSwge1xuXHQgICAga2V5OiBcImlzVmFsaWRcIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBpc1ZhbGlkKGlkKSB7XG5cdCAgICAgIGlmIChpZCA9PSBudWxsKSByZXR1cm4gZmFsc2U7XG5cblx0ICAgICAgaWYgKHR5cGVvZiBpZCA9PT0gJ251bWJlcicpIHtcblx0ICAgICAgICByZXR1cm4gdHJ1ZTtcblx0ICAgICAgfVxuXG5cdCAgICAgIGlmICh0eXBlb2YgaWQgPT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgcmV0dXJuIGlkLmxlbmd0aCA9PT0gMTIgfHwgaWQubGVuZ3RoID09PSAyNCAmJiBjaGVja0ZvckhleFJlZ0V4cC50ZXN0KGlkKTtcblx0ICAgICAgfVxuXG5cdCAgICAgIGlmIChpZCBpbnN0YW5jZW9mIE9iamVjdElkKSB7XG5cdCAgICAgICAgcmV0dXJuIHRydWU7XG5cdCAgICAgIH1cblxuXHQgICAgICBpZiAoaWQgaW5zdGFuY2VvZiBfQnVmZmVyICYmIGlkLmxlbmd0aCA9PT0gMTIpIHtcblx0ICAgICAgICByZXR1cm4gdHJ1ZTtcblx0ICAgICAgfSAvLyBEdWNrLVR5cGluZyBkZXRlY3Rpb24gb2YgT2JqZWN0SWQgbGlrZSBvYmplY3RzXG5cblxuXHQgICAgICBpZiAoaWQudG9IZXhTdHJpbmcpIHtcblx0ICAgICAgICByZXR1cm4gaWQuaWQubGVuZ3RoID09PSAxMiB8fCBpZC5pZC5sZW5ndGggPT09IDI0ICYmIGNoZWNrRm9ySGV4UmVnRXhwLnRlc3QoaWQuaWQpO1xuXHQgICAgICB9XG5cblx0ICAgICAgcmV0dXJuIGZhbHNlO1xuXHQgICAgfVxuXHQgIH0sIHtcblx0ICAgIGtleTogXCJmcm9tRXh0ZW5kZWRKU09OXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gZnJvbUV4dGVuZGVkSlNPTihkb2MpIHtcblx0ICAgICAgcmV0dXJuIG5ldyBPYmplY3RJZChkb2MuJG9pZCk7XG5cdCAgICB9XG5cdCAgfV0pO1xuXG5cdCAgcmV0dXJuIE9iamVjdElkO1xuXHR9KCk7IC8vIERlcHJlY2F0ZWQgbWV0aG9kc1xuXG5cblx0T2JqZWN0SWQuZ2V0X2luYyA9IGRlcHJlY2F0ZSQxKGZ1bmN0aW9uICgpIHtcblx0ICByZXR1cm4gT2JqZWN0SWQuZ2V0SW5jKCk7XG5cdH0sICdQbGVhc2UgdXNlIHRoZSBzdGF0aWMgYE9iamVjdElkLmdldEluYygpYCBpbnN0ZWFkJyk7XG5cdE9iamVjdElkLnByb3RvdHlwZS5nZXRfaW5jID0gZGVwcmVjYXRlJDEoZnVuY3Rpb24gKCkge1xuXHQgIHJldHVybiBPYmplY3RJZC5nZXRJbmMoKTtcblx0fSwgJ1BsZWFzZSB1c2UgdGhlIHN0YXRpYyBgT2JqZWN0SWQuZ2V0SW5jKClgIGluc3RlYWQnKTtcblx0T2JqZWN0SWQucHJvdG90eXBlLmdldEluYyA9IGRlcHJlY2F0ZSQxKGZ1bmN0aW9uICgpIHtcblx0ICByZXR1cm4gT2JqZWN0SWQuZ2V0SW5jKCk7XG5cdH0sICdQbGVhc2UgdXNlIHRoZSBzdGF0aWMgYE9iamVjdElkLmdldEluYygpYCBpbnN0ZWFkJyk7XG5cdE9iamVjdElkLnByb3RvdHlwZS5nZW5lcmF0ZSA9IGRlcHJlY2F0ZSQxKGZ1bmN0aW9uICh0aW1lKSB7XG5cdCAgcmV0dXJuIE9iamVjdElkLmdlbmVyYXRlKHRpbWUpO1xuXHR9LCAnUGxlYXNlIHVzZSB0aGUgc3RhdGljIGBPYmplY3RJZC5nZW5lcmF0ZSh0aW1lKWAgaW5zdGVhZCcpO1xuXHQvKipcblx0ICogQGlnbm9yZVxuXHQgKi9cblxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoT2JqZWN0SWQucHJvdG90eXBlLCAnZ2VuZXJhdGlvblRpbWUnLCB7XG5cdCAgZW51bWVyYWJsZTogdHJ1ZSxcblx0ICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcblx0ICAgIHJldHVybiB0aGlzLmlkWzNdIHwgdGhpcy5pZFsyXSA8PCA4IHwgdGhpcy5pZFsxXSA8PCAxNiB8IHRoaXMuaWRbMF0gPDwgMjQ7XG5cdCAgfSxcblx0ICBzZXQ6IGZ1bmN0aW9uIHNldCh2YWx1ZSkge1xuXHQgICAgLy8gRW5jb2RlIHRpbWUgaW50byBmaXJzdCA0IGJ5dGVzXG5cdCAgICB0aGlzLmlkWzNdID0gdmFsdWUgJiAweGZmO1xuXHQgICAgdGhpcy5pZFsyXSA9IHZhbHVlID4+IDggJiAweGZmO1xuXHQgICAgdGhpcy5pZFsxXSA9IHZhbHVlID4+IDE2ICYgMHhmZjtcblx0ICAgIHRoaXMuaWRbMF0gPSB2YWx1ZSA+PiAyNCAmIDB4ZmY7XG5cdCAgfVxuXHR9KTtcblx0LyoqXG5cdCAqIENvbnZlcnRzIHRvIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgSWQuXG5cdCAqXG5cdCAqIEByZXR1cm4ge1N0cmluZ30gcmV0dXJuIHRoZSAyNCBieXRlIGhleCBzdHJpbmcgcmVwcmVzZW50YXRpb24uXG5cdCAqIEBpZ25vcmVcblx0ICovXG5cblx0T2JqZWN0SWQucHJvdG90eXBlW3V0aWwkMi5pbnNwZWN0LmN1c3RvbSB8fCAnaW5zcGVjdCddID0gT2JqZWN0SWQucHJvdG90eXBlLnRvU3RyaW5nO1xuXHQvKipcblx0ICogQGlnbm9yZVxuXHQgKi9cblxuXHRPYmplY3RJZC5pbmRleCA9IH5+KE1hdGgucmFuZG9tKCkgKiAweGZmZmZmZik7IC8vIEluIDQuMC4wIGFuZCA0LjAuMSwgdGhpcyBwcm9wZXJ0eSBuYW1lIHdhcyBjaGFuZ2VkIHRvIE9iamVjdElkIHRvIG1hdGNoIHRoZSBjbGFzcyBuYW1lLlxuXHQvLyBUaGlzIGNhdXNlZCBpbnRlcm9wZXJhYmlsaXR5IHByb2JsZW1zIHdpdGggcHJldmlvdXMgdmVyc2lvbnMgb2YgdGhlIGxpYnJhcnksIHNvIGluXG5cdC8vIGxhdGVyIGJ1aWxkcyB3ZSBjaGFuZ2VkIGl0IGJhY2sgdG8gT2JqZWN0SUQgKGNhcGl0YWwgRCkgdG8gbWF0Y2ggbGVnYWN5IGltcGxlbWVudGF0aW9ucy5cblxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoT2JqZWN0SWQucHJvdG90eXBlLCAnX2Jzb250eXBlJywge1xuXHQgIHZhbHVlOiAnT2JqZWN0SUQnXG5cdH0pO1xuXHR2YXIgb2JqZWN0aWQgPSBPYmplY3RJZDtcblxuXHRmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2skMyhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cblx0ZnVuY3Rpb24gX2RlZmluZVByb3BlcnRpZXMkMyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9XG5cblx0ZnVuY3Rpb24gX2NyZWF0ZUNsYXNzJDMoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyQzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgX2RlZmluZVByb3BlcnRpZXMkMyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH1cblxuXHRmdW5jdGlvbiBhbHBoYWJldGl6ZShzdHIpIHtcblx0ICByZXR1cm4gc3RyLnNwbGl0KCcnKS5zb3J0KCkuam9pbignJyk7XG5cdH1cblx0LyoqXG5cdCAqIEEgY2xhc3MgcmVwcmVzZW50YXRpb24gb2YgdGhlIEJTT04gUmVnRXhwIHR5cGUuXG5cdCAqL1xuXG5cblx0dmFyIEJTT05SZWdFeHAgPVxuXHQvKiNfX1BVUkVfXyovXG5cdGZ1bmN0aW9uICgpIHtcblx0ICAvKipcblx0ICAgKiBDcmVhdGUgYSBSZWdFeHAgdHlwZVxuXHQgICAqXG5cdCAgICogQHBhcmFtIHtzdHJpbmd9IHBhdHRlcm4gVGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiBwYXR0ZXJuIHRvIG1hdGNoXG5cdCAgICogQHBhcmFtIHtzdHJpbmd9IG9wdGlvbnMgVGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiBvcHRpb25zXG5cdCAgICovXG5cdCAgZnVuY3Rpb24gQlNPTlJlZ0V4cChwYXR0ZXJuLCBvcHRpb25zKSB7XG5cdCAgICBfY2xhc3NDYWxsQ2hlY2skMyh0aGlzLCBCU09OUmVnRXhwKTtcblxuXHQgICAgLy8gRXhlY3V0ZVxuXHQgICAgdGhpcy5wYXR0ZXJuID0gcGF0dGVybiB8fCAnJztcblx0ICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnMgPyBhbHBoYWJldGl6ZShvcHRpb25zKSA6ICcnOyAvLyBWYWxpZGF0ZSBvcHRpb25zXG5cblx0ICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5vcHRpb25zLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgIGlmICghKHRoaXMub3B0aW9uc1tpXSA9PT0gJ2knIHx8IHRoaXMub3B0aW9uc1tpXSA9PT0gJ20nIHx8IHRoaXMub3B0aW9uc1tpXSA9PT0gJ3gnIHx8IHRoaXMub3B0aW9uc1tpXSA9PT0gJ2wnIHx8IHRoaXMub3B0aW9uc1tpXSA9PT0gJ3MnIHx8IHRoaXMub3B0aW9uc1tpXSA9PT0gJ3UnKSkge1xuXHQgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSByZWd1bGFyIGV4cHJlc3Npb24gb3B0aW9uIFtcIi5jb25jYXQodGhpcy5vcHRpb25zW2ldLCBcIl0gaXMgbm90IHN1cHBvcnRlZFwiKSk7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9XG5cdCAgLyoqXG5cdCAgICogQGlnbm9yZVxuXHQgICAqL1xuXG5cblx0ICBfY3JlYXRlQ2xhc3MkMyhCU09OUmVnRXhwLCBbe1xuXHQgICAga2V5OiBcInRvRXh0ZW5kZWRKU09OXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gdG9FeHRlbmRlZEpTT04oKSB7XG5cdCAgICAgIHJldHVybiB7XG5cdCAgICAgICAgJHJlZ3VsYXJFeHByZXNzaW9uOiB7XG5cdCAgICAgICAgICBwYXR0ZXJuOiB0aGlzLnBhdHRlcm4sXG5cdCAgICAgICAgICBvcHRpb25zOiB0aGlzLm9wdGlvbnNcblx0ICAgICAgICB9XG5cdCAgICAgIH07XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEBpZ25vcmVcblx0ICAgICAqL1xuXG5cdCAgfV0sIFt7XG5cdCAgICBrZXk6IFwiZnJvbUV4dGVuZGVkSlNPTlwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIGZyb21FeHRlbmRlZEpTT04oZG9jKSB7XG5cdCAgICAgIHJldHVybiBuZXcgQlNPTlJlZ0V4cChkb2MuJHJlZ3VsYXJFeHByZXNzaW9uLnBhdHRlcm4sIGRvYy4kcmVndWxhckV4cHJlc3Npb24ub3B0aW9ucy5zcGxpdCgnJykuc29ydCgpLmpvaW4oJycpKTtcblx0ICAgIH1cblx0ICB9XSk7XG5cblx0ICByZXR1cm4gQlNPTlJlZ0V4cDtcblx0fSgpO1xuXG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShCU09OUmVnRXhwLnByb3RvdHlwZSwgJ19ic29udHlwZScsIHtcblx0ICB2YWx1ZTogJ0JTT05SZWdFeHAnXG5cdH0pO1xuXHR2YXIgcmVnZXhwID0gQlNPTlJlZ0V4cDtcblxuXHQvKipcblx0ICogQSBjbGFzcyByZXByZXNlbnRhdGlvbiBvZiB0aGUgQlNPTiBTeW1ib2wgdHlwZS5cblx0ICovXG5cblx0ZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrJDQoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG5cdGZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzJDQodGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfVxuXG5cdGZ1bmN0aW9uIF9jcmVhdGVDbGFzcyQ0KENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgX2RlZmluZVByb3BlcnRpZXMkNChDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzJDQoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9XG5cblx0dmFyIEJTT05TeW1ib2wgPVxuXHQvKiNfX1BVUkVfXyovXG5cdGZ1bmN0aW9uICgpIHtcblx0ICAvKipcblx0ICAgKiBDcmVhdGUgYSBTeW1ib2wgdHlwZVxuXHQgICAqXG5cdCAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIHRoZSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBzeW1ib2wuXG5cdCAgICovXG5cdCAgZnVuY3Rpb24gQlNPTlN5bWJvbCh2YWx1ZSkge1xuXHQgICAgX2NsYXNzQ2FsbENoZWNrJDQodGhpcywgQlNPTlN5bWJvbCk7XG5cblx0ICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcblx0ICB9XG5cdCAgLyoqXG5cdCAgICogQWNjZXNzIHRoZSB3cmFwcGVkIHN0cmluZyB2YWx1ZS5cblx0ICAgKlxuXHQgICAqIEBtZXRob2Rcblx0ICAgKiBAcmV0dXJuIHtTdHJpbmd9IHJldHVybnMgdGhlIHdyYXBwZWQgc3RyaW5nLlxuXHQgICAqL1xuXG5cblx0ICBfY3JlYXRlQ2xhc3MkNChCU09OU3ltYm9sLCBbe1xuXHQgICAga2V5OiBcInZhbHVlT2ZcIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB2YWx1ZU9mKCkge1xuXHQgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwidG9TdHJpbmdcIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB0b1N0cmluZygpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEBpZ25vcmVcblx0ICAgICAqL1xuXG5cdCAgfSwge1xuXHQgICAga2V5OiBcImluc3BlY3RcIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBpbnNwZWN0KCkge1xuXHQgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwidG9KU09OXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gdG9KU09OKCkge1xuXHQgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwidG9FeHRlbmRlZEpTT05cIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB0b0V4dGVuZGVkSlNPTigpIHtcblx0ICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAkc3ltYm9sOiB0aGlzLnZhbHVlXG5cdCAgICAgIH07XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEBpZ25vcmVcblx0ICAgICAqL1xuXG5cdCAgfV0sIFt7XG5cdCAgICBrZXk6IFwiZnJvbUV4dGVuZGVkSlNPTlwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIGZyb21FeHRlbmRlZEpTT04oZG9jKSB7XG5cdCAgICAgIHJldHVybiBuZXcgQlNPTlN5bWJvbChkb2MuJHN5bWJvbCk7XG5cdCAgICB9XG5cdCAgfV0pO1xuXG5cdCAgcmV0dXJuIEJTT05TeW1ib2w7XG5cdH0oKTtcblxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoQlNPTlN5bWJvbC5wcm90b3R5cGUsICdfYnNvbnR5cGUnLCB7XG5cdCAgdmFsdWU6ICdTeW1ib2wnXG5cdH0pO1xuXHR2YXIgc3ltYm9sID0gQlNPTlN5bWJvbDtcblxuXHQvKipcblx0ICogQSBjbGFzcyByZXByZXNlbnRhdGlvbiBvZiBhIEJTT04gSW50MzIgdHlwZS5cblx0ICovXG5cblx0ZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrJDUoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG5cdGZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzJDUodGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfVxuXG5cdGZ1bmN0aW9uIF9jcmVhdGVDbGFzcyQ1KENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgX2RlZmluZVByb3BlcnRpZXMkNShDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzJDUoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9XG5cblx0dmFyIEludDMyID1cblx0LyojX19QVVJFX18qL1xuXHRmdW5jdGlvbiAoKSB7XG5cdCAgLyoqXG5cdCAgICogQ3JlYXRlIGFuIEludDMyIHR5cGVcblx0ICAgKlxuXHQgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSB0aGUgbnVtYmVyIHdlIHdhbnQgdG8gcmVwcmVzZW50IGFzIGFuIGludDMyLlxuXHQgICAqIEByZXR1cm4ge0ludDMyfVxuXHQgICAqL1xuXHQgIGZ1bmN0aW9uIEludDMyKHZhbHVlKSB7XG5cdCAgICBfY2xhc3NDYWxsQ2hlY2skNSh0aGlzLCBJbnQzMik7XG5cblx0ICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcblx0ICB9XG5cdCAgLyoqXG5cdCAgICogQWNjZXNzIHRoZSBudW1iZXIgdmFsdWUuXG5cdCAgICpcblx0ICAgKiBAbWV0aG9kXG5cdCAgICogQHJldHVybiB7bnVtYmVyfSByZXR1cm5zIHRoZSB3cmFwcGVkIGludDMyIG51bWJlci5cblx0ICAgKi9cblxuXG5cdCAgX2NyZWF0ZUNsYXNzJDUoSW50MzIsIFt7XG5cdCAgICBrZXk6IFwidmFsdWVPZlwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHZhbHVlT2YoKSB7XG5cdCAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBAaWdub3JlXG5cdCAgICAgKi9cblxuXHQgIH0sIHtcblx0ICAgIGtleTogXCJ0b0pTT05cIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB0b0pTT04oKSB7XG5cdCAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBAaWdub3JlXG5cdCAgICAgKi9cblxuXHQgIH0sIHtcblx0ICAgIGtleTogXCJ0b0V4dGVuZGVkSlNPTlwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHRvRXh0ZW5kZWRKU09OKG9wdGlvbnMpIHtcblx0ICAgICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5yZWxheGVkKSByZXR1cm4gdGhpcy52YWx1ZTtcblx0ICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAkbnVtYmVySW50OiB0aGlzLnZhbHVlLnRvU3RyaW5nKClcblx0ICAgICAgfTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9XSwgW3tcblx0ICAgIGtleTogXCJmcm9tRXh0ZW5kZWRKU09OXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gZnJvbUV4dGVuZGVkSlNPTihkb2MsIG9wdGlvbnMpIHtcblx0ICAgICAgcmV0dXJuIG9wdGlvbnMgJiYgb3B0aW9ucy5yZWxheGVkID8gcGFyc2VJbnQoZG9jLiRudW1iZXJJbnQsIDEwKSA6IG5ldyBJbnQzMihkb2MuJG51bWJlckludCk7XG5cdCAgICB9XG5cdCAgfV0pO1xuXG5cdCAgcmV0dXJuIEludDMyO1xuXHR9KCk7XG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KEludDMyLnByb3RvdHlwZSwgJ19ic29udHlwZScsIHtcblx0ICB2YWx1ZTogJ0ludDMyJ1xuXHR9KTtcblx0dmFyIGludF8zMiA9IEludDMyO1xuXG5cdC8qKlxuXHQgKiBBIGNsYXNzIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBCU09OIENvZGUgdHlwZS5cblx0ICovXG5cblx0ZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrJDYoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG5cdGZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzJDYodGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfVxuXG5cdGZ1bmN0aW9uIF9jcmVhdGVDbGFzcyQ2KENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgX2RlZmluZVByb3BlcnRpZXMkNihDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzJDYoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9XG5cblx0dmFyIENvZGUgPVxuXHQvKiNfX1BVUkVfXyovXG5cdGZ1bmN0aW9uICgpIHtcblx0ICAvKipcblx0ICAgKiBDcmVhdGUgYSBDb2RlIHR5cGVcblx0ICAgKlxuXHQgICAqIEBwYXJhbSB7KHN0cmluZ3xmdW5jdGlvbil9IGNvZGUgYSBzdHJpbmcgb3IgZnVuY3Rpb24uXG5cdCAgICogQHBhcmFtIHtPYmplY3R9IFtzY29wZV0gYW4gb3B0aW9uYWwgc2NvcGUgZm9yIHRoZSBmdW5jdGlvbi5cblx0ICAgKiBAcmV0dXJuIHtDb2RlfVxuXHQgICAqL1xuXHQgIGZ1bmN0aW9uIENvZGUoY29kZSwgc2NvcGUpIHtcblx0ICAgIF9jbGFzc0NhbGxDaGVjayQ2KHRoaXMsIENvZGUpO1xuXG5cdCAgICB0aGlzLmNvZGUgPSBjb2RlO1xuXHQgICAgdGhpcy5zY29wZSA9IHNjb3BlO1xuXHQgIH1cblx0ICAvKipcblx0ICAgKiBAaWdub3JlXG5cdCAgICovXG5cblxuXHQgIF9jcmVhdGVDbGFzcyQ2KENvZGUsIFt7XG5cdCAgICBrZXk6IFwidG9KU09OXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gdG9KU09OKCkge1xuXHQgICAgICByZXR1cm4ge1xuXHQgICAgICAgIHNjb3BlOiB0aGlzLnNjb3BlLFxuXHQgICAgICAgIGNvZGU6IHRoaXMuY29kZVxuXHQgICAgICB9O1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBAaWdub3JlXG5cdCAgICAgKi9cblxuXHQgIH0sIHtcblx0ICAgIGtleTogXCJ0b0V4dGVuZGVkSlNPTlwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHRvRXh0ZW5kZWRKU09OKCkge1xuXHQgICAgICBpZiAodGhpcy5zY29wZSkge1xuXHQgICAgICAgIHJldHVybiB7XG5cdCAgICAgICAgICAkY29kZTogdGhpcy5jb2RlLFxuXHQgICAgICAgICAgJHNjb3BlOiB0aGlzLnNjb3BlXG5cdCAgICAgICAgfTtcblx0ICAgICAgfVxuXG5cdCAgICAgIHJldHVybiB7XG5cdCAgICAgICAgJGNvZGU6IHRoaXMuY29kZVxuXHQgICAgICB9O1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBAaWdub3JlXG5cdCAgICAgKi9cblxuXHQgIH1dLCBbe1xuXHQgICAga2V5OiBcImZyb21FeHRlbmRlZEpTT05cIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tRXh0ZW5kZWRKU09OKGRvYykge1xuXHQgICAgICByZXR1cm4gbmV3IENvZGUoZG9jLiRjb2RlLCBkb2MuJHNjb3BlKTtcblx0ICAgIH1cblx0ICB9XSk7XG5cblx0ICByZXR1cm4gQ29kZTtcblx0fSgpO1xuXG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShDb2RlLnByb3RvdHlwZSwgJ19ic29udHlwZScsIHtcblx0ICB2YWx1ZTogJ0NvZGUnXG5cdH0pO1xuXHR2YXIgY29kZSA9IENvZGU7XG5cblx0dmFyIEJ1ZmZlciQyID0gYnVmZmVyLkJ1ZmZlcjtcblx0dmFyIFBBUlNFX1NUUklOR19SRUdFWFAgPSAvXihcXCt8LSk/KFxcZCt8KFxcZCpcXC5cXGQqKSk/KEV8ZSk/KFstK10pPyhcXGQrKT8kLztcblx0dmFyIFBBUlNFX0lORl9SRUdFWFAgPSAvXihcXCt8LSk/KEluZmluaXR5fGluZikkL2k7XG5cdHZhciBQQVJTRV9OQU5fUkVHRVhQID0gL14oXFwrfC0pP05hTiQvaTtcblx0dmFyIEVYUE9ORU5UX01BWCA9IDYxMTE7XG5cdHZhciBFWFBPTkVOVF9NSU4gPSAtNjE3Njtcblx0dmFyIEVYUE9ORU5UX0JJQVMgPSA2MTc2O1xuXHR2YXIgTUFYX0RJR0lUUyA9IDM0OyAvLyBOYW4gdmFsdWUgYml0cyBhcyAzMiBiaXQgdmFsdWVzIChkdWUgdG8gbGFjayBvZiBsb25ncylcblxuXHR2YXIgTkFOX0JVRkZFUiA9IFsweDdjLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwXS5yZXZlcnNlKCk7IC8vIEluZmluaXR5IHZhbHVlIGJpdHMgMzIgYml0IHZhbHVlcyAoZHVlIHRvIGxhY2sgb2YgbG9uZ3MpXG5cblx0dmFyIElORl9ORUdBVElWRV9CVUZGRVIgPSBbMHhmOCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMF0ucmV2ZXJzZSgpO1xuXHR2YXIgSU5GX1BPU0lUSVZFX0JVRkZFUiA9IFsweDc4LCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwXS5yZXZlcnNlKCk7XG5cdHZhciBFWFBPTkVOVF9SRUdFWCA9IC9eKFstK10pPyhcXGQrKT8kLzsgLy8gRGV0ZWN0IGlmIHRoZSB2YWx1ZSBpcyBhIGRpZ2l0XG5cblx0ZnVuY3Rpb24gaXNEaWdpdCh2YWx1ZSkge1xuXHQgIHJldHVybiAhaXNOYU4ocGFyc2VJbnQodmFsdWUsIDEwKSk7XG5cdH0gLy8gRGl2aWRlIHR3byB1aW50MTI4IHZhbHVlc1xuXG5cblx0ZnVuY3Rpb24gZGl2aWRldTEyOCh2YWx1ZSkge1xuXHQgIHZhciBESVZJU09SID0gbG9uZ18xLmZyb21OdW1iZXIoMTAwMCAqIDEwMDAgKiAxMDAwKTtcblxuXHQgIHZhciBfcmVtID0gbG9uZ18xLmZyb21OdW1iZXIoMCk7XG5cblx0ICBpZiAoIXZhbHVlLnBhcnRzWzBdICYmICF2YWx1ZS5wYXJ0c1sxXSAmJiAhdmFsdWUucGFydHNbMl0gJiYgIXZhbHVlLnBhcnRzWzNdKSB7XG5cdCAgICByZXR1cm4ge1xuXHQgICAgICBxdW90aWVudDogdmFsdWUsXG5cdCAgICAgIHJlbTogX3JlbVxuXHQgICAgfTtcblx0ICB9XG5cblx0ICBmb3IgKHZhciBpID0gMDsgaSA8PSAzOyBpKyspIHtcblx0ICAgIC8vIEFkanVzdCByZW1haW5kZXIgdG8gbWF0Y2ggdmFsdWUgb2YgbmV4dCBkaXZpZGVuZFxuXHQgICAgX3JlbSA9IF9yZW0uc2hpZnRMZWZ0KDMyKTsgLy8gQWRkIHRoZSBkaXZpZGVkIHRvIF9yZW1cblxuXHQgICAgX3JlbSA9IF9yZW0uYWRkKG5ldyBsb25nXzEodmFsdWUucGFydHNbaV0sIDApKTtcblx0ICAgIHZhbHVlLnBhcnRzW2ldID0gX3JlbS5kaXYoRElWSVNPUikubG93O1xuXHQgICAgX3JlbSA9IF9yZW0ubW9kdWxvKERJVklTT1IpO1xuXHQgIH1cblxuXHQgIHJldHVybiB7XG5cdCAgICBxdW90aWVudDogdmFsdWUsXG5cdCAgICByZW06IF9yZW1cblx0ICB9O1xuXHR9IC8vIE11bHRpcGx5IHR3byBMb25nIHZhbHVlcyBhbmQgcmV0dXJuIHRoZSAxMjggYml0IHZhbHVlXG5cblxuXHRmdW5jdGlvbiBtdWx0aXBseTY0eDIobGVmdCwgcmlnaHQpIHtcblx0ICBpZiAoIWxlZnQgJiYgIXJpZ2h0KSB7XG5cdCAgICByZXR1cm4ge1xuXHQgICAgICBoaWdoOiBsb25nXzEuZnJvbU51bWJlcigwKSxcblx0ICAgICAgbG93OiBsb25nXzEuZnJvbU51bWJlcigwKVxuXHQgICAgfTtcblx0ICB9XG5cblx0ICB2YXIgbGVmdEhpZ2ggPSBsZWZ0LnNoaWZ0UmlnaHRVbnNpZ25lZCgzMik7XG5cdCAgdmFyIGxlZnRMb3cgPSBuZXcgbG9uZ18xKGxlZnQuZ2V0TG93Qml0cygpLCAwKTtcblx0ICB2YXIgcmlnaHRIaWdoID0gcmlnaHQuc2hpZnRSaWdodFVuc2lnbmVkKDMyKTtcblx0ICB2YXIgcmlnaHRMb3cgPSBuZXcgbG9uZ18xKHJpZ2h0LmdldExvd0JpdHMoKSwgMCk7XG5cdCAgdmFyIHByb2R1Y3RIaWdoID0gbGVmdEhpZ2gubXVsdGlwbHkocmlnaHRIaWdoKTtcblx0ICB2YXIgcHJvZHVjdE1pZCA9IGxlZnRIaWdoLm11bHRpcGx5KHJpZ2h0TG93KTtcblx0ICB2YXIgcHJvZHVjdE1pZDIgPSBsZWZ0TG93Lm11bHRpcGx5KHJpZ2h0SGlnaCk7XG5cdCAgdmFyIHByb2R1Y3RMb3cgPSBsZWZ0TG93Lm11bHRpcGx5KHJpZ2h0TG93KTtcblx0ICBwcm9kdWN0SGlnaCA9IHByb2R1Y3RIaWdoLmFkZChwcm9kdWN0TWlkLnNoaWZ0UmlnaHRVbnNpZ25lZCgzMikpO1xuXHQgIHByb2R1Y3RNaWQgPSBuZXcgbG9uZ18xKHByb2R1Y3RNaWQuZ2V0TG93Qml0cygpLCAwKS5hZGQocHJvZHVjdE1pZDIpLmFkZChwcm9kdWN0TG93LnNoaWZ0UmlnaHRVbnNpZ25lZCgzMikpO1xuXHQgIHByb2R1Y3RIaWdoID0gcHJvZHVjdEhpZ2guYWRkKHByb2R1Y3RNaWQuc2hpZnRSaWdodFVuc2lnbmVkKDMyKSk7XG5cdCAgcHJvZHVjdExvdyA9IHByb2R1Y3RNaWQuc2hpZnRMZWZ0KDMyKS5hZGQobmV3IGxvbmdfMShwcm9kdWN0TG93LmdldExvd0JpdHMoKSwgMCkpOyAvLyBSZXR1cm4gdGhlIDEyOCBiaXQgcmVzdWx0XG5cblx0ICByZXR1cm4ge1xuXHQgICAgaGlnaDogcHJvZHVjdEhpZ2gsXG5cdCAgICBsb3c6IHByb2R1Y3RMb3dcblx0ICB9O1xuXHR9XG5cblx0ZnVuY3Rpb24gbGVzc1RoYW4obGVmdCwgcmlnaHQpIHtcblx0ICAvLyBNYWtlIHZhbHVlcyB1bnNpZ25lZFxuXHQgIHZhciB1aGxlZnQgPSBsZWZ0LmhpZ2ggPj4+IDA7XG5cdCAgdmFyIHVocmlnaHQgPSByaWdodC5oaWdoID4+PiAwOyAvLyBDb21wYXJlIGhpZ2ggYml0cyBmaXJzdFxuXG5cdCAgaWYgKHVobGVmdCA8IHVocmlnaHQpIHtcblx0ICAgIHJldHVybiB0cnVlO1xuXHQgIH0gZWxzZSBpZiAodWhsZWZ0ID09PSB1aHJpZ2h0KSB7XG5cdCAgICB2YXIgdWxsZWZ0ID0gbGVmdC5sb3cgPj4+IDA7XG5cdCAgICB2YXIgdWxyaWdodCA9IHJpZ2h0LmxvdyA+Pj4gMDtcblx0ICAgIGlmICh1bGxlZnQgPCB1bHJpZ2h0KSByZXR1cm4gdHJ1ZTtcblx0ICB9XG5cblx0ICByZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRmdW5jdGlvbiBpbnZhbGlkRXJyKHN0cmluZywgbWVzc2FnZSkge1xuXHQgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJcXFwiXCIuY29uY2F0KHN0cmluZywgXCJcXFwiIGlzIG5vdCBhIHZhbGlkIERlY2ltYWwxMjggc3RyaW5nIC0gXCIpLmNvbmNhdChtZXNzYWdlKSk7XG5cdH1cblx0LyoqXG5cdCAqIEEgY2xhc3MgcmVwcmVzZW50YXRpb24gb2YgdGhlIEJTT04gRGVjaW1hbDEyOCB0eXBlLlxuXHQgKlxuXHQgKiBAY2xhc3Ncblx0ICogQHBhcmFtIHtCdWZmZXJ9IGJ5dGVzIGEgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIHJhdyBEZWNpbWFsMTI4IGJ5dGVzLlxuXHQgKiBAcmV0dXJuIHtEb3VibGV9XG5cdCAqL1xuXG5cblx0ZnVuY3Rpb24gRGVjaW1hbDEyOChieXRlcykge1xuXHQgIHRoaXMuYnl0ZXMgPSBieXRlcztcblx0fVxuXHQvKipcblx0ICogQ3JlYXRlIGEgRGVjaW1hbDEyOCBpbnN0YW5jZSBmcm9tIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uXG5cdCAqXG5cdCAqIEBtZXRob2Rcblx0ICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBhIG51bWVyaWMgc3RyaW5nIHJlcHJlc2VudGF0aW9uLlxuXHQgKiBAcmV0dXJuIHtEZWNpbWFsMTI4fSByZXR1cm5zIGEgRGVjaW1hbDEyOCBpbnN0YW5jZS5cblx0ICovXG5cblxuXHREZWNpbWFsMTI4LmZyb21TdHJpbmcgPSBmdW5jdGlvbiAoc3RyaW5nKSB7XG5cdCAgLy8gUGFyc2Ugc3RhdGUgdHJhY2tpbmdcblx0ICB2YXIgaXNOZWdhdGl2ZSA9IGZhbHNlO1xuXHQgIHZhciBzYXdSYWRpeCA9IGZhbHNlO1xuXHQgIHZhciBmb3VuZE5vblplcm8gPSBmYWxzZTsgLy8gVG90YWwgbnVtYmVyIG9mIHNpZ25pZmljYW50IGRpZ2l0cyAobm8gbGVhZGluZyBvciB0cmFpbGluZyB6ZXJvKVxuXG5cdCAgdmFyIHNpZ25pZmljYW50RGlnaXRzID0gMDsgLy8gVG90YWwgbnVtYmVyIG9mIHNpZ25pZmljYW5kIGRpZ2l0cyByZWFkXG5cblx0ICB2YXIgbkRpZ2l0c1JlYWQgPSAwOyAvLyBUb3RhbCBudW1iZXIgb2YgZGlnaXRzIChubyBsZWFkaW5nIHplcm9zKVxuXG5cdCAgdmFyIG5EaWdpdHMgPSAwOyAvLyBUaGUgbnVtYmVyIG9mIHRoZSBkaWdpdHMgYWZ0ZXIgcmFkaXhcblxuXHQgIHZhciByYWRpeFBvc2l0aW9uID0gMDsgLy8gVGhlIGluZGV4IG9mIHRoZSBmaXJzdCBub24temVybyBpbiAqc3RyKlxuXG5cdCAgdmFyIGZpcnN0Tm9uWmVybyA9IDA7IC8vIERpZ2l0cyBBcnJheVxuXG5cdCAgdmFyIGRpZ2l0cyA9IFswXTsgLy8gVGhlIG51bWJlciBvZiBkaWdpdHMgaW4gZGlnaXRzXG5cblx0ICB2YXIgbkRpZ2l0c1N0b3JlZCA9IDA7IC8vIEluc2VydGlvbiBwb2ludGVyIGZvciBkaWdpdHNcblxuXHQgIHZhciBkaWdpdHNJbnNlcnQgPSAwOyAvLyBUaGUgaW5kZXggb2YgdGhlIGZpcnN0IG5vbi16ZXJvIGRpZ2l0XG5cblx0ICB2YXIgZmlyc3REaWdpdCA9IDA7IC8vIFRoZSBpbmRleCBvZiB0aGUgbGFzdCBkaWdpdFxuXG5cdCAgdmFyIGxhc3REaWdpdCA9IDA7IC8vIEV4cG9uZW50XG5cblx0ICB2YXIgZXhwb25lbnQgPSAwOyAvLyBsb29wIGluZGV4IG92ZXIgYXJyYXlcblxuXHQgIHZhciBpID0gMDsgLy8gVGhlIGhpZ2ggMTcgZGlnaXRzIG9mIHRoZSBzaWduaWZpY2FuZFxuXG5cdCAgdmFyIHNpZ25pZmljYW5kSGlnaCA9IFswLCAwXTsgLy8gVGhlIGxvdyAxNyBkaWdpdHMgb2YgdGhlIHNpZ25pZmljYW5kXG5cblx0ICB2YXIgc2lnbmlmaWNhbmRMb3cgPSBbMCwgMF07IC8vIFRoZSBiaWFzZWQgZXhwb25lbnRcblxuXHQgIHZhciBiaWFzZWRFeHBvbmVudCA9IDA7IC8vIFJlYWQgaW5kZXhcblxuXHQgIHZhciBpbmRleCA9IDA7IC8vIE5haXZlbHkgcHJldmVudCBhZ2FpbnN0IFJFRE9TIGF0dGFja3MuXG5cdCAgLy8gVE9ETzogaW1wbGVtZW50aW5nIGEgY3VzdG9tIHBhcnNpbmcgZm9yIHRoaXMsIG9yIHJlZmFjdG9yaW5nIHRoZSByZWdleCB3b3VsZCB5aWVsZFxuXHQgIC8vICAgICAgIGZ1cnRoZXIgZ2FpbnMuXG5cblx0ICBpZiAoc3RyaW5nLmxlbmd0aCA+PSA3MDAwKSB7XG5cdCAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCcnICsgc3RyaW5nICsgJyBub3QgYSB2YWxpZCBEZWNpbWFsMTI4IHN0cmluZycpO1xuXHQgIH0gLy8gUmVzdWx0c1xuXG5cblx0ICB2YXIgc3RyaW5nTWF0Y2ggPSBzdHJpbmcubWF0Y2goUEFSU0VfU1RSSU5HX1JFR0VYUCk7XG5cdCAgdmFyIGluZk1hdGNoID0gc3RyaW5nLm1hdGNoKFBBUlNFX0lORl9SRUdFWFApO1xuXHQgIHZhciBuYW5NYXRjaCA9IHN0cmluZy5tYXRjaChQQVJTRV9OQU5fUkVHRVhQKTsgLy8gVmFsaWRhdGUgdGhlIHN0cmluZ1xuXG5cdCAgaWYgKCFzdHJpbmdNYXRjaCAmJiAhaW5mTWF0Y2ggJiYgIW5hbk1hdGNoIHx8IHN0cmluZy5sZW5ndGggPT09IDApIHtcblx0ICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJycgKyBzdHJpbmcgKyAnIG5vdCBhIHZhbGlkIERlY2ltYWwxMjggc3RyaW5nJyk7XG5cdCAgfVxuXG5cdCAgaWYgKHN0cmluZ01hdGNoKSB7XG5cdCAgICAvLyBmdWxsX21hdGNoID0gc3RyaW5nTWF0Y2hbMF1cblx0ICAgIC8vIHNpZ24gPSBzdHJpbmdNYXRjaFsxXVxuXHQgICAgdmFyIHVuc2lnbmVkTnVtYmVyID0gc3RyaW5nTWF0Y2hbMl07IC8vIHN0cmluZ01hdGNoWzNdIGlzIHVuZGVmaW5lZCBpZiBhIHdob2xlIG51bWJlciAoZXggXCIxXCIsIDEyXCIpXG5cdCAgICAvLyBidXQgZGVmaW5lZCBpZiBhIG51bWJlciB3LyBkZWNpbWFsIGluIGl0IChleCBcIjEuMCwgMTIuMlwiKVxuXG5cdCAgICB2YXIgZSA9IHN0cmluZ01hdGNoWzRdO1xuXHQgICAgdmFyIGV4cFNpZ24gPSBzdHJpbmdNYXRjaFs1XTtcblx0ICAgIHZhciBleHBOdW1iZXIgPSBzdHJpbmdNYXRjaFs2XTsgLy8gdGhleSBwcm92aWRlZCBlLCBidXQgZGlkbid0IGdpdmUgYW4gZXhwb25lbnQgbnVtYmVyLiBmb3IgZXggXCIxZVwiXG5cblx0ICAgIGlmIChlICYmIGV4cE51bWJlciA9PT0gdW5kZWZpbmVkKSBpbnZhbGlkRXJyKHN0cmluZywgJ21pc3NpbmcgZXhwb25lbnQgcG93ZXInKTsgLy8gdGhleSBwcm92aWRlZCBlLCBidXQgZGlkbid0IGdpdmUgYSBudW1iZXIgYmVmb3JlIGl0LiBmb3IgZXggXCJlMVwiXG5cblx0ICAgIGlmIChlICYmIHVuc2lnbmVkTnVtYmVyID09PSB1bmRlZmluZWQpIGludmFsaWRFcnIoc3RyaW5nLCAnbWlzc2luZyBleHBvbmVudCBiYXNlJyk7XG5cblx0ICAgIGlmIChlID09PSB1bmRlZmluZWQgJiYgKGV4cFNpZ24gfHwgZXhwTnVtYmVyKSkge1xuXHQgICAgICBpbnZhbGlkRXJyKHN0cmluZywgJ21pc3NpbmcgZSBiZWZvcmUgZXhwb25lbnQnKTtcblx0ICAgIH1cblx0ICB9IC8vIEdldCB0aGUgbmVnYXRpdmUgb3IgcG9zaXRpdmUgc2lnblxuXG5cblx0ICBpZiAoc3RyaW5nW2luZGV4XSA9PT0gJysnIHx8IHN0cmluZ1tpbmRleF0gPT09ICctJykge1xuXHQgICAgaXNOZWdhdGl2ZSA9IHN0cmluZ1tpbmRleCsrXSA9PT0gJy0nO1xuXHQgIH0gLy8gQ2hlY2sgaWYgdXNlciBwYXNzZWQgSW5maW5pdHkgb3IgTmFOXG5cblxuXHQgIGlmICghaXNEaWdpdChzdHJpbmdbaW5kZXhdKSAmJiBzdHJpbmdbaW5kZXhdICE9PSAnLicpIHtcblx0ICAgIGlmIChzdHJpbmdbaW5kZXhdID09PSAnaScgfHwgc3RyaW5nW2luZGV4XSA9PT0gJ0knKSB7XG5cdCAgICAgIHJldHVybiBuZXcgRGVjaW1hbDEyOChCdWZmZXIkMi5mcm9tKGlzTmVnYXRpdmUgPyBJTkZfTkVHQVRJVkVfQlVGRkVSIDogSU5GX1BPU0lUSVZFX0JVRkZFUikpO1xuXHQgICAgfSBlbHNlIGlmIChzdHJpbmdbaW5kZXhdID09PSAnTicpIHtcblx0ICAgICAgcmV0dXJuIG5ldyBEZWNpbWFsMTI4KEJ1ZmZlciQyLmZyb20oTkFOX0JVRkZFUikpO1xuXHQgICAgfVxuXHQgIH0gLy8gUmVhZCBhbGwgdGhlIGRpZ2l0c1xuXG5cblx0ICB3aGlsZSAoaXNEaWdpdChzdHJpbmdbaW5kZXhdKSB8fCBzdHJpbmdbaW5kZXhdID09PSAnLicpIHtcblx0ICAgIGlmIChzdHJpbmdbaW5kZXhdID09PSAnLicpIHtcblx0ICAgICAgaWYgKHNhd1JhZGl4KSBpbnZhbGlkRXJyKHN0cmluZywgJ2NvbnRhaW5zIG11bHRpcGxlIHBlcmlvZHMnKTtcblx0ICAgICAgc2F3UmFkaXggPSB0cnVlO1xuXHQgICAgICBpbmRleCA9IGluZGV4ICsgMTtcblx0ICAgICAgY29udGludWU7XG5cdCAgICB9XG5cblx0ICAgIGlmIChuRGlnaXRzU3RvcmVkIDwgMzQpIHtcblx0ICAgICAgaWYgKHN0cmluZ1tpbmRleF0gIT09ICcwJyB8fCBmb3VuZE5vblplcm8pIHtcblx0ICAgICAgICBpZiAoIWZvdW5kTm9uWmVybykge1xuXHQgICAgICAgICAgZmlyc3ROb25aZXJvID0gbkRpZ2l0c1JlYWQ7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgZm91bmROb25aZXJvID0gdHJ1ZTsgLy8gT25seSBzdG9yZSAzNCBkaWdpdHNcblxuXHQgICAgICAgIGRpZ2l0c1tkaWdpdHNJbnNlcnQrK10gPSBwYXJzZUludChzdHJpbmdbaW5kZXhdLCAxMCk7XG5cdCAgICAgICAgbkRpZ2l0c1N0b3JlZCA9IG5EaWdpdHNTdG9yZWQgKyAxO1xuXHQgICAgICB9XG5cdCAgICB9XG5cblx0ICAgIGlmIChmb3VuZE5vblplcm8pIG5EaWdpdHMgPSBuRGlnaXRzICsgMTtcblx0ICAgIGlmIChzYXdSYWRpeCkgcmFkaXhQb3NpdGlvbiA9IHJhZGl4UG9zaXRpb24gKyAxO1xuXHQgICAgbkRpZ2l0c1JlYWQgPSBuRGlnaXRzUmVhZCArIDE7XG5cdCAgICBpbmRleCA9IGluZGV4ICsgMTtcblx0ICB9XG5cblx0ICBpZiAoc2F3UmFkaXggJiYgIW5EaWdpdHNSZWFkKSB0aHJvdyBuZXcgVHlwZUVycm9yKCcnICsgc3RyaW5nICsgJyBub3QgYSB2YWxpZCBEZWNpbWFsMTI4IHN0cmluZycpOyAvLyBSZWFkIGV4cG9uZW50IGlmIGV4aXN0c1xuXG5cdCAgaWYgKHN0cmluZ1tpbmRleF0gPT09ICdlJyB8fCBzdHJpbmdbaW5kZXhdID09PSAnRScpIHtcblx0ICAgIC8vIFJlYWQgZXhwb25lbnQgZGlnaXRzXG5cdCAgICB2YXIgbWF0Y2ggPSBzdHJpbmcuc3Vic3RyKCsraW5kZXgpLm1hdGNoKEVYUE9ORU5UX1JFR0VYKTsgLy8gTm8gZGlnaXRzIHJlYWRcblxuXHQgICAgaWYgKCFtYXRjaCB8fCAhbWF0Y2hbMl0pIHJldHVybiBuZXcgRGVjaW1hbDEyOChCdWZmZXIkMi5mcm9tKE5BTl9CVUZGRVIpKTsgLy8gR2V0IGV4cG9uZW50XG5cblx0ICAgIGV4cG9uZW50ID0gcGFyc2VJbnQobWF0Y2hbMF0sIDEwKTsgLy8gQWRqdXN0IHRoZSBpbmRleFxuXG5cdCAgICBpbmRleCA9IGluZGV4ICsgbWF0Y2hbMF0ubGVuZ3RoO1xuXHQgIH0gLy8gUmV0dXJuIG5vdCBhIG51bWJlclxuXG5cblx0ICBpZiAoc3RyaW5nW2luZGV4XSkgcmV0dXJuIG5ldyBEZWNpbWFsMTI4KEJ1ZmZlciQyLmZyb20oTkFOX0JVRkZFUikpOyAvLyBEb25lIHJlYWRpbmcgaW5wdXRcblx0ICAvLyBGaW5kIGZpcnN0IG5vbi16ZXJvIGRpZ2l0IGluIGRpZ2l0c1xuXG5cdCAgZmlyc3REaWdpdCA9IDA7XG5cblx0ICBpZiAoIW5EaWdpdHNTdG9yZWQpIHtcblx0ICAgIGZpcnN0RGlnaXQgPSAwO1xuXHQgICAgbGFzdERpZ2l0ID0gMDtcblx0ICAgIGRpZ2l0c1swXSA9IDA7XG5cdCAgICBuRGlnaXRzID0gMTtcblx0ICAgIG5EaWdpdHNTdG9yZWQgPSAxO1xuXHQgICAgc2lnbmlmaWNhbnREaWdpdHMgPSAwO1xuXHQgIH0gZWxzZSB7XG5cdCAgICBsYXN0RGlnaXQgPSBuRGlnaXRzU3RvcmVkIC0gMTtcblx0ICAgIHNpZ25pZmljYW50RGlnaXRzID0gbkRpZ2l0cztcblxuXHQgICAgaWYgKHNpZ25pZmljYW50RGlnaXRzICE9PSAxKSB7XG5cdCAgICAgIHdoaWxlIChzdHJpbmdbZmlyc3ROb25aZXJvICsgc2lnbmlmaWNhbnREaWdpdHMgLSAxXSA9PT0gJzAnKSB7XG5cdCAgICAgICAgc2lnbmlmaWNhbnREaWdpdHMgPSBzaWduaWZpY2FudERpZ2l0cyAtIDE7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9IC8vIE5vcm1hbGl6YXRpb24gb2YgZXhwb25lbnRcblx0ICAvLyBDb3JyZWN0IGV4cG9uZW50IGJhc2VkIG9uIHJhZGl4IHBvc2l0aW9uLCBhbmQgc2hpZnQgc2lnbmlmaWNhbmQgYXMgbmVlZGVkXG5cdCAgLy8gdG8gcmVwcmVzZW50IHVzZXIgaW5wdXRcblx0ICAvLyBPdmVyZmxvdyBwcmV2ZW50aW9uXG5cblxuXHQgIGlmIChleHBvbmVudCA8PSByYWRpeFBvc2l0aW9uICYmIHJhZGl4UG9zaXRpb24gLSBleHBvbmVudCA+IDEgPDwgMTQpIHtcblx0ICAgIGV4cG9uZW50ID0gRVhQT05FTlRfTUlOO1xuXHQgIH0gZWxzZSB7XG5cdCAgICBleHBvbmVudCA9IGV4cG9uZW50IC0gcmFkaXhQb3NpdGlvbjtcblx0ICB9IC8vIEF0dGVtcHQgdG8gbm9ybWFsaXplIHRoZSBleHBvbmVudFxuXG5cblx0ICB3aGlsZSAoZXhwb25lbnQgPiBFWFBPTkVOVF9NQVgpIHtcblx0ICAgIC8vIFNoaWZ0IGV4cG9uZW50IHRvIHNpZ25pZmljYW5kIGFuZCBkZWNyZWFzZVxuXHQgICAgbGFzdERpZ2l0ID0gbGFzdERpZ2l0ICsgMTtcblxuXHQgICAgaWYgKGxhc3REaWdpdCAtIGZpcnN0RGlnaXQgPiBNQVhfRElHSVRTKSB7XG5cdCAgICAgIC8vIENoZWNrIGlmIHdlIGhhdmUgYSB6ZXJvIHRoZW4ganVzdCBoYXJkIGNsYW1wLCBvdGhlcndpc2UgZmFpbFxuXHQgICAgICB2YXIgZGlnaXRzU3RyaW5nID0gZGlnaXRzLmpvaW4oJycpO1xuXG5cdCAgICAgIGlmIChkaWdpdHNTdHJpbmcubWF0Y2goL14wKyQvKSkge1xuXHQgICAgICAgIGV4cG9uZW50ID0gRVhQT05FTlRfTUFYO1xuXHQgICAgICAgIGJyZWFrO1xuXHQgICAgICB9XG5cblx0ICAgICAgaW52YWxpZEVycihzdHJpbmcsICdvdmVyZmxvdycpO1xuXHQgICAgfVxuXG5cdCAgICBleHBvbmVudCA9IGV4cG9uZW50IC0gMTtcblx0ICB9XG5cblx0ICB3aGlsZSAoZXhwb25lbnQgPCBFWFBPTkVOVF9NSU4gfHwgbkRpZ2l0c1N0b3JlZCA8IG5EaWdpdHMpIHtcblx0ICAgIC8vIFNoaWZ0IGxhc3QgZGlnaXQuIGNhbiBvbmx5IGRvIHRoaXMgaWYgPCBzaWduaWZpY2FudCBkaWdpdHMgdGhhbiAjIHN0b3JlZC5cblx0ICAgIGlmIChsYXN0RGlnaXQgPT09IDAgJiYgc2lnbmlmaWNhbnREaWdpdHMgPCBuRGlnaXRzU3RvcmVkKSB7XG5cdCAgICAgIGV4cG9uZW50ID0gRVhQT05FTlRfTUlOO1xuXHQgICAgICBzaWduaWZpY2FudERpZ2l0cyA9IDA7XG5cdCAgICAgIGJyZWFrO1xuXHQgICAgfVxuXG5cdCAgICBpZiAobkRpZ2l0c1N0b3JlZCA8IG5EaWdpdHMpIHtcblx0ICAgICAgLy8gYWRqdXN0IHRvIG1hdGNoIGRpZ2l0cyBub3Qgc3RvcmVkXG5cdCAgICAgIG5EaWdpdHMgPSBuRGlnaXRzIC0gMTtcblx0ICAgIH0gZWxzZSB7XG5cdCAgICAgIC8vIGFkanVzdCB0byByb3VuZFxuXHQgICAgICBsYXN0RGlnaXQgPSBsYXN0RGlnaXQgLSAxO1xuXHQgICAgfVxuXG5cdCAgICBpZiAoZXhwb25lbnQgPCBFWFBPTkVOVF9NQVgpIHtcblx0ICAgICAgZXhwb25lbnQgPSBleHBvbmVudCArIDE7XG5cdCAgICB9IGVsc2Uge1xuXHQgICAgICAvLyBDaGVjayBpZiB3ZSBoYXZlIGEgemVybyB0aGVuIGp1c3QgaGFyZCBjbGFtcCwgb3RoZXJ3aXNlIGZhaWxcblx0ICAgICAgdmFyIF9kaWdpdHNTdHJpbmcgPSBkaWdpdHMuam9pbignJyk7XG5cblx0ICAgICAgaWYgKF9kaWdpdHNTdHJpbmcubWF0Y2goL14wKyQvKSkge1xuXHQgICAgICAgIGV4cG9uZW50ID0gRVhQT05FTlRfTUFYO1xuXHQgICAgICAgIGJyZWFrO1xuXHQgICAgICB9XG5cblx0ICAgICAgaW52YWxpZEVycihzdHJpbmcsICdvdmVyZmxvdycpO1xuXHQgICAgfVxuXHQgIH0gLy8gUm91bmRcblx0ICAvLyBXZSd2ZSBub3JtYWxpemVkIHRoZSBleHBvbmVudCwgYnV0IG1pZ2h0IHN0aWxsIG5lZWQgdG8gcm91bmQuXG5cblxuXHQgIGlmIChsYXN0RGlnaXQgLSBmaXJzdERpZ2l0ICsgMSA8IHNpZ25pZmljYW50RGlnaXRzKSB7XG5cdCAgICB2YXIgZW5kT2ZTdHJpbmcgPSBuRGlnaXRzUmVhZDsgLy8gSWYgd2UgaGF2ZSBzZWVuIGEgcmFkaXggcG9pbnQsICdzdHJpbmcnIGlzIDEgbG9uZ2VyIHRoYW4gd2UgaGF2ZVxuXHQgICAgLy8gZG9jdW1lbnRlZCB3aXRoIG5kaWdpdHNfcmVhZCwgc28gaW5jIHRoZSBwb3NpdGlvbiBvZiB0aGUgZmlyc3Qgbm9uemVyb1xuXHQgICAgLy8gZGlnaXQgYW5kIHRoZSBwb3NpdGlvbiB0aGF0IGRpZ2l0cyBhcmUgcmVhZCB0by5cblxuXHQgICAgaWYgKHNhd1JhZGl4KSB7XG5cdCAgICAgIGZpcnN0Tm9uWmVybyA9IGZpcnN0Tm9uWmVybyArIDE7XG5cdCAgICAgIGVuZE9mU3RyaW5nID0gZW5kT2ZTdHJpbmcgKyAxO1xuXHQgICAgfSAvLyBpZiBuZWdhdGl2ZSwgd2UgbmVlZCB0byBpbmNyZW1lbnQgYWdhaW4gdG8gYWNjb3VudCBmb3IgLSBzaWduIGF0IHN0YXJ0LlxuXG5cblx0ICAgIGlmIChpc05lZ2F0aXZlKSB7XG5cdCAgICAgIGZpcnN0Tm9uWmVybyA9IGZpcnN0Tm9uWmVybyArIDE7XG5cdCAgICAgIGVuZE9mU3RyaW5nID0gZW5kT2ZTdHJpbmcgKyAxO1xuXHQgICAgfVxuXG5cdCAgICB2YXIgcm91bmREaWdpdCA9IHBhcnNlSW50KHN0cmluZ1tmaXJzdE5vblplcm8gKyBsYXN0RGlnaXQgKyAxXSwgMTApO1xuXHQgICAgdmFyIHJvdW5kQml0ID0gMDtcblxuXHQgICAgaWYgKHJvdW5kRGlnaXQgPj0gNSkge1xuXHQgICAgICByb3VuZEJpdCA9IDE7XG5cblx0ICAgICAgaWYgKHJvdW5kRGlnaXQgPT09IDUpIHtcblx0ICAgICAgICByb3VuZEJpdCA9IGRpZ2l0c1tsYXN0RGlnaXRdICUgMiA9PT0gMTtcblxuXHQgICAgICAgIGZvciAoaSA9IGZpcnN0Tm9uWmVybyArIGxhc3REaWdpdCArIDI7IGkgPCBlbmRPZlN0cmluZzsgaSsrKSB7XG5cdCAgICAgICAgICBpZiAocGFyc2VJbnQoc3RyaW5nW2ldLCAxMCkpIHtcblx0ICAgICAgICAgICAgcm91bmRCaXQgPSAxO1xuXHQgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH1cblxuXHQgICAgaWYgKHJvdW5kQml0KSB7XG5cdCAgICAgIHZhciBkSWR4ID0gbGFzdERpZ2l0O1xuXG5cdCAgICAgIGZvciAoOyBkSWR4ID49IDA7IGRJZHgtLSkge1xuXHQgICAgICAgIGlmICgrK2RpZ2l0c1tkSWR4XSA+IDkpIHtcblx0ICAgICAgICAgIGRpZ2l0c1tkSWR4XSA9IDA7IC8vIG92ZXJmbG93ZWQgbW9zdCBzaWduaWZpY2FudCBkaWdpdFxuXG5cdCAgICAgICAgICBpZiAoZElkeCA9PT0gMCkge1xuXHQgICAgICAgICAgICBpZiAoZXhwb25lbnQgPCBFWFBPTkVOVF9NQVgpIHtcblx0ICAgICAgICAgICAgICBleHBvbmVudCA9IGV4cG9uZW50ICsgMTtcblx0ICAgICAgICAgICAgICBkaWdpdHNbZElkeF0gPSAxO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgIHJldHVybiBuZXcgRGVjaW1hbDEyOChCdWZmZXIkMi5mcm9tKGlzTmVnYXRpdmUgPyBJTkZfTkVHQVRJVkVfQlVGRkVSIDogSU5GX1BPU0lUSVZFX0JVRkZFUikpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSAvLyBFbmNvZGUgc2lnbmlmaWNhbmRcblx0ICAvLyBUaGUgaGlnaCAxNyBkaWdpdHMgb2YgdGhlIHNpZ25pZmljYW5kXG5cblxuXHQgIHNpZ25pZmljYW5kSGlnaCA9IGxvbmdfMS5mcm9tTnVtYmVyKDApOyAvLyBUaGUgbG93IDE3IGRpZ2l0cyBvZiB0aGUgc2lnbmlmaWNhbmRcblxuXHQgIHNpZ25pZmljYW5kTG93ID0gbG9uZ18xLmZyb21OdW1iZXIoMCk7IC8vIHJlYWQgYSB6ZXJvXG5cblx0ICBpZiAoc2lnbmlmaWNhbnREaWdpdHMgPT09IDApIHtcblx0ICAgIHNpZ25pZmljYW5kSGlnaCA9IGxvbmdfMS5mcm9tTnVtYmVyKDApO1xuXHQgICAgc2lnbmlmaWNhbmRMb3cgPSBsb25nXzEuZnJvbU51bWJlcigwKTtcblx0ICB9IGVsc2UgaWYgKGxhc3REaWdpdCAtIGZpcnN0RGlnaXQgPCAxNykge1xuXHQgICAgdmFyIF9kSWR4ID0gZmlyc3REaWdpdDtcblx0ICAgIHNpZ25pZmljYW5kTG93ID0gbG9uZ18xLmZyb21OdW1iZXIoZGlnaXRzW19kSWR4KytdKTtcblx0ICAgIHNpZ25pZmljYW5kSGlnaCA9IG5ldyBsb25nXzEoMCwgMCk7XG5cblx0ICAgIGZvciAoOyBfZElkeCA8PSBsYXN0RGlnaXQ7IF9kSWR4KyspIHtcblx0ICAgICAgc2lnbmlmaWNhbmRMb3cgPSBzaWduaWZpY2FuZExvdy5tdWx0aXBseShsb25nXzEuZnJvbU51bWJlcigxMCkpO1xuXHQgICAgICBzaWduaWZpY2FuZExvdyA9IHNpZ25pZmljYW5kTG93LmFkZChsb25nXzEuZnJvbU51bWJlcihkaWdpdHNbX2RJZHhdKSk7XG5cdCAgICB9XG5cdCAgfSBlbHNlIHtcblx0ICAgIHZhciBfZElkeDIgPSBmaXJzdERpZ2l0O1xuXHQgICAgc2lnbmlmaWNhbmRIaWdoID0gbG9uZ18xLmZyb21OdW1iZXIoZGlnaXRzW19kSWR4MisrXSk7XG5cblx0ICAgIGZvciAoOyBfZElkeDIgPD0gbGFzdERpZ2l0IC0gMTc7IF9kSWR4MisrKSB7XG5cdCAgICAgIHNpZ25pZmljYW5kSGlnaCA9IHNpZ25pZmljYW5kSGlnaC5tdWx0aXBseShsb25nXzEuZnJvbU51bWJlcigxMCkpO1xuXHQgICAgICBzaWduaWZpY2FuZEhpZ2ggPSBzaWduaWZpY2FuZEhpZ2guYWRkKGxvbmdfMS5mcm9tTnVtYmVyKGRpZ2l0c1tfZElkeDJdKSk7XG5cdCAgICB9XG5cblx0ICAgIHNpZ25pZmljYW5kTG93ID0gbG9uZ18xLmZyb21OdW1iZXIoZGlnaXRzW19kSWR4MisrXSk7XG5cblx0ICAgIGZvciAoOyBfZElkeDIgPD0gbGFzdERpZ2l0OyBfZElkeDIrKykge1xuXHQgICAgICBzaWduaWZpY2FuZExvdyA9IHNpZ25pZmljYW5kTG93Lm11bHRpcGx5KGxvbmdfMS5mcm9tTnVtYmVyKDEwKSk7XG5cdCAgICAgIHNpZ25pZmljYW5kTG93ID0gc2lnbmlmaWNhbmRMb3cuYWRkKGxvbmdfMS5mcm9tTnVtYmVyKGRpZ2l0c1tfZElkeDJdKSk7XG5cdCAgICB9XG5cdCAgfVxuXG5cdCAgdmFyIHNpZ25pZmljYW5kID0gbXVsdGlwbHk2NHgyKHNpZ25pZmljYW5kSGlnaCwgbG9uZ18xLmZyb21TdHJpbmcoJzEwMDAwMDAwMDAwMDAwMDAwMCcpKTtcblx0ICBzaWduaWZpY2FuZC5sb3cgPSBzaWduaWZpY2FuZC5sb3cuYWRkKHNpZ25pZmljYW5kTG93KTtcblxuXHQgIGlmIChsZXNzVGhhbihzaWduaWZpY2FuZC5sb3csIHNpZ25pZmljYW5kTG93KSkge1xuXHQgICAgc2lnbmlmaWNhbmQuaGlnaCA9IHNpZ25pZmljYW5kLmhpZ2guYWRkKGxvbmdfMS5mcm9tTnVtYmVyKDEpKTtcblx0ICB9IC8vIEJpYXNlZCBleHBvbmVudFxuXG5cblx0ICBiaWFzZWRFeHBvbmVudCA9IGV4cG9uZW50ICsgRVhQT05FTlRfQklBUztcblx0ICB2YXIgZGVjID0ge1xuXHQgICAgbG93OiBsb25nXzEuZnJvbU51bWJlcigwKSxcblx0ICAgIGhpZ2g6IGxvbmdfMS5mcm9tTnVtYmVyKDApXG5cdCAgfTsgLy8gRW5jb2RlIGNvbWJpbmF0aW9uLCBleHBvbmVudCwgYW5kIHNpZ25pZmljYW5kLlxuXG5cdCAgaWYgKHNpZ25pZmljYW5kLmhpZ2guc2hpZnRSaWdodFVuc2lnbmVkKDQ5KS5hbmQobG9uZ18xLmZyb21OdW1iZXIoMSkpLmVxdWFscyhsb25nXzEuZnJvbU51bWJlcigxKSkpIHtcblx0ICAgIC8vIEVuY29kZSAnMTEnIGludG8gYml0cyAxIHRvIDNcblx0ICAgIGRlYy5oaWdoID0gZGVjLmhpZ2gub3IobG9uZ18xLmZyb21OdW1iZXIoMHgzKS5zaGlmdExlZnQoNjEpKTtcblx0ICAgIGRlYy5oaWdoID0gZGVjLmhpZ2gub3IobG9uZ18xLmZyb21OdW1iZXIoYmlhc2VkRXhwb25lbnQpLmFuZChsb25nXzEuZnJvbU51bWJlcigweDNmZmYpLnNoaWZ0TGVmdCg0NykpKTtcblx0ICAgIGRlYy5oaWdoID0gZGVjLmhpZ2gub3Ioc2lnbmlmaWNhbmQuaGlnaC5hbmQobG9uZ18xLmZyb21OdW1iZXIoMHg3ZmZmZmZmZmZmZmYpKSk7XG5cdCAgfSBlbHNlIHtcblx0ICAgIGRlYy5oaWdoID0gZGVjLmhpZ2gub3IobG9uZ18xLmZyb21OdW1iZXIoYmlhc2VkRXhwb25lbnQgJiAweDNmZmYpLnNoaWZ0TGVmdCg0OSkpO1xuXHQgICAgZGVjLmhpZ2ggPSBkZWMuaGlnaC5vcihzaWduaWZpY2FuZC5oaWdoLmFuZChsb25nXzEuZnJvbU51bWJlcigweDFmZmZmZmZmZmZmZmYpKSk7XG5cdCAgfVxuXG5cdCAgZGVjLmxvdyA9IHNpZ25pZmljYW5kLmxvdzsgLy8gRW5jb2RlIHNpZ25cblxuXHQgIGlmIChpc05lZ2F0aXZlKSB7XG5cdCAgICBkZWMuaGlnaCA9IGRlYy5oaWdoLm9yKGxvbmdfMS5mcm9tU3RyaW5nKCc5MjIzMzcyMDM2ODU0Nzc1ODA4JykpO1xuXHQgIH0gLy8gRW5jb2RlIGludG8gYSBidWZmZXJcblxuXG5cdCAgdmFyIGJ1ZmZlciQkMSA9IEJ1ZmZlciQyLmFsbG9jKDE2KTtcblx0ICBpbmRleCA9IDA7IC8vIEVuY29kZSB0aGUgbG93IDY0IGJpdHMgb2YgdGhlIGRlY2ltYWxcblx0ICAvLyBFbmNvZGUgbG93IGJpdHNcblxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGRlYy5sb3cubG93ICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBkZWMubG93LmxvdyA+PiA4ICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBkZWMubG93LmxvdyA+PiAxNiAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gZGVjLmxvdy5sb3cgPj4gMjQgJiAweGZmOyAvLyBFbmNvZGUgaGlnaCBiaXRzXG5cblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBkZWMubG93LmhpZ2ggJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGRlYy5sb3cuaGlnaCA+PiA4ICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBkZWMubG93LmhpZ2ggPj4gMTYgJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGRlYy5sb3cuaGlnaCA+PiAyNCAmIDB4ZmY7IC8vIEVuY29kZSB0aGUgaGlnaCA2NCBiaXRzIG9mIHRoZSBkZWNpbWFsXG5cdCAgLy8gRW5jb2RlIGxvdyBiaXRzXG5cblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBkZWMuaGlnaC5sb3cgJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGRlYy5oaWdoLmxvdyA+PiA4ICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBkZWMuaGlnaC5sb3cgPj4gMTYgJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGRlYy5oaWdoLmxvdyA+PiAyNCAmIDB4ZmY7IC8vIEVuY29kZSBoaWdoIGJpdHNcblxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGRlYy5oaWdoLmhpZ2ggJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGRlYy5oaWdoLmhpZ2ggPj4gOCAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gZGVjLmhpZ2guaGlnaCA+PiAxNiAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gZGVjLmhpZ2guaGlnaCA+PiAyNCAmIDB4ZmY7IC8vIFJldHVybiB0aGUgbmV3IERlY2ltYWwxMjhcblxuXHQgIHJldHVybiBuZXcgRGVjaW1hbDEyOChidWZmZXIkJDEpO1xuXHR9OyAvLyBFeHRyYWN0IGxlYXN0IHNpZ25pZmljYW50IDUgYml0c1xuXG5cblx0dmFyIENPTUJJTkFUSU9OX01BU0sgPSAweDFmOyAvLyBFeHRyYWN0IGxlYXN0IHNpZ25pZmljYW50IDE0IGJpdHNcblxuXHR2YXIgRVhQT05FTlRfTUFTSyA9IDB4M2ZmZjsgLy8gVmFsdWUgb2YgY29tYmluYXRpb24gZmllbGQgZm9yIEluZlxuXG5cdHZhciBDT01CSU5BVElPTl9JTkZJTklUWSA9IDMwOyAvLyBWYWx1ZSBvZiBjb21iaW5hdGlvbiBmaWVsZCBmb3IgTmFOXG5cblx0dmFyIENPTUJJTkFUSU9OX05BTiA9IDMxO1xuXHQvKipcblx0ICogQ3JlYXRlIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSByYXcgRGVjaW1hbDEyOCB2YWx1ZVxuXHQgKlxuXHQgKiBAbWV0aG9kXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gcmV0dXJucyBhIERlY2ltYWwxMjggc3RyaW5nIHJlcHJlc2VudGF0aW9uLlxuXHQgKi9cblxuXHREZWNpbWFsMTI4LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcblx0ICAvLyBOb3RlOiBiaXRzIGluIHRoaXMgcm91dGluZSBhcmUgcmVmZXJyZWQgdG8gc3RhcnRpbmcgYXQgMCxcblx0ICAvLyBmcm9tIHRoZSBzaWduIGJpdCwgdG93YXJkcyB0aGUgY29lZmZpY2llbnQuXG5cdCAgLy8gYml0cyAwIC0gMzFcblx0ICB2YXIgaGlnaDsgLy8gYml0cyAzMiAtIDYzXG5cblx0ICB2YXIgbWlkaDsgLy8gYml0cyA2NCAtIDk1XG5cblx0ICB2YXIgbWlkbDsgLy8gYml0cyA5NiAtIDEyN1xuXG5cdCAgdmFyIGxvdzsgLy8gYml0cyAxIC0gNVxuXG5cdCAgdmFyIGNvbWJpbmF0aW9uOyAvLyBkZWNvZGVkIGJpYXNlZCBleHBvbmVudCAoMTQgYml0cylcblxuXHQgIHZhciBiaWFzZWRfZXhwb25lbnQ7IC8vIHRoZSBudW1iZXIgb2Ygc2lnbmlmaWNhbmQgZGlnaXRzXG5cblx0ICB2YXIgc2lnbmlmaWNhbmRfZGlnaXRzID0gMDsgLy8gdGhlIGJhc2UtMTAgZGlnaXRzIGluIHRoZSBzaWduaWZpY2FuZFxuXG5cdCAgdmFyIHNpZ25pZmljYW5kID0gbmV3IEFycmF5KDM2KTtcblxuXHQgIGZvciAodmFyIGkgPSAwOyBpIDwgc2lnbmlmaWNhbmQubGVuZ3RoOyBpKyspIHtcblx0ICAgIHNpZ25pZmljYW5kW2ldID0gMDtcblx0ICB9IC8vIHJlYWQgcG9pbnRlciBpbnRvIHNpZ25pZmljYW5kXG5cblxuXHQgIHZhciBpbmRleCA9IDA7IC8vIHVuYmlhc2VkIGV4cG9uZW50XG5cblx0ICB2YXIgZXhwb25lbnQ7IC8vIHRoZSBleHBvbmVudCBpZiBzY2llbnRpZmljIG5vdGF0aW9uIGlzIHVzZWRcblxuXHQgIHZhciBzY2llbnRpZmljX2V4cG9uZW50OyAvLyB0cnVlIGlmIHRoZSBudW1iZXIgaXMgemVyb1xuXG5cdCAgdmFyIGlzX3plcm8gPSBmYWxzZTsgLy8gdGhlIG1vc3Qgc2lnbmlmY2FudCBzaWduaWZpY2FuZCBiaXRzICg1MC00NilcblxuXHQgIHZhciBzaWduaWZpY2FuZF9tc2I7IC8vIHRlbXBvcmFyeSBzdG9yYWdlIGZvciBzaWduaWZpY2FuZCBkZWNvZGluZ1xuXG5cdCAgdmFyIHNpZ25pZmljYW5kMTI4ID0ge1xuXHQgICAgcGFydHM6IG5ldyBBcnJheSg0KVxuXHQgIH07IC8vIGluZGV4aW5nIHZhcmlhYmxlc1xuXG5cdCAgdmFyIGosIGs7IC8vIE91dHB1dCBzdHJpbmdcblxuXHQgIHZhciBzdHJpbmcgPSBbXTsgLy8gVW5wYWNrIGluZGV4XG5cblx0ICBpbmRleCA9IDA7IC8vIEJ1ZmZlciByZWZlcmVuY2VcblxuXHQgIHZhciBidWZmZXIkJDEgPSB0aGlzLmJ5dGVzOyAvLyBVbnBhY2sgdGhlIGxvdyA2NGJpdHMgaW50byBhIGxvbmdcblxuXHQgIGxvdyA9IGJ1ZmZlciQkMVtpbmRleCsrXSB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCA4IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDE2IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDI0O1xuXHQgIG1pZGwgPSBidWZmZXIkJDFbaW5kZXgrK10gfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAyNDsgLy8gVW5wYWNrIHRoZSBoaWdoIDY0Yml0cyBpbnRvIGEgbG9uZ1xuXG5cdCAgbWlkaCA9IGJ1ZmZlciQkMVtpbmRleCsrXSB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCA4IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDE2IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDI0O1xuXHQgIGhpZ2ggPSBidWZmZXIkJDFbaW5kZXgrK10gfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAyNDsgLy8gVW5wYWNrIGluZGV4XG5cblx0ICBpbmRleCA9IDA7IC8vIENyZWF0ZSB0aGUgc3RhdGUgb2YgdGhlIGRlY2ltYWxcblxuXHQgIHZhciBkZWMgPSB7XG5cdCAgICBsb3c6IG5ldyBsb25nXzEobG93LCBtaWRsKSxcblx0ICAgIGhpZ2g6IG5ldyBsb25nXzEobWlkaCwgaGlnaClcblx0ICB9O1xuXG5cdCAgaWYgKGRlYy5oaWdoLmxlc3NUaGFuKGxvbmdfMS5aRVJPKSkge1xuXHQgICAgc3RyaW5nLnB1c2goJy0nKTtcblx0ICB9IC8vIERlY29kZSBjb21iaW5hdGlvbiBmaWVsZCBhbmQgZXhwb25lbnRcblxuXG5cdCAgY29tYmluYXRpb24gPSBoaWdoID4+IDI2ICYgQ09NQklOQVRJT05fTUFTSztcblxuXHQgIGlmIChjb21iaW5hdGlvbiA+PiAzID09PSAzKSB7XG5cdCAgICAvLyBDaGVjayBmb3IgJ3NwZWNpYWwnIHZhbHVlc1xuXHQgICAgaWYgKGNvbWJpbmF0aW9uID09PSBDT01CSU5BVElPTl9JTkZJTklUWSkge1xuXHQgICAgICByZXR1cm4gc3RyaW5nLmpvaW4oJycpICsgJ0luZmluaXR5Jztcblx0ICAgIH0gZWxzZSBpZiAoY29tYmluYXRpb24gPT09IENPTUJJTkFUSU9OX05BTikge1xuXHQgICAgICByZXR1cm4gJ05hTic7XG5cdCAgICB9IGVsc2Uge1xuXHQgICAgICBiaWFzZWRfZXhwb25lbnQgPSBoaWdoID4+IDE1ICYgRVhQT05FTlRfTUFTSztcblx0ICAgICAgc2lnbmlmaWNhbmRfbXNiID0gMHgwOCArIChoaWdoID4+IDE0ICYgMHgwMSk7XG5cdCAgICB9XG5cdCAgfSBlbHNlIHtcblx0ICAgIHNpZ25pZmljYW5kX21zYiA9IGhpZ2ggPj4gMTQgJiAweDA3O1xuXHQgICAgYmlhc2VkX2V4cG9uZW50ID0gaGlnaCA+PiAxNyAmIEVYUE9ORU5UX01BU0s7XG5cdCAgfVxuXG5cdCAgZXhwb25lbnQgPSBiaWFzZWRfZXhwb25lbnQgLSBFWFBPTkVOVF9CSUFTOyAvLyBDcmVhdGUgc3RyaW5nIG9mIHNpZ25pZmljYW5kIGRpZ2l0c1xuXHQgIC8vIENvbnZlcnQgdGhlIDExNC1iaXQgYmluYXJ5IG51bWJlciByZXByZXNlbnRlZCBieVxuXHQgIC8vIChzaWduaWZpY2FuZF9oaWdoLCBzaWduaWZpY2FuZF9sb3cpIHRvIGF0IG1vc3QgMzQgZGVjaW1hbFxuXHQgIC8vIGRpZ2l0cyB0aHJvdWdoIG1vZHVsbyBhbmQgZGl2aXNpb24uXG5cblx0ICBzaWduaWZpY2FuZDEyOC5wYXJ0c1swXSA9IChoaWdoICYgMHgzZmZmKSArICgoc2lnbmlmaWNhbmRfbXNiICYgMHhmKSA8PCAxNCk7XG5cdCAgc2lnbmlmaWNhbmQxMjgucGFydHNbMV0gPSBtaWRoO1xuXHQgIHNpZ25pZmljYW5kMTI4LnBhcnRzWzJdID0gbWlkbDtcblx0ICBzaWduaWZpY2FuZDEyOC5wYXJ0c1szXSA9IGxvdztcblxuXHQgIGlmIChzaWduaWZpY2FuZDEyOC5wYXJ0c1swXSA9PT0gMCAmJiBzaWduaWZpY2FuZDEyOC5wYXJ0c1sxXSA9PT0gMCAmJiBzaWduaWZpY2FuZDEyOC5wYXJ0c1syXSA9PT0gMCAmJiBzaWduaWZpY2FuZDEyOC5wYXJ0c1szXSA9PT0gMCkge1xuXHQgICAgaXNfemVybyA9IHRydWU7XG5cdCAgfSBlbHNlIHtcblx0ICAgIGZvciAoayA9IDM7IGsgPj0gMDsgay0tKSB7XG5cdCAgICAgIHZhciBsZWFzdF9kaWdpdHMgPSAwOyAvLyBQZWZvcm0gdGhlIGRpdmlkZVxuXG5cdCAgICAgIHZhciByZXN1bHQgPSBkaXZpZGV1MTI4KHNpZ25pZmljYW5kMTI4KTtcblx0ICAgICAgc2lnbmlmaWNhbmQxMjggPSByZXN1bHQucXVvdGllbnQ7XG5cdCAgICAgIGxlYXN0X2RpZ2l0cyA9IHJlc3VsdC5yZW0ubG93OyAvLyBXZSBub3cgaGF2ZSB0aGUgOSBsZWFzdCBzaWduaWZpY2FudCBkaWdpdHMgKGluIGJhc2UgMikuXG5cdCAgICAgIC8vIENvbnZlcnQgYW5kIG91dHB1dCB0byBzdHJpbmcuXG5cblx0ICAgICAgaWYgKCFsZWFzdF9kaWdpdHMpIGNvbnRpbnVlO1xuXG5cdCAgICAgIGZvciAoaiA9IDg7IGogPj0gMDsgai0tKSB7XG5cdCAgICAgICAgLy8gc2lnbmlmaWNhbmRbayAqIDkgKyBqXSA9IE1hdGgucm91bmQobGVhc3RfZGlnaXRzICUgMTApO1xuXHQgICAgICAgIHNpZ25pZmljYW5kW2sgKiA5ICsgal0gPSBsZWFzdF9kaWdpdHMgJSAxMDsgLy8gbGVhc3RfZGlnaXRzID0gTWF0aC5yb3VuZChsZWFzdF9kaWdpdHMgLyAxMCk7XG5cblx0ICAgICAgICBsZWFzdF9kaWdpdHMgPSBNYXRoLmZsb29yKGxlYXN0X2RpZ2l0cyAvIDEwKTtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0gLy8gT3V0cHV0IGZvcm1hdCBvcHRpb25zOlxuXHQgIC8vIFNjaWVudGlmaWMgLSBbLV1kLmRkZEUoKy8tKWRkIG9yIFstXWRFKCsvLSlkZFxuXHQgIC8vIFJlZ3VsYXIgICAgLSBkZGQuZGRkXG5cblxuXHQgIGlmIChpc196ZXJvKSB7XG5cdCAgICBzaWduaWZpY2FuZF9kaWdpdHMgPSAxO1xuXHQgICAgc2lnbmlmaWNhbmRbaW5kZXhdID0gMDtcblx0ICB9IGVsc2Uge1xuXHQgICAgc2lnbmlmaWNhbmRfZGlnaXRzID0gMzY7XG5cblx0ICAgIHdoaWxlICghc2lnbmlmaWNhbmRbaW5kZXhdKSB7XG5cdCAgICAgIHNpZ25pZmljYW5kX2RpZ2l0cyA9IHNpZ25pZmljYW5kX2RpZ2l0cyAtIDE7XG5cdCAgICAgIGluZGV4ID0gaW5kZXggKyAxO1xuXHQgICAgfVxuXHQgIH1cblxuXHQgIHNjaWVudGlmaWNfZXhwb25lbnQgPSBzaWduaWZpY2FuZF9kaWdpdHMgLSAxICsgZXhwb25lbnQ7IC8vIFRoZSBzY2llbnRpZmljIGV4cG9uZW50IGNoZWNrcyBhcmUgZGljdGF0ZWQgYnkgdGhlIHN0cmluZyBjb252ZXJzaW9uXG5cdCAgLy8gc3BlY2lmaWNhdGlvbiBhbmQgYXJlIHNvbWV3aGF0IGFyYml0cmFyeSBjdXRvZmZzLlxuXHQgIC8vXG5cdCAgLy8gV2UgbXVzdCBjaGVjayBleHBvbmVudCA+IDAsIGJlY2F1c2UgaWYgdGhpcyBpcyB0aGUgY2FzZSwgdGhlIG51bWJlclxuXHQgIC8vIGhhcyB0cmFpbGluZyB6ZXJvcy4gIEhvd2V2ZXIsIHdlICpjYW5ub3QqIG91dHB1dCB0aGVzZSB0cmFpbGluZyB6ZXJvcyxcblx0ICAvLyBiZWNhdXNlIGRvaW5nIHNvIHdvdWxkIGNoYW5nZSB0aGUgcHJlY2lzaW9uIG9mIHRoZSB2YWx1ZSwgYW5kIHdvdWxkXG5cdCAgLy8gY2hhbmdlIHN0b3JlZCBkYXRhIGlmIHRoZSBzdHJpbmcgY29udmVydGVkIG51bWJlciBpcyByb3VuZCB0cmlwcGVkLlxuXG5cdCAgaWYgKHNjaWVudGlmaWNfZXhwb25lbnQgPj0gMzQgfHwgc2NpZW50aWZpY19leHBvbmVudCA8PSAtNyB8fCBleHBvbmVudCA+IDApIHtcblx0ICAgIC8vIFNjaWVudGlmaWMgZm9ybWF0XG5cdCAgICAvLyBpZiB0aGVyZSBhcmUgdG9vIG1hbnkgc2lnbmlmaWNhbnQgZGlnaXRzLCB3ZSBzaG91bGQganVzdCBiZSB0cmVhdGluZyBudW1iZXJzXG5cdCAgICAvLyBhcyArIG9yIC0gMCBhbmQgdXNpbmcgdGhlIG5vbi1zY2llbnRpZmljIGV4cG9uZW50ICh0aGlzIGlzIGZvciB0aGUgXCJpbnZhbGlkXG5cdCAgICAvLyByZXByZXNlbnRhdGlvbiBzaG91bGQgYmUgdHJlYXRlZCBhcyAwLy0wXCIgc3BlYyBjYXNlcyBpbiBkZWNpbWFsMTI4LTEuanNvbilcblx0ICAgIGlmIChzaWduaWZpY2FuZF9kaWdpdHMgPiAzNCkge1xuXHQgICAgICBzdHJpbmcucHVzaCgwKTtcblx0ICAgICAgaWYgKGV4cG9uZW50ID4gMCkgc3RyaW5nLnB1c2goJ0UrJyArIGV4cG9uZW50KTtlbHNlIGlmIChleHBvbmVudCA8IDApIHN0cmluZy5wdXNoKCdFJyArIGV4cG9uZW50KTtcblx0ICAgICAgcmV0dXJuIHN0cmluZy5qb2luKCcnKTtcblx0ICAgIH1cblxuXHQgICAgc3RyaW5nLnB1c2goc2lnbmlmaWNhbmRbaW5kZXgrK10pO1xuXHQgICAgc2lnbmlmaWNhbmRfZGlnaXRzID0gc2lnbmlmaWNhbmRfZGlnaXRzIC0gMTtcblxuXHQgICAgaWYgKHNpZ25pZmljYW5kX2RpZ2l0cykge1xuXHQgICAgICBzdHJpbmcucHVzaCgnLicpO1xuXHQgICAgfVxuXG5cdCAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgc2lnbmlmaWNhbmRfZGlnaXRzOyBfaSsrKSB7XG5cdCAgICAgIHN0cmluZy5wdXNoKHNpZ25pZmljYW5kW2luZGV4KytdKTtcblx0ICAgIH0gLy8gRXhwb25lbnRcblxuXG5cdCAgICBzdHJpbmcucHVzaCgnRScpO1xuXG5cdCAgICBpZiAoc2NpZW50aWZpY19leHBvbmVudCA+IDApIHtcblx0ICAgICAgc3RyaW5nLnB1c2goJysnICsgc2NpZW50aWZpY19leHBvbmVudCk7XG5cdCAgICB9IGVsc2Uge1xuXHQgICAgICBzdHJpbmcucHVzaChzY2llbnRpZmljX2V4cG9uZW50KTtcblx0ICAgIH1cblx0ICB9IGVsc2Uge1xuXHQgICAgLy8gUmVndWxhciBmb3JtYXQgd2l0aCBubyBkZWNpbWFsIHBsYWNlXG5cdCAgICBpZiAoZXhwb25lbnQgPj0gMCkge1xuXHQgICAgICBmb3IgKHZhciBfaTIgPSAwOyBfaTIgPCBzaWduaWZpY2FuZF9kaWdpdHM7IF9pMisrKSB7XG5cdCAgICAgICAgc3RyaW5nLnB1c2goc2lnbmlmaWNhbmRbaW5kZXgrK10pO1xuXHQgICAgICB9XG5cdCAgICB9IGVsc2Uge1xuXHQgICAgICB2YXIgcmFkaXhfcG9zaXRpb24gPSBzaWduaWZpY2FuZF9kaWdpdHMgKyBleHBvbmVudDsgLy8gbm9uLXplcm8gZGlnaXRzIGJlZm9yZSByYWRpeFxuXG5cdCAgICAgIGlmIChyYWRpeF9wb3NpdGlvbiA+IDApIHtcblx0ICAgICAgICBmb3IgKHZhciBfaTMgPSAwOyBfaTMgPCByYWRpeF9wb3NpdGlvbjsgX2kzKyspIHtcblx0ICAgICAgICAgIHN0cmluZy5wdXNoKHNpZ25pZmljYW5kW2luZGV4KytdKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgc3RyaW5nLnB1c2goJzAnKTtcblx0ICAgICAgfVxuXG5cdCAgICAgIHN0cmluZy5wdXNoKCcuJyk7IC8vIGFkZCBsZWFkaW5nIHplcm9zIGFmdGVyIHJhZGl4XG5cblx0ICAgICAgd2hpbGUgKHJhZGl4X3Bvc2l0aW9uKysgPCAwKSB7XG5cdCAgICAgICAgc3RyaW5nLnB1c2goJzAnKTtcblx0ICAgICAgfVxuXG5cdCAgICAgIGZvciAodmFyIF9pNCA9IDA7IF9pNCA8IHNpZ25pZmljYW5kX2RpZ2l0cyAtIE1hdGgubWF4KHJhZGl4X3Bvc2l0aW9uIC0gMSwgMCk7IF9pNCsrKSB7XG5cdCAgICAgICAgc3RyaW5nLnB1c2goc2lnbmlmaWNhbmRbaW5kZXgrK10pO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfVxuXG5cdCAgcmV0dXJuIHN0cmluZy5qb2luKCcnKTtcblx0fTtcblxuXHREZWNpbWFsMTI4LnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiAoKSB7XG5cdCAgcmV0dXJuIHtcblx0ICAgICRudW1iZXJEZWNpbWFsOiB0aGlzLnRvU3RyaW5nKClcblx0ICB9O1xuXHR9O1xuXHQvKipcblx0ICogQGlnbm9yZVxuXHQgKi9cblxuXG5cdERlY2ltYWwxMjgucHJvdG90eXBlLnRvRXh0ZW5kZWRKU09OID0gZnVuY3Rpb24gKCkge1xuXHQgIHJldHVybiB7XG5cdCAgICAkbnVtYmVyRGVjaW1hbDogdGhpcy50b1N0cmluZygpXG5cdCAgfTtcblx0fTtcblx0LyoqXG5cdCAqIEBpZ25vcmVcblx0ICovXG5cblxuXHREZWNpbWFsMTI4LmZyb21FeHRlbmRlZEpTT04gPSBmdW5jdGlvbiAoZG9jKSB7XG5cdCAgcmV0dXJuIERlY2ltYWwxMjguZnJvbVN0cmluZyhkb2MuJG51bWJlckRlY2ltYWwpO1xuXHR9O1xuXG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShEZWNpbWFsMTI4LnByb3RvdHlwZSwgJ19ic29udHlwZScsIHtcblx0ICB2YWx1ZTogJ0RlY2ltYWwxMjgnXG5cdH0pO1xuXHR2YXIgZGVjaW1hbDEyOCA9IERlY2ltYWwxMjg7XG5cblx0LyoqXG5cdCAqIEEgY2xhc3MgcmVwcmVzZW50YXRpb24gb2YgdGhlIEJTT04gTWluS2V5IHR5cGUuXG5cdCAqL1xuXG5cdGZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayQ3KGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxuXHRmdW5jdGlvbiBfZGVmaW5lUHJvcGVydGllcyQ3KHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH1cblxuXHRmdW5jdGlvbiBfY3JlYXRlQ2xhc3MkNyhDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzJDcoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyQ3KENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfVxuXG5cdHZhciBNaW5LZXkgPVxuXHQvKiNfX1BVUkVfXyovXG5cdGZ1bmN0aW9uICgpIHtcblx0ICAvKipcblx0ICAgKiBDcmVhdGUgYSBNaW5LZXkgdHlwZVxuXHQgICAqXG5cdCAgICogQHJldHVybiB7TWluS2V5fSBBIE1pbktleSBpbnN0YW5jZVxuXHQgICAqL1xuXHQgIGZ1bmN0aW9uIE1pbktleSgpIHtcblx0ICAgIF9jbGFzc0NhbGxDaGVjayQ3KHRoaXMsIE1pbktleSk7XG5cdCAgfVxuXHQgIC8qKlxuXHQgICAqIEBpZ25vcmVcblx0ICAgKi9cblxuXG5cdCAgX2NyZWF0ZUNsYXNzJDcoTWluS2V5LCBbe1xuXHQgICAga2V5OiBcInRvRXh0ZW5kZWRKU09OXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gdG9FeHRlbmRlZEpTT04oKSB7XG5cdCAgICAgIHJldHVybiB7XG5cdCAgICAgICAgJG1pbktleTogMVxuXHQgICAgICB9O1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBAaWdub3JlXG5cdCAgICAgKi9cblxuXHQgIH1dLCBbe1xuXHQgICAga2V5OiBcImZyb21FeHRlbmRlZEpTT05cIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tRXh0ZW5kZWRKU09OKCkge1xuXHQgICAgICByZXR1cm4gbmV3IE1pbktleSgpO1xuXHQgICAgfVxuXHQgIH1dKTtcblxuXHQgIHJldHVybiBNaW5LZXk7XG5cdH0oKTtcblxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoTWluS2V5LnByb3RvdHlwZSwgJ19ic29udHlwZScsIHtcblx0ICB2YWx1ZTogJ01pbktleSdcblx0fSk7XG5cdHZhciBtaW5fa2V5ID0gTWluS2V5O1xuXG5cdC8qKlxuXHQgKiBBIGNsYXNzIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBCU09OIE1heEtleSB0eXBlLlxuXHQgKi9cblxuXHRmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2skOChpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cblx0ZnVuY3Rpb24gX2RlZmluZVByb3BlcnRpZXMkOCh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9XG5cblx0ZnVuY3Rpb24gX2NyZWF0ZUNsYXNzJDgoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyQ4KENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgX2RlZmluZVByb3BlcnRpZXMkOChDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH1cblxuXHR2YXIgTWF4S2V5ID1cblx0LyojX19QVVJFX18qL1xuXHRmdW5jdGlvbiAoKSB7XG5cdCAgLyoqXG5cdCAgICogQ3JlYXRlIGEgTWF4S2V5IHR5cGVcblx0ICAgKlxuXHQgICAqIEByZXR1cm4ge01heEtleX0gQSBNYXhLZXkgaW5zdGFuY2Vcblx0ICAgKi9cblx0ICBmdW5jdGlvbiBNYXhLZXkoKSB7XG5cdCAgICBfY2xhc3NDYWxsQ2hlY2skOCh0aGlzLCBNYXhLZXkpO1xuXHQgIH1cblx0ICAvKipcblx0ICAgKiBAaWdub3JlXG5cdCAgICovXG5cblxuXHQgIF9jcmVhdGVDbGFzcyQ4KE1heEtleSwgW3tcblx0ICAgIGtleTogXCJ0b0V4dGVuZGVkSlNPTlwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHRvRXh0ZW5kZWRKU09OKCkge1xuXHQgICAgICByZXR1cm4ge1xuXHQgICAgICAgICRtYXhLZXk6IDFcblx0ICAgICAgfTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9XSwgW3tcblx0ICAgIGtleTogXCJmcm9tRXh0ZW5kZWRKU09OXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gZnJvbUV4dGVuZGVkSlNPTigpIHtcblx0ICAgICAgcmV0dXJuIG5ldyBNYXhLZXkoKTtcblx0ICAgIH1cblx0ICB9XSk7XG5cblx0ICByZXR1cm4gTWF4S2V5O1xuXHR9KCk7XG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KE1heEtleS5wcm90b3R5cGUsICdfYnNvbnR5cGUnLCB7XG5cdCAgdmFsdWU6ICdNYXhLZXknXG5cdH0pO1xuXHR2YXIgbWF4X2tleSA9IE1heEtleTtcblxuXHQvKipcblx0ICogQSBjbGFzcyByZXByZXNlbnRhdGlvbiBvZiB0aGUgQlNPTiBEQlJlZiB0eXBlLlxuXHQgKi9cblxuXHRmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2skOShpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cblx0ZnVuY3Rpb24gX2RlZmluZVByb3BlcnRpZXMkOSh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9XG5cblx0ZnVuY3Rpb24gX2NyZWF0ZUNsYXNzJDkoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyQ5KENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgX2RlZmluZVByb3BlcnRpZXMkOShDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH1cblxuXHR2YXIgREJSZWYgPVxuXHQvKiNfX1BVUkVfXyovXG5cdGZ1bmN0aW9uICgpIHtcblx0ICAvKipcblx0ICAgKiBDcmVhdGUgYSBEQlJlZiB0eXBlXG5cdCAgICpcblx0ICAgKiBAcGFyYW0ge3N0cmluZ30gY29sbGVjdGlvbiB0aGUgY29sbGVjdGlvbiBuYW1lLlxuXHQgICAqIEBwYXJhbSB7T2JqZWN0SWR9IG9pZCB0aGUgcmVmZXJlbmNlIE9iamVjdElkLlxuXHQgICAqIEBwYXJhbSB7c3RyaW5nfSBbZGJdIG9wdGlvbmFsIGRiIG5hbWUsIGlmIG9taXR0ZWQgdGhlIHJlZmVyZW5jZSBpcyBsb2NhbCB0byB0aGUgY3VycmVudCBkYi5cblx0ICAgKiBAcmV0dXJuIHtEQlJlZn1cblx0ICAgKi9cblx0ICBmdW5jdGlvbiBEQlJlZihjb2xsZWN0aW9uLCBvaWQsIGRiLCBmaWVsZHMpIHtcblx0ICAgIF9jbGFzc0NhbGxDaGVjayQ5KHRoaXMsIERCUmVmKTtcblxuXHQgICAgLy8gY2hlY2sgaWYgbmFtZXNwYWNlIGhhcyBiZWVuIHByb3ZpZGVkXG5cdCAgICB2YXIgcGFydHMgPSBjb2xsZWN0aW9uLnNwbGl0KCcuJyk7XG5cblx0ICAgIGlmIChwYXJ0cy5sZW5ndGggPT09IDIpIHtcblx0ICAgICAgZGIgPSBwYXJ0cy5zaGlmdCgpO1xuXHQgICAgICBjb2xsZWN0aW9uID0gcGFydHMuc2hpZnQoKTtcblx0ICAgIH1cblxuXHQgICAgdGhpcy5jb2xsZWN0aW9uID0gY29sbGVjdGlvbjtcblx0ICAgIHRoaXMub2lkID0gb2lkO1xuXHQgICAgdGhpcy5kYiA9IGRiO1xuXHQgICAgdGhpcy5maWVsZHMgPSBmaWVsZHMgfHwge307XG5cdCAgfVxuXHQgIC8qKlxuXHQgICAqIEBpZ25vcmVcblx0ICAgKiBAYXBpIHByaXZhdGVcblx0ICAgKi9cblxuXG5cdCAgX2NyZWF0ZUNsYXNzJDkoREJSZWYsIFt7XG5cdCAgICBrZXk6IFwidG9KU09OXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gdG9KU09OKCkge1xuXHQgICAgICB2YXIgbyA9IE9iamVjdC5hc3NpZ24oe1xuXHQgICAgICAgICRyZWY6IHRoaXMuY29sbGVjdGlvbixcblx0ICAgICAgICAkaWQ6IHRoaXMub2lkXG5cdCAgICAgIH0sIHRoaXMuZmllbGRzKTtcblx0ICAgICAgaWYgKHRoaXMuZGIgIT0gbnVsbCkgby4kZGIgPSB0aGlzLmRiO1xuXHQgICAgICByZXR1cm4gbztcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwidG9FeHRlbmRlZEpTT05cIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB0b0V4dGVuZGVkSlNPTigpIHtcblx0ICAgICAgdmFyIG8gPSB7XG5cdCAgICAgICAgJHJlZjogdGhpcy5jb2xsZWN0aW9uLFxuXHQgICAgICAgICRpZDogdGhpcy5vaWRcblx0ICAgICAgfTtcblx0ICAgICAgaWYgKHRoaXMuZGIpIG8uJGRiID0gdGhpcy5kYjtcblx0ICAgICAgbyA9IE9iamVjdC5hc3NpZ24obywgdGhpcy5maWVsZHMpO1xuXHQgICAgICByZXR1cm4gbztcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9XSwgW3tcblx0ICAgIGtleTogXCJmcm9tRXh0ZW5kZWRKU09OXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gZnJvbUV4dGVuZGVkSlNPTihkb2MpIHtcblx0ICAgICAgdmFyIGNvcHkgPSBPYmplY3QuYXNzaWduKHt9LCBkb2MpO1xuXHQgICAgICBbJyRyZWYnLCAnJGlkJywgJyRkYiddLmZvckVhY2goZnVuY3Rpb24gKGspIHtcblx0ICAgICAgICByZXR1cm4gZGVsZXRlIGNvcHlba107XG5cdCAgICAgIH0pO1xuXHQgICAgICByZXR1cm4gbmV3IERCUmVmKGRvYy4kcmVmLCBkb2MuJGlkLCBkb2MuJGRiLCBjb3B5KTtcblx0ICAgIH1cblx0ICB9XSk7XG5cblx0ICByZXR1cm4gREJSZWY7XG5cdH0oKTtcblxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoREJSZWYucHJvdG90eXBlLCAnX2Jzb250eXBlJywge1xuXHQgIHZhbHVlOiAnREJSZWYnXG5cdH0pOyAvLyB0aGUgMS54IHBhcnNlciB1c2VkIGEgXCJuYW1lc3BhY2VcIiBwcm9wZXJ0eSwgd2hpbGUgNC54IHVzZXMgXCJjb2xsZWN0aW9uXCIuIFRvIGVuc3VyZSBiYWNrd2FyZHNcblx0Ly8gY29tcGF0aWJpbGl0eSwgbGV0J3MgZXhwb3NlIFwibmFtZXNwYWNlXCJcblxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoREJSZWYucHJvdG90eXBlLCAnbmFtZXNwYWNlJywge1xuXHQgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuXHQgICAgcmV0dXJuIHRoaXMuY29sbGVjdGlvbjtcblx0ICB9LFxuXHQgIHNldDogZnVuY3Rpb24gc2V0KHZhbCkge1xuXHQgICAgdGhpcy5jb2xsZWN0aW9uID0gdmFsO1xuXHQgIH0sXG5cdCAgY29uZmlndXJhYmxlOiBmYWxzZVxuXHR9KTtcblx0dmFyIGRiX3JlZiA9IERCUmVmO1xuXG5cdGZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayRhKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxuXHRmdW5jdGlvbiBfZGVmaW5lUHJvcGVydGllcyRhKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH1cblxuXHRmdW5jdGlvbiBfY3JlYXRlQ2xhc3MkYShDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzJGEoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyRhKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfVxuXG5cdHZhciBCdWZmZXIkMyA9IGJ1ZmZlci5CdWZmZXI7XG5cdC8qKlxuXHQgKiBBIGNsYXNzIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBCU09OIEJpbmFyeSB0eXBlLlxuXHQgKi9cblxuXHR2YXIgQmluYXJ5ID1cblx0LyojX19QVVJFX18qL1xuXHRmdW5jdGlvbiAoKSB7XG5cdCAgLyoqXG5cdCAgICogQ3JlYXRlIGEgQmluYXJ5IHR5cGVcblx0ICAgKlxuXHQgICAqIFN1YiB0eXBlc1xuXHQgICAqICAtICoqQlNPTi5CU09OX0JJTkFSWV9TVUJUWVBFX0RFRkFVTFQqKiwgZGVmYXVsdCBCU09OIHR5cGUuXG5cdCAgICogIC0gKipCU09OLkJTT05fQklOQVJZX1NVQlRZUEVfRlVOQ1RJT04qKiwgQlNPTiBmdW5jdGlvbiB0eXBlLlxuXHQgICAqICAtICoqQlNPTi5CU09OX0JJTkFSWV9TVUJUWVBFX0JZVEVfQVJSQVkqKiwgQlNPTiBieXRlIGFycmF5IHR5cGUuXG5cdCAgICogIC0gKipCU09OLkJTT05fQklOQVJZX1NVQlRZUEVfVVVJRCoqLCBCU09OIHV1aWQgdHlwZS5cblx0ICAgKiAgLSAqKkJTT04uQlNPTl9CSU5BUllfU1VCVFlQRV9NRDUqKiwgQlNPTiBtZDUgdHlwZS5cblx0ICAgKiAgLSAqKkJTT04uQlNPTl9CSU5BUllfU1VCVFlQRV9VU0VSX0RFRklORUQqKiwgQlNPTiB1c2VyIGRlZmluZWQgdHlwZS5cblx0ICAgKlxuXHQgICAqIEBwYXJhbSB7QnVmZmVyfSBidWZmZXIgYSBidWZmZXIgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGJpbmFyeSBkYXRhLlxuXHQgICAqIEBwYXJhbSB7TnVtYmVyfSBbc3ViVHlwZV0gdGhlIG9wdGlvbiBiaW5hcnkgdHlwZS5cblx0ICAgKiBAcmV0dXJuIHtCaW5hcnl9XG5cdCAgICovXG5cdCAgZnVuY3Rpb24gQmluYXJ5KGJ1ZmZlciQkMSwgc3ViVHlwZSkge1xuXHQgICAgX2NsYXNzQ2FsbENoZWNrJGEodGhpcywgQmluYXJ5KTtcblxuXHQgICAgaWYgKGJ1ZmZlciQkMSAhPSBudWxsICYmICEodHlwZW9mIGJ1ZmZlciQkMSA9PT0gJ3N0cmluZycpICYmICFCdWZmZXIkMy5pc0J1ZmZlcihidWZmZXIkJDEpICYmICEoYnVmZmVyJCQxIGluc3RhbmNlb2YgVWludDhBcnJheSkgJiYgIUFycmF5LmlzQXJyYXkoYnVmZmVyJCQxKSkge1xuXHQgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvbmx5IFN0cmluZywgQnVmZmVyLCBVaW50OEFycmF5IG9yIEFycmF5IGFjY2VwdGVkJyk7XG5cdCAgICB9XG5cblx0ICAgIHRoaXMuc3ViX3R5cGUgPSBzdWJUeXBlID09IG51bGwgPyBCU09OX0JJTkFSWV9TVUJUWVBFX0RFRkFVTFQgOiBzdWJUeXBlO1xuXHQgICAgdGhpcy5wb3NpdGlvbiA9IDA7XG5cblx0ICAgIGlmIChidWZmZXIkJDEgIT0gbnVsbCAmJiAhKGJ1ZmZlciQkMSBpbnN0YW5jZW9mIE51bWJlcikpIHtcblx0ICAgICAgLy8gT25seSBhY2NlcHQgQnVmZmVyLCBVaW50OEFycmF5IG9yIEFycmF5c1xuXHQgICAgICBpZiAodHlwZW9mIGJ1ZmZlciQkMSA9PT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAvLyBEaWZmZXJlbnQgd2F5cyBvZiB3cml0aW5nIHRoZSBsZW5ndGggb2YgdGhlIHN0cmluZyBmb3IgdGhlIGRpZmZlcmVudCB0eXBlc1xuXHQgICAgICAgIGlmICh0eXBlb2YgQnVmZmVyJDMgIT09ICd1bmRlZmluZWQnKSB7XG5cdCAgICAgICAgICB0aGlzLmJ1ZmZlciA9IEJ1ZmZlciQzLmZyb20oYnVmZmVyJCQxKTtcblx0ICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJyB8fCBBcnJheS5pc0FycmF5KGJ1ZmZlciQkMSkpIHtcblx0ICAgICAgICAgIHRoaXMuYnVmZmVyID0gd3JpdGVTdHJpbmdUb0FycmF5KGJ1ZmZlciQkMSk7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ29ubHkgU3RyaW5nLCBCdWZmZXIsIFVpbnQ4QXJyYXkgb3IgQXJyYXkgYWNjZXB0ZWQnKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgdGhpcy5idWZmZXIgPSBidWZmZXIkJDE7XG5cdCAgICAgIH1cblxuXHQgICAgICB0aGlzLnBvc2l0aW9uID0gYnVmZmVyJCQxLmxlbmd0aDtcblx0ICAgIH0gZWxzZSB7XG5cdCAgICAgIGlmICh0eXBlb2YgQnVmZmVyJDMgIT09ICd1bmRlZmluZWQnKSB7XG5cdCAgICAgICAgdGhpcy5idWZmZXIgPSBCdWZmZXIkMy5hbGxvYyhCaW5hcnkuQlVGRkVSX1NJWkUpO1xuXHQgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJykge1xuXHQgICAgICAgIHRoaXMuYnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkobmV3IEFycmF5QnVmZmVyKEJpbmFyeS5CVUZGRVJfU0laRSkpO1xuXHQgICAgICB9IGVsc2Uge1xuXHQgICAgICAgIHRoaXMuYnVmZmVyID0gbmV3IEFycmF5KEJpbmFyeS5CVUZGRVJfU0laRSk7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9XG5cdCAgLyoqXG5cdCAgICogVXBkYXRlcyB0aGlzIGJpbmFyeSB3aXRoIGJ5dGVfdmFsdWUuXG5cdCAgICpcblx0ICAgKiBAbWV0aG9kXG5cdCAgICogQHBhcmFtIHtzdHJpbmd9IGJ5dGVfdmFsdWUgYSBzaW5nbGUgYnl0ZSB3ZSB3aXNoIHRvIHdyaXRlLlxuXHQgICAqL1xuXG5cblx0ICBfY3JlYXRlQ2xhc3MkYShCaW5hcnksIFt7XG5cdCAgICBrZXk6IFwicHV0XCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gcHV0KGJ5dGVfdmFsdWUpIHtcblx0ICAgICAgLy8gSWYgaXQncyBhIHN0cmluZyBhbmQgYSBoYXMgbW9yZSB0aGFuIG9uZSBjaGFyYWN0ZXIgdGhyb3cgYW4gZXJyb3Jcblx0ICAgICAgaWYgKGJ5dGVfdmFsdWVbJ2xlbmd0aCddICE9IG51bGwgJiYgdHlwZW9mIGJ5dGVfdmFsdWUgIT09ICdudW1iZXInICYmIGJ5dGVfdmFsdWUubGVuZ3RoICE9PSAxKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdvbmx5IGFjY2VwdHMgc2luZ2xlIGNoYXJhY3RlciBTdHJpbmcsIFVpbnQ4QXJyYXkgb3IgQXJyYXknKTtcblx0ICAgICAgaWYgKHR5cGVvZiBieXRlX3ZhbHVlICE9PSAnbnVtYmVyJyAmJiBieXRlX3ZhbHVlIDwgMCB8fCBieXRlX3ZhbHVlID4gMjU1KSB0aHJvdyBuZXcgVHlwZUVycm9yKCdvbmx5IGFjY2VwdHMgbnVtYmVyIGluIGEgdmFsaWQgdW5zaWduZWQgYnl0ZSByYW5nZSAwLTI1NScpOyAvLyBEZWNvZGUgdGhlIGJ5dGUgdmFsdWUgb25jZVxuXG5cdCAgICAgIHZhciBkZWNvZGVkX2J5dGUgPSBudWxsO1xuXG5cdCAgICAgIGlmICh0eXBlb2YgYnl0ZV92YWx1ZSA9PT0gJ3N0cmluZycpIHtcblx0ICAgICAgICBkZWNvZGVkX2J5dGUgPSBieXRlX3ZhbHVlLmNoYXJDb2RlQXQoMCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoYnl0ZV92YWx1ZVsnbGVuZ3RoJ10gIT0gbnVsbCkge1xuXHQgICAgICAgIGRlY29kZWRfYnl0ZSA9IGJ5dGVfdmFsdWVbMF07XG5cdCAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgZGVjb2RlZF9ieXRlID0gYnl0ZV92YWx1ZTtcblx0ICAgICAgfVxuXG5cdCAgICAgIGlmICh0aGlzLmJ1ZmZlci5sZW5ndGggPiB0aGlzLnBvc2l0aW9uKSB7XG5cdCAgICAgICAgdGhpcy5idWZmZXJbdGhpcy5wb3NpdGlvbisrXSA9IGRlY29kZWRfYnl0ZTtcblx0ICAgICAgfSBlbHNlIHtcblx0ICAgICAgICBpZiAodHlwZW9mIEJ1ZmZlciQzICE9PSAndW5kZWZpbmVkJyAmJiBCdWZmZXIkMy5pc0J1ZmZlcih0aGlzLmJ1ZmZlcikpIHtcblx0ICAgICAgICAgIC8vIENyZWF0ZSBhZGRpdGlvbmFsIG92ZXJmbG93IGJ1ZmZlclxuXHQgICAgICAgICAgdmFyIGJ1ZmZlciQkMSA9IEJ1ZmZlciQzLmFsbG9jKEJpbmFyeS5CVUZGRVJfU0laRSArIHRoaXMuYnVmZmVyLmxlbmd0aCk7IC8vIENvbWJpbmUgdGhlIHR3byBidWZmZXJzIHRvZ2V0aGVyXG5cblx0ICAgICAgICAgIHRoaXMuYnVmZmVyLmNvcHkoYnVmZmVyJCQxLCAwLCAwLCB0aGlzLmJ1ZmZlci5sZW5ndGgpO1xuXHQgICAgICAgICAgdGhpcy5idWZmZXIgPSBidWZmZXIkJDE7XG5cdCAgICAgICAgICB0aGlzLmJ1ZmZlclt0aGlzLnBvc2l0aW9uKytdID0gZGVjb2RlZF9ieXRlO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICB2YXIgX2J1ZmZlciA9IG51bGw7IC8vIENyZWF0ZSBhIG5ldyBidWZmZXIgKHR5cGVkIG9yIG5vcm1hbCBhcnJheSlcblxuXHQgICAgICAgICAgaWYgKGlzVWludDhBcnJheSh0aGlzLmJ1ZmZlcikpIHtcblx0ICAgICAgICAgICAgX2J1ZmZlciA9IG5ldyBVaW50OEFycmF5KG5ldyBBcnJheUJ1ZmZlcihCaW5hcnkuQlVGRkVSX1NJWkUgKyB0aGlzLmJ1ZmZlci5sZW5ndGgpKTtcblx0ICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIF9idWZmZXIgPSBuZXcgQXJyYXkoQmluYXJ5LkJVRkZFUl9TSVpFICsgdGhpcy5idWZmZXIubGVuZ3RoKTtcblx0ICAgICAgICAgIH0gLy8gV2UgbmVlZCB0byBjb3B5IGFsbCB0aGUgY29udGVudCB0byB0aGUgbmV3IGFycmF5XG5cblxuXHQgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmJ1ZmZlci5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgICBfYnVmZmVyW2ldID0gdGhpcy5idWZmZXJbaV07XG5cdCAgICAgICAgICB9IC8vIFJlYXNzaWduIHRoZSBidWZmZXJcblxuXG5cdCAgICAgICAgICB0aGlzLmJ1ZmZlciA9IF9idWZmZXI7IC8vIFdyaXRlIHRoZSBieXRlXG5cblx0ICAgICAgICAgIHRoaXMuYnVmZmVyW3RoaXMucG9zaXRpb24rK10gPSBkZWNvZGVkX2J5dGU7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFdyaXRlcyBhIGJ1ZmZlciBvciBzdHJpbmcgdG8gdGhlIGJpbmFyeS5cblx0ICAgICAqXG5cdCAgICAgKiBAbWV0aG9kXG5cdCAgICAgKiBAcGFyYW0geyhCdWZmZXJ8c3RyaW5nKX0gc3RyaW5nIGEgc3RyaW5nIG9yIGJ1ZmZlciB0byBiZSB3cml0dGVuIHRvIHRoZSBCaW5hcnkgQlNPTiBvYmplY3QuXG5cdCAgICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IHNwZWNpZnkgdGhlIGJpbmFyeSBvZiB3aGVyZSB0byB3cml0ZSB0aGUgY29udGVudC5cblx0ICAgICAqIEByZXR1cm4ge251bGx9XG5cdCAgICAgKi9cblxuXHQgIH0sIHtcblx0ICAgIGtleTogXCJ3cml0ZVwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHdyaXRlKHN0cmluZywgb2Zmc2V0KSB7XG5cdCAgICAgIG9mZnNldCA9IHR5cGVvZiBvZmZzZXQgPT09ICdudW1iZXInID8gb2Zmc2V0IDogdGhpcy5wb3NpdGlvbjsgLy8gSWYgdGhlIGJ1ZmZlciBpcyB0byBzbWFsbCBsZXQncyBleHRlbmQgdGhlIGJ1ZmZlclxuXG5cdCAgICAgIGlmICh0aGlzLmJ1ZmZlci5sZW5ndGggPCBvZmZzZXQgKyBzdHJpbmcubGVuZ3RoKSB7XG5cdCAgICAgICAgdmFyIGJ1ZmZlciQkMSA9IG51bGw7IC8vIElmIHdlIGFyZSBpbiBub2RlLmpzXG5cblx0ICAgICAgICBpZiAodHlwZW9mIEJ1ZmZlciQzICE9PSAndW5kZWZpbmVkJyAmJiBCdWZmZXIkMy5pc0J1ZmZlcih0aGlzLmJ1ZmZlcikpIHtcblx0ICAgICAgICAgIGJ1ZmZlciQkMSA9IEJ1ZmZlciQzLmFsbG9jKHRoaXMuYnVmZmVyLmxlbmd0aCArIHN0cmluZy5sZW5ndGgpO1xuXHQgICAgICAgICAgdGhpcy5idWZmZXIuY29weShidWZmZXIkJDEsIDAsIDAsIHRoaXMuYnVmZmVyLmxlbmd0aCk7XG5cdCAgICAgICAgfSBlbHNlIGlmIChpc1VpbnQ4QXJyYXkodGhpcy5idWZmZXIpKSB7XG5cdCAgICAgICAgICAvLyBDcmVhdGUgYSBuZXcgYnVmZmVyXG5cdCAgICAgICAgICBidWZmZXIkJDEgPSBuZXcgVWludDhBcnJheShuZXcgQXJyYXlCdWZmZXIodGhpcy5idWZmZXIubGVuZ3RoICsgc3RyaW5nLmxlbmd0aCkpOyAvLyBDb3B5IHRoZSBjb250ZW50XG5cblx0ICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wb3NpdGlvbjsgaSsrKSB7XG5cdCAgICAgICAgICAgIGJ1ZmZlciQkMVtpXSA9IHRoaXMuYnVmZmVyW2ldO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH0gLy8gQXNzaWduIHRoZSBuZXcgYnVmZmVyXG5cblxuXHQgICAgICAgIHRoaXMuYnVmZmVyID0gYnVmZmVyJCQxO1xuXHQgICAgICB9XG5cblx0ICAgICAgaWYgKHR5cGVvZiBCdWZmZXIkMyAhPT0gJ3VuZGVmaW5lZCcgJiYgQnVmZmVyJDMuaXNCdWZmZXIoc3RyaW5nKSAmJiBCdWZmZXIkMy5pc0J1ZmZlcih0aGlzLmJ1ZmZlcikpIHtcblx0ICAgICAgICBzdHJpbmcuY29weSh0aGlzLmJ1ZmZlciwgb2Zmc2V0LCAwLCBzdHJpbmcubGVuZ3RoKTtcblx0ICAgICAgICB0aGlzLnBvc2l0aW9uID0gb2Zmc2V0ICsgc3RyaW5nLmxlbmd0aCA+IHRoaXMucG9zaXRpb24gPyBvZmZzZXQgKyBzdHJpbmcubGVuZ3RoIDogdGhpcy5wb3NpdGlvbjsgLy8gb2Zmc2V0ID0gc3RyaW5nLmxlbmd0aFxuXHQgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBCdWZmZXIkMyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIHN0cmluZyA9PT0gJ3N0cmluZycgJiYgQnVmZmVyJDMuaXNCdWZmZXIodGhpcy5idWZmZXIpKSB7XG5cdCAgICAgICAgdGhpcy5idWZmZXIud3JpdGUoc3RyaW5nLCBvZmZzZXQsICdiaW5hcnknKTtcblx0ICAgICAgICB0aGlzLnBvc2l0aW9uID0gb2Zmc2V0ICsgc3RyaW5nLmxlbmd0aCA+IHRoaXMucG9zaXRpb24gPyBvZmZzZXQgKyBzdHJpbmcubGVuZ3RoIDogdGhpcy5wb3NpdGlvbjsgLy8gb2Zmc2V0ID0gc3RyaW5nLmxlbmd0aDtcblx0ICAgICAgfSBlbHNlIGlmIChpc1VpbnQ4QXJyYXkoc3RyaW5nKSB8fCBBcnJheS5pc0FycmF5KHN0cmluZykgJiYgdHlwZW9mIHN0cmluZyAhPT0gJ3N0cmluZycpIHtcblx0ICAgICAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgc3RyaW5nLmxlbmd0aDsgX2krKykge1xuXHQgICAgICAgICAgdGhpcy5idWZmZXJbb2Zmc2V0KytdID0gc3RyaW5nW19pXTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICB0aGlzLnBvc2l0aW9uID0gb2Zmc2V0ID4gdGhpcy5wb3NpdGlvbiA/IG9mZnNldCA6IHRoaXMucG9zaXRpb247XG5cdCAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHN0cmluZyA9PT0gJ3N0cmluZycpIHtcblx0ICAgICAgICBmb3IgKHZhciBfaTIgPSAwOyBfaTIgPCBzdHJpbmcubGVuZ3RoOyBfaTIrKykge1xuXHQgICAgICAgICAgdGhpcy5idWZmZXJbb2Zmc2V0KytdID0gc3RyaW5nLmNoYXJDb2RlQXQoX2kyKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICB0aGlzLnBvc2l0aW9uID0gb2Zmc2V0ID4gdGhpcy5wb3NpdGlvbiA/IG9mZnNldCA6IHRoaXMucG9zaXRpb247XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVhZHMgKipsZW5ndGgqKiBieXRlcyBzdGFydGluZyBhdCAqKnBvc2l0aW9uKiouXG5cdCAgICAgKlxuXHQgICAgICogQG1ldGhvZFxuXHQgICAgICogQHBhcmFtIHtudW1iZXJ9IHBvc2l0aW9uIHJlYWQgZnJvbSB0aGUgZ2l2ZW4gcG9zaXRpb24gaW4gdGhlIEJpbmFyeS5cblx0ICAgICAqIEBwYXJhbSB7bnVtYmVyfSBsZW5ndGggdGhlIG51bWJlciBvZiBieXRlcyB0byByZWFkLlxuXHQgICAgICogQHJldHVybiB7QnVmZmVyfVxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwicmVhZFwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHJlYWQocG9zaXRpb24sIGxlbmd0aCkge1xuXHQgICAgICBsZW5ndGggPSBsZW5ndGggJiYgbGVuZ3RoID4gMCA/IGxlbmd0aCA6IHRoaXMucG9zaXRpb247IC8vIExldCdzIHJldHVybiB0aGUgZGF0YSBiYXNlZCBvbiB0aGUgdHlwZSB3ZSBoYXZlXG5cblx0ICAgICAgaWYgKHRoaXMuYnVmZmVyWydzbGljZSddKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuYnVmZmVyLnNsaWNlKHBvc2l0aW9uLCBwb3NpdGlvbiArIGxlbmd0aCk7XG5cdCAgICAgIH0gLy8gQ3JlYXRlIGEgYnVmZmVyIHRvIGtlZXAgdGhlIHJlc3VsdFxuXG5cblx0ICAgICAgdmFyIGJ1ZmZlciQkMSA9IHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJyA/IG5ldyBVaW50OEFycmF5KG5ldyBBcnJheUJ1ZmZlcihsZW5ndGgpKSA6IG5ldyBBcnJheShsZW5ndGgpO1xuXG5cdCAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICBidWZmZXIkJDFbaV0gPSB0aGlzLmJ1ZmZlcltwb3NpdGlvbisrXTtcblx0ICAgICAgfSAvLyBSZXR1cm4gdGhlIGJ1ZmZlclxuXG5cblx0ICAgICAgcmV0dXJuIGJ1ZmZlciQkMTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhpcyBiaW5hcnkgYXMgYSBzdHJpbmcuXG5cdCAgICAgKlxuXHQgICAgICogQG1ldGhvZFxuXHQgICAgICogQHJldHVybiB7c3RyaW5nfVxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwidmFsdWVcIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB2YWx1ZShhc1Jhdykge1xuXHQgICAgICBhc1JhdyA9IGFzUmF3ID09IG51bGwgPyBmYWxzZSA6IGFzUmF3OyAvLyBPcHRpbWl6ZSB0byBzZXJpYWxpemUgZm9yIHRoZSBzaXR1YXRpb24gd2hlcmUgdGhlIGRhdGEgPT0gc2l6ZSBvZiBidWZmZXJcblxuXHQgICAgICBpZiAoYXNSYXcgJiYgdHlwZW9mIEJ1ZmZlciQzICE9PSAndW5kZWZpbmVkJyAmJiBCdWZmZXIkMy5pc0J1ZmZlcih0aGlzLmJ1ZmZlcikgJiYgdGhpcy5idWZmZXIubGVuZ3RoID09PSB0aGlzLnBvc2l0aW9uKSByZXR1cm4gdGhpcy5idWZmZXI7IC8vIElmIGl0J3MgYSBub2RlLmpzIGJ1ZmZlciBvYmplY3RcblxuXHQgICAgICBpZiAodHlwZW9mIEJ1ZmZlciQzICE9PSAndW5kZWZpbmVkJyAmJiBCdWZmZXIkMy5pc0J1ZmZlcih0aGlzLmJ1ZmZlcikpIHtcblx0ICAgICAgICByZXR1cm4gYXNSYXcgPyB0aGlzLmJ1ZmZlci5zbGljZSgwLCB0aGlzLnBvc2l0aW9uKSA6IHRoaXMuYnVmZmVyLnRvU3RyaW5nKCdiaW5hcnknLCAwLCB0aGlzLnBvc2l0aW9uKTtcblx0ICAgICAgfSBlbHNlIHtcblx0ICAgICAgICBpZiAoYXNSYXcpIHtcblx0ICAgICAgICAgIC8vIHdlIHN1cHBvcnQgdGhlIHNsaWNlIGNvbW1hbmQgdXNlIGl0XG5cdCAgICAgICAgICBpZiAodGhpcy5idWZmZXJbJ3NsaWNlJ10gIT0gbnVsbCkge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5idWZmZXIuc2xpY2UoMCwgdGhpcy5wb3NpdGlvbik7XG5cdCAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAvLyBDcmVhdGUgYSBuZXcgYnVmZmVyIHRvIGNvcHkgY29udGVudCB0b1xuXHQgICAgICAgICAgICB2YXIgbmV3QnVmZmVyID0gaXNVaW50OEFycmF5KHRoaXMuYnVmZmVyKSA/IG5ldyBVaW50OEFycmF5KG5ldyBBcnJheUJ1ZmZlcih0aGlzLnBvc2l0aW9uKSkgOiBuZXcgQXJyYXkodGhpcy5wb3NpdGlvbik7IC8vIENvcHkgY29udGVudFxuXG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wb3NpdGlvbjsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgbmV3QnVmZmVyW2ldID0gdGhpcy5idWZmZXJbaV07XG5cdCAgICAgICAgICAgIH0gLy8gUmV0dXJuIHRoZSBidWZmZXJcblxuXG5cdCAgICAgICAgICAgIHJldHVybiBuZXdCdWZmZXI7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIHJldHVybiBjb252ZXJ0QXJyYXl0b1V0ZjhCaW5hcnlTdHJpbmcodGhpcy5idWZmZXIsIDAsIHRoaXMucG9zaXRpb24pO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBMZW5ndGguXG5cdCAgICAgKlxuXHQgICAgICogQG1ldGhvZFxuXHQgICAgICogQHJldHVybiB7bnVtYmVyfSB0aGUgbGVuZ3RoIG9mIHRoZSBiaW5hcnkuXG5cdCAgICAgKi9cblxuXHQgIH0sIHtcblx0ICAgIGtleTogXCJsZW5ndGhcIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBsZW5ndGgoKSB7XG5cdCAgICAgIHJldHVybiB0aGlzLnBvc2l0aW9uO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBAaWdub3JlXG5cdCAgICAgKi9cblxuXHQgIH0sIHtcblx0ICAgIGtleTogXCJ0b0pTT05cIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB0b0pTT04oKSB7XG5cdCAgICAgIHJldHVybiB0aGlzLmJ1ZmZlciAhPSBudWxsID8gdGhpcy5idWZmZXIudG9TdHJpbmcoJ2Jhc2U2NCcpIDogJyc7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEBpZ25vcmVcblx0ICAgICAqL1xuXG5cdCAgfSwge1xuXHQgICAga2V5OiBcInRvU3RyaW5nXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gdG9TdHJpbmcoZm9ybWF0KSB7XG5cdCAgICAgIHJldHVybiB0aGlzLmJ1ZmZlciAhPSBudWxsID8gdGhpcy5idWZmZXIuc2xpY2UoMCwgdGhpcy5wb3NpdGlvbikudG9TdHJpbmcoZm9ybWF0KSA6ICcnO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBAaWdub3JlXG5cdCAgICAgKi9cblxuXHQgIH0sIHtcblx0ICAgIGtleTogXCJ0b0V4dGVuZGVkSlNPTlwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHRvRXh0ZW5kZWRKU09OKCkge1xuXHQgICAgICB2YXIgYmFzZTY0U3RyaW5nID0gQnVmZmVyJDMuaXNCdWZmZXIodGhpcy5idWZmZXIpID8gdGhpcy5idWZmZXIudG9TdHJpbmcoJ2Jhc2U2NCcpIDogQnVmZmVyJDMuZnJvbSh0aGlzLmJ1ZmZlcikudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuXHQgICAgICB2YXIgc3ViVHlwZSA9IE51bWJlcih0aGlzLnN1Yl90eXBlKS50b1N0cmluZygxNik7XG5cdCAgICAgIHJldHVybiB7XG5cdCAgICAgICAgJGJpbmFyeToge1xuXHQgICAgICAgICAgYmFzZTY0OiBiYXNlNjRTdHJpbmcsXG5cdCAgICAgICAgICBzdWJUeXBlOiBzdWJUeXBlLmxlbmd0aCA9PT0gMSA/ICcwJyArIHN1YlR5cGUgOiBzdWJUeXBlXG5cdCAgICAgICAgfVxuXHQgICAgICB9O1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBAaWdub3JlXG5cdCAgICAgKi9cblxuXHQgIH1dLCBbe1xuXHQgICAga2V5OiBcImZyb21FeHRlbmRlZEpTT05cIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tRXh0ZW5kZWRKU09OKGRvYykge1xuXHQgICAgICB2YXIgdHlwZSA9IGRvYy4kYmluYXJ5LnN1YlR5cGUgPyBwYXJzZUludChkb2MuJGJpbmFyeS5zdWJUeXBlLCAxNikgOiAwO1xuXHQgICAgICB2YXIgZGF0YSA9IEJ1ZmZlciQzLmZyb20oZG9jLiRiaW5hcnkuYmFzZTY0LCAnYmFzZTY0Jyk7XG5cdCAgICAgIHJldHVybiBuZXcgQmluYXJ5KGRhdGEsIHR5cGUpO1xuXHQgICAgfVxuXHQgIH1dKTtcblxuXHQgIHJldHVybiBCaW5hcnk7XG5cdH0oKTtcblx0LyoqXG5cdCAqIEJpbmFyeSBkZWZhdWx0IHN1YnR5cGVcblx0ICogQGlnbm9yZVxuXHQgKi9cblxuXG5cdHZhciBCU09OX0JJTkFSWV9TVUJUWVBFX0RFRkFVTFQgPSAwO1xuXG5cdGZ1bmN0aW9uIGlzVWludDhBcnJheShvYmopIHtcblx0ICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0IFVpbnQ4QXJyYXldJztcblx0fVxuXHQvKipcblx0ICogQGlnbm9yZVxuXHQgKi9cblxuXG5cdGZ1bmN0aW9uIHdyaXRlU3RyaW5nVG9BcnJheShkYXRhKSB7XG5cdCAgLy8gQ3JlYXRlIGEgYnVmZmVyXG5cdCAgdmFyIGJ1ZmZlciQkMSA9IHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJyA/IG5ldyBVaW50OEFycmF5KG5ldyBBcnJheUJ1ZmZlcihkYXRhLmxlbmd0aCkpIDogbmV3IEFycmF5KGRhdGEubGVuZ3RoKTsgLy8gV3JpdGUgdGhlIGNvbnRlbnQgdG8gdGhlIGJ1ZmZlclxuXG5cdCAgZm9yICh2YXIgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7XG5cdCAgICBidWZmZXIkJDFbaV0gPSBkYXRhLmNoYXJDb2RlQXQoaSk7XG5cdCAgfSAvLyBXcml0ZSB0aGUgc3RyaW5nIHRvIHRoZSBidWZmZXJcblxuXG5cdCAgcmV0dXJuIGJ1ZmZlciQkMTtcblx0fVxuXHQvKipcblx0ICogQ29udmVydCBBcnJheSBvdCBVaW50OEFycmF5IHRvIEJpbmFyeSBTdHJpbmdcblx0ICpcblx0ICogQGlnbm9yZVxuXHQgKi9cblxuXG5cdGZ1bmN0aW9uIGNvbnZlcnRBcnJheXRvVXRmOEJpbmFyeVN0cmluZyhieXRlQXJyYXksIHN0YXJ0SW5kZXgsIGVuZEluZGV4KSB7XG5cdCAgdmFyIHJlc3VsdCA9ICcnO1xuXG5cdCAgZm9yICh2YXIgaSA9IHN0YXJ0SW5kZXg7IGkgPCBlbmRJbmRleDsgaSsrKSB7XG5cdCAgICByZXN1bHQgPSByZXN1bHQgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVBcnJheVtpXSk7XG5cdCAgfVxuXG5cdCAgcmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdEJpbmFyeS5CVUZGRVJfU0laRSA9IDI1Njtcblx0LyoqXG5cdCAqIERlZmF1bHQgQlNPTiB0eXBlXG5cdCAqXG5cdCAqIEBjbGFzc2NvbnN0YW50IFNVQlRZUEVfREVGQVVMVFxuXHQgKiovXG5cblx0QmluYXJ5LlNVQlRZUEVfREVGQVVMVCA9IDA7XG5cdC8qKlxuXHQgKiBGdW5jdGlvbiBCU09OIHR5cGVcblx0ICpcblx0ICogQGNsYXNzY29uc3RhbnQgU1VCVFlQRV9ERUZBVUxUXG5cdCAqKi9cblxuXHRCaW5hcnkuU1VCVFlQRV9GVU5DVElPTiA9IDE7XG5cdC8qKlxuXHQgKiBCeXRlIEFycmF5IEJTT04gdHlwZVxuXHQgKlxuXHQgKiBAY2xhc3Njb25zdGFudCBTVUJUWVBFX0RFRkFVTFRcblx0ICoqL1xuXG5cdEJpbmFyeS5TVUJUWVBFX0JZVEVfQVJSQVkgPSAyO1xuXHQvKipcblx0ICogT0xEIFVVSUQgQlNPTiB0eXBlXG5cdCAqXG5cdCAqIEBjbGFzc2NvbnN0YW50IFNVQlRZUEVfREVGQVVMVFxuXHQgKiovXG5cblx0QmluYXJ5LlNVQlRZUEVfVVVJRF9PTEQgPSAzO1xuXHQvKipcblx0ICogVVVJRCBCU09OIHR5cGVcblx0ICpcblx0ICogQGNsYXNzY29uc3RhbnQgU1VCVFlQRV9ERUZBVUxUXG5cdCAqKi9cblxuXHRCaW5hcnkuU1VCVFlQRV9VVUlEID0gNDtcblx0LyoqXG5cdCAqIE1ENSBCU09OIHR5cGVcblx0ICpcblx0ICogQGNsYXNzY29uc3RhbnQgU1VCVFlQRV9ERUZBVUxUXG5cdCAqKi9cblxuXHRCaW5hcnkuU1VCVFlQRV9NRDUgPSA1O1xuXHQvKipcblx0ICogVXNlciBCU09OIHR5cGVcblx0ICpcblx0ICogQGNsYXNzY29uc3RhbnQgU1VCVFlQRV9ERUZBVUxUXG5cdCAqKi9cblxuXHRCaW5hcnkuU1VCVFlQRV9VU0VSX0RFRklORUQgPSAxMjg7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShCaW5hcnkucHJvdG90eXBlLCAnX2Jzb250eXBlJywge1xuXHQgIHZhbHVlOiAnQmluYXJ5J1xuXHR9KTtcblx0dmFyIGJpbmFyeSA9IEJpbmFyeTtcblxuXHR2YXIgY29uc3RhbnRzID0ge1xuXHQgIC8vIEJTT04gTUFYIFZBTFVFU1xuXHQgIEJTT05fSU5UMzJfTUFYOiAweDdmZmZmZmZmLFxuXHQgIEJTT05fSU5UMzJfTUlOOiAtMHg4MDAwMDAwMCxcblx0ICBCU09OX0lOVDY0X01BWDogTWF0aC5wb3coMiwgNjMpIC0gMSxcblx0ICBCU09OX0lOVDY0X01JTjogLU1hdGgucG93KDIsIDYzKSxcblx0ICAvLyBKUyBNQVggUFJFQ0lTRSBWQUxVRVNcblx0ICBKU19JTlRfTUFYOiAweDIwMDAwMDAwMDAwMDAwLFxuXHQgIC8vIEFueSBpbnRlZ2VyIHVwIHRvIDJeNTMgY2FuIGJlIHByZWNpc2VseSByZXByZXNlbnRlZCBieSBhIGRvdWJsZS5cblx0ICBKU19JTlRfTUlOOiAtMHgyMDAwMDAwMDAwMDAwMCxcblx0ICAvLyBBbnkgaW50ZWdlciBkb3duIHRvIC0yXjUzIGNhbiBiZSBwcmVjaXNlbHkgcmVwcmVzZW50ZWQgYnkgYSBkb3VibGUuXG5cblx0ICAvKipcblx0ICAgKiBOdW1iZXIgQlNPTiBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0RBVEFfTlVNQkVSXG5cdCAgICoqL1xuXHQgIEJTT05fREFUQV9OVU1CRVI6IDEsXG5cblx0ICAvKipcblx0ICAgKiBTdHJpbmcgQlNPTiBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0RBVEFfU1RSSU5HXG5cdCAgICoqL1xuXHQgIEJTT05fREFUQV9TVFJJTkc6IDIsXG5cblx0ICAvKipcblx0ICAgKiBPYmplY3QgQlNPTiBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0RBVEFfT0JKRUNUXG5cdCAgICoqL1xuXHQgIEJTT05fREFUQV9PQkpFQ1Q6IDMsXG5cblx0ICAvKipcblx0ICAgKiBBcnJheSBCU09OIFR5cGVcblx0ICAgKlxuXHQgICAqIEBjbGFzc2NvbnN0YW50IEJTT05fREFUQV9BUlJBWVxuXHQgICAqKi9cblx0ICBCU09OX0RBVEFfQVJSQVk6IDQsXG5cblx0ICAvKipcblx0ICAgKiBCaW5hcnkgQlNPTiBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0RBVEFfQklOQVJZXG5cdCAgICoqL1xuXHQgIEJTT05fREFUQV9CSU5BUlk6IDUsXG5cblx0ICAvKipcblx0ICAgKiBCaW5hcnkgQlNPTiBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0RBVEFfVU5ERUZJTkVEXG5cdCAgICoqL1xuXHQgIEJTT05fREFUQV9VTkRFRklORUQ6IDYsXG5cblx0ICAvKipcblx0ICAgKiBPYmplY3RJZCBCU09OIFR5cGVcblx0ICAgKlxuXHQgICAqIEBjbGFzc2NvbnN0YW50IEJTT05fREFUQV9PSURcblx0ICAgKiovXG5cdCAgQlNPTl9EQVRBX09JRDogNyxcblxuXHQgIC8qKlxuXHQgICAqIEJvb2xlYW4gQlNPTiBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0RBVEFfQk9PTEVBTlxuXHQgICAqKi9cblx0ICBCU09OX0RBVEFfQk9PTEVBTjogOCxcblxuXHQgIC8qKlxuXHQgICAqIERhdGUgQlNPTiBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0RBVEFfREFURVxuXHQgICAqKi9cblx0ICBCU09OX0RBVEFfREFURTogOSxcblxuXHQgIC8qKlxuXHQgICAqIG51bGwgQlNPTiBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0RBVEFfTlVMTFxuXHQgICAqKi9cblx0ICBCU09OX0RBVEFfTlVMTDogMTAsXG5cblx0ICAvKipcblx0ICAgKiBSZWdFeHAgQlNPTiBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0RBVEFfUkVHRVhQXG5cdCAgICoqL1xuXHQgIEJTT05fREFUQV9SRUdFWFA6IDExLFxuXG5cdCAgLyoqXG5cdCAgICogQ29kZSBCU09OIFR5cGVcblx0ICAgKlxuXHQgICAqIEBjbGFzc2NvbnN0YW50IEJTT05fREFUQV9EQlBPSU5URVJcblx0ICAgKiovXG5cdCAgQlNPTl9EQVRBX0RCUE9JTlRFUjogMTIsXG5cblx0ICAvKipcblx0ICAgKiBDb2RlIEJTT04gVHlwZVxuXHQgICAqXG5cdCAgICogQGNsYXNzY29uc3RhbnQgQlNPTl9EQVRBX0NPREVcblx0ICAgKiovXG5cdCAgQlNPTl9EQVRBX0NPREU6IDEzLFxuXG5cdCAgLyoqXG5cdCAgICogU3ltYm9sIEJTT04gVHlwZVxuXHQgICAqXG5cdCAgICogQGNsYXNzY29uc3RhbnQgQlNPTl9EQVRBX1NZTUJPTFxuXHQgICAqKi9cblx0ICBCU09OX0RBVEFfU1lNQk9MOiAxNCxcblxuXHQgIC8qKlxuXHQgICAqIENvZGUgd2l0aCBTY29wZSBCU09OIFR5cGVcblx0ICAgKlxuXHQgICAqIEBjbGFzc2NvbnN0YW50IEJTT05fREFUQV9DT0RFX1dfU0NPUEVcblx0ICAgKiovXG5cdCAgQlNPTl9EQVRBX0NPREVfV19TQ09QRTogMTUsXG5cblx0ICAvKipcblx0ICAgKiAzMiBiaXQgSW50ZWdlciBCU09OIFR5cGVcblx0ICAgKlxuXHQgICAqIEBjbGFzc2NvbnN0YW50IEJTT05fREFUQV9JTlRcblx0ICAgKiovXG5cdCAgQlNPTl9EQVRBX0lOVDogMTYsXG5cblx0ICAvKipcblx0ICAgKiBUaW1lc3RhbXAgQlNPTiBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0RBVEFfVElNRVNUQU1QXG5cdCAgICoqL1xuXHQgIEJTT05fREFUQV9USU1FU1RBTVA6IDE3LFxuXG5cdCAgLyoqXG5cdCAgICogTG9uZyBCU09OIFR5cGVcblx0ICAgKlxuXHQgICAqIEBjbGFzc2NvbnN0YW50IEJTT05fREFUQV9MT05HXG5cdCAgICoqL1xuXHQgIEJTT05fREFUQV9MT05HOiAxOCxcblxuXHQgIC8qKlxuXHQgICAqIExvbmcgQlNPTiBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0RBVEFfREVDSU1BTDEyOFxuXHQgICAqKi9cblx0ICBCU09OX0RBVEFfREVDSU1BTDEyODogMTksXG5cblx0ICAvKipcblx0ICAgKiBNaW5LZXkgQlNPTiBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0RBVEFfTUlOX0tFWVxuXHQgICAqKi9cblx0ICBCU09OX0RBVEFfTUlOX0tFWTogMHhmZixcblxuXHQgIC8qKlxuXHQgICAqIE1heEtleSBCU09OIFR5cGVcblx0ICAgKlxuXHQgICAqIEBjbGFzc2NvbnN0YW50IEJTT05fREFUQV9NQVhfS0VZXG5cdCAgICoqL1xuXHQgIEJTT05fREFUQV9NQVhfS0VZOiAweDdmLFxuXG5cdCAgLyoqXG5cdCAgICogQmluYXJ5IERlZmF1bHQgVHlwZVxuXHQgICAqXG5cdCAgICogQGNsYXNzY29uc3RhbnQgQlNPTl9CSU5BUllfU1VCVFlQRV9ERUZBVUxUXG5cdCAgICoqL1xuXHQgIEJTT05fQklOQVJZX1NVQlRZUEVfREVGQVVMVDogMCxcblxuXHQgIC8qKlxuXHQgICAqIEJpbmFyeSBGdW5jdGlvbiBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0JJTkFSWV9TVUJUWVBFX0ZVTkNUSU9OXG5cdCAgICoqL1xuXHQgIEJTT05fQklOQVJZX1NVQlRZUEVfRlVOQ1RJT046IDEsXG5cblx0ICAvKipcblx0ICAgKiBCaW5hcnkgQnl0ZSBBcnJheSBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0JJTkFSWV9TVUJUWVBFX0JZVEVfQVJSQVlcblx0ICAgKiovXG5cdCAgQlNPTl9CSU5BUllfU1VCVFlQRV9CWVRFX0FSUkFZOiAyLFxuXG5cdCAgLyoqXG5cdCAgICogQmluYXJ5IFVVSUQgVHlwZVxuXHQgICAqXG5cdCAgICogQGNsYXNzY29uc3RhbnQgQlNPTl9CSU5BUllfU1VCVFlQRV9VVUlEXG5cdCAgICoqL1xuXHQgIEJTT05fQklOQVJZX1NVQlRZUEVfVVVJRDogMyxcblxuXHQgIC8qKlxuXHQgICAqIEJpbmFyeSBNRDUgVHlwZVxuXHQgICAqXG5cdCAgICogQGNsYXNzY29uc3RhbnQgQlNPTl9CSU5BUllfU1VCVFlQRV9NRDVcblx0ICAgKiovXG5cdCAgQlNPTl9CSU5BUllfU1VCVFlQRV9NRDU6IDQsXG5cblx0ICAvKipcblx0ICAgKiBCaW5hcnkgVXNlciBEZWZpbmVkIFR5cGVcblx0ICAgKlxuXHQgICAqIEBjbGFzc2NvbnN0YW50IEJTT05fQklOQVJZX1NVQlRZUEVfVVNFUl9ERUZJTkVEXG5cdCAgICoqL1xuXHQgIEJTT05fQklOQVJZX1NVQlRZUEVfVVNFUl9ERUZJTkVEOiAxMjhcblx0fTtcblxuXHRmdW5jdGlvbiBfdHlwZW9mJDIob2JqKSB7IGlmICh0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIikgeyBfdHlwZW9mJDIgPSBmdW5jdGlvbiBfdHlwZW9mKG9iaikgeyByZXR1cm4gdHlwZW9mIG9iajsgfTsgfSBlbHNlIHsgX3R5cGVvZiQyID0gZnVuY3Rpb24gX3R5cGVvZihvYmopIHsgcmV0dXJuIG9iaiAmJiB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7IH07IH0gcmV0dXJuIF90eXBlb2YkMihvYmopOyB9XG5cdC8vIGNvbnN0IE1hcCA9IHJlcXVpcmUoJy4vbWFwJyk7XG5cblx0LyoqXG5cdCAqIEBuYW1lc3BhY2UgRUpTT05cblx0ICovXG5cdC8vIGFsbCB0aGUgdHlwZXMgd2hlcmUgd2UgZG9uJ3QgbmVlZCB0byBkbyBhbnkgc3BlY2lhbCBwcm9jZXNzaW5nIGFuZCBjYW4ganVzdCBwYXNzIHRoZSBFSlNPTlxuXHQvL3N0cmFpZ2h0IHRvIHR5cGUuZnJvbUV4dGVuZGVkSlNPTlxuXG5cblx0dmFyIGtleXNUb0NvZGVjcyA9IHtcblx0ICAkb2lkOiBvYmplY3RpZCxcblx0ICAkYmluYXJ5OiBiaW5hcnksXG5cdCAgJHN5bWJvbDogc3ltYm9sLFxuXHQgICRudW1iZXJJbnQ6IGludF8zMixcblx0ICAkbnVtYmVyRGVjaW1hbDogZGVjaW1hbDEyOCxcblx0ICAkbnVtYmVyRG91YmxlOiBkb3VibGVfMSxcblx0ICAkbnVtYmVyTG9uZzogbG9uZ18xLFxuXHQgICRtaW5LZXk6IG1pbl9rZXksXG5cdCAgJG1heEtleTogbWF4X2tleSxcblx0ICAkcmVndWxhckV4cHJlc3Npb246IHJlZ2V4cCxcblx0ICAkdGltZXN0YW1wOiB0aW1lc3RhbXBcblx0fTtcblxuXHRmdW5jdGlvbiBkZXNlcmlhbGl6ZVZhbHVlKHNlbGYsIGtleSwgdmFsdWUsIG9wdGlvbnMpIHtcblx0ICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuXHQgICAgaWYgKG9wdGlvbnMucmVsYXhlZCkge1xuXHQgICAgICByZXR1cm4gdmFsdWU7XG5cdCAgICB9IC8vIGlmIGl0J3MgYW4gaW50ZWdlciwgc2hvdWxkIGludGVycHJldCBhcyBzbWFsbGVzdCBCU09OIGludGVnZXJcblx0ICAgIC8vIHRoYXQgY2FuIHJlcHJlc2VudCBpdCBleGFjdGx5LiAoaWYgb3V0IG9mIHJhbmdlLCBpbnRlcnByZXQgYXMgZG91YmxlLilcblxuXG5cdCAgICBpZiAoTWF0aC5mbG9vcih2YWx1ZSkgPT09IHZhbHVlKSB7XG5cdCAgICAgIGlmICh2YWx1ZSA+PSBCU09OX0lOVDMyX01JTiAmJiB2YWx1ZSA8PSBCU09OX0lOVDMyX01BWCkgcmV0dXJuIG5ldyBpbnRfMzIodmFsdWUpO1xuXHQgICAgICBpZiAodmFsdWUgPj0gQlNPTl9JTlQ2NF9NSU4gJiYgdmFsdWUgPD0gQlNPTl9JTlQ2NF9NQVgpIHJldHVybiBuZXcgbG9uZ18xLmZyb21OdW1iZXIodmFsdWUpO1xuXHQgICAgfSAvLyBJZiB0aGUgbnVtYmVyIGlzIGEgbm9uLWludGVnZXIgb3Igb3V0IG9mIGludGVnZXIgcmFuZ2UsIHNob3VsZCBpbnRlcnByZXQgYXMgQlNPTiBEb3VibGUuXG5cblxuXHQgICAgcmV0dXJuIG5ldyBkb3VibGVfMSh2YWx1ZSk7XG5cdCAgfSAvLyBmcm9tIGhlcmUgb24gb3V0IHdlJ3JlIGxvb2tpbmcgZm9yIGJzb24gdHlwZXMsIHNvIGJhaWwgaWYgaXRzIG5vdCBhbiBvYmplY3RcblxuXG5cdCAgaWYgKHZhbHVlID09IG51bGwgfHwgX3R5cGVvZiQyKHZhbHVlKSAhPT0gJ29iamVjdCcpIHJldHVybiB2YWx1ZTsgLy8gdXBncmFkZSBkZXByZWNhdGVkIHVuZGVmaW5lZCB0byBudWxsXG5cblx0ICBpZiAodmFsdWUuJHVuZGVmaW5lZCkgcmV0dXJuIG51bGw7XG5cdCAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh2YWx1ZSkuZmlsdGVyKGZ1bmN0aW9uIChrKSB7XG5cdCAgICByZXR1cm4gay5zdGFydHNXaXRoKCckJykgJiYgdmFsdWVba10gIT0gbnVsbDtcblx0ICB9KTtcblxuXHQgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuXHQgICAgdmFyIGMgPSBrZXlzVG9Db2RlY3Nba2V5c1tpXV07XG5cdCAgICBpZiAoYykgcmV0dXJuIGMuZnJvbUV4dGVuZGVkSlNPTih2YWx1ZSwgb3B0aW9ucyk7XG5cdCAgfVxuXG5cdCAgaWYgKHZhbHVlLiRkYXRlICE9IG51bGwpIHtcblx0ICAgIHZhciBkID0gdmFsdWUuJGRhdGU7XG5cdCAgICB2YXIgZGF0ZSA9IG5ldyBEYXRlKCk7XG5cdCAgICBpZiAodHlwZW9mIGQgPT09ICdzdHJpbmcnKSBkYXRlLnNldFRpbWUoRGF0ZS5wYXJzZShkKSk7ZWxzZSBpZiAobG9uZ18xLmlzTG9uZyhkKSkgZGF0ZS5zZXRUaW1lKGQudG9OdW1iZXIoKSk7ZWxzZSBpZiAodHlwZW9mIGQgPT09ICdudW1iZXInICYmIG9wdGlvbnMucmVsYXhlZCkgZGF0ZS5zZXRUaW1lKGQpO1xuXHQgICAgcmV0dXJuIGRhdGU7XG5cdCAgfVxuXG5cdCAgaWYgKHZhbHVlLiRjb2RlICE9IG51bGwpIHtcblx0ICAgIHZhciBjb3B5ID0gT2JqZWN0LmFzc2lnbih7fSwgdmFsdWUpO1xuXG5cdCAgICBpZiAodmFsdWUuJHNjb3BlKSB7XG5cdCAgICAgIGNvcHkuJHNjb3BlID0gZGVzZXJpYWxpemVWYWx1ZShzZWxmLCBudWxsLCB2YWx1ZS4kc2NvcGUpO1xuXHQgICAgfVxuXG5cdCAgICByZXR1cm4gY29kZS5mcm9tRXh0ZW5kZWRKU09OKHZhbHVlKTtcblx0ICB9XG5cblx0ICBpZiAodmFsdWUuJHJlZiAhPSBudWxsIHx8IHZhbHVlLiRkYlBvaW50ZXIgIT0gbnVsbCkge1xuXHQgICAgdmFyIHYgPSB2YWx1ZS4kcmVmID8gdmFsdWUgOiB2YWx1ZS4kZGJQb2ludGVyOyAvLyB3ZSBydW4gaW50byB0aGlzIGluIGEgXCJkZWdlbmVyYXRlIEVKU09OXCIgY2FzZSAod2l0aCAkaWQgYW5kICRyZWYgb3JkZXIgZmxpcHBlZClcblx0ICAgIC8vIGJlY2F1c2Ugb2YgdGhlIG9yZGVyIEpTT04ucGFyc2UgZ29lcyB0aHJvdWdoIHRoZSBkb2N1bWVudFxuXG5cdCAgICBpZiAodiBpbnN0YW5jZW9mIGRiX3JlZikgcmV0dXJuIHY7XG5cdCAgICB2YXIgZG9sbGFyS2V5cyA9IE9iamVjdC5rZXlzKHYpLmZpbHRlcihmdW5jdGlvbiAoaykge1xuXHQgICAgICByZXR1cm4gay5zdGFydHNXaXRoKCckJyk7XG5cdCAgICB9KTtcblx0ICAgIHZhciB2YWxpZCA9IHRydWU7XG5cdCAgICBkb2xsYXJLZXlzLmZvckVhY2goZnVuY3Rpb24gKGspIHtcblx0ICAgICAgaWYgKFsnJHJlZicsICckaWQnLCAnJGRiJ10uaW5kZXhPZihrKSA9PT0gLTEpIHZhbGlkID0gZmFsc2U7XG5cdCAgICB9KTsgLy8gb25seSBtYWtlIERCUmVmIGlmICQga2V5cyBhcmUgYWxsIHZhbGlkXG5cblx0ICAgIGlmICh2YWxpZCkgcmV0dXJuIGRiX3JlZi5mcm9tRXh0ZW5kZWRKU09OKHYpO1xuXHQgIH1cblxuXHQgIHJldHVybiB2YWx1ZTtcblx0fVxuXHQvKipcblx0ICogUGFyc2UgYW4gRXh0ZW5kZWQgSlNPTiBzdHJpbmcsIGNvbnN0cnVjdGluZyB0aGUgSmF2YVNjcmlwdCB2YWx1ZSBvciBvYmplY3QgZGVzY3JpYmVkIGJ5IHRoYXRcblx0ICogc3RyaW5nLlxuXHQgKlxuXHQgKiBAbWVtYmVyb2YgRUpTT05cblx0ICogQHBhcmFtIHtzdHJpbmd9IHRleHRcblx0ICogQHBhcmFtIHtvYmplY3R9IFtvcHRpb25zXSBPcHRpb25hbCBzZXR0aW5nc1xuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnJlbGF4ZWQ9dHJ1ZV0gQXR0ZW1wdCB0byByZXR1cm4gbmF0aXZlIEpTIHR5cGVzIHdoZXJlIHBvc3NpYmxlLCByYXRoZXIgdGhhbiBCU09OIHR5cGVzIChpZiB0cnVlKVxuXHQgKiBAcmV0dXJuIHtvYmplY3R9XG5cdCAqXG5cdCAqIEBleGFtcGxlXG5cdCAqIGNvbnN0IHsgRUpTT04gfSA9IHJlcXVpcmUoJ2Jzb24nKTtcblx0ICogY29uc3QgdGV4dCA9ICd7IFwiaW50MzJcIjogeyBcIiRudW1iZXJJbnRcIjogXCIxMFwiIH0gfSc7XG5cdCAqXG5cdCAqIC8vIHByaW50cyB7IGludDMyOiB7IFtTdHJpbmc6ICcxMCddIF9ic29udHlwZTogJ0ludDMyJywgdmFsdWU6ICcxMCcgfSB9XG5cdCAqIGNvbnNvbGUubG9nKEVKU09OLnBhcnNlKHRleHQsIHsgcmVsYXhlZDogZmFsc2UgfSkpO1xuXHQgKlxuXHQgKiAvLyBwcmludHMgeyBpbnQzMjogMTAgfVxuXHQgKiBjb25zb2xlLmxvZyhFSlNPTi5wYXJzZSh0ZXh0KSk7XG5cdCAqL1xuXG5cblx0ZnVuY3Rpb24gcGFyc2UodGV4dCwgb3B0aW9ucykge1xuXHQgIHZhciBfdGhpcyA9IHRoaXM7XG5cblx0ICBvcHRpb25zID0gT2JqZWN0LmFzc2lnbih7fSwge1xuXHQgICAgcmVsYXhlZDogdHJ1ZVxuXHQgIH0sIG9wdGlvbnMpOyAvLyByZWxheGVkIGltcGxpZXMgbm90IHN0cmljdFxuXG5cdCAgaWYgKHR5cGVvZiBvcHRpb25zLnJlbGF4ZWQgPT09ICdib29sZWFuJykgb3B0aW9ucy5zdHJpY3QgPSAhb3B0aW9ucy5yZWxheGVkO1xuXHQgIGlmICh0eXBlb2Ygb3B0aW9ucy5zdHJpY3QgPT09ICdib29sZWFuJykgb3B0aW9ucy5yZWxheGVkID0gIW9wdGlvbnMuc3RyaWN0O1xuXHQgIHJldHVybiBKU09OLnBhcnNlKHRleHQsIGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG5cdCAgICByZXR1cm4gZGVzZXJpYWxpemVWYWx1ZShfdGhpcywga2V5LCB2YWx1ZSwgb3B0aW9ucyk7XG5cdCAgfSk7XG5cdH0gLy9cblx0Ly8gU2VyaWFsaXplclxuXHQvL1xuXHQvLyBNQVggSU5UMzIgYm91bmRhcmllc1xuXG5cblx0dmFyIEJTT05fSU5UMzJfTUFYID0gMHg3ZmZmZmZmZixcblx0ICAgIEJTT05fSU5UMzJfTUlOID0gLTB4ODAwMDAwMDAsXG5cdCAgICBCU09OX0lOVDY0X01BWCA9IDB4N2ZmZmZmZmZmZmZmZmZmZixcblx0ICAgIEJTT05fSU5UNjRfTUlOID0gLTB4ODAwMDAwMDAwMDAwMDAwMDtcblx0LyoqXG5cdCAqIENvbnZlcnRzIGEgQlNPTiBkb2N1bWVudCB0byBhbiBFeHRlbmRlZCBKU09OIHN0cmluZywgb3B0aW9uYWxseSByZXBsYWNpbmcgdmFsdWVzIGlmIGEgcmVwbGFjZXJcblx0ICogZnVuY3Rpb24gaXMgc3BlY2lmaWVkIG9yIG9wdGlvbmFsbHkgaW5jbHVkaW5nIG9ubHkgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzIGlmIGEgcmVwbGFjZXIgYXJyYXlcblx0ICogaXMgc3BlY2lmaWVkLlxuXHQgKlxuXHQgKiBAbWVtYmVyb2YgRUpTT05cblx0ICogQHBhcmFtIHtvYmplY3R9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0IHRvIGV4dGVuZGVkIEpTT05cblx0ICogQHBhcmFtIHtmdW5jdGlvbnxhcnJheX0gW3JlcGxhY2VyXSBBIGZ1bmN0aW9uIHRoYXQgYWx0ZXJzIHRoZSBiZWhhdmlvciBvZiB0aGUgc3RyaW5naWZpY2F0aW9uIHByb2Nlc3MsIG9yIGFuIGFycmF5IG9mIFN0cmluZyBhbmQgTnVtYmVyIG9iamVjdHMgdGhhdCBzZXJ2ZSBhcyBhIHdoaXRlbGlzdCBmb3Igc2VsZWN0aW5nL2ZpbHRlcmluZyB0aGUgcHJvcGVydGllcyBvZiB0aGUgdmFsdWUgb2JqZWN0IHRvIGJlIGluY2x1ZGVkIGluIHRoZSBKU09OIHN0cmluZy4gSWYgdGhpcyB2YWx1ZSBpcyBudWxsIG9yIG5vdCBwcm92aWRlZCwgYWxsIHByb3BlcnRpZXMgb2YgdGhlIG9iamVjdCBhcmUgaW5jbHVkZWQgaW4gdGhlIHJlc3VsdGluZyBKU09OIHN0cmluZ1xuXHQgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IFtzcGFjZV0gQSBTdHJpbmcgb3IgTnVtYmVyIG9iamVjdCB0aGF0J3MgdXNlZCB0byBpbnNlcnQgd2hpdGUgc3BhY2UgaW50byB0aGUgb3V0cHV0IEpTT04gc3RyaW5nIGZvciByZWFkYWJpbGl0eSBwdXJwb3Nlcy5cblx0ICogQHBhcmFtIHtvYmplY3R9IFtvcHRpb25zXSBPcHRpb25hbCBzZXR0aW5nc1xuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnJlbGF4ZWQ9dHJ1ZV0gRW5hYmxlZCBFeHRlbmRlZCBKU09OJ3MgYHJlbGF4ZWRgIG1vZGVcblx0ICogQHJldHVybnMge3N0cmluZ31cblx0ICpcblx0ICogQGV4YW1wbGVcblx0ICogY29uc3QgeyBFSlNPTiB9ID0gcmVxdWlyZSgnYnNvbicpO1xuXHQgKiBjb25zdCBJbnQzMiA9IHJlcXVpcmUoJ21vbmdvZGInKS5JbnQzMjtcblx0ICogY29uc3QgZG9jID0geyBpbnQzMjogbmV3IEludDMyKDEwKSB9O1xuXHQgKlxuXHQgKiAvLyBwcmludHMgJ3tcImludDMyXCI6e1wiJG51bWJlckludFwiOlwiMTBcIn19J1xuXHQgKiBjb25zb2xlLmxvZyhFSlNPTi5zdHJpbmdpZnkoZG9jLCB7IHJlbGF4ZWQ6IGZhbHNlIH0pKTtcblx0ICpcblx0ICogLy8gcHJpbnRzICd7XCJpbnQzMlwiOjEwfSdcblx0ICogY29uc29sZS5sb2coRUpTT04uc3RyaW5naWZ5KGRvYykpO1xuXHQgKi9cblxuXHRmdW5jdGlvbiBzdHJpbmdpZnkodmFsdWUsIHJlcGxhY2VyLCBzcGFjZSwgb3B0aW9ucykge1xuXHQgIGlmIChzcGFjZSAhPSBudWxsICYmIF90eXBlb2YkMihzcGFjZSkgPT09ICdvYmplY3QnKSB7XG5cdCAgICBvcHRpb25zID0gc3BhY2U7XG5cdCAgICBzcGFjZSA9IDA7XG5cdCAgfVxuXG5cdCAgaWYgKHJlcGxhY2VyICE9IG51bGwgJiYgX3R5cGVvZiQyKHJlcGxhY2VyKSA9PT0gJ29iamVjdCcgJiYgIUFycmF5LmlzQXJyYXkocmVwbGFjZXIpKSB7XG5cdCAgICBvcHRpb25zID0gcmVwbGFjZXI7XG5cdCAgICByZXBsYWNlciA9IG51bGw7XG5cdCAgICBzcGFjZSA9IDA7XG5cdCAgfVxuXG5cdCAgb3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oe30sIHtcblx0ICAgIHJlbGF4ZWQ6IHRydWVcblx0ICB9LCBvcHRpb25zKTtcblx0ICB2YXIgZG9jID0gQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyBzZXJpYWxpemVBcnJheSh2YWx1ZSwgb3B0aW9ucykgOiBzZXJpYWxpemVEb2N1bWVudCh2YWx1ZSwgb3B0aW9ucyk7XG5cdCAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGRvYywgcmVwbGFjZXIsIHNwYWNlKTtcblx0fVxuXHQvKipcblx0ICogU2VyaWFsaXplcyBhbiBvYmplY3QgdG8gYW4gRXh0ZW5kZWQgSlNPTiBzdHJpbmcsIGFuZCByZXBhcnNlIGl0IGFzIGEgSmF2YVNjcmlwdCBvYmplY3QuXG5cdCAqXG5cdCAqIEBtZW1iZXJvZiBFSlNPTlxuXHQgKiBAcGFyYW0ge29iamVjdH0gYnNvbiBUaGUgb2JqZWN0IHRvIHNlcmlhbGl6ZVxuXHQgKiBAcGFyYW0ge29iamVjdH0gW29wdGlvbnNdIE9wdGlvbmFsIHNldHRpbmdzIHBhc3NlZCB0byB0aGUgYHN0cmluZ2lmeWAgZnVuY3Rpb25cblx0ICogQHJldHVybiB7b2JqZWN0fVxuXHQgKi9cblxuXG5cdGZ1bmN0aW9uIHNlcmlhbGl6ZShic29uLCBvcHRpb25zKSB7XG5cdCAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cdCAgcmV0dXJuIEpTT04ucGFyc2Uoc3RyaW5naWZ5KGJzb24sIG9wdGlvbnMpKTtcblx0fVxuXHQvKipcblx0ICogRGVzZXJpYWxpemVzIGFuIEV4dGVuZGVkIEpTT04gb2JqZWN0IGludG8gYSBwbGFpbiBKYXZhU2NyaXB0IG9iamVjdCB3aXRoIG5hdGl2ZS9CU09OIHR5cGVzXG5cdCAqXG5cdCAqIEBtZW1iZXJvZiBFSlNPTlxuXHQgKiBAcGFyYW0ge29iamVjdH0gZWpzb24gVGhlIEV4dGVuZGVkIEpTT04gb2JqZWN0IHRvIGRlc2VyaWFsaXplXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0aW9uc10gT3B0aW9uYWwgc2V0dGluZ3MgcGFzc2VkIHRvIHRoZSBwYXJzZSBtZXRob2Rcblx0ICogQHJldHVybiB7b2JqZWN0fVxuXHQgKi9cblxuXG5cdGZ1bmN0aW9uIGRlc2VyaWFsaXplKGVqc29uLCBvcHRpb25zKSB7XG5cdCAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cdCAgcmV0dXJuIHBhcnNlKEpTT04uc3RyaW5naWZ5KGVqc29uKSwgb3B0aW9ucyk7XG5cdH1cblxuXHRmdW5jdGlvbiBzZXJpYWxpemVBcnJheShhcnJheSwgb3B0aW9ucykge1xuXHQgIHJldHVybiBhcnJheS5tYXAoZnVuY3Rpb24gKHYpIHtcblx0ICAgIHJldHVybiBzZXJpYWxpemVWYWx1ZSh2LCBvcHRpb25zKTtcblx0ICB9KTtcblx0fVxuXG5cdGZ1bmN0aW9uIGdldElTT1N0cmluZyhkYXRlKSB7XG5cdCAgdmFyIGlzb1N0ciA9IGRhdGUudG9JU09TdHJpbmcoKTsgLy8gd2Ugc2hvdWxkIG9ubHkgc2hvdyBtaWxsaXNlY29uZHMgaW4gdGltZXN0YW1wIGlmIHRoZXkncmUgbm9uLXplcm9cblxuXHQgIHJldHVybiBkYXRlLmdldFVUQ01pbGxpc2Vjb25kcygpICE9PSAwID8gaXNvU3RyIDogaXNvU3RyLnNsaWNlKDAsIC01KSArICdaJztcblx0fVxuXG5cdGZ1bmN0aW9uIHNlcmlhbGl6ZVZhbHVlKHZhbHVlLCBvcHRpb25zKSB7XG5cdCAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSByZXR1cm4gc2VyaWFsaXplQXJyYXkodmFsdWUsIG9wdGlvbnMpO1xuXHQgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gbnVsbDtcblxuXHQgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcblx0ICAgIHZhciBkYXRlTnVtID0gdmFsdWUuZ2V0VGltZSgpLFxuXHQgICAgICAgIC8vIGlzIGl0IGluIHllYXIgcmFuZ2UgMTk3MC05OTk5P1xuXHQgICAgaW5SYW5nZSA9IGRhdGVOdW0gPiAtMSAmJiBkYXRlTnVtIDwgMjUzNDAyMzE4ODAwMDAwO1xuXHQgICAgcmV0dXJuIG9wdGlvbnMucmVsYXhlZCAmJiBpblJhbmdlID8ge1xuXHQgICAgICAkZGF0ZTogZ2V0SVNPU3RyaW5nKHZhbHVlKVxuXHQgICAgfSA6IHtcblx0ICAgICAgJGRhdGU6IHtcblx0ICAgICAgICAkbnVtYmVyTG9uZzogdmFsdWUuZ2V0VGltZSgpLnRvU3RyaW5nKClcblx0ICAgICAgfVxuXHQgICAgfTtcblx0ICB9XG5cblx0ICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiAhb3B0aW9ucy5yZWxheGVkKSB7XG5cdCAgICAvLyBpdCdzIGFuIGludGVnZXJcblx0ICAgIGlmIChNYXRoLmZsb29yKHZhbHVlKSA9PT0gdmFsdWUpIHtcblx0ICAgICAgdmFyIGludDMyUmFuZ2UgPSB2YWx1ZSA+PSBCU09OX0lOVDMyX01JTiAmJiB2YWx1ZSA8PSBCU09OX0lOVDMyX01BWCxcblx0ICAgICAgICAgIGludDY0UmFuZ2UgPSB2YWx1ZSA+PSBCU09OX0lOVDY0X01JTiAmJiB2YWx1ZSA8PSBCU09OX0lOVDY0X01BWDsgLy8gaW50ZXJwcmV0IGFzIGJlaW5nIG9mIHRoZSBzbWFsbGVzdCBCU09OIGludGVnZXIgdHlwZSB0aGF0IGNhbiByZXByZXNlbnQgdGhlIG51bWJlciBleGFjdGx5XG5cblx0ICAgICAgaWYgKGludDMyUmFuZ2UpIHJldHVybiB7XG5cdCAgICAgICAgJG51bWJlckludDogdmFsdWUudG9TdHJpbmcoKVxuXHQgICAgICB9O1xuXHQgICAgICBpZiAoaW50NjRSYW5nZSkgcmV0dXJuIHtcblx0ICAgICAgICAkbnVtYmVyTG9uZzogdmFsdWUudG9TdHJpbmcoKVxuXHQgICAgICB9O1xuXHQgICAgfVxuXG5cdCAgICByZXR1cm4ge1xuXHQgICAgICAkbnVtYmVyRG91YmxlOiB2YWx1ZS50b1N0cmluZygpXG5cdCAgICB9O1xuXHQgIH1cblxuXHQgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuXHQgICAgdmFyIGZsYWdzID0gdmFsdWUuZmxhZ3M7XG5cblx0ICAgIGlmIChmbGFncyA9PT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgIGZsYWdzID0gdmFsdWUudG9TdHJpbmcoKS5tYXRjaCgvW2dpbXV5XSokLylbMF07XG5cdCAgICB9XG5cblx0ICAgIHZhciByeCA9IG5ldyByZWdleHAodmFsdWUuc291cmNlLCBmbGFncyk7XG5cdCAgICByZXR1cm4gcngudG9FeHRlbmRlZEpTT04oKTtcblx0ICB9XG5cblx0ICBpZiAodmFsdWUgIT0gbnVsbCAmJiBfdHlwZW9mJDIodmFsdWUpID09PSAnb2JqZWN0JykgcmV0dXJuIHNlcmlhbGl6ZURvY3VtZW50KHZhbHVlLCBvcHRpb25zKTtcblx0ICByZXR1cm4gdmFsdWU7XG5cdH1cblxuXHR2YXIgQlNPTl9UWVBFX01BUFBJTkdTID0ge1xuXHQgIEJpbmFyeTogZnVuY3Rpb24gQmluYXJ5KG8pIHtcblx0ICAgIHJldHVybiBuZXcgYmluYXJ5KG8udmFsdWUoKSwgby5zdWJ0eXBlKTtcblx0ICB9LFxuXHQgIENvZGU6IGZ1bmN0aW9uIENvZGUobykge1xuXHQgICAgcmV0dXJuIG5ldyBjb2RlKG8uY29kZSwgby5zY29wZSk7XG5cdCAgfSxcblx0ICBEQlJlZjogZnVuY3Rpb24gREJSZWYobykge1xuXHQgICAgcmV0dXJuIG5ldyBkYl9yZWYoby5jb2xsZWN0aW9uIHx8IG8ubmFtZXNwYWNlLCBvLm9pZCwgby5kYiwgby5maWVsZHMpO1xuXHQgIH0sXG5cdCAgLy8gXCJuYW1lc3BhY2VcIiBmb3IgMS54IGxpYnJhcnkgYmFja3dhcmRzIGNvbXBhdFxuXHQgIERlY2ltYWwxMjg6IGZ1bmN0aW9uIERlY2ltYWwxMjgobykge1xuXHQgICAgcmV0dXJuIG5ldyBkZWNpbWFsMTI4KG8uYnl0ZXMpO1xuXHQgIH0sXG5cdCAgRG91YmxlOiBmdW5jdGlvbiBEb3VibGUobykge1xuXHQgICAgcmV0dXJuIG5ldyBkb3VibGVfMShvLnZhbHVlKTtcblx0ICB9LFxuXHQgIEludDMyOiBmdW5jdGlvbiBJbnQzMihvKSB7XG5cdCAgICByZXR1cm4gbmV3IGludF8zMihvLnZhbHVlKTtcblx0ICB9LFxuXHQgIExvbmc6IGZ1bmN0aW9uIExvbmcobykge1xuXHQgICAgcmV0dXJuIGxvbmdfMS5mcm9tQml0cyggLy8gdW5kZXJzY29yZSB2YXJpYW50cyBmb3IgMS54IGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG5cdCAgICBvLmxvdyAhPSBudWxsID8gby5sb3cgOiBvLmxvd18sIG8ubG93ICE9IG51bGwgPyBvLmhpZ2ggOiBvLmhpZ2hfLCBvLmxvdyAhPSBudWxsID8gby51bnNpZ25lZCA6IG8udW5zaWduZWRfKTtcblx0ICB9LFxuXHQgIE1heEtleTogZnVuY3Rpb24gTWF4S2V5KCkge1xuXHQgICAgcmV0dXJuIG5ldyBtYXhfa2V5KCk7XG5cdCAgfSxcblx0ICBNaW5LZXk6IGZ1bmN0aW9uIE1pbktleSgpIHtcblx0ICAgIHJldHVybiBuZXcgbWluX2tleSgpO1xuXHQgIH0sXG5cdCAgT2JqZWN0SUQ6IGZ1bmN0aW9uIE9iamVjdElEKG8pIHtcblx0ICAgIHJldHVybiBuZXcgb2JqZWN0aWQobyk7XG5cdCAgfSxcblx0ICBPYmplY3RJZDogZnVuY3Rpb24gT2JqZWN0SWQobykge1xuXHQgICAgcmV0dXJuIG5ldyBvYmplY3RpZChvKTtcblx0ICB9LFxuXHQgIC8vIHN1cHBvcnQgNC4wLjAvNC4wLjEgYmVmb3JlIF9ic29udHlwZSB3YXMgcmV2ZXJ0ZWQgYmFjayB0byBPYmplY3RJRFxuXHQgIEJTT05SZWdFeHA6IGZ1bmN0aW9uIEJTT05SZWdFeHAobykge1xuXHQgICAgcmV0dXJuIG5ldyByZWdleHAoby5wYXR0ZXJuLCBvLm9wdGlvbnMpO1xuXHQgIH0sXG5cdCAgU3ltYm9sOiBmdW5jdGlvbiBTeW1ib2wobykge1xuXHQgICAgcmV0dXJuIG5ldyBzeW1ib2woby52YWx1ZSk7XG5cdCAgfSxcblx0ICBUaW1lc3RhbXA6IGZ1bmN0aW9uIFRpbWVzdGFtcChvKSB7XG5cdCAgICByZXR1cm4gdGltZXN0YW1wLmZyb21CaXRzKG8ubG93LCBvLmhpZ2gpO1xuXHQgIH1cblx0fTtcblxuXHRmdW5jdGlvbiBzZXJpYWxpemVEb2N1bWVudChkb2MsIG9wdGlvbnMpIHtcblx0ICBpZiAoZG9jID09IG51bGwgfHwgX3R5cGVvZiQyKGRvYykgIT09ICdvYmplY3QnKSB0aHJvdyBuZXcgRXJyb3IoJ25vdCBhbiBvYmplY3QgaW5zdGFuY2UnKTtcblx0ICB2YXIgYnNvbnR5cGUgPSBkb2MuX2Jzb250eXBlO1xuXG5cdCAgaWYgKHR5cGVvZiBic29udHlwZSA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0ICAgIC8vIEl0J3MgYSByZWd1bGFyIG9iamVjdC4gUmVjdXJzaXZlbHkgc2VyaWFsaXplIGl0cyBwcm9wZXJ0eSB2YWx1ZXMuXG5cdCAgICB2YXIgX2RvYyA9IHt9O1xuXG5cdCAgICBmb3IgKHZhciBuYW1lIGluIGRvYykge1xuXHQgICAgICBfZG9jW25hbWVdID0gc2VyaWFsaXplVmFsdWUoZG9jW25hbWVdLCBvcHRpb25zKTtcblx0ICAgIH1cblxuXHQgICAgcmV0dXJuIF9kb2M7XG5cdCAgfSBlbHNlIGlmICh0eXBlb2YgYnNvbnR5cGUgPT09ICdzdHJpbmcnKSB7XG5cdCAgICAvLyB0aGUgXCJkb2N1bWVudFwiIGlzIHJlYWxseSBqdXN0IGEgQlNPTiB0eXBlIG9iamVjdFxuXHQgICAgdmFyIF9kb2MyID0gZG9jO1xuXG5cdCAgICBpZiAodHlwZW9mIF9kb2MyLnRvRXh0ZW5kZWRKU09OICE9PSAnZnVuY3Rpb24nKSB7XG5cdCAgICAgIC8vIFRoZXJlJ3Mgbm8gRUpTT04gc2VyaWFsaXphdGlvbiBmdW5jdGlvbiBvbiB0aGUgb2JqZWN0LiBJdCdzIHByb2JhYmx5IGFuXG5cdCAgICAgIC8vIG9iamVjdCBjcmVhdGVkIGJ5IGEgcHJldmlvdXMgdmVyc2lvbiBvZiB0aGlzIGxpYnJhcnkgKG9yIGFub3RoZXIgbGlicmFyeSlcblx0ICAgICAgLy8gdGhhdCdzIGR1Y2stdHlwaW5nIG9iamVjdHMgdG8gbG9vayBsaWtlIHRoZXkgd2VyZSBnZW5lcmF0ZWQgYnkgdGhpcyBsaWJyYXJ5KS5cblx0ICAgICAgLy8gQ29weSB0aGUgb2JqZWN0IGludG8gdGhpcyBsaWJyYXJ5J3MgdmVyc2lvbiBvZiB0aGF0IHR5cGUuXG5cdCAgICAgIHZhciBtYXBwZXIgPSBCU09OX1RZUEVfTUFQUElOR1NbYnNvbnR5cGVdO1xuXG5cdCAgICAgIGlmICghbWFwcGVyKSB7XG5cdCAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5yZWNvZ25pemVkIG9yIGludmFsaWQgX2Jzb250eXBlOiAnICsgYnNvbnR5cGUpO1xuXHQgICAgICB9XG5cblx0ICAgICAgX2RvYzIgPSBtYXBwZXIoX2RvYzIpO1xuXHQgICAgfSAvLyBUd28gQlNPTiB0eXBlcyBtYXkgaGF2ZSBuZXN0ZWQgb2JqZWN0cyB0aGF0IG1heSBuZWVkIHRvIGJlIHNlcmlhbGl6ZWQgdG9vXG5cblxuXHQgICAgaWYgKGJzb250eXBlID09PSAnQ29kZScgJiYgX2RvYzIuc2NvcGUpIHtcblx0ICAgICAgX2RvYzIgPSBuZXcgY29kZShfZG9jMi5jb2RlLCBzZXJpYWxpemVWYWx1ZShfZG9jMi5zY29wZSwgb3B0aW9ucykpO1xuXHQgICAgfSBlbHNlIGlmIChic29udHlwZSA9PT0gJ0RCUmVmJyAmJiBfZG9jMi5vaWQpIHtcblx0ICAgICAgX2RvYzIgPSBuZXcgZGJfcmVmKF9kb2MyLmNvbGxlY3Rpb24sIHNlcmlhbGl6ZVZhbHVlKF9kb2MyLm9pZCwgb3B0aW9ucyksIF9kb2MyLmRiLCBfZG9jMi5maWVsZHMpO1xuXHQgICAgfVxuXG5cdCAgICByZXR1cm4gX2RvYzIudG9FeHRlbmRlZEpTT04ob3B0aW9ucyk7XG5cdCAgfSBlbHNlIHtcblx0ICAgIHRocm93IG5ldyBFcnJvcignX2Jzb250eXBlIG11c3QgYmUgYSBzdHJpbmcsIGJ1dCB3YXM6ICcgKyBfdHlwZW9mJDIoYnNvbnR5cGUpKTtcblx0ICB9XG5cdH1cblxuXHR2YXIgZXh0ZW5kZWRfanNvbiA9IHtcblx0ICBwYXJzZTogcGFyc2UsXG5cdCAgZGVzZXJpYWxpemU6IGRlc2VyaWFsaXplLFxuXHQgIHNlcmlhbGl6ZTogc2VyaWFsaXplLFxuXHQgIHN0cmluZ2lmeTogc3RyaW5naWZ5XG5cdH07XG5cblx0dmFyIEZJUlNUX0JJVCA9IDB4ODA7XG5cdHZhciBGSVJTVF9UV09fQklUUyA9IDB4YzA7XG5cdHZhciBGSVJTVF9USFJFRV9CSVRTID0gMHhlMDtcblx0dmFyIEZJUlNUX0ZPVVJfQklUUyA9IDB4ZjA7XG5cdHZhciBGSVJTVF9GSVZFX0JJVFMgPSAweGY4O1xuXHR2YXIgVFdPX0JJVF9DSEFSID0gMHhjMDtcblx0dmFyIFRIUkVFX0JJVF9DSEFSID0gMHhlMDtcblx0dmFyIEZPVVJfQklUX0NIQVIgPSAweGYwO1xuXHR2YXIgQ09OVElOVUlOR19DSEFSID0gMHg4MDtcblx0LyoqXG5cdCAqIERldGVybWluZXMgaWYgdGhlIHBhc3NlZCBpbiBieXRlcyBhcmUgdmFsaWQgdXRmOFxuXHQgKiBAcGFyYW0ge0J1ZmZlcnxVaW50OEFycmF5fSBieXRlcyBBbiBhcnJheSBvZiA4LWJpdCBieXRlcy4gTXVzdCBiZSBpbmRleGFibGUgYW5kIGhhdmUgbGVuZ3RoIHByb3BlcnR5XG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBzdGFydCBUaGUgaW5kZXggdG8gc3RhcnQgdmFsaWRhdGluZ1xuXHQgKiBAcGFyYW0ge051bWJlcn0gZW5kIFRoZSBpbmRleCB0byBlbmQgdmFsaWRhdGluZ1xuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWxpZCB1dGY4XG5cdCAqL1xuXG5cdGZ1bmN0aW9uIHZhbGlkYXRlVXRmOChieXRlcywgc3RhcnQsIGVuZCkge1xuXHQgIHZhciBjb250aW51YXRpb24gPSAwO1xuXG5cdCAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpICs9IDEpIHtcblx0ICAgIHZhciBieXRlID0gYnl0ZXNbaV07XG5cblx0ICAgIGlmIChjb250aW51YXRpb24pIHtcblx0ICAgICAgaWYgKChieXRlICYgRklSU1RfVFdPX0JJVFMpICE9PSBDT05USU5VSU5HX0NIQVIpIHtcblx0ICAgICAgICByZXR1cm4gZmFsc2U7XG5cdCAgICAgIH1cblxuXHQgICAgICBjb250aW51YXRpb24gLT0gMTtcblx0ICAgIH0gZWxzZSBpZiAoYnl0ZSAmIEZJUlNUX0JJVCkge1xuXHQgICAgICBpZiAoKGJ5dGUgJiBGSVJTVF9USFJFRV9CSVRTKSA9PT0gVFdPX0JJVF9DSEFSKSB7XG5cdCAgICAgICAgY29udGludWF0aW9uID0gMTtcblx0ICAgICAgfSBlbHNlIGlmICgoYnl0ZSAmIEZJUlNUX0ZPVVJfQklUUykgPT09IFRIUkVFX0JJVF9DSEFSKSB7XG5cdCAgICAgICAgY29udGludWF0aW9uID0gMjtcblx0ICAgICAgfSBlbHNlIGlmICgoYnl0ZSAmIEZJUlNUX0ZJVkVfQklUUykgPT09IEZPVVJfQklUX0NIQVIpIHtcblx0ICAgICAgICBjb250aW51YXRpb24gPSAzO1xuXHQgICAgICB9IGVsc2Uge1xuXHQgICAgICAgIHJldHVybiBmYWxzZTtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH1cblxuXHQgIHJldHVybiAhY29udGludWF0aW9uO1xuXHR9XG5cblx0dmFyIHZhbGlkYXRlVXRmOF8xID0gdmFsaWRhdGVVdGY4O1xuXHR2YXIgdmFsaWRhdGVfdXRmOCA9IHtcblx0ICB2YWxpZGF0ZVV0Zjg6IHZhbGlkYXRlVXRmOF8xXG5cdH07XG5cblx0dmFyIEJ1ZmZlciQ0ID0gYnVmZmVyLkJ1ZmZlcjtcblx0dmFyIHZhbGlkYXRlVXRmOCQxID0gdmFsaWRhdGVfdXRmOC52YWxpZGF0ZVV0Zjg7IC8vIEludGVybmFsIGxvbmcgdmVyc2lvbnNcblxuXHR2YXIgSlNfSU5UX01BWF9MT05HID0gbG9uZ18xLmZyb21OdW1iZXIoY29uc3RhbnRzLkpTX0lOVF9NQVgpO1xuXHR2YXIgSlNfSU5UX01JTl9MT05HID0gbG9uZ18xLmZyb21OdW1iZXIoY29uc3RhbnRzLkpTX0lOVF9NSU4pO1xuXHR2YXIgZnVuY3Rpb25DYWNoZSA9IHt9O1xuXG5cdGZ1bmN0aW9uIGRlc2VyaWFsaXplJDEoYnVmZmVyJCQxLCBvcHRpb25zLCBpc0FycmF5KSB7XG5cdCAgb3B0aW9ucyA9IG9wdGlvbnMgPT0gbnVsbCA/IHt9IDogb3B0aW9ucztcblx0ICB2YXIgaW5kZXggPSBvcHRpb25zICYmIG9wdGlvbnMuaW5kZXggPyBvcHRpb25zLmluZGV4IDogMDsgLy8gUmVhZCB0aGUgZG9jdW1lbnQgc2l6ZVxuXG5cdCAgdmFyIHNpemUgPSBidWZmZXIkJDFbaW5kZXhdIHwgYnVmZmVyJCQxW2luZGV4ICsgMV0gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCArIDJdIDw8IDE2IHwgYnVmZmVyJCQxW2luZGV4ICsgM10gPDwgMjQ7XG5cblx0ICBpZiAoc2l6ZSA8IDUpIHtcblx0ICAgIHRocm93IG5ldyBFcnJvcihcImJzb24gc2l6ZSBtdXN0IGJlID49IDUsIGlzIFwiLmNvbmNhdChzaXplKSk7XG5cdCAgfVxuXG5cdCAgaWYgKG9wdGlvbnMuYWxsb3dPYmplY3RTbWFsbGVyVGhhbkJ1ZmZlclNpemUgJiYgYnVmZmVyJCQxLmxlbmd0aCA8IHNpemUpIHtcblx0ICAgIHRocm93IG5ldyBFcnJvcihcImJ1ZmZlciBsZW5ndGggXCIuY29uY2F0KGJ1ZmZlciQkMS5sZW5ndGgsIFwiIG11c3QgYmUgPj0gYnNvbiBzaXplIFwiKS5jb25jYXQoc2l6ZSkpO1xuXHQgIH1cblxuXHQgIGlmICghb3B0aW9ucy5hbGxvd09iamVjdFNtYWxsZXJUaGFuQnVmZmVyU2l6ZSAmJiBidWZmZXIkJDEubGVuZ3RoICE9PSBzaXplKSB7XG5cdCAgICB0aHJvdyBuZXcgRXJyb3IoXCJidWZmZXIgbGVuZ3RoIFwiLmNvbmNhdChidWZmZXIkJDEubGVuZ3RoLCBcIiBtdXN0ID09PSBic29uIHNpemUgXCIpLmNvbmNhdChzaXplKSk7XG5cdCAgfVxuXG5cdCAgaWYgKHNpemUgKyBpbmRleCA+IGJ1ZmZlciQkMS5sZW5ndGgpIHtcblx0ICAgIHRocm93IG5ldyBFcnJvcihcIihic29uIHNpemUgXCIuY29uY2F0KHNpemUsIFwiICsgb3B0aW9ucy5pbmRleCBcIikuY29uY2F0KGluZGV4LCBcIiBtdXN0IGJlIDw9IGJ1ZmZlciBsZW5ndGggXCIpLmNvbmNhdChCdWZmZXIkNC5ieXRlTGVuZ3RoKGJ1ZmZlciQkMSksIFwiKVwiKSk7XG5cdCAgfSAvLyBJbGxlZ2FsIGVuZCB2YWx1ZVxuXG5cblx0ICBpZiAoYnVmZmVyJCQxW2luZGV4ICsgc2l6ZSAtIDFdICE9PSAwKSB7XG5cdCAgICB0aHJvdyBuZXcgRXJyb3IoXCJPbmUgb2JqZWN0LCBzaXplZCBjb3JyZWN0bHksIHdpdGggYSBzcG90IGZvciBhbiBFT08sIGJ1dCB0aGUgRU9PIGlzbid0IDB4MDBcIik7XG5cdCAgfSAvLyBTdGFydCBkZXNlcmlhbGl6dGlvblxuXG5cblx0ICByZXR1cm4gZGVzZXJpYWxpemVPYmplY3QoYnVmZmVyJCQxLCBpbmRleCwgb3B0aW9ucywgaXNBcnJheSk7XG5cdH1cblxuXHRmdW5jdGlvbiBkZXNlcmlhbGl6ZU9iamVjdChidWZmZXIkJDEsIGluZGV4LCBvcHRpb25zLCBpc0FycmF5KSB7XG5cdCAgdmFyIGV2YWxGdW5jdGlvbnMgPSBvcHRpb25zWydldmFsRnVuY3Rpb25zJ10gPT0gbnVsbCA/IGZhbHNlIDogb3B0aW9uc1snZXZhbEZ1bmN0aW9ucyddO1xuXHQgIHZhciBjYWNoZUZ1bmN0aW9ucyA9IG9wdGlvbnNbJ2NhY2hlRnVuY3Rpb25zJ10gPT0gbnVsbCA/IGZhbHNlIDogb3B0aW9uc1snY2FjaGVGdW5jdGlvbnMnXTtcblx0ICB2YXIgY2FjaGVGdW5jdGlvbnNDcmMzMiA9IG9wdGlvbnNbJ2NhY2hlRnVuY3Rpb25zQ3JjMzInXSA9PSBudWxsID8gZmFsc2UgOiBvcHRpb25zWydjYWNoZUZ1bmN0aW9uc0NyYzMyJ107XG5cdCAgaWYgKCFjYWNoZUZ1bmN0aW9uc0NyYzMyKSB2YXIgY3JjMzIgPSBudWxsO1xuXHQgIHZhciBmaWVsZHNBc1JhdyA9IG9wdGlvbnNbJ2ZpZWxkc0FzUmF3J10gPT0gbnVsbCA/IG51bGwgOiBvcHRpb25zWydmaWVsZHNBc1JhdyddOyAvLyBSZXR1cm4gcmF3IGJzb24gYnVmZmVyIGluc3RlYWQgb2YgcGFyc2luZyBpdFxuXG5cdCAgdmFyIHJhdyA9IG9wdGlvbnNbJ3JhdyddID09IG51bGwgPyBmYWxzZSA6IG9wdGlvbnNbJ3JhdyddOyAvLyBSZXR1cm4gQlNPTlJlZ0V4cCBvYmplY3RzIGluc3RlYWQgb2YgbmF0aXZlIHJlZ3VsYXIgZXhwcmVzc2lvbnNcblxuXHQgIHZhciBic29uUmVnRXhwID0gdHlwZW9mIG9wdGlvbnNbJ2Jzb25SZWdFeHAnXSA9PT0gJ2Jvb2xlYW4nID8gb3B0aW9uc1snYnNvblJlZ0V4cCddIDogZmFsc2U7IC8vIENvbnRyb2xzIHRoZSBwcm9tb3Rpb24gb2YgdmFsdWVzIHZzIHdyYXBwZXIgY2xhc3Nlc1xuXG5cdCAgdmFyIHByb21vdGVCdWZmZXJzID0gb3B0aW9uc1sncHJvbW90ZUJ1ZmZlcnMnXSA9PSBudWxsID8gZmFsc2UgOiBvcHRpb25zWydwcm9tb3RlQnVmZmVycyddO1xuXHQgIHZhciBwcm9tb3RlTG9uZ3MgPSBvcHRpb25zWydwcm9tb3RlTG9uZ3MnXSA9PSBudWxsID8gdHJ1ZSA6IG9wdGlvbnNbJ3Byb21vdGVMb25ncyddO1xuXHQgIHZhciBwcm9tb3RlVmFsdWVzID0gb3B0aW9uc1sncHJvbW90ZVZhbHVlcyddID09IG51bGwgPyB0cnVlIDogb3B0aW9uc1sncHJvbW90ZVZhbHVlcyddOyAvLyBTZXQgdGhlIHN0YXJ0IGluZGV4XG5cblx0ICB2YXIgc3RhcnRJbmRleCA9IGluZGV4OyAvLyBWYWxpZGF0ZSB0aGF0IHdlIGhhdmUgYXQgbGVhc3QgNCBieXRlcyBvZiBidWZmZXJcblxuXHQgIGlmIChidWZmZXIkJDEubGVuZ3RoIDwgNSkgdGhyb3cgbmV3IEVycm9yKCdjb3JydXB0IGJzb24gbWVzc2FnZSA8IDUgYnl0ZXMgbG9uZycpOyAvLyBSZWFkIHRoZSBkb2N1bWVudCBzaXplXG5cblx0ICB2YXIgc2l6ZSA9IGJ1ZmZlciQkMVtpbmRleCsrXSB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCA4IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDE2IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDI0OyAvLyBFbnN1cmUgYnVmZmVyIGlzIHZhbGlkIHNpemVcblxuXHQgIGlmIChzaXplIDwgNSB8fCBzaXplID4gYnVmZmVyJCQxLmxlbmd0aCkgdGhyb3cgbmV3IEVycm9yKCdjb3JydXB0IGJzb24gbWVzc2FnZScpOyAvLyBDcmVhdGUgaG9sZGluZyBvYmplY3RcblxuXHQgIHZhciBvYmplY3QgPSBpc0FycmF5ID8gW10gOiB7fTsgLy8gVXNlZCBmb3IgYXJyYXlzIHRvIHNraXAgaGF2aW5nIHRvIHBlcmZvcm0gdXRmOCBkZWNvZGluZ1xuXG5cdCAgdmFyIGFycmF5SW5kZXggPSAwO1xuXHQgIHZhciBkb25lID0gZmFsc2U7IC8vIFdoaWxlIHdlIGhhdmUgbW9yZSBsZWZ0IGRhdGEgbGVmdCBrZWVwIHBhcnNpbmdcblxuXHQgIHdoaWxlICghZG9uZSkge1xuXHQgICAgLy8gUmVhZCB0aGUgdHlwZVxuXHQgICAgdmFyIGVsZW1lbnRUeXBlID0gYnVmZmVyJCQxW2luZGV4KytdOyAvLyBJZiB3ZSBnZXQgYSB6ZXJvIGl0J3MgdGhlIGxhc3QgYnl0ZSwgZXhpdFxuXG5cdCAgICBpZiAoZWxlbWVudFR5cGUgPT09IDApIGJyZWFrOyAvLyBHZXQgdGhlIHN0YXJ0IHNlYXJjaCBpbmRleFxuXG5cdCAgICB2YXIgaSA9IGluZGV4OyAvLyBMb2NhdGUgdGhlIGVuZCBvZiB0aGUgYyBzdHJpbmdcblxuXHQgICAgd2hpbGUgKGJ1ZmZlciQkMVtpXSAhPT0gMHgwMCAmJiBpIDwgYnVmZmVyJCQxLmxlbmd0aCkge1xuXHQgICAgICBpKys7XG5cdCAgICB9IC8vIElmIGFyZSBhdCB0aGUgZW5kIG9mIHRoZSBidWZmZXIgdGhlcmUgaXMgYSBwcm9ibGVtIHdpdGggdGhlIGRvY3VtZW50XG5cblxuXHQgICAgaWYgKGkgPj0gQnVmZmVyJDQuYnl0ZUxlbmd0aChidWZmZXIkJDEpKSB0aHJvdyBuZXcgRXJyb3IoJ0JhZCBCU09OIERvY3VtZW50OiBpbGxlZ2FsIENTdHJpbmcnKTtcblx0ICAgIHZhciBuYW1lID0gaXNBcnJheSA/IGFycmF5SW5kZXgrKyA6IGJ1ZmZlciQkMS50b1N0cmluZygndXRmOCcsIGluZGV4LCBpKTtcblx0ICAgIGluZGV4ID0gaSArIDE7XG5cblx0ICAgIGlmIChlbGVtZW50VHlwZSA9PT0gY29uc3RhbnRzLkJTT05fREFUQV9TVFJJTkcpIHtcblx0ICAgICAgdmFyIHN0cmluZ1NpemUgPSBidWZmZXIkJDFbaW5kZXgrK10gfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAyNDtcblx0ICAgICAgaWYgKHN0cmluZ1NpemUgPD0gMCB8fCBzdHJpbmdTaXplID4gYnVmZmVyJCQxLmxlbmd0aCAtIGluZGV4IHx8IGJ1ZmZlciQkMVtpbmRleCArIHN0cmluZ1NpemUgLSAxXSAhPT0gMCkgdGhyb3cgbmV3IEVycm9yKCdiYWQgc3RyaW5nIGxlbmd0aCBpbiBic29uJyk7XG5cblx0ICAgICAgaWYgKCF2YWxpZGF0ZVV0ZjgkMShidWZmZXIkJDEsIGluZGV4LCBpbmRleCArIHN0cmluZ1NpemUgLSAxKSkge1xuXHQgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBVVEYtOCBzdHJpbmcgaW4gQlNPTiBkb2N1bWVudCcpO1xuXHQgICAgICB9XG5cblx0ICAgICAgdmFyIHMgPSBidWZmZXIkJDEudG9TdHJpbmcoJ3V0ZjgnLCBpbmRleCwgaW5kZXggKyBzdHJpbmdTaXplIC0gMSk7XG5cdCAgICAgIG9iamVjdFtuYW1lXSA9IHM7XG5cdCAgICAgIGluZGV4ID0gaW5kZXggKyBzdHJpbmdTaXplO1xuXHQgICAgfSBlbHNlIGlmIChlbGVtZW50VHlwZSA9PT0gY29uc3RhbnRzLkJTT05fREFUQV9PSUQpIHtcblx0ICAgICAgdmFyIG9pZCA9IEJ1ZmZlciQ0LmFsbG9jKDEyKTtcblx0ICAgICAgYnVmZmVyJCQxLmNvcHkob2lkLCAwLCBpbmRleCwgaW5kZXggKyAxMik7XG5cdCAgICAgIG9iamVjdFtuYW1lXSA9IG5ldyBvYmplY3RpZChvaWQpO1xuXHQgICAgICBpbmRleCA9IGluZGV4ICsgMTI7XG5cdCAgICB9IGVsc2UgaWYgKGVsZW1lbnRUeXBlID09PSBjb25zdGFudHMuQlNPTl9EQVRBX0lOVCAmJiBwcm9tb3RlVmFsdWVzID09PSBmYWxzZSkge1xuXHQgICAgICBvYmplY3RbbmFtZV0gPSBuZXcgaW50XzMyKGJ1ZmZlciQkMVtpbmRleCsrXSB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCA4IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDE2IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDI0KTtcblx0ICAgIH0gZWxzZSBpZiAoZWxlbWVudFR5cGUgPT09IGNvbnN0YW50cy5CU09OX0RBVEFfSU5UKSB7XG5cdCAgICAgIG9iamVjdFtuYW1lXSA9IGJ1ZmZlciQkMVtpbmRleCsrXSB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCA4IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDE2IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDI0O1xuXHQgICAgfSBlbHNlIGlmIChlbGVtZW50VHlwZSA9PT0gY29uc3RhbnRzLkJTT05fREFUQV9OVU1CRVIgJiYgcHJvbW90ZVZhbHVlcyA9PT0gZmFsc2UpIHtcblx0ICAgICAgb2JqZWN0W25hbWVdID0gbmV3IGRvdWJsZV8xKGJ1ZmZlciQkMS5yZWFkRG91YmxlTEUoaW5kZXgpKTtcblx0ICAgICAgaW5kZXggPSBpbmRleCArIDg7XG5cdCAgICB9IGVsc2UgaWYgKGVsZW1lbnRUeXBlID09PSBjb25zdGFudHMuQlNPTl9EQVRBX05VTUJFUikge1xuXHQgICAgICBvYmplY3RbbmFtZV0gPSBidWZmZXIkJDEucmVhZERvdWJsZUxFKGluZGV4KTtcblx0ICAgICAgaW5kZXggPSBpbmRleCArIDg7XG5cdCAgICB9IGVsc2UgaWYgKGVsZW1lbnRUeXBlID09PSBjb25zdGFudHMuQlNPTl9EQVRBX0RBVEUpIHtcblx0ICAgICAgdmFyIGxvd0JpdHMgPSBidWZmZXIkJDFbaW5kZXgrK10gfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAyNDtcblx0ICAgICAgdmFyIGhpZ2hCaXRzID0gYnVmZmVyJCQxW2luZGV4KytdIHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDggfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMTYgfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMjQ7XG5cdCAgICAgIG9iamVjdFtuYW1lXSA9IG5ldyBEYXRlKG5ldyBsb25nXzEobG93Qml0cywgaGlnaEJpdHMpLnRvTnVtYmVyKCkpO1xuXHQgICAgfSBlbHNlIGlmIChlbGVtZW50VHlwZSA9PT0gY29uc3RhbnRzLkJTT05fREFUQV9CT09MRUFOKSB7XG5cdCAgICAgIGlmIChidWZmZXIkJDFbaW5kZXhdICE9PSAwICYmIGJ1ZmZlciQkMVtpbmRleF0gIT09IDEpIHRocm93IG5ldyBFcnJvcignaWxsZWdhbCBib29sZWFuIHR5cGUgdmFsdWUnKTtcblx0ICAgICAgb2JqZWN0W25hbWVdID0gYnVmZmVyJCQxW2luZGV4KytdID09PSAxO1xuXHQgICAgfSBlbHNlIGlmIChlbGVtZW50VHlwZSA9PT0gY29uc3RhbnRzLkJTT05fREFUQV9PQkpFQ1QpIHtcblx0ICAgICAgdmFyIF9pbmRleCA9IGluZGV4O1xuXHQgICAgICB2YXIgb2JqZWN0U2l6ZSA9IGJ1ZmZlciQkMVtpbmRleF0gfCBidWZmZXIkJDFbaW5kZXggKyAxXSA8PCA4IHwgYnVmZmVyJCQxW2luZGV4ICsgMl0gPDwgMTYgfCBidWZmZXIkJDFbaW5kZXggKyAzXSA8PCAyNDtcblx0ICAgICAgaWYgKG9iamVjdFNpemUgPD0gMCB8fCBvYmplY3RTaXplID4gYnVmZmVyJCQxLmxlbmd0aCAtIGluZGV4KSB0aHJvdyBuZXcgRXJyb3IoJ2JhZCBlbWJlZGRlZCBkb2N1bWVudCBsZW5ndGggaW4gYnNvbicpOyAvLyBXZSBoYXZlIGEgcmF3IHZhbHVlXG5cblx0ICAgICAgaWYgKHJhdykge1xuXHQgICAgICAgIG9iamVjdFtuYW1lXSA9IGJ1ZmZlciQkMS5zbGljZShpbmRleCwgaW5kZXggKyBvYmplY3RTaXplKTtcblx0ICAgICAgfSBlbHNlIHtcblx0ICAgICAgICBvYmplY3RbbmFtZV0gPSBkZXNlcmlhbGl6ZU9iamVjdChidWZmZXIkJDEsIF9pbmRleCwgb3B0aW9ucywgZmFsc2UpO1xuXHQgICAgICB9XG5cblx0ICAgICAgaW5kZXggPSBpbmRleCArIG9iamVjdFNpemU7XG5cdCAgICB9IGVsc2UgaWYgKGVsZW1lbnRUeXBlID09PSBjb25zdGFudHMuQlNPTl9EQVRBX0FSUkFZKSB7XG5cdCAgICAgIHZhciBfaW5kZXgyID0gaW5kZXg7XG5cblx0ICAgICAgdmFyIF9vYmplY3RTaXplID0gYnVmZmVyJCQxW2luZGV4XSB8IGJ1ZmZlciQkMVtpbmRleCArIDFdIDw8IDggfCBidWZmZXIkJDFbaW5kZXggKyAyXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCArIDNdIDw8IDI0O1xuXG5cdCAgICAgIHZhciBhcnJheU9wdGlvbnMgPSBvcHRpb25zOyAvLyBTdG9wIGluZGV4XG5cblx0ICAgICAgdmFyIHN0b3BJbmRleCA9IGluZGV4ICsgX29iamVjdFNpemU7IC8vIEFsbCBlbGVtZW50cyBvZiBhcnJheSB0byBiZSByZXR1cm5lZCBhcyByYXcgYnNvblxuXG5cdCAgICAgIGlmIChmaWVsZHNBc1JhdyAmJiBmaWVsZHNBc1Jhd1tuYW1lXSkge1xuXHQgICAgICAgIGFycmF5T3B0aW9ucyA9IHt9O1xuXG5cdCAgICAgICAgZm9yICh2YXIgbiBpbiBvcHRpb25zKSB7XG5cdCAgICAgICAgICBhcnJheU9wdGlvbnNbbl0gPSBvcHRpb25zW25dO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGFycmF5T3B0aW9uc1sncmF3J10gPSB0cnVlO1xuXHQgICAgICB9XG5cblx0ICAgICAgb2JqZWN0W25hbWVdID0gZGVzZXJpYWxpemVPYmplY3QoYnVmZmVyJCQxLCBfaW5kZXgyLCBhcnJheU9wdGlvbnMsIHRydWUpO1xuXHQgICAgICBpbmRleCA9IGluZGV4ICsgX29iamVjdFNpemU7XG5cdCAgICAgIGlmIChidWZmZXIkJDFbaW5kZXggLSAxXSAhPT0gMCkgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGFycmF5IHRlcm1pbmF0b3IgYnl0ZScpO1xuXHQgICAgICBpZiAoaW5kZXggIT09IHN0b3BJbmRleCkgdGhyb3cgbmV3IEVycm9yKCdjb3JydXB0ZWQgYXJyYXkgYnNvbicpO1xuXHQgICAgfSBlbHNlIGlmIChlbGVtZW50VHlwZSA9PT0gY29uc3RhbnRzLkJTT05fREFUQV9VTkRFRklORUQpIHtcblx0ICAgICAgb2JqZWN0W25hbWVdID0gdW5kZWZpbmVkO1xuXHQgICAgfSBlbHNlIGlmIChlbGVtZW50VHlwZSA9PT0gY29uc3RhbnRzLkJTT05fREFUQV9OVUxMKSB7XG5cdCAgICAgIG9iamVjdFtuYW1lXSA9IG51bGw7XG5cdCAgICB9IGVsc2UgaWYgKGVsZW1lbnRUeXBlID09PSBjb25zdGFudHMuQlNPTl9EQVRBX0xPTkcpIHtcblx0ICAgICAgLy8gVW5wYWNrIHRoZSBsb3cgYW5kIGhpZ2ggYml0c1xuXHQgICAgICB2YXIgX2xvd0JpdHMgPSBidWZmZXIkJDFbaW5kZXgrK10gfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAyNDtcblxuXHQgICAgICB2YXIgX2hpZ2hCaXRzID0gYnVmZmVyJCQxW2luZGV4KytdIHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDggfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMTYgfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMjQ7XG5cblx0ICAgICAgdmFyIGxvbmckJDEgPSBuZXcgbG9uZ18xKF9sb3dCaXRzLCBfaGlnaEJpdHMpOyAvLyBQcm9tb3RlIHRoZSBsb25nIGlmIHBvc3NpYmxlXG5cblx0ICAgICAgaWYgKHByb21vdGVMb25ncyAmJiBwcm9tb3RlVmFsdWVzID09PSB0cnVlKSB7XG5cdCAgICAgICAgb2JqZWN0W25hbWVdID0gbG9uZyQkMS5sZXNzVGhhbk9yRXF1YWwoSlNfSU5UX01BWF9MT05HKSAmJiBsb25nJCQxLmdyZWF0ZXJUaGFuT3JFcXVhbChKU19JTlRfTUlOX0xPTkcpID8gbG9uZyQkMS50b051bWJlcigpIDogbG9uZyQkMTtcblx0ICAgICAgfSBlbHNlIHtcblx0ICAgICAgICBvYmplY3RbbmFtZV0gPSBsb25nJCQxO1xuXHQgICAgICB9XG5cdCAgICB9IGVsc2UgaWYgKGVsZW1lbnRUeXBlID09PSBjb25zdGFudHMuQlNPTl9EQVRBX0RFQ0lNQUwxMjgpIHtcblx0ICAgICAgLy8gQnVmZmVyIHRvIGNvbnRhaW4gdGhlIGRlY2ltYWwgYnl0ZXNcblx0ICAgICAgdmFyIGJ5dGVzID0gQnVmZmVyJDQuYWxsb2MoMTYpOyAvLyBDb3B5IHRoZSBuZXh0IDE2IGJ5dGVzIGludG8gdGhlIGJ5dGVzIGJ1ZmZlclxuXG5cdCAgICAgIGJ1ZmZlciQkMS5jb3B5KGJ5dGVzLCAwLCBpbmRleCwgaW5kZXggKyAxNik7IC8vIFVwZGF0ZSBpbmRleFxuXG5cdCAgICAgIGluZGV4ID0gaW5kZXggKyAxNjsgLy8gQXNzaWduIHRoZSBuZXcgRGVjaW1hbDEyOCB2YWx1ZVxuXG5cdCAgICAgIHZhciBkZWNpbWFsMTI4JCQxID0gbmV3IGRlY2ltYWwxMjgoYnl0ZXMpOyAvLyBJZiB3ZSBoYXZlIGFuIGFsdGVybmF0aXZlIG1hcHBlciB1c2UgdGhhdFxuXG5cdCAgICAgIG9iamVjdFtuYW1lXSA9IGRlY2ltYWwxMjgkJDEudG9PYmplY3QgPyBkZWNpbWFsMTI4JCQxLnRvT2JqZWN0KCkgOiBkZWNpbWFsMTI4JCQxO1xuXHQgICAgfSBlbHNlIGlmIChlbGVtZW50VHlwZSA9PT0gY29uc3RhbnRzLkJTT05fREFUQV9CSU5BUlkpIHtcblx0ICAgICAgdmFyIGJpbmFyeVNpemUgPSBidWZmZXIkJDFbaW5kZXgrK10gfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAyNDtcblx0ICAgICAgdmFyIHRvdGFsQmluYXJ5U2l6ZSA9IGJpbmFyeVNpemU7XG5cdCAgICAgIHZhciBzdWJUeXBlID0gYnVmZmVyJCQxW2luZGV4KytdOyAvLyBEaWQgd2UgaGF2ZSBhIG5lZ2F0aXZlIGJpbmFyeSBzaXplLCB0aHJvd1xuXG5cdCAgICAgIGlmIChiaW5hcnlTaXplIDwgMCkgdGhyb3cgbmV3IEVycm9yKCdOZWdhdGl2ZSBiaW5hcnkgdHlwZSBlbGVtZW50IHNpemUgZm91bmQnKTsgLy8gSXMgdGhlIGxlbmd0aCBsb25nZXIgdGhhbiB0aGUgZG9jdW1lbnRcblxuXHQgICAgICBpZiAoYmluYXJ5U2l6ZSA+IEJ1ZmZlciQ0LmJ5dGVMZW5ndGgoYnVmZmVyJCQxKSkgdGhyb3cgbmV3IEVycm9yKCdCaW5hcnkgdHlwZSBzaXplIGxhcmdlciB0aGFuIGRvY3VtZW50IHNpemUnKTsgLy8gRGVjb2RlIGFzIHJhdyBCdWZmZXIgb2JqZWN0IGlmIG9wdGlvbnMgc3BlY2lmaWVzIGl0XG5cblx0ICAgICAgaWYgKGJ1ZmZlciQkMVsnc2xpY2UnXSAhPSBudWxsKSB7XG5cdCAgICAgICAgLy8gSWYgd2UgaGF2ZSBzdWJ0eXBlIDIgc2tpcCB0aGUgNCBieXRlcyBmb3IgdGhlIHNpemVcblx0ICAgICAgICBpZiAoc3ViVHlwZSA9PT0gYmluYXJ5LlNVQlRZUEVfQllURV9BUlJBWSkge1xuXHQgICAgICAgICAgYmluYXJ5U2l6ZSA9IGJ1ZmZlciQkMVtpbmRleCsrXSB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCA4IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDE2IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDI0O1xuXHQgICAgICAgICAgaWYgKGJpbmFyeVNpemUgPCAwKSB0aHJvdyBuZXcgRXJyb3IoJ05lZ2F0aXZlIGJpbmFyeSB0eXBlIGVsZW1lbnQgc2l6ZSBmb3VuZCBmb3Igc3VidHlwZSAweDAyJyk7XG5cdCAgICAgICAgICBpZiAoYmluYXJ5U2l6ZSA+IHRvdGFsQmluYXJ5U2l6ZSAtIDQpIHRocm93IG5ldyBFcnJvcignQmluYXJ5IHR5cGUgd2l0aCBzdWJ0eXBlIDB4MDIgY29udGFpbnMgdG8gbG9uZyBiaW5hcnkgc2l6ZScpO1xuXHQgICAgICAgICAgaWYgKGJpbmFyeVNpemUgPCB0b3RhbEJpbmFyeVNpemUgLSA0KSB0aHJvdyBuZXcgRXJyb3IoJ0JpbmFyeSB0eXBlIHdpdGggc3VidHlwZSAweDAyIGNvbnRhaW5zIHRvIHNob3J0IGJpbmFyeSBzaXplJyk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgaWYgKHByb21vdGVCdWZmZXJzICYmIHByb21vdGVWYWx1ZXMpIHtcblx0ICAgICAgICAgIG9iamVjdFtuYW1lXSA9IGJ1ZmZlciQkMS5zbGljZShpbmRleCwgaW5kZXggKyBiaW5hcnlTaXplKTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgb2JqZWN0W25hbWVdID0gbmV3IGJpbmFyeShidWZmZXIkJDEuc2xpY2UoaW5kZXgsIGluZGV4ICsgYmluYXJ5U2l6ZSksIHN1YlR5cGUpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfSBlbHNlIHtcblx0ICAgICAgICB2YXIgX2J1ZmZlciA9IHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJyA/IG5ldyBVaW50OEFycmF5KG5ldyBBcnJheUJ1ZmZlcihiaW5hcnlTaXplKSkgOiBuZXcgQXJyYXkoYmluYXJ5U2l6ZSk7IC8vIElmIHdlIGhhdmUgc3VidHlwZSAyIHNraXAgdGhlIDQgYnl0ZXMgZm9yIHRoZSBzaXplXG5cblxuXHQgICAgICAgIGlmIChzdWJUeXBlID09PSBiaW5hcnkuU1VCVFlQRV9CWVRFX0FSUkFZKSB7XG5cdCAgICAgICAgICBiaW5hcnlTaXplID0gYnVmZmVyJCQxW2luZGV4KytdIHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDggfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMTYgfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMjQ7XG5cdCAgICAgICAgICBpZiAoYmluYXJ5U2l6ZSA8IDApIHRocm93IG5ldyBFcnJvcignTmVnYXRpdmUgYmluYXJ5IHR5cGUgZWxlbWVudCBzaXplIGZvdW5kIGZvciBzdWJ0eXBlIDB4MDInKTtcblx0ICAgICAgICAgIGlmIChiaW5hcnlTaXplID4gdG90YWxCaW5hcnlTaXplIC0gNCkgdGhyb3cgbmV3IEVycm9yKCdCaW5hcnkgdHlwZSB3aXRoIHN1YnR5cGUgMHgwMiBjb250YWlucyB0byBsb25nIGJpbmFyeSBzaXplJyk7XG5cdCAgICAgICAgICBpZiAoYmluYXJ5U2l6ZSA8IHRvdGFsQmluYXJ5U2l6ZSAtIDQpIHRocm93IG5ldyBFcnJvcignQmluYXJ5IHR5cGUgd2l0aCBzdWJ0eXBlIDB4MDIgY29udGFpbnMgdG8gc2hvcnQgYmluYXJ5IHNpemUnKTtcblx0ICAgICAgICB9IC8vIENvcHkgdGhlIGRhdGFcblxuXG5cdCAgICAgICAgZm9yIChpID0gMDsgaSA8IGJpbmFyeVNpemU7IGkrKykge1xuXHQgICAgICAgICAgX2J1ZmZlcltpXSA9IGJ1ZmZlciQkMVtpbmRleCArIGldO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmIChwcm9tb3RlQnVmZmVycyAmJiBwcm9tb3RlVmFsdWVzKSB7XG5cdCAgICAgICAgICBvYmplY3RbbmFtZV0gPSBfYnVmZmVyO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICBvYmplY3RbbmFtZV0gPSBuZXcgYmluYXJ5KF9idWZmZXIsIHN1YlR5cGUpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfSAvLyBVcGRhdGUgdGhlIGluZGV4XG5cblxuXHQgICAgICBpbmRleCA9IGluZGV4ICsgYmluYXJ5U2l6ZTtcblx0ICAgIH0gZWxzZSBpZiAoZWxlbWVudFR5cGUgPT09IGNvbnN0YW50cy5CU09OX0RBVEFfUkVHRVhQICYmIGJzb25SZWdFeHAgPT09IGZhbHNlKSB7XG5cdCAgICAgIC8vIEdldCB0aGUgc3RhcnQgc2VhcmNoIGluZGV4XG5cdCAgICAgIGkgPSBpbmRleDsgLy8gTG9jYXRlIHRoZSBlbmQgb2YgdGhlIGMgc3RyaW5nXG5cblx0ICAgICAgd2hpbGUgKGJ1ZmZlciQkMVtpXSAhPT0gMHgwMCAmJiBpIDwgYnVmZmVyJCQxLmxlbmd0aCkge1xuXHQgICAgICAgIGkrKztcblx0ICAgICAgfSAvLyBJZiBhcmUgYXQgdGhlIGVuZCBvZiB0aGUgYnVmZmVyIHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIHRoZSBkb2N1bWVudFxuXG5cblx0ICAgICAgaWYgKGkgPj0gYnVmZmVyJCQxLmxlbmd0aCkgdGhyb3cgbmV3IEVycm9yKCdCYWQgQlNPTiBEb2N1bWVudDogaWxsZWdhbCBDU3RyaW5nJyk7IC8vIFJldHVybiB0aGUgQyBzdHJpbmdcblxuXHQgICAgICB2YXIgc291cmNlID0gYnVmZmVyJCQxLnRvU3RyaW5nKCd1dGY4JywgaW5kZXgsIGkpOyAvLyBDcmVhdGUgdGhlIHJlZ2V4cFxuXG5cdCAgICAgIGluZGV4ID0gaSArIDE7IC8vIEdldCB0aGUgc3RhcnQgc2VhcmNoIGluZGV4XG5cblx0ICAgICAgaSA9IGluZGV4OyAvLyBMb2NhdGUgdGhlIGVuZCBvZiB0aGUgYyBzdHJpbmdcblxuXHQgICAgICB3aGlsZSAoYnVmZmVyJCQxW2ldICE9PSAweDAwICYmIGkgPCBidWZmZXIkJDEubGVuZ3RoKSB7XG5cdCAgICAgICAgaSsrO1xuXHQgICAgICB9IC8vIElmIGFyZSBhdCB0aGUgZW5kIG9mIHRoZSBidWZmZXIgdGhlcmUgaXMgYSBwcm9ibGVtIHdpdGggdGhlIGRvY3VtZW50XG5cblxuXHQgICAgICBpZiAoaSA+PSBidWZmZXIkJDEubGVuZ3RoKSB0aHJvdyBuZXcgRXJyb3IoJ0JhZCBCU09OIERvY3VtZW50OiBpbGxlZ2FsIENTdHJpbmcnKTsgLy8gUmV0dXJuIHRoZSBDIHN0cmluZ1xuXG5cdCAgICAgIHZhciByZWdFeHBPcHRpb25zID0gYnVmZmVyJCQxLnRvU3RyaW5nKCd1dGY4JywgaW5kZXgsIGkpO1xuXHQgICAgICBpbmRleCA9IGkgKyAxOyAvLyBGb3IgZWFjaCBvcHRpb24gYWRkIHRoZSBjb3JyZXNwb25kaW5nIG9uZSBmb3IgamF2YXNjcmlwdFxuXG5cdCAgICAgIHZhciBvcHRpb25zQXJyYXkgPSBuZXcgQXJyYXkocmVnRXhwT3B0aW9ucy5sZW5ndGgpOyAvLyBQYXJzZSBvcHRpb25zXG5cblx0ICAgICAgZm9yIChpID0gMDsgaSA8IHJlZ0V4cE9wdGlvbnMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICBzd2l0Y2ggKHJlZ0V4cE9wdGlvbnNbaV0pIHtcblx0ICAgICAgICAgIGNhc2UgJ20nOlxuXHQgICAgICAgICAgICBvcHRpb25zQXJyYXlbaV0gPSAnbSc7XG5cdCAgICAgICAgICAgIGJyZWFrO1xuXG5cdCAgICAgICAgICBjYXNlICdzJzpcblx0ICAgICAgICAgICAgb3B0aW9uc0FycmF5W2ldID0gJ2cnO1xuXHQgICAgICAgICAgICBicmVhaztcblxuXHQgICAgICAgICAgY2FzZSAnaSc6XG5cdCAgICAgICAgICAgIG9wdGlvbnNBcnJheVtpXSA9ICdpJztcblx0ICAgICAgICAgICAgYnJlYWs7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cblx0ICAgICAgb2JqZWN0W25hbWVdID0gbmV3IFJlZ0V4cChzb3VyY2UsIG9wdGlvbnNBcnJheS5qb2luKCcnKSk7XG5cdCAgICB9IGVsc2UgaWYgKGVsZW1lbnRUeXBlID09PSBjb25zdGFudHMuQlNPTl9EQVRBX1JFR0VYUCAmJiBic29uUmVnRXhwID09PSB0cnVlKSB7XG5cdCAgICAgIC8vIEdldCB0aGUgc3RhcnQgc2VhcmNoIGluZGV4XG5cdCAgICAgIGkgPSBpbmRleDsgLy8gTG9jYXRlIHRoZSBlbmQgb2YgdGhlIGMgc3RyaW5nXG5cblx0ICAgICAgd2hpbGUgKGJ1ZmZlciQkMVtpXSAhPT0gMHgwMCAmJiBpIDwgYnVmZmVyJCQxLmxlbmd0aCkge1xuXHQgICAgICAgIGkrKztcblx0ICAgICAgfSAvLyBJZiBhcmUgYXQgdGhlIGVuZCBvZiB0aGUgYnVmZmVyIHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIHRoZSBkb2N1bWVudFxuXG5cblx0ICAgICAgaWYgKGkgPj0gYnVmZmVyJCQxLmxlbmd0aCkgdGhyb3cgbmV3IEVycm9yKCdCYWQgQlNPTiBEb2N1bWVudDogaWxsZWdhbCBDU3RyaW5nJyk7IC8vIFJldHVybiB0aGUgQyBzdHJpbmdcblxuXHQgICAgICB2YXIgX3NvdXJjZSA9IGJ1ZmZlciQkMS50b1N0cmluZygndXRmOCcsIGluZGV4LCBpKTtcblxuXHQgICAgICBpbmRleCA9IGkgKyAxOyAvLyBHZXQgdGhlIHN0YXJ0IHNlYXJjaCBpbmRleFxuXG5cdCAgICAgIGkgPSBpbmRleDsgLy8gTG9jYXRlIHRoZSBlbmQgb2YgdGhlIGMgc3RyaW5nXG5cblx0ICAgICAgd2hpbGUgKGJ1ZmZlciQkMVtpXSAhPT0gMHgwMCAmJiBpIDwgYnVmZmVyJCQxLmxlbmd0aCkge1xuXHQgICAgICAgIGkrKztcblx0ICAgICAgfSAvLyBJZiBhcmUgYXQgdGhlIGVuZCBvZiB0aGUgYnVmZmVyIHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIHRoZSBkb2N1bWVudFxuXG5cblx0ICAgICAgaWYgKGkgPj0gYnVmZmVyJCQxLmxlbmd0aCkgdGhyb3cgbmV3IEVycm9yKCdCYWQgQlNPTiBEb2N1bWVudDogaWxsZWdhbCBDU3RyaW5nJyk7IC8vIFJldHVybiB0aGUgQyBzdHJpbmdcblxuXHQgICAgICB2YXIgX3JlZ0V4cE9wdGlvbnMgPSBidWZmZXIkJDEudG9TdHJpbmcoJ3V0ZjgnLCBpbmRleCwgaSk7XG5cblx0ICAgICAgaW5kZXggPSBpICsgMTsgLy8gU2V0IHRoZSBvYmplY3RcblxuXHQgICAgICBvYmplY3RbbmFtZV0gPSBuZXcgcmVnZXhwKF9zb3VyY2UsIF9yZWdFeHBPcHRpb25zKTtcblx0ICAgIH0gZWxzZSBpZiAoZWxlbWVudFR5cGUgPT09IGNvbnN0YW50cy5CU09OX0RBVEFfU1lNQk9MKSB7XG5cdCAgICAgIHZhciBfc3RyaW5nU2l6ZSA9IGJ1ZmZlciQkMVtpbmRleCsrXSB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCA4IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDE2IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDI0O1xuXG5cdCAgICAgIGlmIChfc3RyaW5nU2l6ZSA8PSAwIHx8IF9zdHJpbmdTaXplID4gYnVmZmVyJCQxLmxlbmd0aCAtIGluZGV4IHx8IGJ1ZmZlciQkMVtpbmRleCArIF9zdHJpbmdTaXplIC0gMV0gIT09IDApIHRocm93IG5ldyBFcnJvcignYmFkIHN0cmluZyBsZW5ndGggaW4gYnNvbicpOyAvLyBzeW1ib2wgaXMgZGVwcmVjYXRlZCAtIHVwZ3JhZGUgdG8gc3RyaW5nLlxuXG5cdCAgICAgIG9iamVjdFtuYW1lXSA9IGJ1ZmZlciQkMS50b1N0cmluZygndXRmOCcsIGluZGV4LCBpbmRleCArIF9zdHJpbmdTaXplIC0gMSk7XG5cdCAgICAgIGluZGV4ID0gaW5kZXggKyBfc3RyaW5nU2l6ZTtcblx0ICAgIH0gZWxzZSBpZiAoZWxlbWVudFR5cGUgPT09IGNvbnN0YW50cy5CU09OX0RBVEFfVElNRVNUQU1QKSB7XG5cdCAgICAgIHZhciBfbG93Qml0czIgPSBidWZmZXIkJDFbaW5kZXgrK10gfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAyNDtcblxuXHQgICAgICB2YXIgX2hpZ2hCaXRzMiA9IGJ1ZmZlciQkMVtpbmRleCsrXSB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCA4IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDE2IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDI0O1xuXG5cdCAgICAgIG9iamVjdFtuYW1lXSA9IG5ldyB0aW1lc3RhbXAoX2xvd0JpdHMyLCBfaGlnaEJpdHMyKTtcblx0ICAgIH0gZWxzZSBpZiAoZWxlbWVudFR5cGUgPT09IGNvbnN0YW50cy5CU09OX0RBVEFfTUlOX0tFWSkge1xuXHQgICAgICBvYmplY3RbbmFtZV0gPSBuZXcgbWluX2tleSgpO1xuXHQgICAgfSBlbHNlIGlmIChlbGVtZW50VHlwZSA9PT0gY29uc3RhbnRzLkJTT05fREFUQV9NQVhfS0VZKSB7XG5cdCAgICAgIG9iamVjdFtuYW1lXSA9IG5ldyBtYXhfa2V5KCk7XG5cdCAgICB9IGVsc2UgaWYgKGVsZW1lbnRUeXBlID09PSBjb25zdGFudHMuQlNPTl9EQVRBX0NPREUpIHtcblx0ICAgICAgdmFyIF9zdHJpbmdTaXplMiA9IGJ1ZmZlciQkMVtpbmRleCsrXSB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCA4IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDE2IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDI0O1xuXG5cdCAgICAgIGlmIChfc3RyaW5nU2l6ZTIgPD0gMCB8fCBfc3RyaW5nU2l6ZTIgPiBidWZmZXIkJDEubGVuZ3RoIC0gaW5kZXggfHwgYnVmZmVyJCQxW2luZGV4ICsgX3N0cmluZ1NpemUyIC0gMV0gIT09IDApIHRocm93IG5ldyBFcnJvcignYmFkIHN0cmluZyBsZW5ndGggaW4gYnNvbicpO1xuXHQgICAgICB2YXIgZnVuY3Rpb25TdHJpbmcgPSBidWZmZXIkJDEudG9TdHJpbmcoJ3V0ZjgnLCBpbmRleCwgaW5kZXggKyBfc3RyaW5nU2l6ZTIgLSAxKTsgLy8gSWYgd2UgYXJlIGV2YWx1YXRpbmcgdGhlIGZ1bmN0aW9uc1xuXG5cdCAgICAgIGlmIChldmFsRnVuY3Rpb25zKSB7XG5cdCAgICAgICAgLy8gSWYgd2UgaGF2ZSBjYWNoZSBlbmFibGVkIGxldCdzIGxvb2sgZm9yIHRoZSBtZDUgb2YgdGhlIGZ1bmN0aW9uIGluIHRoZSBjYWNoZVxuXHQgICAgICAgIGlmIChjYWNoZUZ1bmN0aW9ucykge1xuXHQgICAgICAgICAgdmFyIGhhc2ggPSBjYWNoZUZ1bmN0aW9uc0NyYzMyID8gY3JjMzIoZnVuY3Rpb25TdHJpbmcpIDogZnVuY3Rpb25TdHJpbmc7IC8vIEdvdCB0byBkbyB0aGlzIHRvIGF2b2lkIFY4IGRlb3B0aW1pemluZyB0aGUgY2FsbCBkdWUgdG8gZmluZGluZyBldmFsXG5cblx0ICAgICAgICAgIG9iamVjdFtuYW1lXSA9IGlzb2xhdGVFdmFsV2l0aEhhc2goZnVuY3Rpb25DYWNoZSwgaGFzaCwgZnVuY3Rpb25TdHJpbmcsIG9iamVjdCk7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIG9iamVjdFtuYW1lXSA9IGlzb2xhdGVFdmFsKGZ1bmN0aW9uU3RyaW5nKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgb2JqZWN0W25hbWVdID0gbmV3IGNvZGUoZnVuY3Rpb25TdHJpbmcpO1xuXHQgICAgICB9IC8vIFVwZGF0ZSBwYXJzZSBpbmRleCBwb3NpdGlvblxuXG5cblx0ICAgICAgaW5kZXggPSBpbmRleCArIF9zdHJpbmdTaXplMjtcblx0ICAgIH0gZWxzZSBpZiAoZWxlbWVudFR5cGUgPT09IGNvbnN0YW50cy5CU09OX0RBVEFfQ09ERV9XX1NDT1BFKSB7XG5cdCAgICAgIHZhciB0b3RhbFNpemUgPSBidWZmZXIkJDFbaW5kZXgrK10gfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAyNDsgLy8gRWxlbWVudCBjYW5ub3QgYmUgc2hvcnRlciB0aGFuIHRvdGFsU2l6ZSArIHN0cmluZ1NpemUgKyBkb2N1bWVudFNpemUgKyB0ZXJtaW5hdG9yXG5cblx0ICAgICAgaWYgKHRvdGFsU2l6ZSA8IDQgKyA0ICsgNCArIDEpIHtcblx0ICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvZGVfd19zY29wZSB0b3RhbCBzaXplIHNob3J0ZXIgbWluaW11bSBleHBlY3RlZCBsZW5ndGgnKTtcblx0ICAgICAgfSAvLyBHZXQgdGhlIGNvZGUgc3RyaW5nIHNpemVcblxuXG5cdCAgICAgIHZhciBfc3RyaW5nU2l6ZTMgPSBidWZmZXIkJDFbaW5kZXgrK10gfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAyNDsgLy8gQ2hlY2sgaWYgd2UgaGF2ZSBhIHZhbGlkIHN0cmluZ1xuXG5cblx0ICAgICAgaWYgKF9zdHJpbmdTaXplMyA8PSAwIHx8IF9zdHJpbmdTaXplMyA+IGJ1ZmZlciQkMS5sZW5ndGggLSBpbmRleCB8fCBidWZmZXIkJDFbaW5kZXggKyBfc3RyaW5nU2l6ZTMgLSAxXSAhPT0gMCkgdGhyb3cgbmV3IEVycm9yKCdiYWQgc3RyaW5nIGxlbmd0aCBpbiBic29uJyk7IC8vIEphdmFzY3JpcHQgZnVuY3Rpb25cblxuXHQgICAgICB2YXIgX2Z1bmN0aW9uU3RyaW5nID0gYnVmZmVyJCQxLnRvU3RyaW5nKCd1dGY4JywgaW5kZXgsIGluZGV4ICsgX3N0cmluZ1NpemUzIC0gMSk7IC8vIFVwZGF0ZSBwYXJzZSBpbmRleCBwb3NpdGlvblxuXG5cblx0ICAgICAgaW5kZXggPSBpbmRleCArIF9zdHJpbmdTaXplMzsgLy8gUGFyc2UgdGhlIGVsZW1lbnRcblxuXHQgICAgICB2YXIgX2luZGV4MyA9IGluZGV4OyAvLyBEZWNvZGUgdGhlIHNpemUgb2YgdGhlIG9iamVjdCBkb2N1bWVudFxuXG5cdCAgICAgIHZhciBfb2JqZWN0U2l6ZTIgPSBidWZmZXIkJDFbaW5kZXhdIHwgYnVmZmVyJCQxW2luZGV4ICsgMV0gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCArIDJdIDw8IDE2IHwgYnVmZmVyJCQxW2luZGV4ICsgM10gPDwgMjQ7IC8vIERlY29kZSB0aGUgc2NvcGUgb2JqZWN0XG5cblxuXHQgICAgICB2YXIgc2NvcGVPYmplY3QgPSBkZXNlcmlhbGl6ZU9iamVjdChidWZmZXIkJDEsIF9pbmRleDMsIG9wdGlvbnMsIGZhbHNlKTsgLy8gQWRqdXN0IHRoZSBpbmRleFxuXG5cdCAgICAgIGluZGV4ID0gaW5kZXggKyBfb2JqZWN0U2l6ZTI7IC8vIENoZWNrIGlmIGZpZWxkIGxlbmd0aCBpcyB0byBzaG9ydFxuXG5cdCAgICAgIGlmICh0b3RhbFNpemUgPCA0ICsgNCArIF9vYmplY3RTaXplMiArIF9zdHJpbmdTaXplMykge1xuXHQgICAgICAgIHRocm93IG5ldyBFcnJvcignY29kZV93X3Njb3BlIHRvdGFsIHNpemUgaXMgdG8gc2hvcnQsIHRydW5jYXRpbmcgc2NvcGUnKTtcblx0ICAgICAgfSAvLyBDaGVjayBpZiB0b3RhbFNpemUgZmllbGQgaXMgdG8gbG9uZ1xuXG5cblx0ICAgICAgaWYgKHRvdGFsU2l6ZSA+IDQgKyA0ICsgX29iamVjdFNpemUyICsgX3N0cmluZ1NpemUzKSB7XG5cdCAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdjb2RlX3dfc2NvcGUgdG90YWwgc2l6ZSBpcyB0byBsb25nLCBjbGlwcyBvdXRlciBkb2N1bWVudCcpO1xuXHQgICAgICB9IC8vIElmIHdlIGFyZSBldmFsdWF0aW5nIHRoZSBmdW5jdGlvbnNcblxuXG5cdCAgICAgIGlmIChldmFsRnVuY3Rpb25zKSB7XG5cdCAgICAgICAgLy8gSWYgd2UgaGF2ZSBjYWNoZSBlbmFibGVkIGxldCdzIGxvb2sgZm9yIHRoZSBtZDUgb2YgdGhlIGZ1bmN0aW9uIGluIHRoZSBjYWNoZVxuXHQgICAgICAgIGlmIChjYWNoZUZ1bmN0aW9ucykge1xuXHQgICAgICAgICAgdmFyIF9oYXNoID0gY2FjaGVGdW5jdGlvbnNDcmMzMiA/IGNyYzMyKF9mdW5jdGlvblN0cmluZykgOiBfZnVuY3Rpb25TdHJpbmc7IC8vIEdvdCB0byBkbyB0aGlzIHRvIGF2b2lkIFY4IGRlb3B0aW1pemluZyB0aGUgY2FsbCBkdWUgdG8gZmluZGluZyBldmFsXG5cblxuXHQgICAgICAgICAgb2JqZWN0W25hbWVdID0gaXNvbGF0ZUV2YWxXaXRoSGFzaChmdW5jdGlvbkNhY2hlLCBfaGFzaCwgX2Z1bmN0aW9uU3RyaW5nLCBvYmplY3QpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICBvYmplY3RbbmFtZV0gPSBpc29sYXRlRXZhbChfZnVuY3Rpb25TdHJpbmcpO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIG9iamVjdFtuYW1lXS5zY29wZSA9IHNjb3BlT2JqZWN0O1xuXHQgICAgICB9IGVsc2Uge1xuXHQgICAgICAgIG9iamVjdFtuYW1lXSA9IG5ldyBjb2RlKF9mdW5jdGlvblN0cmluZywgc2NvcGVPYmplY3QpO1xuXHQgICAgICB9XG5cdCAgICB9IGVsc2UgaWYgKGVsZW1lbnRUeXBlID09PSBjb25zdGFudHMuQlNPTl9EQVRBX0RCUE9JTlRFUikge1xuXHQgICAgICAvLyBHZXQgdGhlIGNvZGUgc3RyaW5nIHNpemVcblx0ICAgICAgdmFyIF9zdHJpbmdTaXplNCA9IGJ1ZmZlciQkMVtpbmRleCsrXSB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCA4IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDE2IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDI0OyAvLyBDaGVjayBpZiB3ZSBoYXZlIGEgdmFsaWQgc3RyaW5nXG5cblxuXHQgICAgICBpZiAoX3N0cmluZ1NpemU0IDw9IDAgfHwgX3N0cmluZ1NpemU0ID4gYnVmZmVyJCQxLmxlbmd0aCAtIGluZGV4IHx8IGJ1ZmZlciQkMVtpbmRleCArIF9zdHJpbmdTaXplNCAtIDFdICE9PSAwKSB0aHJvdyBuZXcgRXJyb3IoJ2JhZCBzdHJpbmcgbGVuZ3RoIGluIGJzb24nKTsgLy8gTmFtZXNwYWNlXG5cblx0ICAgICAgaWYgKCF2YWxpZGF0ZVV0ZjgkMShidWZmZXIkJDEsIGluZGV4LCBpbmRleCArIF9zdHJpbmdTaXplNCAtIDEpKSB7XG5cdCAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIFVURi04IHN0cmluZyBpbiBCU09OIGRvY3VtZW50Jyk7XG5cdCAgICAgIH1cblxuXHQgICAgICB2YXIgbmFtZXNwYWNlID0gYnVmZmVyJCQxLnRvU3RyaW5nKCd1dGY4JywgaW5kZXgsIGluZGV4ICsgX3N0cmluZ1NpemU0IC0gMSk7IC8vIFVwZGF0ZSBwYXJzZSBpbmRleCBwb3NpdGlvblxuXG5cdCAgICAgIGluZGV4ID0gaW5kZXggKyBfc3RyaW5nU2l6ZTQ7IC8vIFJlYWQgdGhlIG9pZFxuXG5cdCAgICAgIHZhciBvaWRCdWZmZXIgPSBCdWZmZXIkNC5hbGxvYygxMik7XG5cdCAgICAgIGJ1ZmZlciQkMS5jb3B5KG9pZEJ1ZmZlciwgMCwgaW5kZXgsIGluZGV4ICsgMTIpO1xuXG5cdCAgICAgIHZhciBfb2lkID0gbmV3IG9iamVjdGlkKG9pZEJ1ZmZlcik7IC8vIFVwZGF0ZSB0aGUgaW5kZXhcblxuXG5cdCAgICAgIGluZGV4ID0gaW5kZXggKyAxMjsgLy8gVXBncmFkZSB0byBEQlJlZiB0eXBlXG5cblx0ICAgICAgb2JqZWN0W25hbWVdID0gbmV3IGRiX3JlZihuYW1lc3BhY2UsIF9vaWQpO1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgdGhyb3cgbmV3IEVycm9yKCdEZXRlY3RlZCB1bmtub3duIEJTT04gdHlwZSAnICsgZWxlbWVudFR5cGUudG9TdHJpbmcoMTYpICsgJyBmb3IgZmllbGRuYW1lIFwiJyArIG5hbWUgKyAnXCIsIGFyZSB5b3UgdXNpbmcgdGhlIGxhdGVzdCBCU09OIHBhcnNlcj8nKTtcblx0ICAgIH1cblx0ICB9IC8vIENoZWNrIGlmIHRoZSBkZXNlcmlhbGl6YXRpb24gd2FzIGFnYWluc3QgYSB2YWxpZCBhcnJheS9vYmplY3RcblxuXG5cdCAgaWYgKHNpemUgIT09IGluZGV4IC0gc3RhcnRJbmRleCkge1xuXHQgICAgaWYgKGlzQXJyYXkpIHRocm93IG5ldyBFcnJvcignY29ycnVwdCBhcnJheSBic29uJyk7XG5cdCAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvcnJ1cHQgb2JqZWN0IGJzb24nKTtcblx0ICB9IC8vIGNoZWNrIGlmIG9iamVjdCdzICQga2V5cyBhcmUgdGhvc2Ugb2YgYSBEQlJlZlxuXG5cblx0ICB2YXIgZG9sbGFyS2V5cyA9IE9iamVjdC5rZXlzKG9iamVjdCkuZmlsdGVyKGZ1bmN0aW9uIChrKSB7XG5cdCAgICByZXR1cm4gay5zdGFydHNXaXRoKCckJyk7XG5cdCAgfSk7XG5cdCAgdmFyIHZhbGlkID0gdHJ1ZTtcblx0ICBkb2xsYXJLZXlzLmZvckVhY2goZnVuY3Rpb24gKGspIHtcblx0ICAgIGlmIChbJyRyZWYnLCAnJGlkJywgJyRkYiddLmluZGV4T2YoaykgPT09IC0xKSB2YWxpZCA9IGZhbHNlO1xuXHQgIH0pOyAvLyBpZiBhICRrZXkgbm90IGluIFwiJHJlZlwiLCBcIiRpZFwiLCBcIiRkYlwiLCBkb24ndCBtYWtlIGEgREJSZWZcblxuXHQgIGlmICghdmFsaWQpIHJldHVybiBvYmplY3Q7XG5cblx0ICBpZiAob2JqZWN0WyckaWQnXSAhPSBudWxsICYmIG9iamVjdFsnJHJlZiddICE9IG51bGwpIHtcblx0ICAgIHZhciBjb3B5ID0gT2JqZWN0LmFzc2lnbih7fSwgb2JqZWN0KTtcblx0ICAgIGRlbGV0ZSBjb3B5LiRyZWY7XG5cdCAgICBkZWxldGUgY29weS4kaWQ7XG5cdCAgICBkZWxldGUgY29weS4kZGI7XG5cdCAgICByZXR1cm4gbmV3IGRiX3JlZihvYmplY3QuJHJlZiwgb2JqZWN0LiRpZCwgb2JqZWN0LiRkYiB8fCBudWxsLCBjb3B5KTtcblx0ICB9XG5cblx0ICByZXR1cm4gb2JqZWN0O1xuXHR9XG5cdC8qKlxuXHQgKiBFbnN1cmUgZXZhbCBpcyBpc29sYXRlZC5cblx0ICpcblx0ICogQGlnbm9yZVxuXHQgKiBAYXBpIHByaXZhdGVcblx0ICovXG5cblxuXHRmdW5jdGlvbiBpc29sYXRlRXZhbFdpdGhIYXNoKGZ1bmN0aW9uQ2FjaGUsIGhhc2gsIGZ1bmN0aW9uU3RyaW5nLCBvYmplY3QpIHtcblx0ICAvLyBDb250YWlucyB0aGUgdmFsdWUgd2UgYXJlIGdvaW5nIHRvIHNldFxuXHQgIHZhciB2YWx1ZSA9IG51bGw7IC8vIENoZWNrIGZvciBjYWNoZSBoaXQsIGV2YWwgaWYgbWlzc2luZyBhbmQgcmV0dXJuIGNhY2hlZCBmdW5jdGlvblxuXG5cdCAgaWYgKGZ1bmN0aW9uQ2FjaGVbaGFzaF0gPT0gbnVsbCkge1xuXHQgICAgZXZhbCgndmFsdWUgPSAnICsgZnVuY3Rpb25TdHJpbmcpO1xuXHQgICAgZnVuY3Rpb25DYWNoZVtoYXNoXSA9IHZhbHVlO1xuXHQgIH0gLy8gU2V0IHRoZSBvYmplY3RcblxuXG5cdCAgcmV0dXJuIGZ1bmN0aW9uQ2FjaGVbaGFzaF0uYmluZChvYmplY3QpO1xuXHR9XG5cdC8qKlxuXHQgKiBFbnN1cmUgZXZhbCBpcyBpc29sYXRlZC5cblx0ICpcblx0ICogQGlnbm9yZVxuXHQgKiBAYXBpIHByaXZhdGVcblx0ICovXG5cblxuXHRmdW5jdGlvbiBpc29sYXRlRXZhbChmdW5jdGlvblN0cmluZykge1xuXHQgIC8vIENvbnRhaW5zIHRoZSB2YWx1ZSB3ZSBhcmUgZ29pbmcgdG8gc2V0XG5cdCAgdmFyIHZhbHVlID0gbnVsbDsgLy8gRXZhbCB0aGUgZnVuY3Rpb25cblxuXHQgIGV2YWwoJ3ZhbHVlID0gJyArIGZ1bmN0aW9uU3RyaW5nKTtcblx0ICByZXR1cm4gdmFsdWU7XG5cdH1cblxuXHR2YXIgZGVzZXJpYWxpemVyID0gZGVzZXJpYWxpemUkMTtcblxuXHQvLyBBbGwgcmlnaHRzIHJlc2VydmVkLlxuXHQvL1xuXHQvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcblx0Ly8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG5cdC8vXG5cdC8vICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcblx0Ly8gICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cblx0Ly9cblx0Ly8gICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuXHQvLyAgICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXG5cdC8vICAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuXHQvL1xuXHQvLyAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEZhaXIgT2FrcyBMYWJzLCBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuXHQvLyAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcblx0Ly8gICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG5cdC8vXG5cdC8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG5cdC8vIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcblx0Ly8gSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0Vcblx0Ly8gQVJFIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRVxuXHQvLyBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG5cdC8vIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG5cdC8vIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuXHQvLyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuXHQvLyBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuXHQvLyBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuXHQvLyBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cblx0Ly9cblx0Ly9cblx0Ly8gTW9kaWZpY2F0aW9ucyB0byB3cml0ZUlFRUU3NTQgdG8gc3VwcG9ydCBuZWdhdGl2ZSB6ZXJvZXMgbWFkZSBieSBCcmlhbiBXaGl0ZVxuXG5cdGZ1bmN0aW9uIHJlYWRJRUVFNzU0KGJ1ZmZlciQkMSwgb2Zmc2V0LCBlbmRpYW4sIG1MZW4sIG5CeXRlcykge1xuXHQgIHZhciBlLFxuXHQgICAgICBtLFxuXHQgICAgICBiQkUgPSBlbmRpYW4gPT09ICdiaWcnLFxuXHQgICAgICBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxLFxuXHQgICAgICBlTWF4ID0gKDEgPDwgZUxlbikgLSAxLFxuXHQgICAgICBlQmlhcyA9IGVNYXggPj4gMSxcblx0ICAgICAgbkJpdHMgPSAtNyxcblx0ICAgICAgaSA9IGJCRSA/IDAgOiBuQnl0ZXMgLSAxLFxuXHQgICAgICBkID0gYkJFID8gMSA6IC0xLFxuXHQgICAgICBzID0gYnVmZmVyJCQxW29mZnNldCArIGldO1xuXHQgIGkgKz0gZDtcblx0ICBlID0gcyAmICgxIDw8IC1uQml0cykgLSAxO1xuXHQgIHMgPj49IC1uQml0cztcblx0ICBuQml0cyArPSBlTGVuO1xuXG5cdCAgZm9yICg7IG5CaXRzID4gMDsgZSA9IGUgKiAyNTYgKyBidWZmZXIkJDFbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge1xuXHQgIH1cblxuXHQgIG0gPSBlICYgKDEgPDwgLW5CaXRzKSAtIDE7XG5cdCAgZSA+Pj0gLW5CaXRzO1xuXHQgIG5CaXRzICs9IG1MZW47XG5cblx0ICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gbSAqIDI1NiArIGJ1ZmZlciQkMVtvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7XG5cdCAgfVxuXG5cdCAgaWYgKGUgPT09IDApIHtcblx0ICAgIGUgPSAxIC0gZUJpYXM7XG5cdCAgfSBlbHNlIGlmIChlID09PSBlTWF4KSB7XG5cdCAgICByZXR1cm4gbSA/IE5hTiA6IChzID8gLTEgOiAxKSAqIEluZmluaXR5O1xuXHQgIH0gZWxzZSB7XG5cdCAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pO1xuXHQgICAgZSA9IGUgLSBlQmlhcztcblx0ICB9XG5cblx0ICByZXR1cm4gKHMgPyAtMSA6IDEpICogbSAqIE1hdGgucG93KDIsIGUgLSBtTGVuKTtcblx0fVxuXG5cdGZ1bmN0aW9uIHdyaXRlSUVFRTc1NChidWZmZXIkJDEsIHZhbHVlLCBvZmZzZXQsIGVuZGlhbiwgbUxlbiwgbkJ5dGVzKSB7XG5cdCAgdmFyIGUsXG5cdCAgICAgIG0sXG5cdCAgICAgIGMsXG5cdCAgICAgIGJCRSA9IGVuZGlhbiA9PT0gJ2JpZycsXG5cdCAgICAgIGVMZW4gPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDEsXG5cdCAgICAgIGVNYXggPSAoMSA8PCBlTGVuKSAtIDEsXG5cdCAgICAgIGVCaWFzID0gZU1heCA+PiAxLFxuXHQgICAgICBydCA9IG1MZW4gPT09IDIzID8gTWF0aC5wb3coMiwgLTI0KSAtIE1hdGgucG93KDIsIC03NykgOiAwLFxuXHQgICAgICBpID0gYkJFID8gbkJ5dGVzIC0gMSA6IDAsXG5cdCAgICAgIGQgPSBiQkUgPyAtMSA6IDEsXG5cdCAgICAgIHMgPSB2YWx1ZSA8IDAgfHwgdmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCA/IDEgOiAwO1xuXHQgIHZhbHVlID0gTWF0aC5hYnModmFsdWUpO1xuXG5cdCAgaWYgKGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA9PT0gSW5maW5pdHkpIHtcblx0ICAgIG0gPSBpc05hTih2YWx1ZSkgPyAxIDogMDtcblx0ICAgIGUgPSBlTWF4O1xuXHQgIH0gZWxzZSB7XG5cdCAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMik7XG5cblx0ICAgIGlmICh2YWx1ZSAqIChjID0gTWF0aC5wb3coMiwgLWUpKSA8IDEpIHtcblx0ICAgICAgZS0tO1xuXHQgICAgICBjICo9IDI7XG5cdCAgICB9XG5cblx0ICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuXHQgICAgICB2YWx1ZSArPSBydCAvIGM7XG5cdCAgICB9IGVsc2Uge1xuXHQgICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcyk7XG5cdCAgICB9XG5cblx0ICAgIGlmICh2YWx1ZSAqIGMgPj0gMikge1xuXHQgICAgICBlKys7XG5cdCAgICAgIGMgLz0gMjtcblx0ICAgIH1cblxuXHQgICAgaWYgKGUgKyBlQmlhcyA+PSBlTWF4KSB7XG5cdCAgICAgIG0gPSAwO1xuXHQgICAgICBlID0gZU1heDtcblx0ICAgIH0gZWxzZSBpZiAoZSArIGVCaWFzID49IDEpIHtcblx0ICAgICAgbSA9ICh2YWx1ZSAqIGMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pO1xuXHQgICAgICBlID0gZSArIGVCaWFzO1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pO1xuXHQgICAgICBlID0gMDtcblx0ICAgIH1cblx0ICB9XG5cblx0ICBpZiAoaXNOYU4odmFsdWUpKSBtID0gMDtcblxuXHQgIHdoaWxlIChtTGVuID49IDgpIHtcblx0ICAgIGJ1ZmZlciQkMVtvZmZzZXQgKyBpXSA9IG0gJiAweGZmO1xuXHQgICAgaSArPSBkO1xuXHQgICAgbSAvPSAyNTY7XG5cdCAgICBtTGVuIC09IDg7XG5cdCAgfVxuXG5cdCAgZSA9IGUgPDwgbUxlbiB8IG07XG5cdCAgaWYgKGlzTmFOKHZhbHVlKSkgZSArPSA4O1xuXHQgIGVMZW4gKz0gbUxlbjtcblxuXHQgIHdoaWxlIChlTGVuID4gMCkge1xuXHQgICAgYnVmZmVyJCQxW29mZnNldCArIGldID0gZSAmIDB4ZmY7XG5cdCAgICBpICs9IGQ7XG5cdCAgICBlIC89IDI1Njtcblx0ICAgIGVMZW4gLT0gODtcblx0ICB9XG5cblx0ICBidWZmZXIkJDFbb2Zmc2V0ICsgaSAtIGRdIHw9IHMgKiAxMjg7XG5cdH1cblxuXHR2YXIgZmxvYXRfcGFyc2VyID0ge1xuXHQgIHJlYWRJRUVFNzU0OiByZWFkSUVFRTc1NCxcblx0ICB3cml0ZUlFRUU3NTQ6IHdyaXRlSUVFRTc1NFxuXHR9O1xuXG5cdGZ1bmN0aW9uIF90eXBlb2YkMyhvYmopIHsgaWYgKHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSBcInN5bWJvbFwiKSB7IF90eXBlb2YkMyA9IGZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9OyB9IGVsc2UgeyBfdHlwZW9mJDMgPSBmdW5jdGlvbiBfdHlwZW9mKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajsgfTsgfSByZXR1cm4gX3R5cGVvZiQzKG9iaik7IH1cblxuXHR2YXIgQnVmZmVyJDUgPSBidWZmZXIuQnVmZmVyO1xuXHR2YXIgd3JpdGVJRUVFNzU0JDEgPSBmbG9hdF9wYXJzZXIud3JpdGVJRUVFNzU0O1xuXHR2YXIgbm9ybWFsaXplZEZ1bmN0aW9uU3RyaW5nJDEgPSB1dGlscy5ub3JtYWxpemVkRnVuY3Rpb25TdHJpbmc7XG5cdHZhciByZWdleHAkMSA9IC9cXHgwMC87IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tY29udHJvbC1yZWdleFxuXG5cdHZhciBpZ25vcmVLZXlzID0gbmV3IFNldChbJyRkYicsICckcmVmJywgJyRpZCcsICckY2x1c3RlclRpbWUnXSk7IC8vIFRvIGVuc3VyZSB0aGF0IDAuNCBvZiBub2RlIHdvcmtzIGNvcnJlY3RseVxuXG5cdHZhciBpc0RhdGUkMSA9IGZ1bmN0aW9uIGlzRGF0ZShkKSB7XG5cdCAgcmV0dXJuIF90eXBlb2YkMyhkKSA9PT0gJ29iamVjdCcgJiYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGQpID09PSAnW29iamVjdCBEYXRlXSc7XG5cdH07XG5cblx0dmFyIGlzUmVnRXhwJDEgPSBmdW5jdGlvbiBpc1JlZ0V4cChkKSB7XG5cdCAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChkKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG5cdH07XG5cblx0ZnVuY3Rpb24gc2VyaWFsaXplU3RyaW5nKGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIGlzQXJyYXkpIHtcblx0ICAvLyBFbmNvZGUgU3RyaW5nIHR5cGVcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBjb25zdGFudHMuQlNPTl9EQVRBX1NUUklORzsgLy8gTnVtYmVyIG9mIHdyaXR0ZW4gYnl0ZXNcblxuXHQgIHZhciBudW1iZXJPZldyaXR0ZW5CeXRlcyA9ICFpc0FycmF5ID8gYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICd1dGY4JykgOiBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ2FzY2lpJyk7IC8vIEVuY29kZSB0aGUgbmFtZVxuXG5cdCAgaW5kZXggPSBpbmRleCArIG51bWJlck9mV3JpdHRlbkJ5dGVzICsgMTtcblx0ICBidWZmZXIkJDFbaW5kZXggLSAxXSA9IDA7IC8vIFdyaXRlIHRoZSBzdHJpbmdcblxuXHQgIHZhciBzaXplID0gYnVmZmVyJCQxLndyaXRlKHZhbHVlLCBpbmRleCArIDQsICd1dGY4Jyk7IC8vIFdyaXRlIHRoZSBzaXplIG9mIHRoZSBzdHJpbmcgdG8gYnVmZmVyXG5cblx0ICBidWZmZXIkJDFbaW5kZXggKyAzXSA9IHNpemUgKyAxID4+IDI0ICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXggKyAyXSA9IHNpemUgKyAxID4+IDE2ICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXggKyAxXSA9IHNpemUgKyAxID4+IDggJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleF0gPSBzaXplICsgMSAmIDB4ZmY7IC8vIFVwZGF0ZSBpbmRleFxuXG5cdCAgaW5kZXggPSBpbmRleCArIDQgKyBzaXplOyAvLyBXcml0ZSB6ZXJvXG5cblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSAwO1xuXHQgIHJldHVybiBpbmRleDtcblx0fVxuXG5cdGZ1bmN0aW9uIHNlcmlhbGl6ZU51bWJlcihidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCBpc0FycmF5KSB7XG5cdCAgLy8gV2UgaGF2ZSBhbiBpbnRlZ2VyIHZhbHVlXG5cdCAgaWYgKE1hdGguZmxvb3IodmFsdWUpID09PSB2YWx1ZSAmJiB2YWx1ZSA+PSBjb25zdGFudHMuSlNfSU5UX01JTiAmJiB2YWx1ZSA8PSBjb25zdGFudHMuSlNfSU5UX01BWCkge1xuXHQgICAgLy8gSWYgdGhlIHZhbHVlIGZpdHMgaW4gMzIgYml0cyBlbmNvZGUgYXMgaW50LCBpZiBpdCBmaXRzIGluIGEgZG91YmxlXG5cdCAgICAvLyBlbmNvZGUgaXQgYXMgYSBkb3VibGUsIG90aGVyd2lzZSBsb25nXG5cdCAgICBpZiAodmFsdWUgPj0gY29uc3RhbnRzLkJTT05fSU5UMzJfTUlOICYmIHZhbHVlIDw9IGNvbnN0YW50cy5CU09OX0lOVDMyX01BWCkge1xuXHQgICAgICAvLyBTZXQgaW50IHR5cGUgMzIgYml0cyBvciBsZXNzXG5cdCAgICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGNvbnN0YW50cy5CU09OX0RBVEFfSU5UOyAvLyBOdW1iZXIgb2Ygd3JpdHRlbiBieXRlc1xuXG5cdCAgICAgIHZhciBudW1iZXJPZldyaXR0ZW5CeXRlcyA9ICFpc0FycmF5ID8gYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICd1dGY4JykgOiBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ2FzY2lpJyk7IC8vIEVuY29kZSB0aGUgbmFtZVxuXG5cdCAgICAgIGluZGV4ID0gaW5kZXggKyBudW1iZXJPZldyaXR0ZW5CeXRlcztcblx0ICAgICAgYnVmZmVyJCQxW2luZGV4KytdID0gMDsgLy8gV3JpdGUgdGhlIGludCB2YWx1ZVxuXG5cdCAgICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHZhbHVlICYgMHhmZjtcblx0ICAgICAgYnVmZmVyJCQxW2luZGV4KytdID0gdmFsdWUgPj4gOCAmIDB4ZmY7XG5cdCAgICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHZhbHVlID4+IDE2ICYgMHhmZjtcblx0ICAgICAgYnVmZmVyJCQxW2luZGV4KytdID0gdmFsdWUgPj4gMjQgJiAweGZmO1xuXHQgICAgfSBlbHNlIGlmICh2YWx1ZSA+PSBjb25zdGFudHMuSlNfSU5UX01JTiAmJiB2YWx1ZSA8PSBjb25zdGFudHMuSlNfSU5UX01BWCkge1xuXHQgICAgICAvLyBFbmNvZGUgYXMgZG91YmxlXG5cdCAgICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGNvbnN0YW50cy5CU09OX0RBVEFfTlVNQkVSOyAvLyBOdW1iZXIgb2Ygd3JpdHRlbiBieXRlc1xuXG5cdCAgICAgIHZhciBfbnVtYmVyT2ZXcml0dGVuQnl0ZXMgPSAhaXNBcnJheSA/IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAndXRmOCcpIDogYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICdhc2NpaScpOyAvLyBFbmNvZGUgdGhlIG5hbWVcblxuXG5cdCAgICAgIGluZGV4ID0gaW5kZXggKyBfbnVtYmVyT2ZXcml0dGVuQnl0ZXM7XG5cdCAgICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDA7IC8vIFdyaXRlIGZsb2F0XG5cblx0ICAgICAgd3JpdGVJRUVFNzU0JDEoYnVmZmVyJCQxLCB2YWx1ZSwgaW5kZXgsICdsaXR0bGUnLCA1MiwgOCk7IC8vIEFqdXN0IGluZGV4XG5cblx0ICAgICAgaW5kZXggPSBpbmRleCArIDg7XG5cdCAgICB9IGVsc2Uge1xuXHQgICAgICAvLyBTZXQgbG9uZyB0eXBlXG5cdCAgICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGNvbnN0YW50cy5CU09OX0RBVEFfTE9ORzsgLy8gTnVtYmVyIG9mIHdyaXR0ZW4gYnl0ZXNcblxuXHQgICAgICB2YXIgX251bWJlck9mV3JpdHRlbkJ5dGVzMiA9ICFpc0FycmF5ID8gYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICd1dGY4JykgOiBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ2FzY2lpJyk7IC8vIEVuY29kZSB0aGUgbmFtZVxuXG5cblx0ICAgICAgaW5kZXggPSBpbmRleCArIF9udW1iZXJPZldyaXR0ZW5CeXRlczI7XG5cdCAgICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDA7XG5cdCAgICAgIHZhciBsb25nVmFsID0gbG9uZ18xLmZyb21OdW1iZXIodmFsdWUpO1xuXHQgICAgICB2YXIgbG93Qml0cyA9IGxvbmdWYWwuZ2V0TG93Qml0cygpO1xuXHQgICAgICB2YXIgaGlnaEJpdHMgPSBsb25nVmFsLmdldEhpZ2hCaXRzKCk7IC8vIEVuY29kZSBsb3cgYml0c1xuXG5cdCAgICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGxvd0JpdHMgJiAweGZmO1xuXHQgICAgICBidWZmZXIkJDFbaW5kZXgrK10gPSBsb3dCaXRzID4+IDggJiAweGZmO1xuXHQgICAgICBidWZmZXIkJDFbaW5kZXgrK10gPSBsb3dCaXRzID4+IDE2ICYgMHhmZjtcblx0ICAgICAgYnVmZmVyJCQxW2luZGV4KytdID0gbG93Qml0cyA+PiAyNCAmIDB4ZmY7IC8vIEVuY29kZSBoaWdoIGJpdHNcblxuXHQgICAgICBidWZmZXIkJDFbaW5kZXgrK10gPSBoaWdoQml0cyAmIDB4ZmY7XG5cdCAgICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGhpZ2hCaXRzID4+IDggJiAweGZmO1xuXHQgICAgICBidWZmZXIkJDFbaW5kZXgrK10gPSBoaWdoQml0cyA+PiAxNiAmIDB4ZmY7XG5cdCAgICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGhpZ2hCaXRzID4+IDI0ICYgMHhmZjtcblx0ICAgIH1cblx0ICB9IGVsc2Uge1xuXHQgICAgLy8gRW5jb2RlIGFzIGRvdWJsZVxuXHQgICAgYnVmZmVyJCQxW2luZGV4KytdID0gY29uc3RhbnRzLkJTT05fREFUQV9OVU1CRVI7IC8vIE51bWJlciBvZiB3cml0dGVuIGJ5dGVzXG5cblx0ICAgIHZhciBfbnVtYmVyT2ZXcml0dGVuQnl0ZXMzID0gIWlzQXJyYXkgPyBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ3V0ZjgnKSA6IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAnYXNjaWknKTsgLy8gRW5jb2RlIHRoZSBuYW1lXG5cblxuXHQgICAgaW5kZXggPSBpbmRleCArIF9udW1iZXJPZldyaXR0ZW5CeXRlczM7XG5cdCAgICBidWZmZXIkJDFbaW5kZXgrK10gPSAwOyAvLyBXcml0ZSBmbG9hdFxuXG5cdCAgICB3cml0ZUlFRUU3NTQkMShidWZmZXIkJDEsIHZhbHVlLCBpbmRleCwgJ2xpdHRsZScsIDUyLCA4KTsgLy8gQWp1c3QgaW5kZXhcblxuXHQgICAgaW5kZXggPSBpbmRleCArIDg7XG5cdCAgfVxuXG5cdCAgcmV0dXJuIGluZGV4O1xuXHR9XG5cblx0ZnVuY3Rpb24gc2VyaWFsaXplTnVsbChidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCBpc0FycmF5KSB7XG5cdCAgLy8gU2V0IGxvbmcgdHlwZVxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGNvbnN0YW50cy5CU09OX0RBVEFfTlVMTDsgLy8gTnVtYmVyIG9mIHdyaXR0ZW4gYnl0ZXNcblxuXHQgIHZhciBudW1iZXJPZldyaXR0ZW5CeXRlcyA9ICFpc0FycmF5ID8gYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICd1dGY4JykgOiBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ2FzY2lpJyk7IC8vIEVuY29kZSB0aGUgbmFtZVxuXG5cdCAgaW5kZXggPSBpbmRleCArIG51bWJlck9mV3JpdHRlbkJ5dGVzO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDA7XG5cdCAgcmV0dXJuIGluZGV4O1xuXHR9XG5cblx0ZnVuY3Rpb24gc2VyaWFsaXplQm9vbGVhbihidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCBpc0FycmF5KSB7XG5cdCAgLy8gV3JpdGUgdGhlIHR5cGVcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBjb25zdGFudHMuQlNPTl9EQVRBX0JPT0xFQU47IC8vIE51bWJlciBvZiB3cml0dGVuIGJ5dGVzXG5cblx0ICB2YXIgbnVtYmVyT2ZXcml0dGVuQnl0ZXMgPSAhaXNBcnJheSA/IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAndXRmOCcpIDogYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICdhc2NpaScpOyAvLyBFbmNvZGUgdGhlIG5hbWVcblxuXHQgIGluZGV4ID0gaW5kZXggKyBudW1iZXJPZldyaXR0ZW5CeXRlcztcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSAwOyAvLyBFbmNvZGUgdGhlIGJvb2xlYW4gdmFsdWVcblxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHZhbHVlID8gMSA6IDA7XG5cdCAgcmV0dXJuIGluZGV4O1xuXHR9XG5cblx0ZnVuY3Rpb24gc2VyaWFsaXplRGF0ZShidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCBpc0FycmF5KSB7XG5cdCAgLy8gV3JpdGUgdGhlIHR5cGVcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBjb25zdGFudHMuQlNPTl9EQVRBX0RBVEU7IC8vIE51bWJlciBvZiB3cml0dGVuIGJ5dGVzXG5cblx0ICB2YXIgbnVtYmVyT2ZXcml0dGVuQnl0ZXMgPSAhaXNBcnJheSA/IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAndXRmOCcpIDogYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICdhc2NpaScpOyAvLyBFbmNvZGUgdGhlIG5hbWVcblxuXHQgIGluZGV4ID0gaW5kZXggKyBudW1iZXJPZldyaXR0ZW5CeXRlcztcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSAwOyAvLyBXcml0ZSB0aGUgZGF0ZVxuXG5cdCAgdmFyIGRhdGVJbk1pbGlzID0gbG9uZ18xLmZyb21OdW1iZXIodmFsdWUuZ2V0VGltZSgpKTtcblx0ICB2YXIgbG93Qml0cyA9IGRhdGVJbk1pbGlzLmdldExvd0JpdHMoKTtcblx0ICB2YXIgaGlnaEJpdHMgPSBkYXRlSW5NaWxpcy5nZXRIaWdoQml0cygpOyAvLyBFbmNvZGUgbG93IGJpdHNcblxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGxvd0JpdHMgJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGxvd0JpdHMgPj4gOCAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gbG93Qml0cyA+PiAxNiAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gbG93Qml0cyA+PiAyNCAmIDB4ZmY7IC8vIEVuY29kZSBoaWdoIGJpdHNcblxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGhpZ2hCaXRzICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBoaWdoQml0cyA+PiA4ICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBoaWdoQml0cyA+PiAxNiAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gaGlnaEJpdHMgPj4gMjQgJiAweGZmO1xuXHQgIHJldHVybiBpbmRleDtcblx0fVxuXG5cdGZ1bmN0aW9uIHNlcmlhbGl6ZVJlZ0V4cChidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCBpc0FycmF5KSB7XG5cdCAgLy8gV3JpdGUgdGhlIHR5cGVcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBjb25zdGFudHMuQlNPTl9EQVRBX1JFR0VYUDsgLy8gTnVtYmVyIG9mIHdyaXR0ZW4gYnl0ZXNcblxuXHQgIHZhciBudW1iZXJPZldyaXR0ZW5CeXRlcyA9ICFpc0FycmF5ID8gYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICd1dGY4JykgOiBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ2FzY2lpJyk7IC8vIEVuY29kZSB0aGUgbmFtZVxuXG5cdCAgaW5kZXggPSBpbmRleCArIG51bWJlck9mV3JpdHRlbkJ5dGVzO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDA7XG5cblx0ICBpZiAodmFsdWUuc291cmNlICYmIHZhbHVlLnNvdXJjZS5tYXRjaChyZWdleHAkMSkgIT0gbnVsbCkge1xuXHQgICAgdGhyb3cgRXJyb3IoJ3ZhbHVlICcgKyB2YWx1ZS5zb3VyY2UgKyAnIG11c3Qgbm90IGNvbnRhaW4gbnVsbCBieXRlcycpO1xuXHQgIH0gLy8gQWRqdXN0IHRoZSBpbmRleFxuXG5cblx0ICBpbmRleCA9IGluZGV4ICsgYnVmZmVyJCQxLndyaXRlKHZhbHVlLnNvdXJjZSwgaW5kZXgsICd1dGY4Jyk7IC8vIFdyaXRlIHplcm9cblxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDB4MDA7IC8vIFdyaXRlIHRoZSBwYXJhbWV0ZXJzXG5cblx0ICBpZiAodmFsdWUuaWdub3JlQ2FzZSkgYnVmZmVyJCQxW2luZGV4KytdID0gMHg2OTsgLy8gaVxuXG5cdCAgaWYgKHZhbHVlLmdsb2JhbCkgYnVmZmVyJCQxW2luZGV4KytdID0gMHg3MzsgLy8gc1xuXG5cdCAgaWYgKHZhbHVlLm11bHRpbGluZSkgYnVmZmVyJCQxW2luZGV4KytdID0gMHg2ZDsgLy8gbVxuXHQgIC8vIEFkZCBlbmRpbmcgemVyb1xuXG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gMHgwMDtcblx0ICByZXR1cm4gaW5kZXg7XG5cdH1cblxuXHRmdW5jdGlvbiBzZXJpYWxpemVCU09OUmVnRXhwKGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIGlzQXJyYXkpIHtcblx0ICAvLyBXcml0ZSB0aGUgdHlwZVxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGNvbnN0YW50cy5CU09OX0RBVEFfUkVHRVhQOyAvLyBOdW1iZXIgb2Ygd3JpdHRlbiBieXRlc1xuXG5cdCAgdmFyIG51bWJlck9mV3JpdHRlbkJ5dGVzID0gIWlzQXJyYXkgPyBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ3V0ZjgnKSA6IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAnYXNjaWknKTsgLy8gRW5jb2RlIHRoZSBuYW1lXG5cblx0ICBpbmRleCA9IGluZGV4ICsgbnVtYmVyT2ZXcml0dGVuQnl0ZXM7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gMDsgLy8gQ2hlY2sgdGhlIHBhdHRlcm4gZm9yIDAgYnl0ZXNcblxuXHQgIGlmICh2YWx1ZS5wYXR0ZXJuLm1hdGNoKHJlZ2V4cCQxKSAhPSBudWxsKSB7XG5cdCAgICAvLyBUaGUgQlNPTiBzcGVjIGRvZXNuJ3QgYWxsb3cga2V5cyB3aXRoIG51bGwgYnl0ZXMgYmVjYXVzZSBrZXlzIGFyZVxuXHQgICAgLy8gbnVsbC10ZXJtaW5hdGVkLlxuXHQgICAgdGhyb3cgRXJyb3IoJ3BhdHRlcm4gJyArIHZhbHVlLnBhdHRlcm4gKyAnIG11c3Qgbm90IGNvbnRhaW4gbnVsbCBieXRlcycpO1xuXHQgIH0gLy8gQWRqdXN0IHRoZSBpbmRleFxuXG5cblx0ICBpbmRleCA9IGluZGV4ICsgYnVmZmVyJCQxLndyaXRlKHZhbHVlLnBhdHRlcm4sIGluZGV4LCAndXRmOCcpOyAvLyBXcml0ZSB6ZXJvXG5cblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSAweDAwOyAvLyBXcml0ZSB0aGUgb3B0aW9uc1xuXG5cdCAgaW5kZXggPSBpbmRleCArIGJ1ZmZlciQkMS53cml0ZSh2YWx1ZS5vcHRpb25zLnNwbGl0KCcnKS5zb3J0KCkuam9pbignJyksIGluZGV4LCAndXRmOCcpOyAvLyBBZGQgZW5kaW5nIHplcm9cblxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDB4MDA7XG5cdCAgcmV0dXJuIGluZGV4O1xuXHR9XG5cblx0ZnVuY3Rpb24gc2VyaWFsaXplTWluTWF4KGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIGlzQXJyYXkpIHtcblx0ICAvLyBXcml0ZSB0aGUgdHlwZSBvZiBlaXRoZXIgbWluIG9yIG1heCBrZXlcblx0ICBpZiAodmFsdWUgPT09IG51bGwpIHtcblx0ICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGNvbnN0YW50cy5CU09OX0RBVEFfTlVMTDtcblx0ICB9IGVsc2UgaWYgKHZhbHVlLl9ic29udHlwZSA9PT0gJ01pbktleScpIHtcblx0ICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGNvbnN0YW50cy5CU09OX0RBVEFfTUlOX0tFWTtcblx0ICB9IGVsc2Uge1xuXHQgICAgYnVmZmVyJCQxW2luZGV4KytdID0gY29uc3RhbnRzLkJTT05fREFUQV9NQVhfS0VZO1xuXHQgIH0gLy8gTnVtYmVyIG9mIHdyaXR0ZW4gYnl0ZXNcblxuXG5cdCAgdmFyIG51bWJlck9mV3JpdHRlbkJ5dGVzID0gIWlzQXJyYXkgPyBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ3V0ZjgnKSA6IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAnYXNjaWknKTsgLy8gRW5jb2RlIHRoZSBuYW1lXG5cblx0ICBpbmRleCA9IGluZGV4ICsgbnVtYmVyT2ZXcml0dGVuQnl0ZXM7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gMDtcblx0ICByZXR1cm4gaW5kZXg7XG5cdH1cblxuXHRmdW5jdGlvbiBzZXJpYWxpemVPYmplY3RJZChidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCBpc0FycmF5KSB7XG5cdCAgLy8gV3JpdGUgdGhlIHR5cGVcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBjb25zdGFudHMuQlNPTl9EQVRBX09JRDsgLy8gTnVtYmVyIG9mIHdyaXR0ZW4gYnl0ZXNcblxuXHQgIHZhciBudW1iZXJPZldyaXR0ZW5CeXRlcyA9ICFpc0FycmF5ID8gYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICd1dGY4JykgOiBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ2FzY2lpJyk7IC8vIEVuY29kZSB0aGUgbmFtZVxuXG5cdCAgaW5kZXggPSBpbmRleCArIG51bWJlck9mV3JpdHRlbkJ5dGVzO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDA7IC8vIFdyaXRlIHRoZSBvYmplY3RJZCBpbnRvIHRoZSBzaGFyZWQgYnVmZmVyXG5cblx0ICBpZiAodHlwZW9mIHZhbHVlLmlkID09PSAnc3RyaW5nJykge1xuXHQgICAgYnVmZmVyJCQxLndyaXRlKHZhbHVlLmlkLCBpbmRleCwgJ2JpbmFyeScpO1xuXHQgIH0gZWxzZSBpZiAodmFsdWUuaWQgJiYgdmFsdWUuaWQuY29weSkge1xuXHQgICAgdmFsdWUuaWQuY29weShidWZmZXIkJDEsIGluZGV4LCAwLCAxMik7XG5cdCAgfSBlbHNlIHtcblx0ICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ29iamVjdCBbJyArIEpTT04uc3RyaW5naWZ5KHZhbHVlKSArICddIGlzIG5vdCBhIHZhbGlkIE9iamVjdElkJyk7XG5cdCAgfSAvLyBBanVzdCBpbmRleFxuXG5cblx0ICByZXR1cm4gaW5kZXggKyAxMjtcblx0fVxuXG5cdGZ1bmN0aW9uIHNlcmlhbGl6ZUJ1ZmZlcihidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCBpc0FycmF5KSB7XG5cdCAgLy8gV3JpdGUgdGhlIHR5cGVcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBjb25zdGFudHMuQlNPTl9EQVRBX0JJTkFSWTsgLy8gTnVtYmVyIG9mIHdyaXR0ZW4gYnl0ZXNcblxuXHQgIHZhciBudW1iZXJPZldyaXR0ZW5CeXRlcyA9ICFpc0FycmF5ID8gYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICd1dGY4JykgOiBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ2FzY2lpJyk7IC8vIEVuY29kZSB0aGUgbmFtZVxuXG5cdCAgaW5kZXggPSBpbmRleCArIG51bWJlck9mV3JpdHRlbkJ5dGVzO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDA7IC8vIEdldCBzaXplIG9mIHRoZSBidWZmZXIgKGN1cnJlbnQgd3JpdGUgcG9pbnQpXG5cblx0ICB2YXIgc2l6ZSA9IHZhbHVlLmxlbmd0aDsgLy8gV3JpdGUgdGhlIHNpemUgb2YgdGhlIHN0cmluZyB0byBidWZmZXJcblxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHNpemUgJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHNpemUgPj4gOCAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gc2l6ZSA+PiAxNiAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gc2l6ZSA+PiAyNCAmIDB4ZmY7IC8vIFdyaXRlIHRoZSBkZWZhdWx0IHN1YnR5cGVcblxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGNvbnN0YW50cy5CU09OX0JJTkFSWV9TVUJUWVBFX0RFRkFVTFQ7IC8vIENvcHkgdGhlIGNvbnRlbnQgZm9ybSB0aGUgYmluYXJ5IGZpZWxkIHRvIHRoZSBidWZmZXJcblxuXHQgIHZhbHVlLmNvcHkoYnVmZmVyJCQxLCBpbmRleCwgMCwgc2l6ZSk7IC8vIEFkanVzdCB0aGUgaW5kZXhcblxuXHQgIGluZGV4ID0gaW5kZXggKyBzaXplO1xuXHQgIHJldHVybiBpbmRleDtcblx0fVxuXG5cdGZ1bmN0aW9uIHNlcmlhbGl6ZU9iamVjdChidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCBjaGVja0tleXMsIGRlcHRoLCBzZXJpYWxpemVGdW5jdGlvbnMsIGlnbm9yZVVuZGVmaW5lZCwgaXNBcnJheSwgcGF0aCkge1xuXHQgIGZvciAodmFyIGkgPSAwOyBpIDwgcGF0aC5sZW5ndGg7IGkrKykge1xuXHQgICAgaWYgKHBhdGhbaV0gPT09IHZhbHVlKSB0aHJvdyBuZXcgRXJyb3IoJ2N5Y2xpYyBkZXBlbmRlbmN5IGRldGVjdGVkJyk7XG5cdCAgfSAvLyBQdXNoIHZhbHVlIHRvIHN0YWNrXG5cblxuXHQgIHBhdGgucHVzaCh2YWx1ZSk7IC8vIFdyaXRlIHRoZSB0eXBlXG5cblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBBcnJheS5pc0FycmF5KHZhbHVlKSA/IGNvbnN0YW50cy5CU09OX0RBVEFfQVJSQVkgOiBjb25zdGFudHMuQlNPTl9EQVRBX09CSkVDVDsgLy8gTnVtYmVyIG9mIHdyaXR0ZW4gYnl0ZXNcblxuXHQgIHZhciBudW1iZXJPZldyaXR0ZW5CeXRlcyA9ICFpc0FycmF5ID8gYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICd1dGY4JykgOiBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ2FzY2lpJyk7IC8vIEVuY29kZSB0aGUgbmFtZVxuXG5cdCAgaW5kZXggPSBpbmRleCArIG51bWJlck9mV3JpdHRlbkJ5dGVzO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDA7XG5cdCAgdmFyIGVuZEluZGV4ID0gc2VyaWFsaXplSW50byhidWZmZXIkJDEsIHZhbHVlLCBjaGVja0tleXMsIGluZGV4LCBkZXB0aCArIDEsIHNlcmlhbGl6ZUZ1bmN0aW9ucywgaWdub3JlVW5kZWZpbmVkLCBwYXRoKTsgLy8gUG9wIHN0YWNrXG5cblx0ICBwYXRoLnBvcCgpO1xuXHQgIHJldHVybiBlbmRJbmRleDtcblx0fVxuXG5cdGZ1bmN0aW9uIHNlcmlhbGl6ZURlY2ltYWwxMjgoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgaXNBcnJheSkge1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGNvbnN0YW50cy5CU09OX0RBVEFfREVDSU1BTDEyODsgLy8gTnVtYmVyIG9mIHdyaXR0ZW4gYnl0ZXNcblxuXHQgIHZhciBudW1iZXJPZldyaXR0ZW5CeXRlcyA9ICFpc0FycmF5ID8gYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICd1dGY4JykgOiBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ2FzY2lpJyk7IC8vIEVuY29kZSB0aGUgbmFtZVxuXG5cdCAgaW5kZXggPSBpbmRleCArIG51bWJlck9mV3JpdHRlbkJ5dGVzO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDA7IC8vIFdyaXRlIHRoZSBkYXRhIGZyb20gdGhlIHZhbHVlXG5cblx0ICB2YWx1ZS5ieXRlcy5jb3B5KGJ1ZmZlciQkMSwgaW5kZXgsIDAsIDE2KTtcblx0ICByZXR1cm4gaW5kZXggKyAxNjtcblx0fVxuXG5cdGZ1bmN0aW9uIHNlcmlhbGl6ZUxvbmcoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgaXNBcnJheSkge1xuXHQgIC8vIFdyaXRlIHRoZSB0eXBlXG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gdmFsdWUuX2Jzb250eXBlID09PSAnTG9uZycgPyBjb25zdGFudHMuQlNPTl9EQVRBX0xPTkcgOiBjb25zdGFudHMuQlNPTl9EQVRBX1RJTUVTVEFNUDsgLy8gTnVtYmVyIG9mIHdyaXR0ZW4gYnl0ZXNcblxuXHQgIHZhciBudW1iZXJPZldyaXR0ZW5CeXRlcyA9ICFpc0FycmF5ID8gYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICd1dGY4JykgOiBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ2FzY2lpJyk7IC8vIEVuY29kZSB0aGUgbmFtZVxuXG5cdCAgaW5kZXggPSBpbmRleCArIG51bWJlck9mV3JpdHRlbkJ5dGVzO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDA7IC8vIFdyaXRlIHRoZSBkYXRlXG5cblx0ICB2YXIgbG93Qml0cyA9IHZhbHVlLmdldExvd0JpdHMoKTtcblx0ICB2YXIgaGlnaEJpdHMgPSB2YWx1ZS5nZXRIaWdoQml0cygpOyAvLyBFbmNvZGUgbG93IGJpdHNcblxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGxvd0JpdHMgJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGxvd0JpdHMgPj4gOCAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gbG93Qml0cyA+PiAxNiAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gbG93Qml0cyA+PiAyNCAmIDB4ZmY7IC8vIEVuY29kZSBoaWdoIGJpdHNcblxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGhpZ2hCaXRzICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBoaWdoQml0cyA+PiA4ICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBoaWdoQml0cyA+PiAxNiAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gaGlnaEJpdHMgPj4gMjQgJiAweGZmO1xuXHQgIHJldHVybiBpbmRleDtcblx0fVxuXG5cdGZ1bmN0aW9uIHNlcmlhbGl6ZUludDMyKGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIGlzQXJyYXkpIHtcblx0ICAvLyBTZXQgaW50IHR5cGUgMzIgYml0cyBvciBsZXNzXG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gY29uc3RhbnRzLkJTT05fREFUQV9JTlQ7IC8vIE51bWJlciBvZiB3cml0dGVuIGJ5dGVzXG5cblx0ICB2YXIgbnVtYmVyT2ZXcml0dGVuQnl0ZXMgPSAhaXNBcnJheSA/IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAndXRmOCcpIDogYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICdhc2NpaScpOyAvLyBFbmNvZGUgdGhlIG5hbWVcblxuXHQgIGluZGV4ID0gaW5kZXggKyBudW1iZXJPZldyaXR0ZW5CeXRlcztcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSAwOyAvLyBXcml0ZSB0aGUgaW50IHZhbHVlXG5cblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSB2YWx1ZSAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gdmFsdWUgPj4gOCAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gdmFsdWUgPj4gMTYgJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHZhbHVlID4+IDI0ICYgMHhmZjtcblx0ICByZXR1cm4gaW5kZXg7XG5cdH1cblxuXHRmdW5jdGlvbiBzZXJpYWxpemVEb3VibGUoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgaXNBcnJheSkge1xuXHQgIC8vIEVuY29kZSBhcyBkb3VibGVcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBjb25zdGFudHMuQlNPTl9EQVRBX05VTUJFUjsgLy8gTnVtYmVyIG9mIHdyaXR0ZW4gYnl0ZXNcblxuXHQgIHZhciBudW1iZXJPZldyaXR0ZW5CeXRlcyA9ICFpc0FycmF5ID8gYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICd1dGY4JykgOiBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ2FzY2lpJyk7IC8vIEVuY29kZSB0aGUgbmFtZVxuXG5cdCAgaW5kZXggPSBpbmRleCArIG51bWJlck9mV3JpdHRlbkJ5dGVzO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDA7IC8vIFdyaXRlIGZsb2F0XG5cblx0ICB3cml0ZUlFRUU3NTQkMShidWZmZXIkJDEsIHZhbHVlLnZhbHVlLCBpbmRleCwgJ2xpdHRsZScsIDUyLCA4KTsgLy8gQWRqdXN0IGluZGV4XG5cblx0ICBpbmRleCA9IGluZGV4ICsgODtcblx0ICByZXR1cm4gaW5kZXg7XG5cdH1cblxuXHRmdW5jdGlvbiBzZXJpYWxpemVGdW5jdGlvbihidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCBjaGVja0tleXMsIGRlcHRoLCBpc0FycmF5KSB7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gY29uc3RhbnRzLkJTT05fREFUQV9DT0RFOyAvLyBOdW1iZXIgb2Ygd3JpdHRlbiBieXRlc1xuXG5cdCAgdmFyIG51bWJlck9mV3JpdHRlbkJ5dGVzID0gIWlzQXJyYXkgPyBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ3V0ZjgnKSA6IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAnYXNjaWknKTsgLy8gRW5jb2RlIHRoZSBuYW1lXG5cblx0ICBpbmRleCA9IGluZGV4ICsgbnVtYmVyT2ZXcml0dGVuQnl0ZXM7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gMDsgLy8gRnVuY3Rpb24gc3RyaW5nXG5cblx0ICB2YXIgZnVuY3Rpb25TdHJpbmcgPSBub3JtYWxpemVkRnVuY3Rpb25TdHJpbmckMSh2YWx1ZSk7IC8vIFdyaXRlIHRoZSBzdHJpbmdcblxuXHQgIHZhciBzaXplID0gYnVmZmVyJCQxLndyaXRlKGZ1bmN0aW9uU3RyaW5nLCBpbmRleCArIDQsICd1dGY4JykgKyAxOyAvLyBXcml0ZSB0aGUgc2l6ZSBvZiB0aGUgc3RyaW5nIHRvIGJ1ZmZlclxuXG5cdCAgYnVmZmVyJCQxW2luZGV4XSA9IHNpemUgJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCArIDFdID0gc2l6ZSA+PiA4ICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXggKyAyXSA9IHNpemUgPj4gMTYgJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCArIDNdID0gc2l6ZSA+PiAyNCAmIDB4ZmY7IC8vIFVwZGF0ZSBpbmRleFxuXG5cdCAgaW5kZXggPSBpbmRleCArIDQgKyBzaXplIC0gMTsgLy8gV3JpdGUgemVyb1xuXG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gMDtcblx0ICByZXR1cm4gaW5kZXg7XG5cdH1cblxuXHRmdW5jdGlvbiBzZXJpYWxpemVDb2RlKGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIGNoZWNrS2V5cywgZGVwdGgsIHNlcmlhbGl6ZUZ1bmN0aW9ucywgaWdub3JlVW5kZWZpbmVkLCBpc0FycmF5KSB7XG5cdCAgaWYgKHZhbHVlLnNjb3BlICYmIF90eXBlb2YkMyh2YWx1ZS5zY29wZSkgPT09ICdvYmplY3QnKSB7XG5cdCAgICAvLyBXcml0ZSB0aGUgdHlwZVxuXHQgICAgYnVmZmVyJCQxW2luZGV4KytdID0gY29uc3RhbnRzLkJTT05fREFUQV9DT0RFX1dfU0NPUEU7IC8vIE51bWJlciBvZiB3cml0dGVuIGJ5dGVzXG5cblx0ICAgIHZhciBudW1iZXJPZldyaXR0ZW5CeXRlcyA9ICFpc0FycmF5ID8gYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICd1dGY4JykgOiBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ2FzY2lpJyk7IC8vIEVuY29kZSB0aGUgbmFtZVxuXG5cdCAgICBpbmRleCA9IGluZGV4ICsgbnVtYmVyT2ZXcml0dGVuQnl0ZXM7XG5cdCAgICBidWZmZXIkJDFbaW5kZXgrK10gPSAwOyAvLyBTdGFydGluZyBpbmRleFxuXG5cdCAgICB2YXIgc3RhcnRJbmRleCA9IGluZGV4OyAvLyBTZXJpYWxpemUgdGhlIGZ1bmN0aW9uXG5cdCAgICAvLyBHZXQgdGhlIGZ1bmN0aW9uIHN0cmluZ1xuXG5cdCAgICB2YXIgZnVuY3Rpb25TdHJpbmcgPSB0eXBlb2YgdmFsdWUuY29kZSA9PT0gJ3N0cmluZycgPyB2YWx1ZS5jb2RlIDogdmFsdWUuY29kZS50b1N0cmluZygpOyAvLyBJbmRleCBhZGp1c3RtZW50XG5cblx0ICAgIGluZGV4ID0gaW5kZXggKyA0OyAvLyBXcml0ZSBzdHJpbmcgaW50byBidWZmZXJcblxuXHQgICAgdmFyIGNvZGVTaXplID0gYnVmZmVyJCQxLndyaXRlKGZ1bmN0aW9uU3RyaW5nLCBpbmRleCArIDQsICd1dGY4JykgKyAxOyAvLyBXcml0ZSB0aGUgc2l6ZSBvZiB0aGUgc3RyaW5nIHRvIGJ1ZmZlclxuXG5cdCAgICBidWZmZXIkJDFbaW5kZXhdID0gY29kZVNpemUgJiAweGZmO1xuXHQgICAgYnVmZmVyJCQxW2luZGV4ICsgMV0gPSBjb2RlU2l6ZSA+PiA4ICYgMHhmZjtcblx0ICAgIGJ1ZmZlciQkMVtpbmRleCArIDJdID0gY29kZVNpemUgPj4gMTYgJiAweGZmO1xuXHQgICAgYnVmZmVyJCQxW2luZGV4ICsgM10gPSBjb2RlU2l6ZSA+PiAyNCAmIDB4ZmY7IC8vIFdyaXRlIGVuZCAwXG5cblx0ICAgIGJ1ZmZlciQkMVtpbmRleCArIDQgKyBjb2RlU2l6ZSAtIDFdID0gMDsgLy8gV3JpdGUgdGhlXG5cblx0ICAgIGluZGV4ID0gaW5kZXggKyBjb2RlU2l6ZSArIDQ7IC8vXG5cdCAgICAvLyBTZXJpYWxpemUgdGhlIHNjb3BlIHZhbHVlXG5cblx0ICAgIHZhciBlbmRJbmRleCA9IHNlcmlhbGl6ZUludG8oYnVmZmVyJCQxLCB2YWx1ZS5zY29wZSwgY2hlY2tLZXlzLCBpbmRleCwgZGVwdGggKyAxLCBzZXJpYWxpemVGdW5jdGlvbnMsIGlnbm9yZVVuZGVmaW5lZCk7XG5cdCAgICBpbmRleCA9IGVuZEluZGV4IC0gMTsgLy8gV3JpdCB0aGUgdG90YWxcblxuXHQgICAgdmFyIHRvdGFsU2l6ZSA9IGVuZEluZGV4IC0gc3RhcnRJbmRleDsgLy8gV3JpdGUgdGhlIHRvdGFsIHNpemUgb2YgdGhlIG9iamVjdFxuXG5cdCAgICBidWZmZXIkJDFbc3RhcnRJbmRleCsrXSA9IHRvdGFsU2l6ZSAmIDB4ZmY7XG5cdCAgICBidWZmZXIkJDFbc3RhcnRJbmRleCsrXSA9IHRvdGFsU2l6ZSA+PiA4ICYgMHhmZjtcblx0ICAgIGJ1ZmZlciQkMVtzdGFydEluZGV4KytdID0gdG90YWxTaXplID4+IDE2ICYgMHhmZjtcblx0ICAgIGJ1ZmZlciQkMVtzdGFydEluZGV4KytdID0gdG90YWxTaXplID4+IDI0ICYgMHhmZjsgLy8gV3JpdGUgdHJhaWxpbmcgemVyb1xuXG5cdCAgICBidWZmZXIkJDFbaW5kZXgrK10gPSAwO1xuXHQgIH0gZWxzZSB7XG5cdCAgICBidWZmZXIkJDFbaW5kZXgrK10gPSBjb25zdGFudHMuQlNPTl9EQVRBX0NPREU7IC8vIE51bWJlciBvZiB3cml0dGVuIGJ5dGVzXG5cblx0ICAgIHZhciBfbnVtYmVyT2ZXcml0dGVuQnl0ZXM0ID0gIWlzQXJyYXkgPyBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ3V0ZjgnKSA6IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAnYXNjaWknKTsgLy8gRW5jb2RlIHRoZSBuYW1lXG5cblxuXHQgICAgaW5kZXggPSBpbmRleCArIF9udW1iZXJPZldyaXR0ZW5CeXRlczQ7XG5cdCAgICBidWZmZXIkJDFbaW5kZXgrK10gPSAwOyAvLyBGdW5jdGlvbiBzdHJpbmdcblxuXHQgICAgdmFyIF9mdW5jdGlvblN0cmluZyA9IHZhbHVlLmNvZGUudG9TdHJpbmcoKTsgLy8gV3JpdGUgdGhlIHN0cmluZ1xuXG5cblx0ICAgIHZhciBzaXplID0gYnVmZmVyJCQxLndyaXRlKF9mdW5jdGlvblN0cmluZywgaW5kZXggKyA0LCAndXRmOCcpICsgMTsgLy8gV3JpdGUgdGhlIHNpemUgb2YgdGhlIHN0cmluZyB0byBidWZmZXJcblxuXHQgICAgYnVmZmVyJCQxW2luZGV4XSA9IHNpemUgJiAweGZmO1xuXHQgICAgYnVmZmVyJCQxW2luZGV4ICsgMV0gPSBzaXplID4+IDggJiAweGZmO1xuXHQgICAgYnVmZmVyJCQxW2luZGV4ICsgMl0gPSBzaXplID4+IDE2ICYgMHhmZjtcblx0ICAgIGJ1ZmZlciQkMVtpbmRleCArIDNdID0gc2l6ZSA+PiAyNCAmIDB4ZmY7IC8vIFVwZGF0ZSBpbmRleFxuXG5cdCAgICBpbmRleCA9IGluZGV4ICsgNCArIHNpemUgLSAxOyAvLyBXcml0ZSB6ZXJvXG5cblx0ICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDA7XG5cdCAgfVxuXG5cdCAgcmV0dXJuIGluZGV4O1xuXHR9XG5cblx0ZnVuY3Rpb24gc2VyaWFsaXplQmluYXJ5KGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIGlzQXJyYXkpIHtcblx0ICAvLyBXcml0ZSB0aGUgdHlwZVxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGNvbnN0YW50cy5CU09OX0RBVEFfQklOQVJZOyAvLyBOdW1iZXIgb2Ygd3JpdHRlbiBieXRlc1xuXG5cdCAgdmFyIG51bWJlck9mV3JpdHRlbkJ5dGVzID0gIWlzQXJyYXkgPyBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ3V0ZjgnKSA6IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAnYXNjaWknKTsgLy8gRW5jb2RlIHRoZSBuYW1lXG5cblx0ICBpbmRleCA9IGluZGV4ICsgbnVtYmVyT2ZXcml0dGVuQnl0ZXM7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gMDsgLy8gRXh0cmFjdCB0aGUgYnVmZmVyXG5cblx0ICB2YXIgZGF0YSA9IHZhbHVlLnZhbHVlKHRydWUpOyAvLyBDYWxjdWxhdGUgc2l6ZVxuXG5cdCAgdmFyIHNpemUgPSB2YWx1ZS5wb3NpdGlvbjsgLy8gQWRkIHRoZSBkZXByZWNhdGVkIDAyIHR5cGUgNCBieXRlcyBvZiBzaXplIHRvIHRvdGFsXG5cblx0ICBpZiAodmFsdWUuc3ViX3R5cGUgPT09IGJpbmFyeS5TVUJUWVBFX0JZVEVfQVJSQVkpIHNpemUgPSBzaXplICsgNDsgLy8gV3JpdGUgdGhlIHNpemUgb2YgdGhlIHN0cmluZyB0byBidWZmZXJcblxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHNpemUgJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHNpemUgPj4gOCAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gc2l6ZSA+PiAxNiAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gc2l6ZSA+PiAyNCAmIDB4ZmY7IC8vIFdyaXRlIHRoZSBzdWJ0eXBlIHRvIHRoZSBidWZmZXJcblxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHZhbHVlLnN1Yl90eXBlOyAvLyBJZiB3ZSBoYXZlIGJpbmFyeSB0eXBlIDIgdGhlIDQgZmlyc3QgYnl0ZXMgYXJlIHRoZSBzaXplXG5cblx0ICBpZiAodmFsdWUuc3ViX3R5cGUgPT09IGJpbmFyeS5TVUJUWVBFX0JZVEVfQVJSQVkpIHtcblx0ICAgIHNpemUgPSBzaXplIC0gNDtcblx0ICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHNpemUgJiAweGZmO1xuXHQgICAgYnVmZmVyJCQxW2luZGV4KytdID0gc2l6ZSA+PiA4ICYgMHhmZjtcblx0ICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHNpemUgPj4gMTYgJiAweGZmO1xuXHQgICAgYnVmZmVyJCQxW2luZGV4KytdID0gc2l6ZSA+PiAyNCAmIDB4ZmY7XG5cdCAgfSAvLyBXcml0ZSB0aGUgZGF0YSB0byB0aGUgb2JqZWN0XG5cblxuXHQgIGRhdGEuY29weShidWZmZXIkJDEsIGluZGV4LCAwLCB2YWx1ZS5wb3NpdGlvbik7IC8vIEFkanVzdCB0aGUgaW5kZXhcblxuXHQgIGluZGV4ID0gaW5kZXggKyB2YWx1ZS5wb3NpdGlvbjtcblx0ICByZXR1cm4gaW5kZXg7XG5cdH1cblxuXHRmdW5jdGlvbiBzZXJpYWxpemVTeW1ib2woYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgaXNBcnJheSkge1xuXHQgIC8vIFdyaXRlIHRoZSB0eXBlXG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gY29uc3RhbnRzLkJTT05fREFUQV9TWU1CT0w7IC8vIE51bWJlciBvZiB3cml0dGVuIGJ5dGVzXG5cblx0ICB2YXIgbnVtYmVyT2ZXcml0dGVuQnl0ZXMgPSAhaXNBcnJheSA/IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAndXRmOCcpIDogYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICdhc2NpaScpOyAvLyBFbmNvZGUgdGhlIG5hbWVcblxuXHQgIGluZGV4ID0gaW5kZXggKyBudW1iZXJPZldyaXR0ZW5CeXRlcztcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSAwOyAvLyBXcml0ZSB0aGUgc3RyaW5nXG5cblx0ICB2YXIgc2l6ZSA9IGJ1ZmZlciQkMS53cml0ZSh2YWx1ZS52YWx1ZSwgaW5kZXggKyA0LCAndXRmOCcpICsgMTsgLy8gV3JpdGUgdGhlIHNpemUgb2YgdGhlIHN0cmluZyB0byBidWZmZXJcblxuXHQgIGJ1ZmZlciQkMVtpbmRleF0gPSBzaXplICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXggKyAxXSA9IHNpemUgPj4gOCAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4ICsgMl0gPSBzaXplID4+IDE2ICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXggKyAzXSA9IHNpemUgPj4gMjQgJiAweGZmOyAvLyBVcGRhdGUgaW5kZXhcblxuXHQgIGluZGV4ID0gaW5kZXggKyA0ICsgc2l6ZSAtIDE7IC8vIFdyaXRlIHplcm9cblxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDB4MDA7XG5cdCAgcmV0dXJuIGluZGV4O1xuXHR9XG5cblx0ZnVuY3Rpb24gc2VyaWFsaXplREJSZWYoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgZGVwdGgsIHNlcmlhbGl6ZUZ1bmN0aW9ucywgaXNBcnJheSkge1xuXHQgIC8vIFdyaXRlIHRoZSB0eXBlXG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gY29uc3RhbnRzLkJTT05fREFUQV9PQkpFQ1Q7IC8vIE51bWJlciBvZiB3cml0dGVuIGJ5dGVzXG5cblx0ICB2YXIgbnVtYmVyT2ZXcml0dGVuQnl0ZXMgPSAhaXNBcnJheSA/IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAndXRmOCcpIDogYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICdhc2NpaScpOyAvLyBFbmNvZGUgdGhlIG5hbWVcblxuXHQgIGluZGV4ID0gaW5kZXggKyBudW1iZXJPZldyaXR0ZW5CeXRlcztcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSAwO1xuXHQgIHZhciBzdGFydEluZGV4ID0gaW5kZXg7XG5cdCAgdmFyIGVuZEluZGV4O1xuXHQgIHZhciBvdXRwdXQgPSB7XG5cdCAgICAkcmVmOiB2YWx1ZS5jb2xsZWN0aW9uIHx8IHZhbHVlLm5hbWVzcGFjZSxcblx0ICAgIC8vIFwibmFtZXNwYWNlXCIgd2FzIHdoYXQgbGlicmFyeSAxLnggY2FsbGVkIFwiY29sbGVjdGlvblwiXG5cdCAgICAkaWQ6IHZhbHVlLm9pZFxuXHQgIH07XG5cdCAgaWYgKHZhbHVlLmRiICE9IG51bGwpIG91dHB1dC4kZGIgPSB2YWx1ZS5kYjtcblx0ICBvdXRwdXQgPSBPYmplY3QuYXNzaWduKG91dHB1dCwgdmFsdWUuZmllbGRzKTtcblx0ICBlbmRJbmRleCA9IHNlcmlhbGl6ZUludG8oYnVmZmVyJCQxLCBvdXRwdXQsIGZhbHNlLCBpbmRleCwgZGVwdGggKyAxLCBzZXJpYWxpemVGdW5jdGlvbnMpOyAvLyBDYWxjdWxhdGUgb2JqZWN0IHNpemVcblxuXHQgIHZhciBzaXplID0gZW5kSW5kZXggLSBzdGFydEluZGV4OyAvLyBXcml0ZSB0aGUgc2l6ZVxuXG5cdCAgYnVmZmVyJCQxW3N0YXJ0SW5kZXgrK10gPSBzaXplICYgMHhmZjtcblx0ICBidWZmZXIkJDFbc3RhcnRJbmRleCsrXSA9IHNpemUgPj4gOCAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW3N0YXJ0SW5kZXgrK10gPSBzaXplID4+IDE2ICYgMHhmZjtcblx0ICBidWZmZXIkJDFbc3RhcnRJbmRleCsrXSA9IHNpemUgPj4gMjQgJiAweGZmOyAvLyBTZXQgaW5kZXhcblxuXHQgIHJldHVybiBlbmRJbmRleDtcblx0fVxuXG5cdGZ1bmN0aW9uIHNlcmlhbGl6ZUludG8oYnVmZmVyJCQxLCBvYmplY3QsIGNoZWNrS2V5cywgc3RhcnRpbmdJbmRleCwgZGVwdGgsIHNlcmlhbGl6ZUZ1bmN0aW9ucywgaWdub3JlVW5kZWZpbmVkLCBwYXRoKSB7XG5cdCAgc3RhcnRpbmdJbmRleCA9IHN0YXJ0aW5nSW5kZXggfHwgMDtcblx0ICBwYXRoID0gcGF0aCB8fCBbXTsgLy8gUHVzaCB0aGUgb2JqZWN0IHRvIHRoZSBwYXRoXG5cblx0ICBwYXRoLnB1c2gob2JqZWN0KTsgLy8gU3RhcnQgcGxhY2UgdG8gc2VyaWFsaXplIGludG9cblxuXHQgIHZhciBpbmRleCA9IHN0YXJ0aW5nSW5kZXggKyA0OyAvLyBTcGVjaWFsIGNhc2UgaXNBcnJheVxuXG5cdCAgaWYgKEFycmF5LmlzQXJyYXkob2JqZWN0KSkge1xuXHQgICAgLy8gR2V0IG9iamVjdCBrZXlzXG5cdCAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5sZW5ndGg7IGkrKykge1xuXHQgICAgICB2YXIga2V5ID0gJycgKyBpO1xuXHQgICAgICB2YXIgdmFsdWUgPSBvYmplY3RbaV07IC8vIElzIHRoZXJlIGFuIG92ZXJyaWRlIHZhbHVlXG5cblx0ICAgICAgaWYgKHZhbHVlICYmIHZhbHVlLnRvQlNPTikge1xuXHQgICAgICAgIGlmICh0eXBlb2YgdmFsdWUudG9CU09OICE9PSAnZnVuY3Rpb24nKSB0aHJvdyBuZXcgVHlwZUVycm9yKCd0b0JTT04gaXMgbm90IGEgZnVuY3Rpb24nKTtcblx0ICAgICAgICB2YWx1ZSA9IHZhbHVlLnRvQlNPTigpO1xuXHQgICAgICB9XG5cblx0ICAgICAgdmFyIHR5cGUgPSBfdHlwZW9mJDModmFsdWUpO1xuXG5cdCAgICAgIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplU3RyaW5nKGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIHRydWUpO1xuXHQgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVOdW1iZXIoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgdHJ1ZSk7XG5cdCAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVCb29sZWFuKGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIHRydWUpO1xuXHQgICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSB8fCBpc0RhdGUkMSh2YWx1ZSkpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZURhdGUoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgdHJ1ZSk7XG5cdCAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplTnVsbChidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCB0cnVlKTtcblx0ICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplTnVsbChidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCB0cnVlKTtcblx0ICAgICAgfSBlbHNlIGlmICh2YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdPYmplY3RJZCcgfHwgdmFsdWVbJ19ic29udHlwZSddID09PSAnT2JqZWN0SUQnKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVPYmplY3RJZChidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCB0cnVlKTtcblx0ICAgICAgfSBlbHNlIGlmIChCdWZmZXIkNS5pc0J1ZmZlcih2YWx1ZSkpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZUJ1ZmZlcihidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCB0cnVlKTtcblx0ICAgICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFJlZ0V4cCB8fCBpc1JlZ0V4cCQxKHZhbHVlKSkge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplUmVnRXhwKGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIHRydWUpO1xuXHQgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdvYmplY3QnICYmIHZhbHVlWydfYnNvbnR5cGUnXSA9PSBudWxsKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVPYmplY3QoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgY2hlY2tLZXlzLCBkZXB0aCwgc2VyaWFsaXplRnVuY3Rpb25zLCBpZ25vcmVVbmRlZmluZWQsIHRydWUsIHBhdGgpO1xuXHQgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdvYmplY3QnICYmIHZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ0RlY2ltYWwxMjgnKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVEZWNpbWFsMTI4KGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIHRydWUpO1xuXHQgICAgICB9IGVsc2UgaWYgKHZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ0xvbmcnIHx8IHZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ1RpbWVzdGFtcCcpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZUxvbmcoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgdHJ1ZSk7XG5cdCAgICAgIH0gZWxzZSBpZiAodmFsdWVbJ19ic29udHlwZSddID09PSAnRG91YmxlJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplRG91YmxlKGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIHRydWUpO1xuXHQgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyAmJiBzZXJpYWxpemVGdW5jdGlvbnMpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZUZ1bmN0aW9uKGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIGNoZWNrS2V5cywgZGVwdGgsIHNlcmlhbGl6ZUZ1bmN0aW9ucywgdHJ1ZSk7XG5cdCAgICAgIH0gZWxzZSBpZiAodmFsdWVbJ19ic29udHlwZSddID09PSAnQ29kZScpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZUNvZGUoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgY2hlY2tLZXlzLCBkZXB0aCwgc2VyaWFsaXplRnVuY3Rpb25zLCBpZ25vcmVVbmRlZmluZWQsIHRydWUpO1xuXHQgICAgICB9IGVsc2UgaWYgKHZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ0JpbmFyeScpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZUJpbmFyeShidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCB0cnVlKTtcblx0ICAgICAgfSBlbHNlIGlmICh2YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdTeW1ib2wnKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVTeW1ib2woYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgdHJ1ZSk7XG5cdCAgICAgIH0gZWxzZSBpZiAodmFsdWVbJ19ic29udHlwZSddID09PSAnREJSZWYnKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVEQlJlZihidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCBkZXB0aCwgc2VyaWFsaXplRnVuY3Rpb25zLCB0cnVlKTtcblx0ICAgICAgfSBlbHNlIGlmICh2YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdCU09OUmVnRXhwJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplQlNPTlJlZ0V4cChidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCB0cnVlKTtcblx0ICAgICAgfSBlbHNlIGlmICh2YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdJbnQzMicpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZUludDMyKGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIHRydWUpO1xuXHQgICAgICB9IGVsc2UgaWYgKHZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ01pbktleScgfHwgdmFsdWVbJ19ic29udHlwZSddID09PSAnTWF4S2V5Jykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplTWluTWF4KGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIHRydWUpO1xuXHQgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZVsnX2Jzb250eXBlJ10gIT09ICd1bmRlZmluZWQnKSB7XG5cdCAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5yZWNvZ25pemVkIG9yIGludmFsaWQgX2Jzb250eXBlOiAnICsgdmFsdWVbJ19ic29udHlwZSddKTtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0gZWxzZSBpZiAob2JqZWN0IGluc3RhbmNlb2YgbWFwKSB7XG5cdCAgICB2YXIgaXRlcmF0b3IgPSBvYmplY3QuZW50cmllcygpO1xuXHQgICAgdmFyIGRvbmUgPSBmYWxzZTtcblxuXHQgICAgd2hpbGUgKCFkb25lKSB7XG5cdCAgICAgIC8vIFVucGFjayB0aGUgbmV4dCBlbnRyeVxuXHQgICAgICB2YXIgZW50cnkgPSBpdGVyYXRvci5uZXh0KCk7XG5cdCAgICAgIGRvbmUgPSBlbnRyeS5kb25lOyAvLyBBcmUgd2UgZG9uZSwgdGhlbiBza2lwIGFuZCB0ZXJtaW5hdGVcblxuXHQgICAgICBpZiAoZG9uZSkgY29udGludWU7IC8vIEdldCB0aGUgZW50cnkgdmFsdWVzXG5cblx0ICAgICAgdmFyIF9rZXkgPSBlbnRyeS52YWx1ZVswXTtcblx0ICAgICAgdmFyIF92YWx1ZSA9IGVudHJ5LnZhbHVlWzFdOyAvLyBDaGVjayB0aGUgdHlwZSBvZiB0aGUgdmFsdWVcblxuXHQgICAgICB2YXIgX3R5cGUgPSBfdHlwZW9mJDMoX3ZhbHVlKTsgLy8gQ2hlY2sgdGhlIGtleSBhbmQgdGhyb3cgZXJyb3IgaWYgaXQncyBpbGxlZ2FsXG5cblxuXHQgICAgICBpZiAodHlwZW9mIF9rZXkgPT09ICdzdHJpbmcnICYmICFpZ25vcmVLZXlzLmhhcyhfa2V5KSkge1xuXHQgICAgICAgIGlmIChfa2V5Lm1hdGNoKHJlZ2V4cCQxKSAhPSBudWxsKSB7XG5cdCAgICAgICAgICAvLyBUaGUgQlNPTiBzcGVjIGRvZXNuJ3QgYWxsb3cga2V5cyB3aXRoIG51bGwgYnl0ZXMgYmVjYXVzZSBrZXlzIGFyZVxuXHQgICAgICAgICAgLy8gbnVsbC10ZXJtaW5hdGVkLlxuXHQgICAgICAgICAgdGhyb3cgRXJyb3IoJ2tleSAnICsgX2tleSArICcgbXVzdCBub3QgY29udGFpbiBudWxsIGJ5dGVzJyk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgaWYgKGNoZWNrS2V5cykge1xuXHQgICAgICAgICAgaWYgKCckJyA9PT0gX2tleVswXSkge1xuXHQgICAgICAgICAgICB0aHJvdyBFcnJvcigna2V5ICcgKyBfa2V5ICsgXCIgbXVzdCBub3Qgc3RhcnQgd2l0aCAnJCdcIik7XG5cdCAgICAgICAgICB9IGVsc2UgaWYgKH5fa2V5LmluZGV4T2YoJy4nKSkge1xuXHQgICAgICAgICAgICB0aHJvdyBFcnJvcigna2V5ICcgKyBfa2V5ICsgXCIgbXVzdCBub3QgY29udGFpbiAnLidcIik7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cblx0ICAgICAgaWYgKF90eXBlID09PSAnc3RyaW5nJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplU3RyaW5nKGJ1ZmZlciQkMSwgX2tleSwgX3ZhbHVlLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3R5cGUgPT09ICdudW1iZXInKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVOdW1iZXIoYnVmZmVyJCQxLCBfa2V5LCBfdmFsdWUsIGluZGV4KTtcblx0ICAgICAgfSBlbHNlIGlmIChfdHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVCb29sZWFuKGJ1ZmZlciQkMSwgX2tleSwgX3ZhbHVlLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3ZhbHVlIGluc3RhbmNlb2YgRGF0ZSB8fCBpc0RhdGUkMShfdmFsdWUpKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVEYXRlKGJ1ZmZlciQkMSwgX2tleSwgX3ZhbHVlLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3ZhbHVlID09PSBudWxsIHx8IF92YWx1ZSA9PT0gdW5kZWZpbmVkICYmIGlnbm9yZVVuZGVmaW5lZCA9PT0gZmFsc2UpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZU51bGwoYnVmZmVyJCQxLCBfa2V5LCBfdmFsdWUsIGluZGV4KTtcblx0ICAgICAgfSBlbHNlIGlmIChfdmFsdWVbJ19ic29udHlwZSddID09PSAnT2JqZWN0SWQnIHx8IF92YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdPYmplY3RJRCcpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZU9iamVjdElkKGJ1ZmZlciQkMSwgX2tleSwgX3ZhbHVlLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoQnVmZmVyJDUuaXNCdWZmZXIoX3ZhbHVlKSkge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplQnVmZmVyKGJ1ZmZlciQkMSwgX2tleSwgX3ZhbHVlLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3ZhbHVlIGluc3RhbmNlb2YgUmVnRXhwIHx8IGlzUmVnRXhwJDEoX3ZhbHVlKSkge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplUmVnRXhwKGJ1ZmZlciQkMSwgX2tleSwgX3ZhbHVlLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3R5cGUgPT09ICdvYmplY3QnICYmIF92YWx1ZVsnX2Jzb250eXBlJ10gPT0gbnVsbCkge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplT2JqZWN0KGJ1ZmZlciQkMSwgX2tleSwgX3ZhbHVlLCBpbmRleCwgY2hlY2tLZXlzLCBkZXB0aCwgc2VyaWFsaXplRnVuY3Rpb25zLCBpZ25vcmVVbmRlZmluZWQsIGZhbHNlLCBwYXRoKTtcblx0ICAgICAgfSBlbHNlIGlmIChfdHlwZSA9PT0gJ29iamVjdCcgJiYgX3ZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ0RlY2ltYWwxMjgnKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVEZWNpbWFsMTI4KGJ1ZmZlciQkMSwgX2tleSwgX3ZhbHVlLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3ZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ0xvbmcnIHx8IF92YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdUaW1lc3RhbXAnKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVMb25nKGJ1ZmZlciQkMSwgX2tleSwgX3ZhbHVlLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3ZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ0RvdWJsZScpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZURvdWJsZShidWZmZXIkJDEsIF9rZXksIF92YWx1ZSwgaW5kZXgpO1xuXHQgICAgICB9IGVsc2UgaWYgKF92YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdDb2RlJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplQ29kZShidWZmZXIkJDEsIF9rZXksIF92YWx1ZSwgaW5kZXgsIGNoZWNrS2V5cywgZGVwdGgsIHNlcmlhbGl6ZUZ1bmN0aW9ucywgaWdub3JlVW5kZWZpbmVkKTtcblx0ICAgICAgfSBlbHNlIGlmICh0eXBlb2YgX3ZhbHVlID09PSAnZnVuY3Rpb24nICYmIHNlcmlhbGl6ZUZ1bmN0aW9ucykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplRnVuY3Rpb24oYnVmZmVyJCQxLCBfa2V5LCBfdmFsdWUsIGluZGV4LCBjaGVja0tleXMsIGRlcHRoLCBzZXJpYWxpemVGdW5jdGlvbnMpO1xuXHQgICAgICB9IGVsc2UgaWYgKF92YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdCaW5hcnknKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVCaW5hcnkoYnVmZmVyJCQxLCBfa2V5LCBfdmFsdWUsIGluZGV4KTtcblx0ICAgICAgfSBlbHNlIGlmIChfdmFsdWVbJ19ic29udHlwZSddID09PSAnU3ltYm9sJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplU3ltYm9sKGJ1ZmZlciQkMSwgX2tleSwgX3ZhbHVlLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3ZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ0RCUmVmJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplREJSZWYoYnVmZmVyJCQxLCBfa2V5LCBfdmFsdWUsIGluZGV4LCBkZXB0aCwgc2VyaWFsaXplRnVuY3Rpb25zKTtcblx0ICAgICAgfSBlbHNlIGlmIChfdmFsdWVbJ19ic29udHlwZSddID09PSAnQlNPTlJlZ0V4cCcpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZUJTT05SZWdFeHAoYnVmZmVyJCQxLCBfa2V5LCBfdmFsdWUsIGluZGV4KTtcblx0ICAgICAgfSBlbHNlIGlmIChfdmFsdWVbJ19ic29udHlwZSddID09PSAnSW50MzInKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVJbnQzMihidWZmZXIkJDEsIF9rZXksIF92YWx1ZSwgaW5kZXgpO1xuXHQgICAgICB9IGVsc2UgaWYgKF92YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdNaW5LZXknIHx8IF92YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdNYXhLZXknKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVNaW5NYXgoYnVmZmVyJCQxLCBfa2V5LCBfdmFsdWUsIGluZGV4KTtcblx0ICAgICAgfSBlbHNlIGlmICh0eXBlb2YgX3ZhbHVlWydfYnNvbnR5cGUnXSAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0ICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbnJlY29nbml6ZWQgb3IgaW52YWxpZCBfYnNvbnR5cGU6ICcgKyBfdmFsdWVbJ19ic29udHlwZSddKTtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0gZWxzZSB7XG5cdCAgICAvLyBEaWQgd2UgcHJvdmlkZSBhIGN1c3RvbSBzZXJpYWxpemF0aW9uIG1ldGhvZFxuXHQgICAgaWYgKG9iamVjdC50b0JTT04pIHtcblx0ICAgICAgaWYgKHR5cGVvZiBvYmplY3QudG9CU09OICE9PSAnZnVuY3Rpb24nKSB0aHJvdyBuZXcgVHlwZUVycm9yKCd0b0JTT04gaXMgbm90IGEgZnVuY3Rpb24nKTtcblx0ICAgICAgb2JqZWN0ID0gb2JqZWN0LnRvQlNPTigpO1xuXHQgICAgICBpZiAob2JqZWN0ICE9IG51bGwgJiYgX3R5cGVvZiQzKG9iamVjdCkgIT09ICdvYmplY3QnKSB0aHJvdyBuZXcgVHlwZUVycm9yKCd0b0JTT04gZnVuY3Rpb24gZGlkIG5vdCByZXR1cm4gYW4gb2JqZWN0Jyk7XG5cdCAgICB9IC8vIEl0ZXJhdGUgb3ZlciBhbGwgdGhlIGtleXNcblxuXG5cdCAgICBmb3IgKHZhciBfa2V5MiBpbiBvYmplY3QpIHtcblx0ICAgICAgdmFyIF92YWx1ZTIgPSBvYmplY3RbX2tleTJdOyAvLyBJcyB0aGVyZSBhbiBvdmVycmlkZSB2YWx1ZVxuXG5cdCAgICAgIGlmIChfdmFsdWUyICYmIF92YWx1ZTIudG9CU09OKSB7XG5cdCAgICAgICAgaWYgKHR5cGVvZiBfdmFsdWUyLnRvQlNPTiAhPT0gJ2Z1bmN0aW9uJykgdGhyb3cgbmV3IFR5cGVFcnJvcigndG9CU09OIGlzIG5vdCBhIGZ1bmN0aW9uJyk7XG5cdCAgICAgICAgX3ZhbHVlMiA9IF92YWx1ZTIudG9CU09OKCk7XG5cdCAgICAgIH0gLy8gQ2hlY2sgdGhlIHR5cGUgb2YgdGhlIHZhbHVlXG5cblxuXHQgICAgICB2YXIgX3R5cGUyID0gX3R5cGVvZiQzKF92YWx1ZTIpOyAvLyBDaGVjayB0aGUga2V5IGFuZCB0aHJvdyBlcnJvciBpZiBpdCdzIGlsbGVnYWxcblxuXG5cdCAgICAgIGlmICh0eXBlb2YgX2tleTIgPT09ICdzdHJpbmcnICYmICFpZ25vcmVLZXlzLmhhcyhfa2V5MikpIHtcblx0ICAgICAgICBpZiAoX2tleTIubWF0Y2gocmVnZXhwJDEpICE9IG51bGwpIHtcblx0ICAgICAgICAgIC8vIFRoZSBCU09OIHNwZWMgZG9lc24ndCBhbGxvdyBrZXlzIHdpdGggbnVsbCBieXRlcyBiZWNhdXNlIGtleXMgYXJlXG5cdCAgICAgICAgICAvLyBudWxsLXRlcm1pbmF0ZWQuXG5cdCAgICAgICAgICB0aHJvdyBFcnJvcigna2V5ICcgKyBfa2V5MiArICcgbXVzdCBub3QgY29udGFpbiBudWxsIGJ5dGVzJyk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgaWYgKGNoZWNrS2V5cykge1xuXHQgICAgICAgICAgaWYgKCckJyA9PT0gX2tleTJbMF0pIHtcblx0ICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ2tleSAnICsgX2tleTIgKyBcIiBtdXN0IG5vdCBzdGFydCB3aXRoICckJ1wiKTtcblx0ICAgICAgICAgIH0gZWxzZSBpZiAofl9rZXkyLmluZGV4T2YoJy4nKSkge1xuXHQgICAgICAgICAgICB0aHJvdyBFcnJvcigna2V5ICcgKyBfa2V5MiArIFwiIG11c3Qgbm90IGNvbnRhaW4gJy4nXCIpO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXG5cdCAgICAgIGlmIChfdHlwZTIgPT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVTdHJpbmcoYnVmZmVyJCQxLCBfa2V5MiwgX3ZhbHVlMiwgaW5kZXgpO1xuXHQgICAgICB9IGVsc2UgaWYgKF90eXBlMiA9PT0gJ251bWJlcicpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZU51bWJlcihidWZmZXIkJDEsIF9rZXkyLCBfdmFsdWUyLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3R5cGUyID09PSAnYm9vbGVhbicpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZUJvb2xlYW4oYnVmZmVyJCQxLCBfa2V5MiwgX3ZhbHVlMiwgaW5kZXgpO1xuXHQgICAgICB9IGVsc2UgaWYgKF92YWx1ZTIgaW5zdGFuY2VvZiBEYXRlIHx8IGlzRGF0ZSQxKF92YWx1ZTIpKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVEYXRlKGJ1ZmZlciQkMSwgX2tleTIsIF92YWx1ZTIsIGluZGV4KTtcblx0ICAgICAgfSBlbHNlIGlmIChfdmFsdWUyID09PSB1bmRlZmluZWQpIHtcblx0ICAgICAgICBpZiAoaWdub3JlVW5kZWZpbmVkID09PSBmYWxzZSkgaW5kZXggPSBzZXJpYWxpemVOdWxsKGJ1ZmZlciQkMSwgX2tleTIsIF92YWx1ZTIsIGluZGV4KTtcblx0ICAgICAgfSBlbHNlIGlmIChfdmFsdWUyID09PSBudWxsKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVOdWxsKGJ1ZmZlciQkMSwgX2tleTIsIF92YWx1ZTIsIGluZGV4KTtcblx0ICAgICAgfSBlbHNlIGlmIChfdmFsdWUyWydfYnNvbnR5cGUnXSA9PT0gJ09iamVjdElkJyB8fCBfdmFsdWUyWydfYnNvbnR5cGUnXSA9PT0gJ09iamVjdElEJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplT2JqZWN0SWQoYnVmZmVyJCQxLCBfa2V5MiwgX3ZhbHVlMiwgaW5kZXgpO1xuXHQgICAgICB9IGVsc2UgaWYgKEJ1ZmZlciQ1LmlzQnVmZmVyKF92YWx1ZTIpKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVCdWZmZXIoYnVmZmVyJCQxLCBfa2V5MiwgX3ZhbHVlMiwgaW5kZXgpO1xuXHQgICAgICB9IGVsc2UgaWYgKF92YWx1ZTIgaW5zdGFuY2VvZiBSZWdFeHAgfHwgaXNSZWdFeHAkMShfdmFsdWUyKSkge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplUmVnRXhwKGJ1ZmZlciQkMSwgX2tleTIsIF92YWx1ZTIsIGluZGV4KTtcblx0ICAgICAgfSBlbHNlIGlmIChfdHlwZTIgPT09ICdvYmplY3QnICYmIF92YWx1ZTJbJ19ic29udHlwZSddID09IG51bGwpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZU9iamVjdChidWZmZXIkJDEsIF9rZXkyLCBfdmFsdWUyLCBpbmRleCwgY2hlY2tLZXlzLCBkZXB0aCwgc2VyaWFsaXplRnVuY3Rpb25zLCBpZ25vcmVVbmRlZmluZWQsIGZhbHNlLCBwYXRoKTtcblx0ICAgICAgfSBlbHNlIGlmIChfdHlwZTIgPT09ICdvYmplY3QnICYmIF92YWx1ZTJbJ19ic29udHlwZSddID09PSAnRGVjaW1hbDEyOCcpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZURlY2ltYWwxMjgoYnVmZmVyJCQxLCBfa2V5MiwgX3ZhbHVlMiwgaW5kZXgpO1xuXHQgICAgICB9IGVsc2UgaWYgKF92YWx1ZTJbJ19ic29udHlwZSddID09PSAnTG9uZycgfHwgX3ZhbHVlMlsnX2Jzb250eXBlJ10gPT09ICdUaW1lc3RhbXAnKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVMb25nKGJ1ZmZlciQkMSwgX2tleTIsIF92YWx1ZTIsIGluZGV4KTtcblx0ICAgICAgfSBlbHNlIGlmIChfdmFsdWUyWydfYnNvbnR5cGUnXSA9PT0gJ0RvdWJsZScpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZURvdWJsZShidWZmZXIkJDEsIF9rZXkyLCBfdmFsdWUyLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3ZhbHVlMlsnX2Jzb250eXBlJ10gPT09ICdDb2RlJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplQ29kZShidWZmZXIkJDEsIF9rZXkyLCBfdmFsdWUyLCBpbmRleCwgY2hlY2tLZXlzLCBkZXB0aCwgc2VyaWFsaXplRnVuY3Rpb25zLCBpZ25vcmVVbmRlZmluZWQpO1xuXHQgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBfdmFsdWUyID09PSAnZnVuY3Rpb24nICYmIHNlcmlhbGl6ZUZ1bmN0aW9ucykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplRnVuY3Rpb24oYnVmZmVyJCQxLCBfa2V5MiwgX3ZhbHVlMiwgaW5kZXgsIGNoZWNrS2V5cywgZGVwdGgsIHNlcmlhbGl6ZUZ1bmN0aW9ucyk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3ZhbHVlMlsnX2Jzb250eXBlJ10gPT09ICdCaW5hcnknKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVCaW5hcnkoYnVmZmVyJCQxLCBfa2V5MiwgX3ZhbHVlMiwgaW5kZXgpO1xuXHQgICAgICB9IGVsc2UgaWYgKF92YWx1ZTJbJ19ic29udHlwZSddID09PSAnU3ltYm9sJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplU3ltYm9sKGJ1ZmZlciQkMSwgX2tleTIsIF92YWx1ZTIsIGluZGV4KTtcblx0ICAgICAgfSBlbHNlIGlmIChfdmFsdWUyWydfYnNvbnR5cGUnXSA9PT0gJ0RCUmVmJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplREJSZWYoYnVmZmVyJCQxLCBfa2V5MiwgX3ZhbHVlMiwgaW5kZXgsIGRlcHRoLCBzZXJpYWxpemVGdW5jdGlvbnMpO1xuXHQgICAgICB9IGVsc2UgaWYgKF92YWx1ZTJbJ19ic29udHlwZSddID09PSAnQlNPTlJlZ0V4cCcpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZUJTT05SZWdFeHAoYnVmZmVyJCQxLCBfa2V5MiwgX3ZhbHVlMiwgaW5kZXgpO1xuXHQgICAgICB9IGVsc2UgaWYgKF92YWx1ZTJbJ19ic29udHlwZSddID09PSAnSW50MzInKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVJbnQzMihidWZmZXIkJDEsIF9rZXkyLCBfdmFsdWUyLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3ZhbHVlMlsnX2Jzb250eXBlJ10gPT09ICdNaW5LZXknIHx8IF92YWx1ZTJbJ19ic29udHlwZSddID09PSAnTWF4S2V5Jykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplTWluTWF4KGJ1ZmZlciQkMSwgX2tleTIsIF92YWx1ZTIsIGluZGV4KTtcblx0ICAgICAgfSBlbHNlIGlmICh0eXBlb2YgX3ZhbHVlMlsnX2Jzb250eXBlJ10gIT09ICd1bmRlZmluZWQnKSB7XG5cdCAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5yZWNvZ25pemVkIG9yIGludmFsaWQgX2Jzb250eXBlOiAnICsgX3ZhbHVlMlsnX2Jzb250eXBlJ10pO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSAvLyBSZW1vdmUgdGhlIHBhdGhcblxuXG5cdCAgcGF0aC5wb3AoKTsgLy8gRmluYWwgcGFkZGluZyBieXRlIGZvciBvYmplY3RcblxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDB4MDA7IC8vIEZpbmFsIHNpemVcblxuXHQgIHZhciBzaXplID0gaW5kZXggLSBzdGFydGluZ0luZGV4OyAvLyBXcml0ZSB0aGUgc2l6ZSBvZiB0aGUgb2JqZWN0XG5cblx0ICBidWZmZXIkJDFbc3RhcnRpbmdJbmRleCsrXSA9IHNpemUgJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtzdGFydGluZ0luZGV4KytdID0gc2l6ZSA+PiA4ICYgMHhmZjtcblx0ICBidWZmZXIkJDFbc3RhcnRpbmdJbmRleCsrXSA9IHNpemUgPj4gMTYgJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtzdGFydGluZ0luZGV4KytdID0gc2l6ZSA+PiAyNCAmIDB4ZmY7XG5cdCAgcmV0dXJuIGluZGV4O1xuXHR9XG5cblx0dmFyIHNlcmlhbGl6ZXIgPSBzZXJpYWxpemVJbnRvO1xuXG5cdGZ1bmN0aW9uIF90eXBlb2YkNChvYmopIHsgaWYgKHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSBcInN5bWJvbFwiKSB7IF90eXBlb2YkNCA9IGZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9OyB9IGVsc2UgeyBfdHlwZW9mJDQgPSBmdW5jdGlvbiBfdHlwZW9mKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajsgfTsgfSByZXR1cm4gX3R5cGVvZiQ0KG9iaik7IH1cblxuXHR2YXIgQnVmZmVyJDYgPSBidWZmZXIuQnVmZmVyO1xuXHR2YXIgbm9ybWFsaXplZEZ1bmN0aW9uU3RyaW5nJDIgPSB1dGlscy5ub3JtYWxpemVkRnVuY3Rpb25TdHJpbmc7IC8vIFRvIGVuc3VyZSB0aGF0IDAuNCBvZiBub2RlIHdvcmtzIGNvcnJlY3RseVxuXG5cdGZ1bmN0aW9uIGlzRGF0ZSQyKGQpIHtcblx0ICByZXR1cm4gX3R5cGVvZiQ0KGQpID09PSAnb2JqZWN0JyAmJiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZCkgPT09ICdbb2JqZWN0IERhdGVdJztcblx0fVxuXG5cdGZ1bmN0aW9uIGNhbGN1bGF0ZU9iamVjdFNpemUob2JqZWN0LCBzZXJpYWxpemVGdW5jdGlvbnMsIGlnbm9yZVVuZGVmaW5lZCkge1xuXHQgIHZhciB0b3RhbExlbmd0aCA9IDQgKyAxO1xuXG5cdCAgaWYgKEFycmF5LmlzQXJyYXkob2JqZWN0KSkge1xuXHQgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgdG90YWxMZW5ndGggKz0gY2FsY3VsYXRlRWxlbWVudChpLnRvU3RyaW5nKCksIG9iamVjdFtpXSwgc2VyaWFsaXplRnVuY3Rpb25zLCB0cnVlLCBpZ25vcmVVbmRlZmluZWQpO1xuXHQgICAgfVxuXHQgIH0gZWxzZSB7XG5cdCAgICAvLyBJZiB3ZSBoYXZlIHRvQlNPTiBkZWZpbmVkLCBvdmVycmlkZSB0aGUgY3VycmVudCBvYmplY3Rcblx0ICAgIGlmIChvYmplY3QudG9CU09OKSB7XG5cdCAgICAgIG9iamVjdCA9IG9iamVjdC50b0JTT04oKTtcblx0ICAgIH0gLy8gQ2FsY3VsYXRlIHNpemVcblxuXG5cdCAgICBmb3IgKHZhciBrZXkgaW4gb2JqZWN0KSB7XG5cdCAgICAgIHRvdGFsTGVuZ3RoICs9IGNhbGN1bGF0ZUVsZW1lbnQoa2V5LCBvYmplY3Rba2V5XSwgc2VyaWFsaXplRnVuY3Rpb25zLCBmYWxzZSwgaWdub3JlVW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICB9XG5cblx0ICByZXR1cm4gdG90YWxMZW5ndGg7XG5cdH1cblx0LyoqXG5cdCAqIEBpZ25vcmVcblx0ICogQGFwaSBwcml2YXRlXG5cdCAqL1xuXG5cblx0ZnVuY3Rpb24gY2FsY3VsYXRlRWxlbWVudChuYW1lLCB2YWx1ZSwgc2VyaWFsaXplRnVuY3Rpb25zLCBpc0FycmF5LCBpZ25vcmVVbmRlZmluZWQpIHtcblx0ICAvLyBJZiB3ZSBoYXZlIHRvQlNPTiBkZWZpbmVkLCBvdmVycmlkZSB0aGUgY3VycmVudCBvYmplY3Rcblx0ICBpZiAodmFsdWUgJiYgdmFsdWUudG9CU09OKSB7XG5cdCAgICB2YWx1ZSA9IHZhbHVlLnRvQlNPTigpO1xuXHQgIH1cblxuXHQgIHN3aXRjaCAoX3R5cGVvZiQ0KHZhbHVlKSkge1xuXHQgICAgY2FzZSAnc3RyaW5nJzpcblx0ICAgICAgcmV0dXJuIDEgKyBCdWZmZXIkNi5ieXRlTGVuZ3RoKG5hbWUsICd1dGY4JykgKyAxICsgNCArIEJ1ZmZlciQ2LmJ5dGVMZW5ndGgodmFsdWUsICd1dGY4JykgKyAxO1xuXG5cdCAgICBjYXNlICdudW1iZXInOlxuXHQgICAgICBpZiAoTWF0aC5mbG9vcih2YWx1ZSkgPT09IHZhbHVlICYmIHZhbHVlID49IGNvbnN0YW50cy5KU19JTlRfTUlOICYmIHZhbHVlIDw9IGNvbnN0YW50cy5KU19JTlRfTUFYKSB7XG5cdCAgICAgICAgaWYgKHZhbHVlID49IGNvbnN0YW50cy5CU09OX0lOVDMyX01JTiAmJiB2YWx1ZSA8PSBjb25zdGFudHMuQlNPTl9JTlQzMl9NQVgpIHtcblx0ICAgICAgICAgIC8vIDMyIGJpdFxuXHQgICAgICAgICAgcmV0dXJuIChuYW1lICE9IG51bGwgPyBCdWZmZXIkNi5ieXRlTGVuZ3RoKG5hbWUsICd1dGY4JykgKyAxIDogMCkgKyAoNCArIDEpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICByZXR1cm4gKG5hbWUgIT0gbnVsbCA/IEJ1ZmZlciQ2LmJ5dGVMZW5ndGgobmFtZSwgJ3V0ZjgnKSArIDEgOiAwKSArICg4ICsgMSk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9IGVsc2Uge1xuXHQgICAgICAgIC8vIDY0IGJpdFxuXHQgICAgICAgIHJldHVybiAobmFtZSAhPSBudWxsID8gQnVmZmVyJDYuYnl0ZUxlbmd0aChuYW1lLCAndXRmOCcpICsgMSA6IDApICsgKDggKyAxKTtcblx0ICAgICAgfVxuXG5cdCAgICBjYXNlICd1bmRlZmluZWQnOlxuXHQgICAgICBpZiAoaXNBcnJheSB8fCAhaWdub3JlVW5kZWZpbmVkKSByZXR1cm4gKG5hbWUgIT0gbnVsbCA/IEJ1ZmZlciQ2LmJ5dGVMZW5ndGgobmFtZSwgJ3V0ZjgnKSArIDEgOiAwKSArIDE7XG5cdCAgICAgIHJldHVybiAwO1xuXG5cdCAgICBjYXNlICdib29sZWFuJzpcblx0ICAgICAgcmV0dXJuIChuYW1lICE9IG51bGwgPyBCdWZmZXIkNi5ieXRlTGVuZ3RoKG5hbWUsICd1dGY4JykgKyAxIDogMCkgKyAoMSArIDEpO1xuXG5cdCAgICBjYXNlICdvYmplY3QnOlxuXHQgICAgICBpZiAodmFsdWUgPT0gbnVsbCB8fCB2YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdNaW5LZXknIHx8IHZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ01heEtleScpIHtcblx0ICAgICAgICByZXR1cm4gKG5hbWUgIT0gbnVsbCA/IEJ1ZmZlciQ2LmJ5dGVMZW5ndGgobmFtZSwgJ3V0ZjgnKSArIDEgOiAwKSArIDE7XG5cdCAgICAgIH0gZWxzZSBpZiAodmFsdWVbJ19ic29udHlwZSddID09PSAnT2JqZWN0SWQnIHx8IHZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ09iamVjdElEJykge1xuXHQgICAgICAgIHJldHVybiAobmFtZSAhPSBudWxsID8gQnVmZmVyJDYuYnl0ZUxlbmd0aChuYW1lLCAndXRmOCcpICsgMSA6IDApICsgKDEyICsgMSk7XG5cdCAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlIHx8IGlzRGF0ZSQyKHZhbHVlKSkge1xuXHQgICAgICAgIHJldHVybiAobmFtZSAhPSBudWxsID8gQnVmZmVyJDYuYnl0ZUxlbmd0aChuYW1lLCAndXRmOCcpICsgMSA6IDApICsgKDggKyAxKTtcblx0ICAgICAgfSBlbHNlIGlmICh0eXBlb2YgQnVmZmVyJDYgIT09ICd1bmRlZmluZWQnICYmIEJ1ZmZlciQ2LmlzQnVmZmVyKHZhbHVlKSkge1xuXHQgICAgICAgIHJldHVybiAobmFtZSAhPSBudWxsID8gQnVmZmVyJDYuYnl0ZUxlbmd0aChuYW1lLCAndXRmOCcpICsgMSA6IDApICsgKDEgKyA0ICsgMSkgKyB2YWx1ZS5sZW5ndGg7XG5cdCAgICAgIH0gZWxzZSBpZiAodmFsdWVbJ19ic29udHlwZSddID09PSAnTG9uZycgfHwgdmFsdWVbJ19ic29udHlwZSddID09PSAnRG91YmxlJyB8fCB2YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdUaW1lc3RhbXAnKSB7XG5cdCAgICAgICAgcmV0dXJuIChuYW1lICE9IG51bGwgPyBCdWZmZXIkNi5ieXRlTGVuZ3RoKG5hbWUsICd1dGY4JykgKyAxIDogMCkgKyAoOCArIDEpO1xuXHQgICAgICB9IGVsc2UgaWYgKHZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ0RlY2ltYWwxMjgnKSB7XG5cdCAgICAgICAgcmV0dXJuIChuYW1lICE9IG51bGwgPyBCdWZmZXIkNi5ieXRlTGVuZ3RoKG5hbWUsICd1dGY4JykgKyAxIDogMCkgKyAoMTYgKyAxKTtcblx0ICAgICAgfSBlbHNlIGlmICh2YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdDb2RlJykge1xuXHQgICAgICAgIC8vIENhbGN1bGF0ZSBzaXplIGRlcGVuZGluZyBvbiB0aGUgYXZhaWxhYmlsaXR5IG9mIGEgc2NvcGVcblx0ICAgICAgICBpZiAodmFsdWUuc2NvcGUgIT0gbnVsbCAmJiBPYmplY3Qua2V5cyh2YWx1ZS5zY29wZSkubGVuZ3RoID4gMCkge1xuXHQgICAgICAgICAgcmV0dXJuIChuYW1lICE9IG51bGwgPyBCdWZmZXIkNi5ieXRlTGVuZ3RoKG5hbWUsICd1dGY4JykgKyAxIDogMCkgKyAxICsgNCArIDQgKyBCdWZmZXIkNi5ieXRlTGVuZ3RoKHZhbHVlLmNvZGUudG9TdHJpbmcoKSwgJ3V0ZjgnKSArIDEgKyBjYWxjdWxhdGVPYmplY3RTaXplKHZhbHVlLnNjb3BlLCBzZXJpYWxpemVGdW5jdGlvbnMsIGlnbm9yZVVuZGVmaW5lZCk7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIHJldHVybiAobmFtZSAhPSBudWxsID8gQnVmZmVyJDYuYnl0ZUxlbmd0aChuYW1lLCAndXRmOCcpICsgMSA6IDApICsgMSArIDQgKyBCdWZmZXIkNi5ieXRlTGVuZ3RoKHZhbHVlLmNvZGUudG9TdHJpbmcoKSwgJ3V0ZjgnKSArIDE7XG5cdCAgICAgICAgfVxuXHQgICAgICB9IGVsc2UgaWYgKHZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ0JpbmFyeScpIHtcblx0ICAgICAgICAvLyBDaGVjayB3aGF0IGtpbmQgb2Ygc3VidHlwZSB3ZSBoYXZlXG5cdCAgICAgICAgaWYgKHZhbHVlLnN1Yl90eXBlID09PSBiaW5hcnkuU1VCVFlQRV9CWVRFX0FSUkFZKSB7XG5cdCAgICAgICAgICByZXR1cm4gKG5hbWUgIT0gbnVsbCA/IEJ1ZmZlciQ2LmJ5dGVMZW5ndGgobmFtZSwgJ3V0ZjgnKSArIDEgOiAwKSArICh2YWx1ZS5wb3NpdGlvbiArIDEgKyA0ICsgMSArIDQpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICByZXR1cm4gKG5hbWUgIT0gbnVsbCA/IEJ1ZmZlciQ2LmJ5dGVMZW5ndGgobmFtZSwgJ3V0ZjgnKSArIDEgOiAwKSArICh2YWx1ZS5wb3NpdGlvbiArIDEgKyA0ICsgMSk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9IGVsc2UgaWYgKHZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ1N5bWJvbCcpIHtcblx0ICAgICAgICByZXR1cm4gKG5hbWUgIT0gbnVsbCA/IEJ1ZmZlciQ2LmJ5dGVMZW5ndGgobmFtZSwgJ3V0ZjgnKSArIDEgOiAwKSArIEJ1ZmZlciQ2LmJ5dGVMZW5ndGgodmFsdWUudmFsdWUsICd1dGY4JykgKyA0ICsgMSArIDE7XG5cdCAgICAgIH0gZWxzZSBpZiAodmFsdWVbJ19ic29udHlwZSddID09PSAnREJSZWYnKSB7XG5cdCAgICAgICAgLy8gU2V0IHVwIGNvcnJlY3Qgb2JqZWN0IGZvciBzZXJpYWxpemF0aW9uXG5cdCAgICAgICAgdmFyIG9yZGVyZWRfdmFsdWVzID0gT2JqZWN0LmFzc2lnbih7XG5cdCAgICAgICAgICAkcmVmOiB2YWx1ZS5jb2xsZWN0aW9uLFxuXHQgICAgICAgICAgJGlkOiB2YWx1ZS5vaWRcblx0ICAgICAgICB9LCB2YWx1ZS5maWVsZHMpOyAvLyBBZGQgZGIgcmVmZXJlbmNlIGlmIGl0IGV4aXN0c1xuXG5cdCAgICAgICAgaWYgKHZhbHVlLmRiICE9IG51bGwpIHtcblx0ICAgICAgICAgIG9yZGVyZWRfdmFsdWVzWyckZGInXSA9IHZhbHVlLmRiO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIHJldHVybiAobmFtZSAhPSBudWxsID8gQnVmZmVyJDYuYnl0ZUxlbmd0aChuYW1lLCAndXRmOCcpICsgMSA6IDApICsgMSArIGNhbGN1bGF0ZU9iamVjdFNpemUob3JkZXJlZF92YWx1ZXMsIHNlcmlhbGl6ZUZ1bmN0aW9ucywgaWdub3JlVW5kZWZpbmVkKTtcblx0ICAgICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFJlZ0V4cCB8fCBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpID09PSAnW29iamVjdCBSZWdFeHBdJykge1xuXHQgICAgICAgIHJldHVybiAobmFtZSAhPSBudWxsID8gQnVmZmVyJDYuYnl0ZUxlbmd0aChuYW1lLCAndXRmOCcpICsgMSA6IDApICsgMSArIEJ1ZmZlciQ2LmJ5dGVMZW5ndGgodmFsdWUuc291cmNlLCAndXRmOCcpICsgMSArICh2YWx1ZS5nbG9iYWwgPyAxIDogMCkgKyAodmFsdWUuaWdub3JlQ2FzZSA/IDEgOiAwKSArICh2YWx1ZS5tdWx0aWxpbmUgPyAxIDogMCkgKyAxO1xuXHQgICAgICB9IGVsc2UgaWYgKHZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ0JTT05SZWdFeHAnKSB7XG5cdCAgICAgICAgcmV0dXJuIChuYW1lICE9IG51bGwgPyBCdWZmZXIkNi5ieXRlTGVuZ3RoKG5hbWUsICd1dGY4JykgKyAxIDogMCkgKyAxICsgQnVmZmVyJDYuYnl0ZUxlbmd0aCh2YWx1ZS5wYXR0ZXJuLCAndXRmOCcpICsgMSArIEJ1ZmZlciQ2LmJ5dGVMZW5ndGgodmFsdWUub3B0aW9ucywgJ3V0ZjgnKSArIDE7XG5cdCAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgcmV0dXJuIChuYW1lICE9IG51bGwgPyBCdWZmZXIkNi5ieXRlTGVuZ3RoKG5hbWUsICd1dGY4JykgKyAxIDogMCkgKyBjYWxjdWxhdGVPYmplY3RTaXplKHZhbHVlLCBzZXJpYWxpemVGdW5jdGlvbnMsIGlnbm9yZVVuZGVmaW5lZCkgKyAxO1xuXHQgICAgICB9XG5cblx0ICAgIGNhc2UgJ2Z1bmN0aW9uJzpcblx0ICAgICAgLy8gV1RGIGZvciAwLjQuWCB3aGVyZSB0eXBlb2YgL3NvbWVyZWdleHAvID09PSAnZnVuY3Rpb24nXG5cdCAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFJlZ0V4cCB8fCBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpID09PSAnW29iamVjdCBSZWdFeHBdJyB8fCBTdHJpbmcuY2FsbCh2YWx1ZSkgPT09ICdbb2JqZWN0IFJlZ0V4cF0nKSB7XG5cdCAgICAgICAgcmV0dXJuIChuYW1lICE9IG51bGwgPyBCdWZmZXIkNi5ieXRlTGVuZ3RoKG5hbWUsICd1dGY4JykgKyAxIDogMCkgKyAxICsgQnVmZmVyJDYuYnl0ZUxlbmd0aCh2YWx1ZS5zb3VyY2UsICd1dGY4JykgKyAxICsgKHZhbHVlLmdsb2JhbCA/IDEgOiAwKSArICh2YWx1ZS5pZ25vcmVDYXNlID8gMSA6IDApICsgKHZhbHVlLm11bHRpbGluZSA/IDEgOiAwKSArIDE7XG5cdCAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgaWYgKHNlcmlhbGl6ZUZ1bmN0aW9ucyAmJiB2YWx1ZS5zY29wZSAhPSBudWxsICYmIE9iamVjdC5rZXlzKHZhbHVlLnNjb3BlKS5sZW5ndGggPiAwKSB7XG5cdCAgICAgICAgICByZXR1cm4gKG5hbWUgIT0gbnVsbCA/IEJ1ZmZlciQ2LmJ5dGVMZW5ndGgobmFtZSwgJ3V0ZjgnKSArIDEgOiAwKSArIDEgKyA0ICsgNCArIEJ1ZmZlciQ2LmJ5dGVMZW5ndGgobm9ybWFsaXplZEZ1bmN0aW9uU3RyaW5nJDIodmFsdWUpLCAndXRmOCcpICsgMSArIGNhbGN1bGF0ZU9iamVjdFNpemUodmFsdWUuc2NvcGUsIHNlcmlhbGl6ZUZ1bmN0aW9ucywgaWdub3JlVW5kZWZpbmVkKTtcblx0ICAgICAgICB9IGVsc2UgaWYgKHNlcmlhbGl6ZUZ1bmN0aW9ucykge1xuXHQgICAgICAgICAgcmV0dXJuIChuYW1lICE9IG51bGwgPyBCdWZmZXIkNi5ieXRlTGVuZ3RoKG5hbWUsICd1dGY4JykgKyAxIDogMCkgKyAxICsgNCArIEJ1ZmZlciQ2LmJ5dGVMZW5ndGgobm9ybWFsaXplZEZ1bmN0aW9uU3RyaW5nJDIodmFsdWUpLCAndXRmOCcpICsgMTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblxuXHQgIH1cblxuXHQgIHJldHVybiAwO1xuXHR9XG5cblx0dmFyIGNhbGN1bGF0ZV9zaXplID0gY2FsY3VsYXRlT2JqZWN0U2l6ZTtcblxuXHR2YXIgQnVmZmVyJDcgPSBidWZmZXIuQnVmZmVyO1xuXHQvKipcblx0ICogTWFrZXMgc3VyZSB0aGF0LCBpZiBhIFVpbnQ4QXJyYXkgaXMgcGFzc2VkIGluLCBpdCBpcyB3cmFwcGVkIGluIGEgQnVmZmVyLlxuXHQgKlxuXHQgKiBAcGFyYW0ge0J1ZmZlcnxVaW50OEFycmF5fSBwb3RlbnRpYWxCdWZmZXIgVGhlIHBvdGVudGlhbCBidWZmZXJcblx0ICogQHJldHVybnMge0J1ZmZlcn0gdGhlIGlucHV0IGlmIHBvdGVudGlhbEJ1ZmZlciBpcyBhIGJ1ZmZlciwgb3IgYSBidWZmZXIgdGhhdFxuXHQgKiB3cmFwcyBhIHBhc3NlZCBpbiBVaW50OEFycmF5XG5cdCAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYW55dGhpbmcgb3RoZXIgdGhhbiBhIEJ1ZmZlciBvciBVaW50OEFycmF5IGlzIHBhc3NlZCBpblxuXHQgKi9cblxuXHR2YXIgZW5zdXJlX2J1ZmZlciA9IGZ1bmN0aW9uIGVuc3VyZUJ1ZmZlcihwb3RlbnRpYWxCdWZmZXIpIHtcblx0ICBpZiAocG90ZW50aWFsQnVmZmVyIGluc3RhbmNlb2YgQnVmZmVyJDcpIHtcblx0ICAgIHJldHVybiBwb3RlbnRpYWxCdWZmZXI7XG5cdCAgfVxuXG5cdCAgaWYgKHBvdGVudGlhbEJ1ZmZlciBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcblx0ICAgIHJldHVybiBCdWZmZXIkNy5mcm9tKHBvdGVudGlhbEJ1ZmZlci5idWZmZXIpO1xuXHQgIH1cblxuXHQgIHRocm93IG5ldyBUeXBlRXJyb3IoJ011c3QgdXNlIGVpdGhlciBCdWZmZXIgb3IgVWludDhBcnJheScpO1xuXHR9O1xuXG5cdHZhciBCdWZmZXIkOCA9IGJ1ZmZlci5CdWZmZXI7IC8vIFBhcnRzIG9mIHRoZSBwYXJzZXJcblxuXHQvKipcblx0ICogQGlnbm9yZVxuXHQgKi9cblx0Ly8gRGVmYXVsdCBNYXggU2l6ZVxuXG5cdHZhciBNQVhTSVpFID0gMTAyNCAqIDEwMjQgKiAxNzsgLy8gQ3VycmVudCBJbnRlcm5hbCBUZW1wb3JhcnkgU2VyaWFsaXphdGlvbiBCdWZmZXJcblxuXHR2YXIgYnVmZmVyJDEgPSBCdWZmZXIkOC5hbGxvYyhNQVhTSVpFKTtcblx0LyoqXG5cdCAqIFNldHMgdGhlIHNpemUgb2YgdGhlIGludGVybmFsIHNlcmlhbGl6YXRpb24gYnVmZmVyLlxuXHQgKlxuXHQgKiBAbWV0aG9kXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIFRoZSBkZXNpcmVkIHNpemUgZm9yIHRoZSBpbnRlcm5hbCBzZXJpYWxpemF0aW9uIGJ1ZmZlclxuXHQgKi9cblxuXHRmdW5jdGlvbiBzZXRJbnRlcm5hbEJ1ZmZlclNpemUoc2l6ZSkge1xuXHQgIC8vIFJlc2l6ZSB0aGUgaW50ZXJuYWwgc2VyaWFsaXphdGlvbiBidWZmZXIgaWYgbmVlZGVkXG5cdCAgaWYgKGJ1ZmZlciQxLmxlbmd0aCA8IHNpemUpIHtcblx0ICAgIGJ1ZmZlciQxID0gQnVmZmVyJDguYWxsb2Moc2l6ZSk7XG5cdCAgfVxuXHR9XG5cdC8qKlxuXHQgKiBTZXJpYWxpemUgYSBKYXZhc2NyaXB0IG9iamVjdC5cblx0ICpcblx0ICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCB0aGUgSmF2YXNjcmlwdCBvYmplY3QgdG8gc2VyaWFsaXplLlxuXHQgKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLmNoZWNrS2V5c10gdGhlIHNlcmlhbGl6ZXIgd2lsbCBjaGVjayBpZiBrZXlzIGFyZSB2YWxpZC5cblx0ICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5zZXJpYWxpemVGdW5jdGlvbnM9ZmFsc2VdIHNlcmlhbGl6ZSB0aGUgamF2YXNjcmlwdCBmdW5jdGlvbnMgKiooZGVmYXVsdDpmYWxzZSkqKi5cblx0ICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5pZ25vcmVVbmRlZmluZWQ9dHJ1ZV0gaWdub3JlIHVuZGVmaW5lZCBmaWVsZHMgKiooZGVmYXVsdDp0cnVlKSoqLlxuXHQgKiBAcmV0dXJuIHtCdWZmZXJ9IHJldHVybnMgdGhlIEJ1ZmZlciBvYmplY3QgY29udGFpbmluZyB0aGUgc2VyaWFsaXplZCBvYmplY3QuXG5cdCAqL1xuXG5cblx0ZnVuY3Rpb24gc2VyaWFsaXplJDEob2JqZWN0LCBvcHRpb25zKSB7XG5cdCAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307IC8vIFVucGFjayB0aGUgb3B0aW9uc1xuXG5cdCAgdmFyIGNoZWNrS2V5cyA9IHR5cGVvZiBvcHRpb25zLmNoZWNrS2V5cyA9PT0gJ2Jvb2xlYW4nID8gb3B0aW9ucy5jaGVja0tleXMgOiBmYWxzZTtcblx0ICB2YXIgc2VyaWFsaXplRnVuY3Rpb25zID0gdHlwZW9mIG9wdGlvbnMuc2VyaWFsaXplRnVuY3Rpb25zID09PSAnYm9vbGVhbicgPyBvcHRpb25zLnNlcmlhbGl6ZUZ1bmN0aW9ucyA6IGZhbHNlO1xuXHQgIHZhciBpZ25vcmVVbmRlZmluZWQgPSB0eXBlb2Ygb3B0aW9ucy5pZ25vcmVVbmRlZmluZWQgPT09ICdib29sZWFuJyA/IG9wdGlvbnMuaWdub3JlVW5kZWZpbmVkIDogdHJ1ZTtcblx0ICB2YXIgbWluSW50ZXJuYWxCdWZmZXJTaXplID0gdHlwZW9mIG9wdGlvbnMubWluSW50ZXJuYWxCdWZmZXJTaXplID09PSAnbnVtYmVyJyA/IG9wdGlvbnMubWluSW50ZXJuYWxCdWZmZXJTaXplIDogTUFYU0laRTsgLy8gUmVzaXplIHRoZSBpbnRlcm5hbCBzZXJpYWxpemF0aW9uIGJ1ZmZlciBpZiBuZWVkZWRcblxuXHQgIGlmIChidWZmZXIkMS5sZW5ndGggPCBtaW5JbnRlcm5hbEJ1ZmZlclNpemUpIHtcblx0ICAgIGJ1ZmZlciQxID0gQnVmZmVyJDguYWxsb2MobWluSW50ZXJuYWxCdWZmZXJTaXplKTtcblx0ICB9IC8vIEF0dGVtcHQgdG8gc2VyaWFsaXplXG5cblxuXHQgIHZhciBzZXJpYWxpemF0aW9uSW5kZXggPSBzZXJpYWxpemVyKGJ1ZmZlciQxLCBvYmplY3QsIGNoZWNrS2V5cywgMCwgMCwgc2VyaWFsaXplRnVuY3Rpb25zLCBpZ25vcmVVbmRlZmluZWQsIFtdKTsgLy8gQ3JlYXRlIHRoZSBmaW5hbCBidWZmZXJcblxuXHQgIHZhciBmaW5pc2hlZEJ1ZmZlciA9IEJ1ZmZlciQ4LmFsbG9jKHNlcmlhbGl6YXRpb25JbmRleCk7IC8vIENvcHkgaW50byB0aGUgZmluaXNoZWQgYnVmZmVyXG5cblx0ICBidWZmZXIkMS5jb3B5KGZpbmlzaGVkQnVmZmVyLCAwLCAwLCBmaW5pc2hlZEJ1ZmZlci5sZW5ndGgpOyAvLyBSZXR1cm4gdGhlIGJ1ZmZlclxuXG5cdCAgcmV0dXJuIGZpbmlzaGVkQnVmZmVyO1xuXHR9XG5cdC8qKlxuXHQgKiBTZXJpYWxpemUgYSBKYXZhc2NyaXB0IG9iamVjdCB1c2luZyBhIHByZWRlZmluZWQgQnVmZmVyIGFuZCBpbmRleCBpbnRvIHRoZSBidWZmZXIsIHVzZWZ1bCB3aGVuIHByZS1hbGxvY2F0aW5nIHRoZSBzcGFjZSBmb3Igc2VyaWFsaXphdGlvbi5cblx0ICpcblx0ICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCB0aGUgSmF2YXNjcmlwdCBvYmplY3QgdG8gc2VyaWFsaXplLlxuXHQgKiBAcGFyYW0ge0J1ZmZlcn0gYnVmZmVyIHRoZSBCdWZmZXIgeW91IHByZS1hbGxvY2F0ZWQgdG8gc3RvcmUgdGhlIHNlcmlhbGl6ZWQgQlNPTiBvYmplY3QuXG5cdCAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdGlvbnMuY2hlY2tLZXlzXSB0aGUgc2VyaWFsaXplciB3aWxsIGNoZWNrIGlmIGtleXMgYXJlIHZhbGlkLlxuXHQgKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLnNlcmlhbGl6ZUZ1bmN0aW9ucz1mYWxzZV0gc2VyaWFsaXplIHRoZSBqYXZhc2NyaXB0IGZ1bmN0aW9ucyAqKihkZWZhdWx0OmZhbHNlKSoqLlxuXHQgKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLmlnbm9yZVVuZGVmaW5lZD10cnVlXSBpZ25vcmUgdW5kZWZpbmVkIGZpZWxkcyAqKihkZWZhdWx0OnRydWUpKiouXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0aW9ucy5pbmRleF0gdGhlIGluZGV4IGluIHRoZSBidWZmZXIgd2hlcmUgd2Ugd2lzaCB0byBzdGFydCBzZXJpYWxpemluZyBpbnRvLlxuXHQgKiBAcmV0dXJuIHtOdW1iZXJ9IHJldHVybnMgdGhlIGluZGV4IHBvaW50aW5nIHRvIHRoZSBsYXN0IHdyaXR0ZW4gYnl0ZSBpbiB0aGUgYnVmZmVyLlxuXHQgKi9cblxuXG5cdGZ1bmN0aW9uIHNlcmlhbGl6ZVdpdGhCdWZmZXJBbmRJbmRleChvYmplY3QsIGZpbmFsQnVmZmVyLCBvcHRpb25zKSB7XG5cdCAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307IC8vIFVucGFjayB0aGUgb3B0aW9uc1xuXG5cdCAgdmFyIGNoZWNrS2V5cyA9IHR5cGVvZiBvcHRpb25zLmNoZWNrS2V5cyA9PT0gJ2Jvb2xlYW4nID8gb3B0aW9ucy5jaGVja0tleXMgOiBmYWxzZTtcblx0ICB2YXIgc2VyaWFsaXplRnVuY3Rpb25zID0gdHlwZW9mIG9wdGlvbnMuc2VyaWFsaXplRnVuY3Rpb25zID09PSAnYm9vbGVhbicgPyBvcHRpb25zLnNlcmlhbGl6ZUZ1bmN0aW9ucyA6IGZhbHNlO1xuXHQgIHZhciBpZ25vcmVVbmRlZmluZWQgPSB0eXBlb2Ygb3B0aW9ucy5pZ25vcmVVbmRlZmluZWQgPT09ICdib29sZWFuJyA/IG9wdGlvbnMuaWdub3JlVW5kZWZpbmVkIDogdHJ1ZTtcblx0ICB2YXIgc3RhcnRJbmRleCA9IHR5cGVvZiBvcHRpb25zLmluZGV4ID09PSAnbnVtYmVyJyA/IG9wdGlvbnMuaW5kZXggOiAwOyAvLyBBdHRlbXB0IHRvIHNlcmlhbGl6ZVxuXG5cdCAgdmFyIHNlcmlhbGl6YXRpb25JbmRleCA9IHNlcmlhbGl6ZXIoYnVmZmVyJDEsIG9iamVjdCwgY2hlY2tLZXlzLCAwLCAwLCBzZXJpYWxpemVGdW5jdGlvbnMsIGlnbm9yZVVuZGVmaW5lZCk7XG5cdCAgYnVmZmVyJDEuY29weShmaW5hbEJ1ZmZlciwgc3RhcnRJbmRleCwgMCwgc2VyaWFsaXphdGlvbkluZGV4KTsgLy8gUmV0dXJuIHRoZSBpbmRleFxuXG5cdCAgcmV0dXJuIHN0YXJ0SW5kZXggKyBzZXJpYWxpemF0aW9uSW5kZXggLSAxO1xuXHR9XG5cdC8qKlxuXHQgKiBEZXNlcmlhbGl6ZSBkYXRhIGFzIEJTT04uXG5cdCAqXG5cdCAqIEBwYXJhbSB7QnVmZmVyfSBidWZmZXIgdGhlIGJ1ZmZlciBjb250YWluaW5nIHRoZSBzZXJpYWxpemVkIHNldCBvZiBCU09OIGRvY3VtZW50cy5cblx0ICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLmV2YWxGdW5jdGlvbnM9ZmFsc2VdIGV2YWx1YXRlIGZ1bmN0aW9ucyBpbiB0aGUgQlNPTiBkb2N1bWVudCBzY29wZWQgdG8gdGhlIG9iamVjdCBkZXNlcmlhbGl6ZWQuXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5jYWNoZUZ1bmN0aW9ucz1mYWxzZV0gY2FjaGUgZXZhbHVhdGVkIGZ1bmN0aW9ucyBmb3IgcmV1c2UuXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5jYWNoZUZ1bmN0aW9uc0NyYzMyPWZhbHNlXSB1c2UgYSBjcmMzMiBjb2RlIGZvciBjYWNoaW5nLCBvdGhlcndpc2UgdXNlIHRoZSBzdHJpbmcgb2YgdGhlIGZ1bmN0aW9uLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMucHJvbW90ZUxvbmdzPXRydWVdIHdoZW4gZGVzZXJpYWxpemluZyBhIExvbmcgd2lsbCBmaXQgaXQgaW50byBhIE51bWJlciBpZiBpdCdzIHNtYWxsZXIgdGhhbiA1MyBiaXRzXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5wcm9tb3RlQnVmZmVycz1mYWxzZV0gd2hlbiBkZXNlcmlhbGl6aW5nIGEgQmluYXJ5IHdpbGwgcmV0dXJuIGl0IGFzIGEgbm9kZS5qcyBCdWZmZXIgaW5zdGFuY2UuXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5wcm9tb3RlVmFsdWVzPWZhbHNlXSB3aGVuIGRlc2VyaWFsaXppbmcgd2lsbCBwcm9tb3RlIEJTT04gdmFsdWVzIHRvIHRoZWlyIE5vZGUuanMgY2xvc2VzdCBlcXVpdmFsZW50IHR5cGVzLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMuZmllbGRzQXNSYXc9bnVsbF0gYWxsb3cgdG8gc3BlY2lmeSBpZiB0aGVyZSB3aGF0IGZpZWxkcyB3ZSB3aXNoIHRvIHJldHVybiBhcyB1bnNlcmlhbGl6ZWQgcmF3IGJ1ZmZlci5cblx0ICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLmJzb25SZWdFeHA9ZmFsc2VdIHJldHVybiBCU09OIHJlZ3VsYXIgZXhwcmVzc2lvbnMgYXMgQlNPTlJlZ0V4cCBpbnN0YW5jZXMuXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMuYWxsb3dPYmplY3RTbWFsbGVyVGhhbkJ1ZmZlclNpemU9ZmFsc2VdIGFsbG93cyB0aGUgYnVmZmVyIHRvIGJlIGxhcmdlciB0aGFuIHRoZSBwYXJzZWQgQlNPTiBvYmplY3Rcblx0ICogQHJldHVybiB7T2JqZWN0fSByZXR1cm5zIHRoZSBkZXNlcmlhbGl6ZWQgSmF2YXNjcmlwdCBPYmplY3QuXG5cdCAqL1xuXG5cblx0ZnVuY3Rpb24gZGVzZXJpYWxpemUkMihidWZmZXIkJDEsIG9wdGlvbnMpIHtcblx0ICBidWZmZXIkJDEgPSBlbnN1cmVfYnVmZmVyKGJ1ZmZlciQkMSk7XG5cdCAgcmV0dXJuIGRlc2VyaWFsaXplcihidWZmZXIkJDEsIG9wdGlvbnMpO1xuXHR9XG5cdC8qKlxuXHQgKiBDYWxjdWxhdGUgdGhlIGJzb24gc2l6ZSBmb3IgYSBwYXNzZWQgaW4gSmF2YXNjcmlwdCBvYmplY3QuXG5cdCAqXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgdGhlIEphdmFzY3JpcHQgb2JqZWN0IHRvIGNhbGN1bGF0ZSB0aGUgQlNPTiBieXRlIHNpemUgZm9yLlxuXHQgKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLnNlcmlhbGl6ZUZ1bmN0aW9ucz1mYWxzZV0gc2VyaWFsaXplIHRoZSBqYXZhc2NyaXB0IGZ1bmN0aW9ucyAqKihkZWZhdWx0OmZhbHNlKSoqLlxuXHQgKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLmlnbm9yZVVuZGVmaW5lZD10cnVlXSBpZ25vcmUgdW5kZWZpbmVkIGZpZWxkcyAqKihkZWZhdWx0OnRydWUpKiouXG5cdCAqIEByZXR1cm4ge051bWJlcn0gcmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoZSBCU09OIG9iamVjdCB3aWxsIHRha2UgdXAuXG5cdCAqL1xuXG5cblx0ZnVuY3Rpb24gY2FsY3VsYXRlT2JqZWN0U2l6ZSQxKG9iamVjdCwgb3B0aW9ucykge1xuXHQgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXHQgIHZhciBzZXJpYWxpemVGdW5jdGlvbnMgPSB0eXBlb2Ygb3B0aW9ucy5zZXJpYWxpemVGdW5jdGlvbnMgPT09ICdib29sZWFuJyA/IG9wdGlvbnMuc2VyaWFsaXplRnVuY3Rpb25zIDogZmFsc2U7XG5cdCAgdmFyIGlnbm9yZVVuZGVmaW5lZCA9IHR5cGVvZiBvcHRpb25zLmlnbm9yZVVuZGVmaW5lZCA9PT0gJ2Jvb2xlYW4nID8gb3B0aW9ucy5pZ25vcmVVbmRlZmluZWQgOiB0cnVlO1xuXHQgIHJldHVybiBjYWxjdWxhdGVfc2l6ZShvYmplY3QsIHNlcmlhbGl6ZUZ1bmN0aW9ucywgaWdub3JlVW5kZWZpbmVkKTtcblx0fVxuXHQvKipcblx0ICogRGVzZXJpYWxpemUgc3RyZWFtIGRhdGEgYXMgQlNPTiBkb2N1bWVudHMuXG5cdCAqXG5cdCAqIEBwYXJhbSB7QnVmZmVyfSBkYXRhIHRoZSBidWZmZXIgY29udGFpbmluZyB0aGUgc2VyaWFsaXplZCBzZXQgb2YgQlNPTiBkb2N1bWVudHMuXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBzdGFydEluZGV4IHRoZSBzdGFydCBpbmRleCBpbiB0aGUgZGF0YSBCdWZmZXIgd2hlcmUgdGhlIGRlc2VyaWFsaXphdGlvbiBpcyB0byBzdGFydC5cblx0ICogQHBhcmFtIHtOdW1iZXJ9IG51bWJlck9mRG9jdW1lbnRzIG51bWJlciBvZiBkb2N1bWVudHMgdG8gZGVzZXJpYWxpemUuXG5cdCAqIEBwYXJhbSB7QXJyYXl9IGRvY3VtZW50cyBhbiBhcnJheSB3aGVyZSB0byBzdG9yZSB0aGUgZGVzZXJpYWxpemVkIGRvY3VtZW50cy5cblx0ICogQHBhcmFtIHtOdW1iZXJ9IGRvY1N0YXJ0SW5kZXggdGhlIGluZGV4IGluIHRoZSBkb2N1bWVudHMgYXJyYXkgZnJvbSB3aGVyZSB0byBzdGFydCBpbnNlcnRpbmcgZG9jdW1lbnRzLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIGFkZGl0aW9uYWwgb3B0aW9ucyB1c2VkIGZvciB0aGUgZGVzZXJpYWxpemF0aW9uLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMuZXZhbEZ1bmN0aW9ucz1mYWxzZV0gZXZhbHVhdGUgZnVuY3Rpb25zIGluIHRoZSBCU09OIGRvY3VtZW50IHNjb3BlZCB0byB0aGUgb2JqZWN0IGRlc2VyaWFsaXplZC5cblx0ICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLmNhY2hlRnVuY3Rpb25zPWZhbHNlXSBjYWNoZSBldmFsdWF0ZWQgZnVuY3Rpb25zIGZvciByZXVzZS5cblx0ICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLmNhY2hlRnVuY3Rpb25zQ3JjMzI9ZmFsc2VdIHVzZSBhIGNyYzMyIGNvZGUgZm9yIGNhY2hpbmcsIG90aGVyd2lzZSB1c2UgdGhlIHN0cmluZyBvZiB0aGUgZnVuY3Rpb24uXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5wcm9tb3RlTG9uZ3M9dHJ1ZV0gd2hlbiBkZXNlcmlhbGl6aW5nIGEgTG9uZyB3aWxsIGZpdCBpdCBpbnRvIGEgTnVtYmVyIGlmIGl0J3Mgc21hbGxlciB0aGFuIDUzIGJpdHNcblx0ICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLnByb21vdGVCdWZmZXJzPWZhbHNlXSB3aGVuIGRlc2VyaWFsaXppbmcgYSBCaW5hcnkgd2lsbCByZXR1cm4gaXQgYXMgYSBub2RlLmpzIEJ1ZmZlciBpbnN0YW5jZS5cblx0ICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLnByb21vdGVWYWx1ZXM9ZmFsc2VdIHdoZW4gZGVzZXJpYWxpemluZyB3aWxsIHByb21vdGUgQlNPTiB2YWx1ZXMgdG8gdGhlaXIgTm9kZS5qcyBjbG9zZXN0IGVxdWl2YWxlbnQgdHlwZXMuXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5maWVsZHNBc1Jhdz1udWxsXSBhbGxvdyB0byBzcGVjaWZ5IGlmIHRoZXJlIHdoYXQgZmllbGRzIHdlIHdpc2ggdG8gcmV0dXJuIGFzIHVuc2VyaWFsaXplZCByYXcgYnVmZmVyLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMuYnNvblJlZ0V4cD1mYWxzZV0gcmV0dXJuIEJTT04gcmVndWxhciBleHByZXNzaW9ucyBhcyBCU09OUmVnRXhwIGluc3RhbmNlcy5cblx0ICogQHJldHVybiB7TnVtYmVyfSByZXR1cm5zIHRoZSBuZXh0IGluZGV4IGluIHRoZSBidWZmZXIgYWZ0ZXIgZGVzZXJpYWxpemF0aW9uICoqeCoqIG51bWJlcnMgb2YgZG9jdW1lbnRzLlxuXHQgKi9cblxuXG5cdGZ1bmN0aW9uIGRlc2VyaWFsaXplU3RyZWFtKGRhdGEsIHN0YXJ0SW5kZXgsIG51bWJlck9mRG9jdW1lbnRzLCBkb2N1bWVudHMsIGRvY1N0YXJ0SW5kZXgsIG9wdGlvbnMpIHtcblx0ICBvcHRpb25zID0gT2JqZWN0LmFzc2lnbih7XG5cdCAgICBhbGxvd09iamVjdFNtYWxsZXJUaGFuQnVmZmVyU2l6ZTogdHJ1ZVxuXHQgIH0sIG9wdGlvbnMpO1xuXHQgIGRhdGEgPSBlbnN1cmVfYnVmZmVyKGRhdGEpO1xuXHQgIHZhciBpbmRleCA9IHN0YXJ0SW5kZXg7IC8vIExvb3Agb3ZlciBhbGwgZG9jdW1lbnRzXG5cblx0ICBmb3IgKHZhciBpID0gMDsgaSA8IG51bWJlck9mRG9jdW1lbnRzOyBpKyspIHtcblx0ICAgIC8vIEZpbmQgc2l6ZSBvZiB0aGUgZG9jdW1lbnRcblx0ICAgIHZhciBzaXplID0gZGF0YVtpbmRleF0gfCBkYXRhW2luZGV4ICsgMV0gPDwgOCB8IGRhdGFbaW5kZXggKyAyXSA8PCAxNiB8IGRhdGFbaW5kZXggKyAzXSA8PCAyNDsgLy8gVXBkYXRlIG9wdGlvbnMgd2l0aCBpbmRleFxuXG5cdCAgICBvcHRpb25zLmluZGV4ID0gaW5kZXg7IC8vIFBhcnNlIHRoZSBkb2N1bWVudCBhdCB0aGlzIHBvaW50XG5cblx0ICAgIGRvY3VtZW50c1tkb2NTdGFydEluZGV4ICsgaV0gPSBkZXNlcmlhbGl6ZXIoZGF0YSwgb3B0aW9ucyk7IC8vIEFkanVzdCBpbmRleCBieSB0aGUgZG9jdW1lbnQgc2l6ZVxuXG5cdCAgICBpbmRleCA9IGluZGV4ICsgc2l6ZTtcblx0ICB9IC8vIFJldHVybiBvYmplY3QgY29udGFpbmluZyBlbmQgaW5kZXggb2YgcGFyc2luZyBhbmQgbGlzdCBvZiBkb2N1bWVudHNcblxuXG5cdCAgcmV0dXJuIGluZGV4O1xuXHR9XG5cblx0dmFyIGJzb24gPSB7XG5cdCAgLy8gY29uc3RhbnRzXG5cdCAgLy8gTk9URTogdGhpcyBpcyBkb25lIHRoaXMgd2F5IGJlY2F1c2Ugcm9sbHVwIGNhbid0IHJlc29sdmUgYW4gYE9iamVjdC5hc3NpZ25gZWQgZXhwb3J0XG5cdCAgQlNPTl9JTlQzMl9NQVg6IGNvbnN0YW50cy5CU09OX0lOVDMyX01BWCxcblx0ICBCU09OX0lOVDMyX01JTjogY29uc3RhbnRzLkJTT05fSU5UMzJfTUlOLFxuXHQgIEJTT05fSU5UNjRfTUFYOiBjb25zdGFudHMuQlNPTl9JTlQ2NF9NQVgsXG5cdCAgQlNPTl9JTlQ2NF9NSU46IGNvbnN0YW50cy5CU09OX0lOVDY0X01JTixcblx0ICBKU19JTlRfTUFYOiBjb25zdGFudHMuSlNfSU5UX01BWCxcblx0ICBKU19JTlRfTUlOOiBjb25zdGFudHMuSlNfSU5UX01JTixcblx0ICBCU09OX0RBVEFfTlVNQkVSOiBjb25zdGFudHMuQlNPTl9EQVRBX05VTUJFUixcblx0ICBCU09OX0RBVEFfU1RSSU5HOiBjb25zdGFudHMuQlNPTl9EQVRBX1NUUklORyxcblx0ICBCU09OX0RBVEFfT0JKRUNUOiBjb25zdGFudHMuQlNPTl9EQVRBX09CSkVDVCxcblx0ICBCU09OX0RBVEFfQVJSQVk6IGNvbnN0YW50cy5CU09OX0RBVEFfQVJSQVksXG5cdCAgQlNPTl9EQVRBX0JJTkFSWTogY29uc3RhbnRzLkJTT05fREFUQV9CSU5BUlksXG5cdCAgQlNPTl9EQVRBX1VOREVGSU5FRDogY29uc3RhbnRzLkJTT05fREFUQV9VTkRFRklORUQsXG5cdCAgQlNPTl9EQVRBX09JRDogY29uc3RhbnRzLkJTT05fREFUQV9PSUQsXG5cdCAgQlNPTl9EQVRBX0JPT0xFQU46IGNvbnN0YW50cy5CU09OX0RBVEFfQk9PTEVBTixcblx0ICBCU09OX0RBVEFfREFURTogY29uc3RhbnRzLkJTT05fREFUQV9EQVRFLFxuXHQgIEJTT05fREFUQV9OVUxMOiBjb25zdGFudHMuQlNPTl9EQVRBX05VTEwsXG5cdCAgQlNPTl9EQVRBX1JFR0VYUDogY29uc3RhbnRzLkJTT05fREFUQV9SRUdFWFAsXG5cdCAgQlNPTl9EQVRBX0RCUE9JTlRFUjogY29uc3RhbnRzLkJTT05fREFUQV9EQlBPSU5URVIsXG5cdCAgQlNPTl9EQVRBX0NPREU6IGNvbnN0YW50cy5CU09OX0RBVEFfQ09ERSxcblx0ICBCU09OX0RBVEFfU1lNQk9MOiBjb25zdGFudHMuQlNPTl9EQVRBX1NZTUJPTCxcblx0ICBCU09OX0RBVEFfQ09ERV9XX1NDT1BFOiBjb25zdGFudHMuQlNPTl9EQVRBX0NPREVfV19TQ09QRSxcblx0ICBCU09OX0RBVEFfSU5UOiBjb25zdGFudHMuQlNPTl9EQVRBX0lOVCxcblx0ICBCU09OX0RBVEFfVElNRVNUQU1QOiBjb25zdGFudHMuQlNPTl9EQVRBX1RJTUVTVEFNUCxcblx0ICBCU09OX0RBVEFfTE9ORzogY29uc3RhbnRzLkJTT05fREFUQV9MT05HLFxuXHQgIEJTT05fREFUQV9ERUNJTUFMMTI4OiBjb25zdGFudHMuQlNPTl9EQVRBX0RFQ0lNQUwxMjgsXG5cdCAgQlNPTl9EQVRBX01JTl9LRVk6IGNvbnN0YW50cy5CU09OX0RBVEFfTUlOX0tFWSxcblx0ICBCU09OX0RBVEFfTUFYX0tFWTogY29uc3RhbnRzLkJTT05fREFUQV9NQVhfS0VZLFxuXHQgIEJTT05fQklOQVJZX1NVQlRZUEVfREVGQVVMVDogY29uc3RhbnRzLkJTT05fQklOQVJZX1NVQlRZUEVfREVGQVVMVCxcblx0ICBCU09OX0JJTkFSWV9TVUJUWVBFX0ZVTkNUSU9OOiBjb25zdGFudHMuQlNPTl9CSU5BUllfU1VCVFlQRV9GVU5DVElPTixcblx0ICBCU09OX0JJTkFSWV9TVUJUWVBFX0JZVEVfQVJSQVk6IGNvbnN0YW50cy5CU09OX0JJTkFSWV9TVUJUWVBFX0JZVEVfQVJSQVksXG5cdCAgQlNPTl9CSU5BUllfU1VCVFlQRV9VVUlEOiBjb25zdGFudHMuQlNPTl9CSU5BUllfU1VCVFlQRV9VVUlELFxuXHQgIEJTT05fQklOQVJZX1NVQlRZUEVfTUQ1OiBjb25zdGFudHMuQlNPTl9CSU5BUllfU1VCVFlQRV9NRDUsXG5cdCAgQlNPTl9CSU5BUllfU1VCVFlQRV9VU0VSX0RFRklORUQ6IGNvbnN0YW50cy5CU09OX0JJTkFSWV9TVUJUWVBFX1VTRVJfREVGSU5FRCxcblx0ICAvLyB3cmFwcGVkIHR5cGVzXG5cdCAgQ29kZTogY29kZSxcblx0ICBNYXA6IG1hcCxcblx0ICBCU09OU3ltYm9sOiBzeW1ib2wsXG5cdCAgREJSZWY6IGRiX3JlZixcblx0ICBCaW5hcnk6IGJpbmFyeSxcblx0ICBPYmplY3RJZDogb2JqZWN0aWQsXG5cdCAgTG9uZzogbG9uZ18xLFxuXHQgIFRpbWVzdGFtcDogdGltZXN0YW1wLFxuXHQgIERvdWJsZTogZG91YmxlXzEsXG5cdCAgSW50MzI6IGludF8zMixcblx0ICBNaW5LZXk6IG1pbl9rZXksXG5cdCAgTWF4S2V5OiBtYXhfa2V5LFxuXHQgIEJTT05SZWdFeHA6IHJlZ2V4cCxcblx0ICBEZWNpbWFsMTI4OiBkZWNpbWFsMTI4LFxuXHQgIC8vIG1ldGhvZHNcblx0ICBzZXJpYWxpemU6IHNlcmlhbGl6ZSQxLFxuXHQgIHNlcmlhbGl6ZVdpdGhCdWZmZXJBbmRJbmRleDogc2VyaWFsaXplV2l0aEJ1ZmZlckFuZEluZGV4LFxuXHQgIGRlc2VyaWFsaXplOiBkZXNlcmlhbGl6ZSQyLFxuXHQgIGNhbGN1bGF0ZU9iamVjdFNpemU6IGNhbGN1bGF0ZU9iamVjdFNpemUkMSxcblx0ICBkZXNlcmlhbGl6ZVN0cmVhbTogZGVzZXJpYWxpemVTdHJlYW0sXG5cdCAgc2V0SW50ZXJuYWxCdWZmZXJTaXplOiBzZXRJbnRlcm5hbEJ1ZmZlclNpemUsXG5cdCAgLy8gbGVnYWN5IHN1cHBvcnRcblx0ICBPYmplY3RJRDogb2JqZWN0aWQsXG5cdCAgLy8gRXh0ZW5kZWQgSlNPTlxuXHQgIEVKU09OOiBleHRlbmRlZF9qc29uXG5cdH07XG5cdHZhciBic29uXzEgPSBic29uLkJTT05fSU5UMzJfTUFYO1xuXHR2YXIgYnNvbl8yID0gYnNvbi5CU09OX0lOVDMyX01JTjtcblx0dmFyIGJzb25fMyA9IGJzb24uQlNPTl9JTlQ2NF9NQVg7XG5cdHZhciBic29uXzQgPSBic29uLkJTT05fSU5UNjRfTUlOO1xuXHR2YXIgYnNvbl81ID0gYnNvbi5KU19JTlRfTUFYO1xuXHR2YXIgYnNvbl82ID0gYnNvbi5KU19JTlRfTUlOO1xuXHR2YXIgYnNvbl83ID0gYnNvbi5CU09OX0RBVEFfTlVNQkVSO1xuXHR2YXIgYnNvbl84ID0gYnNvbi5CU09OX0RBVEFfU1RSSU5HO1xuXHR2YXIgYnNvbl85ID0gYnNvbi5CU09OX0RBVEFfT0JKRUNUO1xuXHR2YXIgYnNvbl8xMCA9IGJzb24uQlNPTl9EQVRBX0FSUkFZO1xuXHR2YXIgYnNvbl8xMSA9IGJzb24uQlNPTl9EQVRBX0JJTkFSWTtcblx0dmFyIGJzb25fMTIgPSBic29uLkJTT05fREFUQV9VTkRFRklORUQ7XG5cdHZhciBic29uXzEzID0gYnNvbi5CU09OX0RBVEFfT0lEO1xuXHR2YXIgYnNvbl8xNCA9IGJzb24uQlNPTl9EQVRBX0JPT0xFQU47XG5cdHZhciBic29uXzE1ID0gYnNvbi5CU09OX0RBVEFfREFURTtcblx0dmFyIGJzb25fMTYgPSBic29uLkJTT05fREFUQV9OVUxMO1xuXHR2YXIgYnNvbl8xNyA9IGJzb24uQlNPTl9EQVRBX1JFR0VYUDtcblx0dmFyIGJzb25fMTggPSBic29uLkJTT05fREFUQV9EQlBPSU5URVI7XG5cdHZhciBic29uXzE5ID0gYnNvbi5CU09OX0RBVEFfQ09ERTtcblx0dmFyIGJzb25fMjAgPSBic29uLkJTT05fREFUQV9TWU1CT0w7XG5cdHZhciBic29uXzIxID0gYnNvbi5CU09OX0RBVEFfQ09ERV9XX1NDT1BFO1xuXHR2YXIgYnNvbl8yMiA9IGJzb24uQlNPTl9EQVRBX0lOVDtcblx0dmFyIGJzb25fMjMgPSBic29uLkJTT05fREFUQV9USU1FU1RBTVA7XG5cdHZhciBic29uXzI0ID0gYnNvbi5CU09OX0RBVEFfTE9ORztcblx0dmFyIGJzb25fMjUgPSBic29uLkJTT05fREFUQV9ERUNJTUFMMTI4O1xuXHR2YXIgYnNvbl8yNiA9IGJzb24uQlNPTl9EQVRBX01JTl9LRVk7XG5cdHZhciBic29uXzI3ID0gYnNvbi5CU09OX0RBVEFfTUFYX0tFWTtcblx0dmFyIGJzb25fMjggPSBic29uLkJTT05fQklOQVJZX1NVQlRZUEVfREVGQVVMVDtcblx0dmFyIGJzb25fMjkgPSBic29uLkJTT05fQklOQVJZX1NVQlRZUEVfRlVOQ1RJT047XG5cdHZhciBic29uXzMwID0gYnNvbi5CU09OX0JJTkFSWV9TVUJUWVBFX0JZVEVfQVJSQVk7XG5cdHZhciBic29uXzMxID0gYnNvbi5CU09OX0JJTkFSWV9TVUJUWVBFX1VVSUQ7XG5cdHZhciBic29uXzMyID0gYnNvbi5CU09OX0JJTkFSWV9TVUJUWVBFX01ENTtcblx0dmFyIGJzb25fMzMgPSBic29uLkJTT05fQklOQVJZX1NVQlRZUEVfVVNFUl9ERUZJTkVEO1xuXHR2YXIgYnNvbl8zNCA9IGJzb24uQ29kZTtcblx0dmFyIGJzb25fMzUgPSBic29uLkJTT05TeW1ib2w7XG5cdHZhciBic29uXzM2ID0gYnNvbi5EQlJlZjtcblx0dmFyIGJzb25fMzcgPSBic29uLkJpbmFyeTtcblx0dmFyIGJzb25fMzggPSBic29uLk9iamVjdElkO1xuXHR2YXIgYnNvbl8zOSA9IGJzb24uTG9uZztcblx0dmFyIGJzb25fNDAgPSBic29uLlRpbWVzdGFtcDtcblx0dmFyIGJzb25fNDEgPSBic29uLkRvdWJsZTtcblx0dmFyIGJzb25fNDIgPSBic29uLkludDMyO1xuXHR2YXIgYnNvbl80MyA9IGJzb24uTWluS2V5O1xuXHR2YXIgYnNvbl80NCA9IGJzb24uTWF4S2V5O1xuXHR2YXIgYnNvbl80NSA9IGJzb24uQlNPTlJlZ0V4cDtcblx0dmFyIGJzb25fNDYgPSBic29uLkRlY2ltYWwxMjg7XG5cdHZhciBic29uXzQ3ID0gYnNvbi5zZXJpYWxpemU7XG5cdHZhciBic29uXzQ4ID0gYnNvbi5zZXJpYWxpemVXaXRoQnVmZmVyQW5kSW5kZXg7XG5cdHZhciBic29uXzQ5ID0gYnNvbi5kZXNlcmlhbGl6ZTtcblx0dmFyIGJzb25fNTAgPSBic29uLmNhbGN1bGF0ZU9iamVjdFNpemU7XG5cdHZhciBic29uXzUxID0gYnNvbi5kZXNlcmlhbGl6ZVN0cmVhbTtcblx0dmFyIGJzb25fNTIgPSBic29uLnNldEludGVybmFsQnVmZmVyU2l6ZTtcblx0dmFyIGJzb25fNTMgPSBic29uLk9iamVjdElEO1xuXHR2YXIgYnNvbl81NCA9IGJzb24uRUpTT047XG5cblx0ZXhwb3J0cy5kZWZhdWx0ID0gYnNvbjtcblx0ZXhwb3J0cy5CU09OX0lOVDMyX01BWCA9IGJzb25fMTtcblx0ZXhwb3J0cy5CU09OX0lOVDMyX01JTiA9IGJzb25fMjtcblx0ZXhwb3J0cy5CU09OX0lOVDY0X01BWCA9IGJzb25fMztcblx0ZXhwb3J0cy5CU09OX0lOVDY0X01JTiA9IGJzb25fNDtcblx0ZXhwb3J0cy5KU19JTlRfTUFYID0gYnNvbl81O1xuXHRleHBvcnRzLkpTX0lOVF9NSU4gPSBic29uXzY7XG5cdGV4cG9ydHMuQlNPTl9EQVRBX05VTUJFUiA9IGJzb25fNztcblx0ZXhwb3J0cy5CU09OX0RBVEFfU1RSSU5HID0gYnNvbl84O1xuXHRleHBvcnRzLkJTT05fREFUQV9PQkpFQ1QgPSBic29uXzk7XG5cdGV4cG9ydHMuQlNPTl9EQVRBX0FSUkFZID0gYnNvbl8xMDtcblx0ZXhwb3J0cy5CU09OX0RBVEFfQklOQVJZID0gYnNvbl8xMTtcblx0ZXhwb3J0cy5CU09OX0RBVEFfVU5ERUZJTkVEID0gYnNvbl8xMjtcblx0ZXhwb3J0cy5CU09OX0RBVEFfT0lEID0gYnNvbl8xMztcblx0ZXhwb3J0cy5CU09OX0RBVEFfQk9PTEVBTiA9IGJzb25fMTQ7XG5cdGV4cG9ydHMuQlNPTl9EQVRBX0RBVEUgPSBic29uXzE1O1xuXHRleHBvcnRzLkJTT05fREFUQV9OVUxMID0gYnNvbl8xNjtcblx0ZXhwb3J0cy5CU09OX0RBVEFfUkVHRVhQID0gYnNvbl8xNztcblx0ZXhwb3J0cy5CU09OX0RBVEFfREJQT0lOVEVSID0gYnNvbl8xODtcblx0ZXhwb3J0cy5CU09OX0RBVEFfQ09ERSA9IGJzb25fMTk7XG5cdGV4cG9ydHMuQlNPTl9EQVRBX1NZTUJPTCA9IGJzb25fMjA7XG5cdGV4cG9ydHMuQlNPTl9EQVRBX0NPREVfV19TQ09QRSA9IGJzb25fMjE7XG5cdGV4cG9ydHMuQlNPTl9EQVRBX0lOVCA9IGJzb25fMjI7XG5cdGV4cG9ydHMuQlNPTl9EQVRBX1RJTUVTVEFNUCA9IGJzb25fMjM7XG5cdGV4cG9ydHMuQlNPTl9EQVRBX0xPTkcgPSBic29uXzI0O1xuXHRleHBvcnRzLkJTT05fREFUQV9ERUNJTUFMMTI4ID0gYnNvbl8yNTtcblx0ZXhwb3J0cy5CU09OX0RBVEFfTUlOX0tFWSA9IGJzb25fMjY7XG5cdGV4cG9ydHMuQlNPTl9EQVRBX01BWF9LRVkgPSBic29uXzI3O1xuXHRleHBvcnRzLkJTT05fQklOQVJZX1NVQlRZUEVfREVGQVVMVCA9IGJzb25fMjg7XG5cdGV4cG9ydHMuQlNPTl9CSU5BUllfU1VCVFlQRV9GVU5DVElPTiA9IGJzb25fMjk7XG5cdGV4cG9ydHMuQlNPTl9CSU5BUllfU1VCVFlQRV9CWVRFX0FSUkFZID0gYnNvbl8zMDtcblx0ZXhwb3J0cy5CU09OX0JJTkFSWV9TVUJUWVBFX1VVSUQgPSBic29uXzMxO1xuXHRleHBvcnRzLkJTT05fQklOQVJZX1NVQlRZUEVfTUQ1ID0gYnNvbl8zMjtcblx0ZXhwb3J0cy5CU09OX0JJTkFSWV9TVUJUWVBFX1VTRVJfREVGSU5FRCA9IGJzb25fMzM7XG5cdGV4cG9ydHMuQ29kZSA9IGJzb25fMzQ7XG5cdGV4cG9ydHMuQlNPTlN5bWJvbCA9IGJzb25fMzU7XG5cdGV4cG9ydHMuREJSZWYgPSBic29uXzM2O1xuXHRleHBvcnRzLkJpbmFyeSA9IGJzb25fMzc7XG5cdGV4cG9ydHMuT2JqZWN0SWQgPSBic29uXzM4O1xuXHRleHBvcnRzLkxvbmcgPSBic29uXzM5O1xuXHRleHBvcnRzLlRpbWVzdGFtcCA9IGJzb25fNDA7XG5cdGV4cG9ydHMuRG91YmxlID0gYnNvbl80MTtcblx0ZXhwb3J0cy5JbnQzMiA9IGJzb25fNDI7XG5cdGV4cG9ydHMuTWluS2V5ID0gYnNvbl80Mztcblx0ZXhwb3J0cy5NYXhLZXkgPSBic29uXzQ0O1xuXHRleHBvcnRzLkJTT05SZWdFeHAgPSBic29uXzQ1O1xuXHRleHBvcnRzLkRlY2ltYWwxMjggPSBic29uXzQ2O1xuXHRleHBvcnRzLnNlcmlhbGl6ZSA9IGJzb25fNDc7XG5cdGV4cG9ydHMuc2VyaWFsaXplV2l0aEJ1ZmZlckFuZEluZGV4ID0gYnNvbl80ODtcblx0ZXhwb3J0cy5kZXNlcmlhbGl6ZSA9IGJzb25fNDk7XG5cdGV4cG9ydHMuY2FsY3VsYXRlT2JqZWN0U2l6ZSA9IGJzb25fNTA7XG5cdGV4cG9ydHMuZGVzZXJpYWxpemVTdHJlYW0gPSBic29uXzUxO1xuXHRleHBvcnRzLnNldEludGVybmFsQnVmZmVyU2l6ZSA9IGJzb25fNTI7XG5cdGV4cG9ydHMuT2JqZWN0SUQgPSBic29uXzUzO1xuXHRleHBvcnRzLkVKU09OID0gYnNvbl81NDtcblxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG59KSkpO1xuXG4vKiBXRUJQQUNLIFZBUiBJTkpFQ1RJT04gKi99LmNhbGwoZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXygwKSwgX193ZWJwYWNrX3JlcXVpcmVfXygxKS5CdWZmZXIpKVxuXG4vKioqLyB9KSxcbi8qIDMgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXCJ1c2Ugc3RyaWN0XCI7XG5cblxuZXhwb3J0cy5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuZXhwb3J0cy50b0J5dGVBcnJheSA9IHRvQnl0ZUFycmF5XG5leHBvcnRzLmZyb21CeXRlQXJyYXkgPSBmcm9tQnl0ZUFycmF5XG5cbnZhciBsb29rdXAgPSBbXVxudmFyIHJldkxvb2t1cCA9IFtdXG52YXIgQXJyID0gdHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnID8gVWludDhBcnJheSA6IEFycmF5XG5cbnZhciBjb2RlID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nXG5mb3IgKHZhciBpID0gMCwgbGVuID0gY29kZS5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICBsb29rdXBbaV0gPSBjb2RlW2ldXG4gIHJldkxvb2t1cFtjb2RlLmNoYXJDb2RlQXQoaSldID0gaVxufVxuXG4vLyBTdXBwb3J0IGRlY29kaW5nIFVSTC1zYWZlIGJhc2U2NCBzdHJpbmdzLCBhcyBOb2RlLmpzIGRvZXMuXG4vLyBTZWU6IGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Jhc2U2NCNVUkxfYXBwbGljYXRpb25zXG5yZXZMb29rdXBbJy0nLmNoYXJDb2RlQXQoMCldID0gNjJcbnJldkxvb2t1cFsnXycuY2hhckNvZGVBdCgwKV0gPSA2M1xuXG5mdW5jdGlvbiBnZXRMZW5zIChiNjQpIHtcbiAgdmFyIGxlbiA9IGI2NC5sZW5ndGhcblxuICBpZiAobGVuICUgNCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnKVxuICB9XG5cbiAgLy8gVHJpbSBvZmYgZXh0cmEgYnl0ZXMgYWZ0ZXIgcGxhY2Vob2xkZXIgYnl0ZXMgYXJlIGZvdW5kXG4gIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2JlYXRnYW1taXQvYmFzZTY0LWpzL2lzc3Vlcy80MlxuICB2YXIgdmFsaWRMZW4gPSBiNjQuaW5kZXhPZignPScpXG4gIGlmICh2YWxpZExlbiA9PT0gLTEpIHZhbGlkTGVuID0gbGVuXG5cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IHZhbGlkTGVuID09PSBsZW5cbiAgICA/IDBcbiAgICA6IDQgLSAodmFsaWRMZW4gJSA0KVxuXG4gIHJldHVybiBbdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbl1cbn1cblxuLy8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChiNjQpIHtcbiAgdmFyIGxlbnMgPSBnZXRMZW5zKGI2NClcbiAgdmFyIHZhbGlkTGVuID0gbGVuc1swXVxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gbGVuc1sxXVxuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gX2J5dGVMZW5ndGggKGI2NCwgdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbikge1xuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gdG9CeXRlQXJyYXkgKGI2NCkge1xuICB2YXIgdG1wXG4gIHZhciBsZW5zID0gZ2V0TGVucyhiNjQpXG4gIHZhciB2YWxpZExlbiA9IGxlbnNbMF1cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IGxlbnNbMV1cblxuICB2YXIgYXJyID0gbmV3IEFycihfYnl0ZUxlbmd0aChiNjQsIHZhbGlkTGVuLCBwbGFjZUhvbGRlcnNMZW4pKVxuXG4gIHZhciBjdXJCeXRlID0gMFxuXG4gIC8vIGlmIHRoZXJlIGFyZSBwbGFjZWhvbGRlcnMsIG9ubHkgZ2V0IHVwIHRvIHRoZSBsYXN0IGNvbXBsZXRlIDQgY2hhcnNcbiAgdmFyIGxlbiA9IHBsYWNlSG9sZGVyc0xlbiA+IDBcbiAgICA/IHZhbGlkTGVuIC0gNFxuICAgIDogdmFsaWRMZW5cblxuICB2YXIgaVxuICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpICs9IDQpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTgpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCAxMikgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMildIDw8IDYpIHxcbiAgICAgIHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMyldXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDE2KSAmIDB4RkZcbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gOCkgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICBpZiAocGxhY2VIb2xkZXJzTGVuID09PSAyKSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDIpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA+PiA0KVxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgaWYgKHBsYWNlSG9sZGVyc0xlbiA9PT0gMSkge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAxMCkgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMSldIDw8IDQpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA+PiAyKVxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiA4KSAmIDB4RkZcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBhcnJcbn1cblxuZnVuY3Rpb24gdHJpcGxldFRvQmFzZTY0IChudW0pIHtcbiAgcmV0dXJuIGxvb2t1cFtudW0gPj4gMTggJiAweDNGXSArXG4gICAgbG9va3VwW251bSA+PiAxMiAmIDB4M0ZdICtcbiAgICBsb29rdXBbbnVtID4+IDYgJiAweDNGXSArXG4gICAgbG9va3VwW251bSAmIDB4M0ZdXG59XG5cbmZ1bmN0aW9uIGVuY29kZUNodW5rICh1aW50OCwgc3RhcnQsIGVuZCkge1xuICB2YXIgdG1wXG4gIHZhciBvdXRwdXQgPSBbXVxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkgKz0gMykge1xuICAgIHRtcCA9XG4gICAgICAoKHVpbnQ4W2ldIDw8IDE2KSAmIDB4RkYwMDAwKSArXG4gICAgICAoKHVpbnQ4W2kgKyAxXSA8PCA4KSAmIDB4RkYwMCkgK1xuICAgICAgKHVpbnQ4W2kgKyAyXSAmIDB4RkYpXG4gICAgb3V0cHV0LnB1c2godHJpcGxldFRvQmFzZTY0KHRtcCkpXG4gIH1cbiAgcmV0dXJuIG91dHB1dC5qb2luKCcnKVxufVxuXG5mdW5jdGlvbiBmcm9tQnl0ZUFycmF5ICh1aW50OCkge1xuICB2YXIgdG1wXG4gIHZhciBsZW4gPSB1aW50OC5sZW5ndGhcbiAgdmFyIGV4dHJhQnl0ZXMgPSBsZW4gJSAzIC8vIGlmIHdlIGhhdmUgMSBieXRlIGxlZnQsIHBhZCAyIGJ5dGVzXG4gIHZhciBwYXJ0cyA9IFtdXG4gIHZhciBtYXhDaHVua0xlbmd0aCA9IDE2MzgzIC8vIG11c3QgYmUgbXVsdGlwbGUgb2YgM1xuXG4gIC8vIGdvIHRocm91Z2ggdGhlIGFycmF5IGV2ZXJ5IHRocmVlIGJ5dGVzLCB3ZSdsbCBkZWFsIHdpdGggdHJhaWxpbmcgc3R1ZmYgbGF0ZXJcbiAgZm9yICh2YXIgaSA9IDAsIGxlbjIgPSBsZW4gLSBleHRyYUJ5dGVzOyBpIDwgbGVuMjsgaSArPSBtYXhDaHVua0xlbmd0aCkge1xuICAgIHBhcnRzLnB1c2goZW5jb2RlQ2h1bmsoXG4gICAgICB1aW50OCwgaSwgKGkgKyBtYXhDaHVua0xlbmd0aCkgPiBsZW4yID8gbGVuMiA6IChpICsgbWF4Q2h1bmtMZW5ndGgpXG4gICAgKSlcbiAgfVxuXG4gIC8vIHBhZCB0aGUgZW5kIHdpdGggemVyb3MsIGJ1dCBtYWtlIHN1cmUgdG8gbm90IGZvcmdldCB0aGUgZXh0cmEgYnl0ZXNcbiAgaWYgKGV4dHJhQnl0ZXMgPT09IDEpIHtcbiAgICB0bXAgPSB1aW50OFtsZW4gLSAxXVxuICAgIHBhcnRzLnB1c2goXG4gICAgICBsb29rdXBbdG1wID4+IDJdICtcbiAgICAgIGxvb2t1cFsodG1wIDw8IDQpICYgMHgzRl0gK1xuICAgICAgJz09J1xuICAgIClcbiAgfSBlbHNlIGlmIChleHRyYUJ5dGVzID09PSAyKSB7XG4gICAgdG1wID0gKHVpbnQ4W2xlbiAtIDJdIDw8IDgpICsgdWludDhbbGVuIC0gMV1cbiAgICBwYXJ0cy5wdXNoKFxuICAgICAgbG9va3VwW3RtcCA+PiAxMF0gK1xuICAgICAgbG9va3VwWyh0bXAgPj4gNCkgJiAweDNGXSArXG4gICAgICBsb29rdXBbKHRtcCA8PCAyKSAmIDB4M0ZdICtcbiAgICAgICc9J1xuICAgIClcbiAgfVxuXG4gIHJldHVybiBwYXJ0cy5qb2luKCcnKVxufVxuXG5cbi8qKiovIH0pLFxuLyogNCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5leHBvcnRzLnJlYWQgPSBmdW5jdGlvbiAoYnVmZmVyLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbVxuICB2YXIgZUxlbiA9IChuQnl0ZXMgKiA4KSAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgbkJpdHMgPSAtN1xuICB2YXIgaSA9IGlzTEUgPyAobkJ5dGVzIC0gMSkgOiAwXG4gIHZhciBkID0gaXNMRSA/IC0xIDogMVxuICB2YXIgcyA9IGJ1ZmZlcltvZmZzZXQgKyBpXVxuXG4gIGkgKz0gZFxuXG4gIGUgPSBzICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIHMgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IGVMZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IChlICogMjU2KSArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIG0gPSBlICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIGUgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IG1MZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgbSA9IChtICogMjU2KSArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhc1xuICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcbiAgICByZXR1cm4gbSA/IE5hTiA6ICgocyA/IC0xIDogMSkgKiBJbmZpbml0eSlcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pXG4gICAgZSA9IGUgLSBlQmlhc1xuICB9XG4gIHJldHVybiAocyA/IC0xIDogMSkgKiBtICogTWF0aC5wb3coMiwgZSAtIG1MZW4pXG59XG5cbmV4cG9ydHMud3JpdGUgPSBmdW5jdGlvbiAoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGNcbiAgdmFyIGVMZW4gPSAobkJ5dGVzICogOCkgLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIHJ0ID0gKG1MZW4gPT09IDIzID8gTWF0aC5wb3coMiwgLTI0KSAtIE1hdGgucG93KDIsIC03NykgOiAwKVxuICB2YXIgaSA9IGlzTEUgPyAwIDogKG5CeXRlcyAtIDEpXG4gIHZhciBkID0gaXNMRSA/IDEgOiAtMVxuICB2YXIgcyA9IHZhbHVlIDwgMCB8fCAodmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCkgPyAxIDogMFxuXG4gIHZhbHVlID0gTWF0aC5hYnModmFsdWUpXG5cbiAgaWYgKGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA9PT0gSW5maW5pdHkpIHtcbiAgICBtID0gaXNOYU4odmFsdWUpID8gMSA6IDBcbiAgICBlID0gZU1heFxuICB9IGVsc2Uge1xuICAgIGUgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbHVlKSAvIE1hdGguTE4yKVxuICAgIGlmICh2YWx1ZSAqIChjID0gTWF0aC5wb3coMiwgLWUpKSA8IDEpIHtcbiAgICAgIGUtLVxuICAgICAgYyAqPSAyXG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgdmFsdWUgKz0gcnQgLyBjXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlICs9IHJ0ICogTWF0aC5wb3coMiwgMSAtIGVCaWFzKVxuICAgIH1cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrK1xuICAgICAgYyAvPSAyXG4gICAgfVxuXG4gICAgaWYgKGUgKyBlQmlhcyA+PSBlTWF4KSB7XG4gICAgICBtID0gMFxuICAgICAgZSA9IGVNYXhcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKCh2YWx1ZSAqIGMpIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IGUgKyBlQmlhc1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gdmFsdWUgKiBNYXRoLnBvdygyLCBlQmlhcyAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSAwXG4gICAgfVxuICB9XG5cbiAgZm9yICg7IG1MZW4gPj0gODsgYnVmZmVyW29mZnNldCArIGldID0gbSAmIDB4ZmYsIGkgKz0gZCwgbSAvPSAyNTYsIG1MZW4gLT0gOCkge31cblxuICBlID0gKGUgPDwgbUxlbikgfCBtXG4gIGVMZW4gKz0gbUxlblxuICBmb3IgKDsgZUxlbiA+IDA7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IGUgJiAweGZmLCBpICs9IGQsIGUgLz0gMjU2LCBlTGVuIC09IDgpIHt9XG5cbiAgYnVmZmVyW29mZnNldCArIGkgLSBkXSB8PSBzICogMTI4XG59XG5cblxuLyoqKi8gfSksXG4vKiA1ICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbnZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKGFycikge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChhcnIpID09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuXG5cbi8qKiovIH0pLFxuLyogNiAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5tb2R1bGUuZXhwb3J0cyA9IExvbmc7XHJcblxyXG4vKipcclxuICogd2FzbSBvcHRpbWl6YXRpb25zLCB0byBkbyBuYXRpdmUgaTY0IG11bHRpcGxpY2F0aW9uIGFuZCBkaXZpZGVcclxuICovXHJcbnZhciB3YXNtID0gbnVsbDtcclxuXHJcbnRyeSB7XHJcbiAgd2FzbSA9IG5ldyBXZWJBc3NlbWJseS5JbnN0YW5jZShuZXcgV2ViQXNzZW1ibHkuTW9kdWxlKG5ldyBVaW50OEFycmF5KFtcclxuICAgIDAsIDk3LCAxMTUsIDEwOSwgMSwgMCwgMCwgMCwgMSwgMTMsIDIsIDk2LCAwLCAxLCAxMjcsIDk2LCA0LCAxMjcsIDEyNywgMTI3LCAxMjcsIDEsIDEyNywgMywgNywgNiwgMCwgMSwgMSwgMSwgMSwgMSwgNiwgNiwgMSwgMTI3LCAxLCA2NSwgMCwgMTEsIDcsIDUwLCA2LCAzLCAxMDksIDExNywgMTA4LCAwLCAxLCA1LCAxMDAsIDEwNSwgMTE4LCA5NSwgMTE1LCAwLCAyLCA1LCAxMDAsIDEwNSwgMTE4LCA5NSwgMTE3LCAwLCAzLCA1LCAxMTQsIDEwMSwgMTA5LCA5NSwgMTE1LCAwLCA0LCA1LCAxMTQsIDEwMSwgMTA5LCA5NSwgMTE3LCAwLCA1LCA4LCAxMDMsIDEwMSwgMTE2LCA5NSwgMTA0LCAxMDUsIDEwMywgMTA0LCAwLCAwLCAxMCwgMTkxLCAxLCA2LCA0LCAwLCAzNSwgMCwgMTEsIDM2LCAxLCAxLCAxMjYsIDMyLCAwLCAxNzMsIDMyLCAxLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDMyLCAyLCAxNzMsIDMyLCAzLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDEyNiwgMzQsIDQsIDY2LCAzMiwgMTM1LCAxNjcsIDM2LCAwLCAzMiwgNCwgMTY3LCAxMSwgMzYsIDEsIDEsIDEyNiwgMzIsIDAsIDE3MywgMzIsIDEsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMzIsIDIsIDE3MywgMzIsIDMsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMTI3LCAzNCwgNCwgNjYsIDMyLCAxMzUsIDE2NywgMzYsIDAsIDMyLCA0LCAxNjcsIDExLCAzNiwgMSwgMSwgMTI2LCAzMiwgMCwgMTczLCAzMiwgMSwgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAzMiwgMiwgMTczLCAzMiwgMywgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAxMjgsIDM0LCA0LCA2NiwgMzIsIDEzNSwgMTY3LCAzNiwgMCwgMzIsIDQsIDE2NywgMTEsIDM2LCAxLCAxLCAxMjYsIDMyLCAwLCAxNzMsIDMyLCAxLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDMyLCAyLCAxNzMsIDMyLCAzLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDEyOSwgMzQsIDQsIDY2LCAzMiwgMTM1LCAxNjcsIDM2LCAwLCAzMiwgNCwgMTY3LCAxMSwgMzYsIDEsIDEsIDEyNiwgMzIsIDAsIDE3MywgMzIsIDEsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMzIsIDIsIDE3MywgMzIsIDMsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMTMwLCAzNCwgNCwgNjYsIDMyLCAxMzUsIDE2NywgMzYsIDAsIDMyLCA0LCAxNjcsIDExXHJcbiAgXSkpLCB7fSkuZXhwb3J0cztcclxufSBjYXRjaCAoZSkge1xyXG4gIC8vIG5vIHdhc20gc3VwcG9ydCA6KFxyXG59XHJcblxyXG4vKipcclxuICogQ29uc3RydWN0cyBhIDY0IGJpdCB0d28ncy1jb21wbGVtZW50IGludGVnZXIsIGdpdmVuIGl0cyBsb3cgYW5kIGhpZ2ggMzIgYml0IHZhbHVlcyBhcyAqc2lnbmVkKiBpbnRlZ2Vycy5cclxuICogIFNlZSB0aGUgZnJvbSogZnVuY3Rpb25zIGJlbG93IGZvciBtb3JlIGNvbnZlbmllbnQgd2F5cyBvZiBjb25zdHJ1Y3RpbmcgTG9uZ3MuXHJcbiAqIEBleHBvcnRzIExvbmdcclxuICogQGNsYXNzIEEgTG9uZyBjbGFzcyBmb3IgcmVwcmVzZW50aW5nIGEgNjQgYml0IHR3bydzLWNvbXBsZW1lbnQgaW50ZWdlciB2YWx1ZS5cclxuICogQHBhcmFtIHtudW1iZXJ9IGxvdyBUaGUgbG93IChzaWduZWQpIDMyIGJpdHMgb2YgdGhlIGxvbmdcclxuICogQHBhcmFtIHtudW1iZXJ9IGhpZ2ggVGhlIGhpZ2ggKHNpZ25lZCkgMzIgYml0cyBvZiB0aGUgbG9uZ1xyXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXHJcbiAqIEBjb25zdHJ1Y3RvclxyXG4gKi9cclxuZnVuY3Rpb24gTG9uZyhsb3csIGhpZ2gsIHVuc2lnbmVkKSB7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbG93IDMyIGJpdHMgYXMgYSBzaWduZWQgdmFsdWUuXHJcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxyXG4gICAgICovXHJcbiAgICB0aGlzLmxvdyA9IGxvdyB8IDA7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgaGlnaCAzMiBiaXRzIGFzIGEgc2lnbmVkIHZhbHVlLlxyXG4gICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAqL1xyXG4gICAgdGhpcy5oaWdoID0gaGlnaCB8IDA7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdC5cclxuICAgICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICB0aGlzLnVuc2lnbmVkID0gISF1bnNpZ25lZDtcclxufVxyXG5cclxuLy8gVGhlIGludGVybmFsIHJlcHJlc2VudGF0aW9uIG9mIGEgbG9uZyBpcyB0aGUgdHdvIGdpdmVuIHNpZ25lZCwgMzItYml0IHZhbHVlcy5cclxuLy8gV2UgdXNlIDMyLWJpdCBwaWVjZXMgYmVjYXVzZSB0aGVzZSBhcmUgdGhlIHNpemUgb2YgaW50ZWdlcnMgb24gd2hpY2hcclxuLy8gSmF2YXNjcmlwdCBwZXJmb3JtcyBiaXQtb3BlcmF0aW9ucy4gIEZvciBvcGVyYXRpb25zIGxpa2UgYWRkaXRpb24gYW5kXHJcbi8vIG11bHRpcGxpY2F0aW9uLCB3ZSBzcGxpdCBlYWNoIG51bWJlciBpbnRvIDE2IGJpdCBwaWVjZXMsIHdoaWNoIGNhbiBlYXNpbHkgYmVcclxuLy8gbXVsdGlwbGllZCB3aXRoaW4gSmF2YXNjcmlwdCdzIGZsb2F0aW5nLXBvaW50IHJlcHJlc2VudGF0aW9uIHdpdGhvdXQgb3ZlcmZsb3dcclxuLy8gb3IgY2hhbmdlIGluIHNpZ24uXHJcbi8vXHJcbi8vIEluIHRoZSBhbGdvcml0aG1zIGJlbG93LCB3ZSBmcmVxdWVudGx5IHJlZHVjZSB0aGUgbmVnYXRpdmUgY2FzZSB0byB0aGVcclxuLy8gcG9zaXRpdmUgY2FzZSBieSBuZWdhdGluZyB0aGUgaW5wdXQocykgYW5kIHRoZW4gcG9zdC1wcm9jZXNzaW5nIHRoZSByZXN1bHQuXHJcbi8vIE5vdGUgdGhhdCB3ZSBtdXN0IEFMV0FZUyBjaGVjayBzcGVjaWFsbHkgd2hldGhlciB0aG9zZSB2YWx1ZXMgYXJlIE1JTl9WQUxVRVxyXG4vLyAoLTJeNjMpIGJlY2F1c2UgLU1JTl9WQUxVRSA9PSBNSU5fVkFMVUUgKHNpbmNlIDJeNjMgY2Fubm90IGJlIHJlcHJlc2VudGVkIGFzXHJcbi8vIGEgcG9zaXRpdmUgbnVtYmVyLCBpdCBvdmVyZmxvd3MgYmFjayBpbnRvIGEgbmVnYXRpdmUpLiAgTm90IGhhbmRsaW5nIHRoaXNcclxuLy8gY2FzZSB3b3VsZCBvZnRlbiByZXN1bHQgaW4gaW5maW5pdGUgcmVjdXJzaW9uLlxyXG4vL1xyXG4vLyBDb21tb24gY29uc3RhbnQgdmFsdWVzIFpFUk8sIE9ORSwgTkVHX09ORSwgZXRjLiBhcmUgZGVmaW5lZCBiZWxvdyB0aGUgZnJvbSpcclxuLy8gbWV0aG9kcyBvbiB3aGljaCB0aGV5IGRlcGVuZC5cclxuXHJcbi8qKlxyXG4gKiBBbiBpbmRpY2F0b3IgdXNlZCB0byByZWxpYWJseSBkZXRlcm1pbmUgaWYgYW4gb2JqZWN0IGlzIGEgTG9uZyBvciBub3QuXHJcbiAqIEB0eXBlIHtib29sZWFufVxyXG4gKiBAY29uc3RcclxuICogQHByaXZhdGVcclxuICovXHJcbkxvbmcucHJvdG90eXBlLl9faXNMb25nX187XHJcblxyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoTG9uZy5wcm90b3R5cGUsIFwiX19pc0xvbmdfX1wiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG5cclxuLyoqXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0geyp9IG9iaiBPYmplY3RcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqIEBpbm5lclxyXG4gKi9cclxuZnVuY3Rpb24gaXNMb25nKG9iaikge1xyXG4gICAgcmV0dXJuIChvYmogJiYgb2JqW1wiX19pc0xvbmdfX1wiXSkgPT09IHRydWU7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBhIExvbmcuXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0geyp9IG9iaiBPYmplY3RcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nLmlzTG9uZyA9IGlzTG9uZztcclxuXHJcbi8qKlxyXG4gKiBBIGNhY2hlIG9mIHRoZSBMb25nIHJlcHJlc2VudGF0aW9ucyBvZiBzbWFsbCBpbnRlZ2VyIHZhbHVlcy5cclxuICogQHR5cGUgeyFPYmplY3R9XHJcbiAqIEBpbm5lclxyXG4gKi9cclxudmFyIElOVF9DQUNIRSA9IHt9O1xyXG5cclxuLyoqXHJcbiAqIEEgY2FjaGUgb2YgdGhlIExvbmcgcmVwcmVzZW50YXRpb25zIG9mIHNtYWxsIHVuc2lnbmVkIGludGVnZXIgdmFsdWVzLlxyXG4gKiBAdHlwZSB7IU9iamVjdH1cclxuICogQGlubmVyXHJcbiAqL1xyXG52YXIgVUlOVF9DQUNIRSA9IHt9O1xyXG5cclxuLyoqXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxyXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZFxyXG4gKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAqIEBpbm5lclxyXG4gKi9cclxuZnVuY3Rpb24gZnJvbUludCh2YWx1ZSwgdW5zaWduZWQpIHtcclxuICAgIHZhciBvYmosIGNhY2hlZE9iaiwgY2FjaGU7XHJcbiAgICBpZiAodW5zaWduZWQpIHtcclxuICAgICAgICB2YWx1ZSA+Pj49IDA7XHJcbiAgICAgICAgaWYgKGNhY2hlID0gKDAgPD0gdmFsdWUgJiYgdmFsdWUgPCAyNTYpKSB7XHJcbiAgICAgICAgICAgIGNhY2hlZE9iaiA9IFVJTlRfQ0FDSEVbdmFsdWVdO1xyXG4gICAgICAgICAgICBpZiAoY2FjaGVkT2JqKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNhY2hlZE9iajtcclxuICAgICAgICB9XHJcbiAgICAgICAgb2JqID0gZnJvbUJpdHModmFsdWUsICh2YWx1ZSB8IDApIDwgMCA/IC0xIDogMCwgdHJ1ZSk7XHJcbiAgICAgICAgaWYgKGNhY2hlKVxyXG4gICAgICAgICAgICBVSU5UX0NBQ0hFW3ZhbHVlXSA9IG9iajtcclxuICAgICAgICByZXR1cm4gb2JqO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICB2YWx1ZSB8PSAwO1xyXG4gICAgICAgIGlmIChjYWNoZSA9ICgtMTI4IDw9IHZhbHVlICYmIHZhbHVlIDwgMTI4KSkge1xyXG4gICAgICAgICAgICBjYWNoZWRPYmogPSBJTlRfQ0FDSEVbdmFsdWVdO1xyXG4gICAgICAgICAgICBpZiAoY2FjaGVkT2JqKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNhY2hlZE9iajtcclxuICAgICAgICB9XHJcbiAgICAgICAgb2JqID0gZnJvbUJpdHModmFsdWUsIHZhbHVlIDwgMCA/IC0xIDogMCwgZmFsc2UpO1xyXG4gICAgICAgIGlmIChjYWNoZSlcclxuICAgICAgICAgICAgSU5UX0NBQ0hFW3ZhbHVlXSA9IG9iajtcclxuICAgICAgICByZXR1cm4gb2JqO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50aW5nIHRoZSBnaXZlbiAzMiBiaXQgaW50ZWdlciB2YWx1ZS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBUaGUgMzIgYml0IGludGVnZXIgaW4gcXVlc3Rpb25cclxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcclxuICovXHJcbkxvbmcuZnJvbUludCA9IGZyb21JbnQ7XHJcblxyXG4vKipcclxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXHJcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkXHJcbiAqIEByZXR1cm5zIHshTG9uZ31cclxuICogQGlubmVyXHJcbiAqL1xyXG5mdW5jdGlvbiBmcm9tTnVtYmVyKHZhbHVlLCB1bnNpZ25lZCkge1xyXG4gICAgaWYgKGlzTmFOKHZhbHVlKSlcclxuICAgICAgICByZXR1cm4gdW5zaWduZWQgPyBVWkVSTyA6IFpFUk87XHJcbiAgICBpZiAodW5zaWduZWQpIHtcclxuICAgICAgICBpZiAodmFsdWUgPCAwKVxyXG4gICAgICAgICAgICByZXR1cm4gVVpFUk87XHJcbiAgICAgICAgaWYgKHZhbHVlID49IFRXT19QV1JfNjRfREJMKVxyXG4gICAgICAgICAgICByZXR1cm4gTUFYX1VOU0lHTkVEX1ZBTFVFO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICBpZiAodmFsdWUgPD0gLVRXT19QV1JfNjNfREJMKVxyXG4gICAgICAgICAgICByZXR1cm4gTUlOX1ZBTFVFO1xyXG4gICAgICAgIGlmICh2YWx1ZSArIDEgPj0gVFdPX1BXUl82M19EQkwpXHJcbiAgICAgICAgICAgIHJldHVybiBNQVhfVkFMVUU7XHJcbiAgICB9XHJcbiAgICBpZiAodmFsdWUgPCAwKVxyXG4gICAgICAgIHJldHVybiBmcm9tTnVtYmVyKC12YWx1ZSwgdW5zaWduZWQpLm5lZygpO1xyXG4gICAgcmV0dXJuIGZyb21CaXRzKCh2YWx1ZSAlIFRXT19QV1JfMzJfREJMKSB8IDAsICh2YWx1ZSAvIFRXT19QV1JfMzJfREJMKSB8IDAsIHVuc2lnbmVkKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgYSBMb25nIHJlcHJlc2VudGluZyB0aGUgZ2l2ZW4gdmFsdWUsIHByb3ZpZGVkIHRoYXQgaXQgaXMgYSBmaW5pdGUgbnVtYmVyLiBPdGhlcndpc2UsIHplcm8gaXMgcmV0dXJuZWQuXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVGhlIG51bWJlciBpbiBxdWVzdGlvblxyXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gVGhlIGNvcnJlc3BvbmRpbmcgTG9uZyB2YWx1ZVxyXG4gKi9cclxuTG9uZy5mcm9tTnVtYmVyID0gZnJvbU51bWJlcjtcclxuXHJcbi8qKlxyXG4gKiBAcGFyYW0ge251bWJlcn0gbG93Qml0c1xyXG4gKiBAcGFyYW0ge251bWJlcn0gaGlnaEJpdHNcclxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWRcclxuICogQHJldHVybnMgeyFMb25nfVxyXG4gKiBAaW5uZXJcclxuICovXHJcbmZ1bmN0aW9uIGZyb21CaXRzKGxvd0JpdHMsIGhpZ2hCaXRzLCB1bnNpZ25lZCkge1xyXG4gICAgcmV0dXJuIG5ldyBMb25nKGxvd0JpdHMsIGhpZ2hCaXRzLCB1bnNpZ25lZCk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIGEgTG9uZyByZXByZXNlbnRpbmcgdGhlIDY0IGJpdCBpbnRlZ2VyIHRoYXQgY29tZXMgYnkgY29uY2F0ZW5hdGluZyB0aGUgZ2l2ZW4gbG93IGFuZCBoaWdoIGJpdHMuIEVhY2ggaXNcclxuICogIGFzc3VtZWQgdG8gdXNlIDMyIGJpdHMuXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge251bWJlcn0gbG93Qml0cyBUaGUgbG93IDMyIGJpdHNcclxuICogQHBhcmFtIHtudW1iZXJ9IGhpZ2hCaXRzIFRoZSBoaWdoIDMyIGJpdHNcclxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcclxuICovXHJcbkxvbmcuZnJvbUJpdHMgPSBmcm9tQml0cztcclxuXHJcbi8qKlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtudW1iZXJ9IGJhc2VcclxuICogQHBhcmFtIHtudW1iZXJ9IGV4cG9uZW50XHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9XHJcbiAqIEBpbm5lclxyXG4gKi9cclxudmFyIHBvd19kYmwgPSBNYXRoLnBvdzsgLy8gVXNlZCA0IHRpbWVzICg0KjggdG8gMTUrNClcclxuXHJcbi8qKlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyXHJcbiAqIEBwYXJhbSB7KGJvb2xlYW58bnVtYmVyKT19IHVuc2lnbmVkXHJcbiAqIEBwYXJhbSB7bnVtYmVyPX0gcmFkaXhcclxuICogQHJldHVybnMgeyFMb25nfVxyXG4gKiBAaW5uZXJcclxuICovXHJcbmZ1bmN0aW9uIGZyb21TdHJpbmcoc3RyLCB1bnNpZ25lZCwgcmFkaXgpIHtcclxuICAgIGlmIChzdHIubGVuZ3RoID09PSAwKVxyXG4gICAgICAgIHRocm93IEVycm9yKCdlbXB0eSBzdHJpbmcnKTtcclxuICAgIGlmIChzdHIgPT09IFwiTmFOXCIgfHwgc3RyID09PSBcIkluZmluaXR5XCIgfHwgc3RyID09PSBcIitJbmZpbml0eVwiIHx8IHN0ciA9PT0gXCItSW5maW5pdHlcIilcclxuICAgICAgICByZXR1cm4gWkVSTztcclxuICAgIGlmICh0eXBlb2YgdW5zaWduZWQgPT09ICdudW1iZXInKSB7XHJcbiAgICAgICAgLy8gRm9yIGdvb2cubWF0aC5sb25nIGNvbXBhdGliaWxpdHlcclxuICAgICAgICByYWRpeCA9IHVuc2lnbmVkLFxyXG4gICAgICAgIHVuc2lnbmVkID0gZmFsc2U7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIHVuc2lnbmVkID0gISEgdW5zaWduZWQ7XHJcbiAgICB9XHJcbiAgICByYWRpeCA9IHJhZGl4IHx8IDEwO1xyXG4gICAgaWYgKHJhZGl4IDwgMiB8fCAzNiA8IHJhZGl4KVxyXG4gICAgICAgIHRocm93IFJhbmdlRXJyb3IoJ3JhZGl4Jyk7XHJcblxyXG4gICAgdmFyIHA7XHJcbiAgICBpZiAoKHAgPSBzdHIuaW5kZXhPZignLScpKSA+IDApXHJcbiAgICAgICAgdGhyb3cgRXJyb3IoJ2ludGVyaW9yIGh5cGhlbicpO1xyXG4gICAgZWxzZSBpZiAocCA9PT0gMCkge1xyXG4gICAgICAgIHJldHVybiBmcm9tU3RyaW5nKHN0ci5zdWJzdHJpbmcoMSksIHVuc2lnbmVkLCByYWRpeCkubmVnKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gRG8gc2V2ZXJhbCAoOCkgZGlnaXRzIGVhY2ggdGltZSB0aHJvdWdoIHRoZSBsb29wLCBzbyBhcyB0b1xyXG4gICAgLy8gbWluaW1pemUgdGhlIGNhbGxzIHRvIHRoZSB2ZXJ5IGV4cGVuc2l2ZSBlbXVsYXRlZCBkaXYuXHJcbiAgICB2YXIgcmFkaXhUb1Bvd2VyID0gZnJvbU51bWJlcihwb3dfZGJsKHJhZGl4LCA4KSk7XHJcblxyXG4gICAgdmFyIHJlc3VsdCA9IFpFUk87XHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkgKz0gOCkge1xyXG4gICAgICAgIHZhciBzaXplID0gTWF0aC5taW4oOCwgc3RyLmxlbmd0aCAtIGkpLFxyXG4gICAgICAgICAgICB2YWx1ZSA9IHBhcnNlSW50KHN0ci5zdWJzdHJpbmcoaSwgaSArIHNpemUpLCByYWRpeCk7XHJcbiAgICAgICAgaWYgKHNpemUgPCA4KSB7XHJcbiAgICAgICAgICAgIHZhciBwb3dlciA9IGZyb21OdW1iZXIocG93X2RibChyYWRpeCwgc2l6ZSkpO1xyXG4gICAgICAgICAgICByZXN1bHQgPSByZXN1bHQubXVsKHBvd2VyKS5hZGQoZnJvbU51bWJlcih2YWx1ZSkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5tdWwocmFkaXhUb1Bvd2VyKTtcclxuICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LmFkZChmcm9tTnVtYmVyKHZhbHVlKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmVzdWx0LnVuc2lnbmVkID0gdW5zaWduZWQ7XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG4vKipcclxuICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGdpdmVuIHN0cmluZywgd3JpdHRlbiB1c2luZyB0aGUgc3BlY2lmaWVkIHJhZGl4LlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtzdHJpbmd9IHN0ciBUaGUgdGV4dHVhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgTG9uZ1xyXG4gKiBAcGFyYW0geyhib29sZWFufG51bWJlcik9fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXHJcbiAqIEBwYXJhbSB7bnVtYmVyPX0gcmFkaXggVGhlIHJhZGl4IGluIHdoaWNoIHRoZSB0ZXh0IGlzIHdyaXR0ZW4gKDItMzYpLCBkZWZhdWx0cyB0byAxMFxyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcclxuICovXHJcbkxvbmcuZnJvbVN0cmluZyA9IGZyb21TdHJpbmc7XHJcblxyXG4vKipcclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ3whe2xvdzogbnVtYmVyLCBoaWdoOiBudW1iZXIsIHVuc2lnbmVkOiBib29sZWFufX0gdmFsXHJcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkXHJcbiAqIEByZXR1cm5zIHshTG9uZ31cclxuICogQGlubmVyXHJcbiAqL1xyXG5mdW5jdGlvbiBmcm9tVmFsdWUodmFsLCB1bnNpZ25lZCkge1xyXG4gICAgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKVxyXG4gICAgICAgIHJldHVybiBmcm9tTnVtYmVyKHZhbCwgdW5zaWduZWQpO1xyXG4gICAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKVxyXG4gICAgICAgIHJldHVybiBmcm9tU3RyaW5nKHZhbCwgdW5zaWduZWQpO1xyXG4gICAgLy8gVGhyb3dzIGZvciBub24tb2JqZWN0cywgY29udmVydHMgbm9uLWluc3RhbmNlb2YgTG9uZzpcclxuICAgIHJldHVybiBmcm9tQml0cyh2YWwubG93LCB2YWwuaGlnaCwgdHlwZW9mIHVuc2lnbmVkID09PSAnYm9vbGVhbicgPyB1bnNpZ25lZCA6IHZhbC51bnNpZ25lZCk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDb252ZXJ0cyB0aGUgc3BlY2lmaWVkIHZhbHVlIHRvIGEgTG9uZyB1c2luZyB0aGUgYXBwcm9wcmlhdGUgZnJvbSogZnVuY3Rpb24gZm9yIGl0cyB0eXBlLlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfCF7bG93OiBudW1iZXIsIGhpZ2g6IG51bWJlciwgdW5zaWduZWQ6IGJvb2xlYW59fSB2YWwgVmFsdWVcclxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxyXG4gKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAqL1xyXG5Mb25nLmZyb21WYWx1ZSA9IGZyb21WYWx1ZTtcclxuXHJcbi8vIE5PVEU6IHRoZSBjb21waWxlciBzaG91bGQgaW5saW5lIHRoZXNlIGNvbnN0YW50IHZhbHVlcyBiZWxvdyBhbmQgdGhlbiByZW1vdmUgdGhlc2UgdmFyaWFibGVzLCBzbyB0aGVyZSBzaG91bGQgYmVcclxuLy8gbm8gcnVudGltZSBwZW5hbHR5IGZvciB0aGVzZS5cclxuXHJcbi8qKlxyXG4gKiBAdHlwZSB7bnVtYmVyfVxyXG4gKiBAY29uc3RcclxuICogQGlubmVyXHJcbiAqL1xyXG52YXIgVFdPX1BXUl8xNl9EQkwgPSAxIDw8IDE2O1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlIHtudW1iZXJ9XHJcbiAqIEBjb25zdFxyXG4gKiBAaW5uZXJcclxuICovXHJcbnZhciBUV09fUFdSXzI0X0RCTCA9IDEgPDwgMjQ7XHJcblxyXG4vKipcclxuICogQHR5cGUge251bWJlcn1cclxuICogQGNvbnN0XHJcbiAqIEBpbm5lclxyXG4gKi9cclxudmFyIFRXT19QV1JfMzJfREJMID0gVFdPX1BXUl8xNl9EQkwgKiBUV09fUFdSXzE2X0RCTDtcclxuXHJcbi8qKlxyXG4gKiBAdHlwZSB7bnVtYmVyfVxyXG4gKiBAY29uc3RcclxuICogQGlubmVyXHJcbiAqL1xyXG52YXIgVFdPX1BXUl82NF9EQkwgPSBUV09fUFdSXzMyX0RCTCAqIFRXT19QV1JfMzJfREJMO1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlIHtudW1iZXJ9XHJcbiAqIEBjb25zdFxyXG4gKiBAaW5uZXJcclxuICovXHJcbnZhciBUV09fUFdSXzYzX0RCTCA9IFRXT19QV1JfNjRfREJMIC8gMjtcclxuXHJcbi8qKlxyXG4gKiBAdHlwZSB7IUxvbmd9XHJcbiAqIEBjb25zdFxyXG4gKiBAaW5uZXJcclxuICovXHJcbnZhciBUV09fUFdSXzI0ID0gZnJvbUludChUV09fUFdSXzI0X0RCTCk7XHJcblxyXG4vKipcclxuICogQHR5cGUgeyFMb25nfVxyXG4gKiBAaW5uZXJcclxuICovXHJcbnZhciBaRVJPID0gZnJvbUludCgwKTtcclxuXHJcbi8qKlxyXG4gKiBTaWduZWQgemVyby5cclxuICogQHR5cGUgeyFMb25nfVxyXG4gKi9cclxuTG9uZy5aRVJPID0gWkVSTztcclxuXHJcbi8qKlxyXG4gKiBAdHlwZSB7IUxvbmd9XHJcbiAqIEBpbm5lclxyXG4gKi9cclxudmFyIFVaRVJPID0gZnJvbUludCgwLCB0cnVlKTtcclxuXHJcbi8qKlxyXG4gKiBVbnNpZ25lZCB6ZXJvLlxyXG4gKiBAdHlwZSB7IUxvbmd9XHJcbiAqL1xyXG5Mb25nLlVaRVJPID0gVVpFUk87XHJcblxyXG4vKipcclxuICogQHR5cGUgeyFMb25nfVxyXG4gKiBAaW5uZXJcclxuICovXHJcbnZhciBPTkUgPSBmcm9tSW50KDEpO1xyXG5cclxuLyoqXHJcbiAqIFNpZ25lZCBvbmUuXHJcbiAqIEB0eXBlIHshTG9uZ31cclxuICovXHJcbkxvbmcuT05FID0gT05FO1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlIHshTG9uZ31cclxuICogQGlubmVyXHJcbiAqL1xyXG52YXIgVU9ORSA9IGZyb21JbnQoMSwgdHJ1ZSk7XHJcblxyXG4vKipcclxuICogVW5zaWduZWQgb25lLlxyXG4gKiBAdHlwZSB7IUxvbmd9XHJcbiAqL1xyXG5Mb25nLlVPTkUgPSBVT05FO1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlIHshTG9uZ31cclxuICogQGlubmVyXHJcbiAqL1xyXG52YXIgTkVHX09ORSA9IGZyb21JbnQoLTEpO1xyXG5cclxuLyoqXHJcbiAqIFNpZ25lZCBuZWdhdGl2ZSBvbmUuXHJcbiAqIEB0eXBlIHshTG9uZ31cclxuICovXHJcbkxvbmcuTkVHX09ORSA9IE5FR19PTkU7XHJcblxyXG4vKipcclxuICogQHR5cGUgeyFMb25nfVxyXG4gKiBAaW5uZXJcclxuICovXHJcbnZhciBNQVhfVkFMVUUgPSBmcm9tQml0cygweEZGRkZGRkZGfDAsIDB4N0ZGRkZGRkZ8MCwgZmFsc2UpO1xyXG5cclxuLyoqXHJcbiAqIE1heGltdW0gc2lnbmVkIHZhbHVlLlxyXG4gKiBAdHlwZSB7IUxvbmd9XHJcbiAqL1xyXG5Mb25nLk1BWF9WQUxVRSA9IE1BWF9WQUxVRTtcclxuXHJcbi8qKlxyXG4gKiBAdHlwZSB7IUxvbmd9XHJcbiAqIEBpbm5lclxyXG4gKi9cclxudmFyIE1BWF9VTlNJR05FRF9WQUxVRSA9IGZyb21CaXRzKDB4RkZGRkZGRkZ8MCwgMHhGRkZGRkZGRnwwLCB0cnVlKTtcclxuXHJcbi8qKlxyXG4gKiBNYXhpbXVtIHVuc2lnbmVkIHZhbHVlLlxyXG4gKiBAdHlwZSB7IUxvbmd9XHJcbiAqL1xyXG5Mb25nLk1BWF9VTlNJR05FRF9WQUxVRSA9IE1BWF9VTlNJR05FRF9WQUxVRTtcclxuXHJcbi8qKlxyXG4gKiBAdHlwZSB7IUxvbmd9XHJcbiAqIEBpbm5lclxyXG4gKi9cclxudmFyIE1JTl9WQUxVRSA9IGZyb21CaXRzKDAsIDB4ODAwMDAwMDB8MCwgZmFsc2UpO1xyXG5cclxuLyoqXHJcbiAqIE1pbmltdW0gc2lnbmVkIHZhbHVlLlxyXG4gKiBAdHlwZSB7IUxvbmd9XHJcbiAqL1xyXG5Mb25nLk1JTl9WQUxVRSA9IE1JTl9WQUxVRTtcclxuXHJcbi8qKlxyXG4gKiBAYWxpYXMgTG9uZy5wcm90b3R5cGVcclxuICogQGlubmVyXHJcbiAqL1xyXG52YXIgTG9uZ1Byb3RvdHlwZSA9IExvbmcucHJvdG90eXBlO1xyXG5cclxuLyoqXHJcbiAqIENvbnZlcnRzIHRoZSBMb25nIHRvIGEgMzIgYml0IGludGVnZXIsIGFzc3VtaW5nIGl0IGlzIGEgMzIgYml0IGludGVnZXIuXHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnRvSW50ID0gZnVuY3Rpb24gdG9JbnQoKSB7XHJcbiAgICByZXR1cm4gdGhpcy51bnNpZ25lZCA/IHRoaXMubG93ID4+PiAwIDogdGhpcy5sb3c7XHJcbn07XHJcblxyXG4vKipcclxuICogQ29udmVydHMgdGhlIExvbmcgdG8gYSB0aGUgbmVhcmVzdCBmbG9hdGluZy1wb2ludCByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHZhbHVlIChkb3VibGUsIDUzIGJpdCBtYW50aXNzYSkuXHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnRvTnVtYmVyID0gZnVuY3Rpb24gdG9OdW1iZXIoKSB7XHJcbiAgICBpZiAodGhpcy51bnNpZ25lZClcclxuICAgICAgICByZXR1cm4gKCh0aGlzLmhpZ2ggPj4+IDApICogVFdPX1BXUl8zMl9EQkwpICsgKHRoaXMubG93ID4+PiAwKTtcclxuICAgIHJldHVybiB0aGlzLmhpZ2ggKiBUV09fUFdSXzMyX0RCTCArICh0aGlzLmxvdyA+Pj4gMCk7XHJcbn07XHJcblxyXG4vKipcclxuICogQ29udmVydHMgdGhlIExvbmcgdG8gYSBzdHJpbmcgd3JpdHRlbiBpbiB0aGUgc3BlY2lmaWVkIHJhZGl4LlxyXG4gKiBAcGFyYW0ge251bWJlcj19IHJhZGl4IFJhZGl4ICgyLTM2KSwgZGVmYXVsdHMgdG8gMTBcclxuICogQHJldHVybnMge3N0cmluZ31cclxuICogQG92ZXJyaWRlXHJcbiAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGByYWRpeGAgaXMgb3V0IG9mIHJhbmdlXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcocmFkaXgpIHtcclxuICAgIHJhZGl4ID0gcmFkaXggfHwgMTA7XHJcbiAgICBpZiAocmFkaXggPCAyIHx8IDM2IDwgcmFkaXgpXHJcbiAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcigncmFkaXgnKTtcclxuICAgIGlmICh0aGlzLmlzWmVybygpKVxyXG4gICAgICAgIHJldHVybiAnMCc7XHJcbiAgICBpZiAodGhpcy5pc05lZ2F0aXZlKCkpIHsgLy8gVW5zaWduZWQgTG9uZ3MgYXJlIG5ldmVyIG5lZ2F0aXZlXHJcbiAgICAgICAgaWYgKHRoaXMuZXEoTUlOX1ZBTFVFKSkge1xyXG4gICAgICAgICAgICAvLyBXZSBuZWVkIHRvIGNoYW5nZSB0aGUgTG9uZyB2YWx1ZSBiZWZvcmUgaXQgY2FuIGJlIG5lZ2F0ZWQsIHNvIHdlIHJlbW92ZVxyXG4gICAgICAgICAgICAvLyB0aGUgYm90dG9tLW1vc3QgZGlnaXQgaW4gdGhpcyBiYXNlIGFuZCB0aGVuIHJlY3Vyc2UgdG8gZG8gdGhlIHJlc3QuXHJcbiAgICAgICAgICAgIHZhciByYWRpeExvbmcgPSBmcm9tTnVtYmVyKHJhZGl4KSxcclxuICAgICAgICAgICAgICAgIGRpdiA9IHRoaXMuZGl2KHJhZGl4TG9uZyksXHJcbiAgICAgICAgICAgICAgICByZW0xID0gZGl2Lm11bChyYWRpeExvbmcpLnN1Yih0aGlzKTtcclxuICAgICAgICAgICAgcmV0dXJuIGRpdi50b1N0cmluZyhyYWRpeCkgKyByZW0xLnRvSW50KCkudG9TdHJpbmcocmFkaXgpO1xyXG4gICAgICAgIH0gZWxzZVxyXG4gICAgICAgICAgICByZXR1cm4gJy0nICsgdGhpcy5uZWcoKS50b1N0cmluZyhyYWRpeCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gRG8gc2V2ZXJhbCAoNikgZGlnaXRzIGVhY2ggdGltZSB0aHJvdWdoIHRoZSBsb29wLCBzbyBhcyB0b1xyXG4gICAgLy8gbWluaW1pemUgdGhlIGNhbGxzIHRvIHRoZSB2ZXJ5IGV4cGVuc2l2ZSBlbXVsYXRlZCBkaXYuXHJcbiAgICB2YXIgcmFkaXhUb1Bvd2VyID0gZnJvbU51bWJlcihwb3dfZGJsKHJhZGl4LCA2KSwgdGhpcy51bnNpZ25lZCksXHJcbiAgICAgICAgcmVtID0gdGhpcztcclxuICAgIHZhciByZXN1bHQgPSAnJztcclxuICAgIHdoaWxlICh0cnVlKSB7XHJcbiAgICAgICAgdmFyIHJlbURpdiA9IHJlbS5kaXYocmFkaXhUb1Bvd2VyKSxcclxuICAgICAgICAgICAgaW50dmFsID0gcmVtLnN1YihyZW1EaXYubXVsKHJhZGl4VG9Qb3dlcikpLnRvSW50KCkgPj4+IDAsXHJcbiAgICAgICAgICAgIGRpZ2l0cyA9IGludHZhbC50b1N0cmluZyhyYWRpeCk7XHJcbiAgICAgICAgcmVtID0gcmVtRGl2O1xyXG4gICAgICAgIGlmIChyZW0uaXNaZXJvKCkpXHJcbiAgICAgICAgICAgIHJldHVybiBkaWdpdHMgKyByZXN1bHQ7XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHdoaWxlIChkaWdpdHMubGVuZ3RoIDwgNilcclxuICAgICAgICAgICAgICAgIGRpZ2l0cyA9ICcwJyArIGRpZ2l0cztcclxuICAgICAgICAgICAgcmVzdWx0ID0gJycgKyBkaWdpdHMgKyByZXN1bHQ7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59O1xyXG5cclxuLyoqXHJcbiAqIEdldHMgdGhlIGhpZ2ggMzIgYml0cyBhcyBhIHNpZ25lZCBpbnRlZ2VyLlxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBTaWduZWQgaGlnaCBiaXRzXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmdldEhpZ2hCaXRzID0gZnVuY3Rpb24gZ2V0SGlnaEJpdHMoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5oaWdoO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEdldHMgdGhlIGhpZ2ggMzIgYml0cyBhcyBhbiB1bnNpZ25lZCBpbnRlZ2VyLlxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBVbnNpZ25lZCBoaWdoIGJpdHNcclxuICovXHJcbkxvbmdQcm90b3R5cGUuZ2V0SGlnaEJpdHNVbnNpZ25lZCA9IGZ1bmN0aW9uIGdldEhpZ2hCaXRzVW5zaWduZWQoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5oaWdoID4+PiAwO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEdldHMgdGhlIGxvdyAzMiBiaXRzIGFzIGEgc2lnbmVkIGludGVnZXIuXHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFNpZ25lZCBsb3cgYml0c1xyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5nZXRMb3dCaXRzID0gZnVuY3Rpb24gZ2V0TG93Qml0cygpIHtcclxuICAgIHJldHVybiB0aGlzLmxvdztcclxufTtcclxuXHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBsb3cgMzIgYml0cyBhcyBhbiB1bnNpZ25lZCBpbnRlZ2VyLlxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBVbnNpZ25lZCBsb3cgYml0c1xyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5nZXRMb3dCaXRzVW5zaWduZWQgPSBmdW5jdGlvbiBnZXRMb3dCaXRzVW5zaWduZWQoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5sb3cgPj4+IDA7XHJcbn07XHJcblxyXG4vKipcclxuICogR2V0cyB0aGUgbnVtYmVyIG9mIGJpdHMgbmVlZGVkIHRvIHJlcHJlc2VudCB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhpcyBMb25nLlxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5nZXROdW1CaXRzQWJzID0gZnVuY3Rpb24gZ2V0TnVtQml0c0FicygpIHtcclxuICAgIGlmICh0aGlzLmlzTmVnYXRpdmUoKSkgLy8gVW5zaWduZWQgTG9uZ3MgYXJlIG5ldmVyIG5lZ2F0aXZlXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZXEoTUlOX1ZBTFVFKSA/IDY0IDogdGhpcy5uZWcoKS5nZXROdW1CaXRzQWJzKCk7XHJcbiAgICB2YXIgdmFsID0gdGhpcy5oaWdoICE9IDAgPyB0aGlzLmhpZ2ggOiB0aGlzLmxvdztcclxuICAgIGZvciAodmFyIGJpdCA9IDMxOyBiaXQgPiAwOyBiaXQtLSlcclxuICAgICAgICBpZiAoKHZhbCAmICgxIDw8IGJpdCkpICE9IDApXHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgcmV0dXJuIHRoaXMuaGlnaCAhPSAwID8gYml0ICsgMzMgOiBiaXQgKyAxO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGVxdWFscyB6ZXJvLlxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUuaXNaZXJvID0gZnVuY3Rpb24gaXNaZXJvKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuaGlnaCA9PT0gMCAmJiB0aGlzLmxvdyA9PT0gMDtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBlcXVhbHMgemVyby4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNpc1plcm99LlxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUuZXF6ID0gTG9uZ1Byb3RvdHlwZS5pc1plcm87XHJcblxyXG4vKipcclxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbmVnYXRpdmUuXHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5pc05lZ2F0aXZlID0gZnVuY3Rpb24gaXNOZWdhdGl2ZSgpIHtcclxuICAgIHJldHVybiAhdGhpcy51bnNpZ25lZCAmJiB0aGlzLmhpZ2ggPCAwO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIHBvc2l0aXZlLlxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUuaXNQb3NpdGl2ZSA9IGZ1bmN0aW9uIGlzUG9zaXRpdmUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy51bnNpZ25lZCB8fCB0aGlzLmhpZ2ggPj0gMDtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBvZGQuXHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5pc09kZCA9IGZ1bmN0aW9uIGlzT2RkKCkge1xyXG4gICAgcmV0dXJuICh0aGlzLmxvdyAmIDEpID09PSAxO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGV2ZW4uXHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5pc0V2ZW4gPSBmdW5jdGlvbiBpc0V2ZW4oKSB7XHJcbiAgICByZXR1cm4gKHRoaXMubG93ICYgMSkgPT09IDA7XHJcbn07XHJcblxyXG4vKipcclxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZXF1YWxzIHRoZSBzcGVjaWZpZWQncy5cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gZXF1YWxzKG90aGVyKSB7XHJcbiAgICBpZiAoIWlzTG9uZyhvdGhlcikpXHJcbiAgICAgICAgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xyXG4gICAgaWYgKHRoaXMudW5zaWduZWQgIT09IG90aGVyLnVuc2lnbmVkICYmICh0aGlzLmhpZ2ggPj4+IDMxKSA9PT0gMSAmJiAob3RoZXIuaGlnaCA+Pj4gMzEpID09PSAxKVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIHJldHVybiB0aGlzLmhpZ2ggPT09IG90aGVyLmhpZ2ggJiYgdGhpcy5sb3cgPT09IG90aGVyLmxvdztcclxufTtcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBlcXVhbHMgdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2VxdWFsc30uXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5lcSA9IExvbmdQcm90b3R5cGUuZXF1YWxzO1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGRpZmZlcnMgZnJvbSB0aGUgc3BlY2lmaWVkJ3MuXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLm5vdEVxdWFscyA9IGZ1bmN0aW9uIG5vdEVxdWFscyhvdGhlcikge1xyXG4gICAgcmV0dXJuICF0aGlzLmVxKC8qIHZhbGlkYXRlcyAqLyBvdGhlcik7XHJcbn07XHJcblxyXG4vKipcclxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZGlmZmVycyBmcm9tIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNub3RFcXVhbHN9LlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUubmVxID0gTG9uZ1Byb3RvdHlwZS5ub3RFcXVhbHM7XHJcblxyXG4vKipcclxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZGlmZmVycyBmcm9tIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNub3RFcXVhbHN9LlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUubmUgPSBMb25nUHJvdG90eXBlLm5vdEVxdWFscztcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gdGhlIHNwZWNpZmllZCdzLlxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbiA9IGZ1bmN0aW9uIGxlc3NUaGFuKG90aGVyKSB7XHJcbiAgICByZXR1cm4gdGhpcy5jb21wKC8qIHZhbGlkYXRlcyAqLyBvdGhlcikgPCAwO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGxlc3MgdGhhbiB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbGVzc1RoYW59LlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUubHQgPSBMb25nUHJvdG90eXBlLmxlc3NUaGFuO1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmxlc3NUaGFuT3JFcXVhbCA9IGZ1bmN0aW9uIGxlc3NUaGFuT3JFcXVhbChvdGhlcikge1xyXG4gICAgcmV0dXJuIHRoaXMuY29tcCgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpIDw9IDA7XHJcbn07XHJcblxyXG4vKipcclxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNsZXNzVGhhbk9yRXF1YWx9LlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUubHRlID0gTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbk9yRXF1YWw7XHJcblxyXG4vKipcclxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNsZXNzVGhhbk9yRXF1YWx9LlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUubGUgPSBMb25nUHJvdG90eXBlLmxlc3NUaGFuT3JFcXVhbDtcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gdGhlIHNwZWNpZmllZCdzLlxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbiA9IGZ1bmN0aW9uIGdyZWF0ZXJUaGFuKG90aGVyKSB7XHJcbiAgICByZXR1cm4gdGhpcy5jb21wKC8qIHZhbGlkYXRlcyAqLyBvdGhlcikgPiAwO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjZ3JlYXRlclRoYW59LlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUuZ3QgPSBMb25nUHJvdG90eXBlLmdyZWF0ZXJUaGFuO1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmdyZWF0ZXJUaGFuT3JFcXVhbCA9IGZ1bmN0aW9uIGdyZWF0ZXJUaGFuT3JFcXVhbChvdGhlcikge1xyXG4gICAgcmV0dXJuIHRoaXMuY29tcCgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpID49IDA7XHJcbn07XHJcblxyXG4vKipcclxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNncmVhdGVyVGhhbk9yRXF1YWx9LlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUuZ3RlID0gTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbk9yRXF1YWw7XHJcblxyXG4vKipcclxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNncmVhdGVyVGhhbk9yRXF1YWx9LlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUuZ2UgPSBMb25nUHJvdG90eXBlLmdyZWF0ZXJUaGFuT3JFcXVhbDtcclxuXHJcbi8qKlxyXG4gKiBDb21wYXJlcyB0aGlzIExvbmcncyB2YWx1ZSB3aXRoIHRoZSBzcGVjaWZpZWQncy5cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSAwIGlmIHRoZXkgYXJlIHRoZSBzYW1lLCAxIGlmIHRoZSB0aGlzIGlzIGdyZWF0ZXIgYW5kIC0xXHJcbiAqICBpZiB0aGUgZ2l2ZW4gb25lIGlzIGdyZWF0ZXJcclxuICovXHJcbkxvbmdQcm90b3R5cGUuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUob3RoZXIpIHtcclxuICAgIGlmICghaXNMb25nKG90aGVyKSlcclxuICAgICAgICBvdGhlciA9IGZyb21WYWx1ZShvdGhlcik7XHJcbiAgICBpZiAodGhpcy5lcShvdGhlcikpXHJcbiAgICAgICAgcmV0dXJuIDA7XHJcbiAgICB2YXIgdGhpc05lZyA9IHRoaXMuaXNOZWdhdGl2ZSgpLFxyXG4gICAgICAgIG90aGVyTmVnID0gb3RoZXIuaXNOZWdhdGl2ZSgpO1xyXG4gICAgaWYgKHRoaXNOZWcgJiYgIW90aGVyTmVnKVxyXG4gICAgICAgIHJldHVybiAtMTtcclxuICAgIGlmICghdGhpc05lZyAmJiBvdGhlck5lZylcclxuICAgICAgICByZXR1cm4gMTtcclxuICAgIC8vIEF0IHRoaXMgcG9pbnQgdGhlIHNpZ24gYml0cyBhcmUgdGhlIHNhbWVcclxuICAgIGlmICghdGhpcy51bnNpZ25lZClcclxuICAgICAgICByZXR1cm4gdGhpcy5zdWIob3RoZXIpLmlzTmVnYXRpdmUoKSA/IC0xIDogMTtcclxuICAgIC8vIEJvdGggYXJlIHBvc2l0aXZlIGlmIGF0IGxlYXN0IG9uZSBpcyB1bnNpZ25lZFxyXG4gICAgcmV0dXJuIChvdGhlci5oaWdoID4+PiAwKSA+ICh0aGlzLmhpZ2ggPj4+IDApIHx8IChvdGhlci5oaWdoID09PSB0aGlzLmhpZ2ggJiYgKG90aGVyLmxvdyA+Pj4gMCkgPiAodGhpcy5sb3cgPj4+IDApKSA/IC0xIDogMTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBDb21wYXJlcyB0aGlzIExvbmcncyB2YWx1ZSB3aXRoIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNjb21wYXJlfS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge251bWJlcn0gMCBpZiB0aGV5IGFyZSB0aGUgc2FtZSwgMSBpZiB0aGUgdGhpcyBpcyBncmVhdGVyIGFuZCAtMVxyXG4gKiAgaWYgdGhlIGdpdmVuIG9uZSBpcyBncmVhdGVyXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmNvbXAgPSBMb25nUHJvdG90eXBlLmNvbXBhcmU7XHJcblxyXG4vKipcclxuICogTmVnYXRlcyB0aGlzIExvbmcncyB2YWx1ZS5cclxuICogQHJldHVybnMgeyFMb25nfSBOZWdhdGVkIExvbmdcclxuICovXHJcbkxvbmdQcm90b3R5cGUubmVnYXRlID0gZnVuY3Rpb24gbmVnYXRlKCkge1xyXG4gICAgaWYgKCF0aGlzLnVuc2lnbmVkICYmIHRoaXMuZXEoTUlOX1ZBTFVFKSlcclxuICAgICAgICByZXR1cm4gTUlOX1ZBTFVFO1xyXG4gICAgcmV0dXJuIHRoaXMubm90KCkuYWRkKE9ORSk7XHJcbn07XHJcblxyXG4vKipcclxuICogTmVnYXRlcyB0aGlzIExvbmcncyB2YWx1ZS4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNuZWdhdGV9LlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHJldHVybnMgeyFMb25nfSBOZWdhdGVkIExvbmdcclxuICovXHJcbkxvbmdQcm90b3R5cGUubmVnID0gTG9uZ1Byb3RvdHlwZS5uZWdhdGU7XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGUgc3VtIG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy5cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBhZGRlbmQgQWRkZW5kXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gU3VtXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIGFkZChhZGRlbmQpIHtcclxuICAgIGlmICghaXNMb25nKGFkZGVuZCkpXHJcbiAgICAgICAgYWRkZW5kID0gZnJvbVZhbHVlKGFkZGVuZCk7XHJcblxyXG4gICAgLy8gRGl2aWRlIGVhY2ggbnVtYmVyIGludG8gNCBjaHVua3Mgb2YgMTYgYml0cywgYW5kIHRoZW4gc3VtIHRoZSBjaHVua3MuXHJcblxyXG4gICAgdmFyIGE0OCA9IHRoaXMuaGlnaCA+Pj4gMTY7XHJcbiAgICB2YXIgYTMyID0gdGhpcy5oaWdoICYgMHhGRkZGO1xyXG4gICAgdmFyIGExNiA9IHRoaXMubG93ID4+PiAxNjtcclxuICAgIHZhciBhMDAgPSB0aGlzLmxvdyAmIDB4RkZGRjtcclxuXHJcbiAgICB2YXIgYjQ4ID0gYWRkZW5kLmhpZ2ggPj4+IDE2O1xyXG4gICAgdmFyIGIzMiA9IGFkZGVuZC5oaWdoICYgMHhGRkZGO1xyXG4gICAgdmFyIGIxNiA9IGFkZGVuZC5sb3cgPj4+IDE2O1xyXG4gICAgdmFyIGIwMCA9IGFkZGVuZC5sb3cgJiAweEZGRkY7XHJcblxyXG4gICAgdmFyIGM0OCA9IDAsIGMzMiA9IDAsIGMxNiA9IDAsIGMwMCA9IDA7XHJcbiAgICBjMDAgKz0gYTAwICsgYjAwO1xyXG4gICAgYzE2ICs9IGMwMCA+Pj4gMTY7XHJcbiAgICBjMDAgJj0gMHhGRkZGO1xyXG4gICAgYzE2ICs9IGExNiArIGIxNjtcclxuICAgIGMzMiArPSBjMTYgPj4+IDE2O1xyXG4gICAgYzE2ICY9IDB4RkZGRjtcclxuICAgIGMzMiArPSBhMzIgKyBiMzI7XHJcbiAgICBjNDggKz0gYzMyID4+PiAxNjtcclxuICAgIGMzMiAmPSAweEZGRkY7XHJcbiAgICBjNDggKz0gYTQ4ICsgYjQ4O1xyXG4gICAgYzQ4ICY9IDB4RkZGRjtcclxuICAgIHJldHVybiBmcm9tQml0cygoYzE2IDw8IDE2KSB8IGMwMCwgKGM0OCA8PCAxNikgfCBjMzIsIHRoaXMudW5zaWduZWQpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhlIGRpZmZlcmVuY2Ugb2YgdGhpcyBhbmQgdGhlIHNwZWNpZmllZCBMb25nLlxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IHN1YnRyYWhlbmQgU3VidHJhaGVuZFxyXG4gKiBAcmV0dXJucyB7IUxvbmd9IERpZmZlcmVuY2VcclxuICovXHJcbkxvbmdQcm90b3R5cGUuc3VidHJhY3QgPSBmdW5jdGlvbiBzdWJ0cmFjdChzdWJ0cmFoZW5kKSB7XHJcbiAgICBpZiAoIWlzTG9uZyhzdWJ0cmFoZW5kKSlcclxuICAgICAgICBzdWJ0cmFoZW5kID0gZnJvbVZhbHVlKHN1YnRyYWhlbmQpO1xyXG4gICAgcmV0dXJuIHRoaXMuYWRkKHN1YnRyYWhlbmQubmVnKCkpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhlIGRpZmZlcmVuY2Ugb2YgdGhpcyBhbmQgdGhlIHNwZWNpZmllZCBMb25nLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI3N1YnRyYWN0fS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gc3VidHJhaGVuZCBTdWJ0cmFoZW5kXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gRGlmZmVyZW5jZVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5zdWIgPSBMb25nUHJvdG90eXBlLnN1YnRyYWN0O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhlIHByb2R1Y3Qgb2YgdGhpcyBhbmQgdGhlIHNwZWNpZmllZCBMb25nLlxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG11bHRpcGxpZXIgTXVsdGlwbGllclxyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFByb2R1Y3RcclxuICovXHJcbkxvbmdQcm90b3R5cGUubXVsdGlwbHkgPSBmdW5jdGlvbiBtdWx0aXBseShtdWx0aXBsaWVyKSB7XHJcbiAgICBpZiAodGhpcy5pc1plcm8oKSlcclxuICAgICAgICByZXR1cm4gWkVSTztcclxuICAgIGlmICghaXNMb25nKG11bHRpcGxpZXIpKVxyXG4gICAgICAgIG11bHRpcGxpZXIgPSBmcm9tVmFsdWUobXVsdGlwbGllcik7XHJcblxyXG4gICAgLy8gdXNlIHdhc20gc3VwcG9ydCBpZiBwcmVzZW50XHJcbiAgICBpZiAod2FzbSkge1xyXG4gICAgICAgIHZhciBsb3cgPSB3YXNtLm11bCh0aGlzLmxvdyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5oaWdoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBtdWx0aXBsaWVyLmxvdyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgbXVsdGlwbGllci5oaWdoKTtcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHMobG93LCB3YXNtLmdldF9oaWdoKCksIHRoaXMudW5zaWduZWQpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChtdWx0aXBsaWVyLmlzWmVybygpKVxyXG4gICAgICAgIHJldHVybiBaRVJPO1xyXG4gICAgaWYgKHRoaXMuZXEoTUlOX1ZBTFVFKSlcclxuICAgICAgICByZXR1cm4gbXVsdGlwbGllci5pc09kZCgpID8gTUlOX1ZBTFVFIDogWkVSTztcclxuICAgIGlmIChtdWx0aXBsaWVyLmVxKE1JTl9WQUxVRSkpXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNPZGQoKSA/IE1JTl9WQUxVRSA6IFpFUk87XHJcblxyXG4gICAgaWYgKHRoaXMuaXNOZWdhdGl2ZSgpKSB7XHJcbiAgICAgICAgaWYgKG11bHRpcGxpZXIuaXNOZWdhdGl2ZSgpKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5uZWcoKS5tdWwobXVsdGlwbGllci5uZWcoKSk7XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5uZWcoKS5tdWwobXVsdGlwbGllcikubmVnKCk7XHJcbiAgICB9IGVsc2UgaWYgKG11bHRpcGxpZXIuaXNOZWdhdGl2ZSgpKVxyXG4gICAgICAgIHJldHVybiB0aGlzLm11bChtdWx0aXBsaWVyLm5lZygpKS5uZWcoKTtcclxuXHJcbiAgICAvLyBJZiBib3RoIGxvbmdzIGFyZSBzbWFsbCwgdXNlIGZsb2F0IG11bHRpcGxpY2F0aW9uXHJcbiAgICBpZiAodGhpcy5sdChUV09fUFdSXzI0KSAmJiBtdWx0aXBsaWVyLmx0KFRXT19QV1JfMjQpKVxyXG4gICAgICAgIHJldHVybiBmcm9tTnVtYmVyKHRoaXMudG9OdW1iZXIoKSAqIG11bHRpcGxpZXIudG9OdW1iZXIoKSwgdGhpcy51bnNpZ25lZCk7XHJcblxyXG4gICAgLy8gRGl2aWRlIGVhY2ggbG9uZyBpbnRvIDQgY2h1bmtzIG9mIDE2IGJpdHMsIGFuZCB0aGVuIGFkZCB1cCA0eDQgcHJvZHVjdHMuXHJcbiAgICAvLyBXZSBjYW4gc2tpcCBwcm9kdWN0cyB0aGF0IHdvdWxkIG92ZXJmbG93LlxyXG5cclxuICAgIHZhciBhNDggPSB0aGlzLmhpZ2ggPj4+IDE2O1xyXG4gICAgdmFyIGEzMiA9IHRoaXMuaGlnaCAmIDB4RkZGRjtcclxuICAgIHZhciBhMTYgPSB0aGlzLmxvdyA+Pj4gMTY7XHJcbiAgICB2YXIgYTAwID0gdGhpcy5sb3cgJiAweEZGRkY7XHJcblxyXG4gICAgdmFyIGI0OCA9IG11bHRpcGxpZXIuaGlnaCA+Pj4gMTY7XHJcbiAgICB2YXIgYjMyID0gbXVsdGlwbGllci5oaWdoICYgMHhGRkZGO1xyXG4gICAgdmFyIGIxNiA9IG11bHRpcGxpZXIubG93ID4+PiAxNjtcclxuICAgIHZhciBiMDAgPSBtdWx0aXBsaWVyLmxvdyAmIDB4RkZGRjtcclxuXHJcbiAgICB2YXIgYzQ4ID0gMCwgYzMyID0gMCwgYzE2ID0gMCwgYzAwID0gMDtcclxuICAgIGMwMCArPSBhMDAgKiBiMDA7XHJcbiAgICBjMTYgKz0gYzAwID4+PiAxNjtcclxuICAgIGMwMCAmPSAweEZGRkY7XHJcbiAgICBjMTYgKz0gYTE2ICogYjAwO1xyXG4gICAgYzMyICs9IGMxNiA+Pj4gMTY7XHJcbiAgICBjMTYgJj0gMHhGRkZGO1xyXG4gICAgYzE2ICs9IGEwMCAqIGIxNjtcclxuICAgIGMzMiArPSBjMTYgPj4+IDE2O1xyXG4gICAgYzE2ICY9IDB4RkZGRjtcclxuICAgIGMzMiArPSBhMzIgKiBiMDA7XHJcbiAgICBjNDggKz0gYzMyID4+PiAxNjtcclxuICAgIGMzMiAmPSAweEZGRkY7XHJcbiAgICBjMzIgKz0gYTE2ICogYjE2O1xyXG4gICAgYzQ4ICs9IGMzMiA+Pj4gMTY7XHJcbiAgICBjMzIgJj0gMHhGRkZGO1xyXG4gICAgYzMyICs9IGEwMCAqIGIzMjtcclxuICAgIGM0OCArPSBjMzIgPj4+IDE2O1xyXG4gICAgYzMyICY9IDB4RkZGRjtcclxuICAgIGM0OCArPSBhNDggKiBiMDAgKyBhMzIgKiBiMTYgKyBhMTYgKiBiMzIgKyBhMDAgKiBiNDg7XHJcbiAgICBjNDggJj0gMHhGRkZGO1xyXG4gICAgcmV0dXJuIGZyb21CaXRzKChjMTYgPDwgMTYpIHwgYzAwLCAoYzQ4IDw8IDE2KSB8IGMzMiwgdGhpcy51bnNpZ25lZCk7XHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGUgcHJvZHVjdCBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbXVsdGlwbHl9LlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBtdWx0aXBsaWVyIE11bHRpcGxpZXJcclxuICogQHJldHVybnMgeyFMb25nfSBQcm9kdWN0XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLm11bCA9IExvbmdQcm90b3R5cGUubXVsdGlwbHk7XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGlzIExvbmcgZGl2aWRlZCBieSB0aGUgc3BlY2lmaWVkLiBUaGUgcmVzdWx0IGlzIHNpZ25lZCBpZiB0aGlzIExvbmcgaXMgc2lnbmVkIG9yXHJcbiAqICB1bnNpZ25lZCBpZiB0aGlzIExvbmcgaXMgdW5zaWduZWQuXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gZGl2aXNvciBEaXZpc29yXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gUXVvdGllbnRcclxuICovXHJcbkxvbmdQcm90b3R5cGUuZGl2aWRlID0gZnVuY3Rpb24gZGl2aWRlKGRpdmlzb3IpIHtcclxuICAgIGlmICghaXNMb25nKGRpdmlzb3IpKVxyXG4gICAgICAgIGRpdmlzb3IgPSBmcm9tVmFsdWUoZGl2aXNvcik7XHJcbiAgICBpZiAoZGl2aXNvci5pc1plcm8oKSlcclxuICAgICAgICB0aHJvdyBFcnJvcignZGl2aXNpb24gYnkgemVybycpO1xyXG5cclxuICAgIC8vIHVzZSB3YXNtIHN1cHBvcnQgaWYgcHJlc2VudFxyXG4gICAgaWYgKHdhc20pIHtcclxuICAgICAgICAvLyBndWFyZCBhZ2FpbnN0IHNpZ25lZCBkaXZpc2lvbiBvdmVyZmxvdzogdGhlIGxhcmdlc3RcclxuICAgICAgICAvLyBuZWdhdGl2ZSBudW1iZXIgLyAtMSB3b3VsZCBiZSAxIGxhcmdlciB0aGFuIHRoZSBsYXJnZXN0XHJcbiAgICAgICAgLy8gcG9zaXRpdmUgbnVtYmVyLCBkdWUgdG8gdHdvJ3MgY29tcGxlbWVudC5cclxuICAgICAgICBpZiAoIXRoaXMudW5zaWduZWQgJiZcclxuICAgICAgICAgICAgdGhpcy5oaWdoID09PSAtMHg4MDAwMDAwMCAmJlxyXG4gICAgICAgICAgICBkaXZpc29yLmxvdyA9PT0gLTEgJiYgZGl2aXNvci5oaWdoID09PSAtMSkge1xyXG4gICAgICAgICAgICAvLyBiZSBjb25zaXN0ZW50IHdpdGggbm9uLXdhc20gY29kZSBwYXRoXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgbG93ID0gKHRoaXMudW5zaWduZWQgPyB3YXNtLmRpdl91IDogd2FzbS5kaXZfcykoXHJcbiAgICAgICAgICAgIHRoaXMubG93LFxyXG4gICAgICAgICAgICB0aGlzLmhpZ2gsXHJcbiAgICAgICAgICAgIGRpdmlzb3IubG93LFxyXG4gICAgICAgICAgICBkaXZpc29yLmhpZ2hcclxuICAgICAgICApO1xyXG4gICAgICAgIHJldHVybiBmcm9tQml0cyhsb3csIHdhc20uZ2V0X2hpZ2goKSwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuaXNaZXJvKCkpXHJcbiAgICAgICAgcmV0dXJuIHRoaXMudW5zaWduZWQgPyBVWkVSTyA6IFpFUk87XHJcbiAgICB2YXIgYXBwcm94LCByZW0sIHJlcztcclxuICAgIGlmICghdGhpcy51bnNpZ25lZCkge1xyXG4gICAgICAgIC8vIFRoaXMgc2VjdGlvbiBpcyBvbmx5IHJlbGV2YW50IGZvciBzaWduZWQgbG9uZ3MgYW5kIGlzIGRlcml2ZWQgZnJvbSB0aGVcclxuICAgICAgICAvLyBjbG9zdXJlIGxpYnJhcnkgYXMgYSB3aG9sZS5cclxuICAgICAgICBpZiAodGhpcy5lcShNSU5fVkFMVUUpKSB7XHJcbiAgICAgICAgICAgIGlmIChkaXZpc29yLmVxKE9ORSkgfHwgZGl2aXNvci5lcShORUdfT05FKSlcclxuICAgICAgICAgICAgICAgIHJldHVybiBNSU5fVkFMVUU7ICAvLyByZWNhbGwgdGhhdCAtTUlOX1ZBTFVFID09IE1JTl9WQUxVRVxyXG4gICAgICAgICAgICBlbHNlIGlmIChkaXZpc29yLmVxKE1JTl9WQUxVRSkpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gT05FO1xyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vIEF0IHRoaXMgcG9pbnQsIHdlIGhhdmUgfG90aGVyfCA+PSAyLCBzbyB8dGhpcy9vdGhlcnwgPCB8TUlOX1ZBTFVFfC5cclxuICAgICAgICAgICAgICAgIHZhciBoYWxmVGhpcyA9IHRoaXMuc2hyKDEpO1xyXG4gICAgICAgICAgICAgICAgYXBwcm94ID0gaGFsZlRoaXMuZGl2KGRpdmlzb3IpLnNobCgxKTtcclxuICAgICAgICAgICAgICAgIGlmIChhcHByb3guZXEoWkVSTykpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGl2aXNvci5pc05lZ2F0aXZlKCkgPyBPTkUgOiBORUdfT05FO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICByZW0gPSB0aGlzLnN1YihkaXZpc29yLm11bChhcHByb3gpKTtcclxuICAgICAgICAgICAgICAgICAgICByZXMgPSBhcHByb3guYWRkKHJlbS5kaXYoZGl2aXNvcikpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXM7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgaWYgKGRpdmlzb3IuZXEoTUlOX1ZBTFVFKSlcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudW5zaWduZWQgPyBVWkVSTyA6IFpFUk87XHJcbiAgICAgICAgaWYgKHRoaXMuaXNOZWdhdGl2ZSgpKSB7XHJcbiAgICAgICAgICAgIGlmIChkaXZpc29yLmlzTmVnYXRpdmUoKSlcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm5lZygpLmRpdihkaXZpc29yLm5lZygpKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubmVnKCkuZGl2KGRpdmlzb3IpLm5lZygpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoZGl2aXNvci5pc05lZ2F0aXZlKCkpXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRpdihkaXZpc29yLm5lZygpKS5uZWcoKTtcclxuICAgICAgICByZXMgPSBaRVJPO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICAvLyBUaGUgYWxnb3JpdGhtIGJlbG93IGhhcyBub3QgYmVlbiBtYWRlIGZvciB1bnNpZ25lZCBsb25ncy4gSXQncyB0aGVyZWZvcmVcclxuICAgICAgICAvLyByZXF1aXJlZCB0byB0YWtlIHNwZWNpYWwgY2FyZSBvZiB0aGUgTVNCIHByaW9yIHRvIHJ1bm5pbmcgaXQuXHJcbiAgICAgICAgaWYgKCFkaXZpc29yLnVuc2lnbmVkKVxyXG4gICAgICAgICAgICBkaXZpc29yID0gZGl2aXNvci50b1Vuc2lnbmVkKCk7XHJcbiAgICAgICAgaWYgKGRpdmlzb3IuZ3QodGhpcykpXHJcbiAgICAgICAgICAgIHJldHVybiBVWkVSTztcclxuICAgICAgICBpZiAoZGl2aXNvci5ndCh0aGlzLnNocnUoMSkpKSAvLyAxNSA+Pj4gMSA9IDcgOyB3aXRoIGRpdmlzb3IgPSA4IDsgdHJ1ZVxyXG4gICAgICAgICAgICByZXR1cm4gVU9ORTtcclxuICAgICAgICByZXMgPSBVWkVSTztcclxuICAgIH1cclxuXHJcbiAgICAvLyBSZXBlYXQgdGhlIGZvbGxvd2luZyB1bnRpbCB0aGUgcmVtYWluZGVyIGlzIGxlc3MgdGhhbiBvdGhlcjogIGZpbmQgYVxyXG4gICAgLy8gZmxvYXRpbmctcG9pbnQgdGhhdCBhcHByb3hpbWF0ZXMgcmVtYWluZGVyIC8gb3RoZXIgKmZyb20gYmVsb3cqLCBhZGQgdGhpc1xyXG4gICAgLy8gaW50byB0aGUgcmVzdWx0LCBhbmQgc3VidHJhY3QgaXQgZnJvbSB0aGUgcmVtYWluZGVyLiAgSXQgaXMgY3JpdGljYWwgdGhhdFxyXG4gICAgLy8gdGhlIGFwcHJveGltYXRlIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgcmVhbCB2YWx1ZSBzbyB0aGF0IHRoZVxyXG4gICAgLy8gcmVtYWluZGVyIG5ldmVyIGJlY29tZXMgbmVnYXRpdmUuXHJcbiAgICByZW0gPSB0aGlzO1xyXG4gICAgd2hpbGUgKHJlbS5ndGUoZGl2aXNvcikpIHtcclxuICAgICAgICAvLyBBcHByb3hpbWF0ZSB0aGUgcmVzdWx0IG9mIGRpdmlzaW9uLiBUaGlzIG1heSBiZSBhIGxpdHRsZSBncmVhdGVyIG9yXHJcbiAgICAgICAgLy8gc21hbGxlciB0aGFuIHRoZSBhY3R1YWwgdmFsdWUuXHJcbiAgICAgICAgYXBwcm94ID0gTWF0aC5tYXgoMSwgTWF0aC5mbG9vcihyZW0udG9OdW1iZXIoKSAvIGRpdmlzb3IudG9OdW1iZXIoKSkpO1xyXG5cclxuICAgICAgICAvLyBXZSB3aWxsIHR3ZWFrIHRoZSBhcHByb3hpbWF0ZSByZXN1bHQgYnkgY2hhbmdpbmcgaXQgaW4gdGhlIDQ4LXRoIGRpZ2l0IG9yXHJcbiAgICAgICAgLy8gdGhlIHNtYWxsZXN0IG5vbi1mcmFjdGlvbmFsIGRpZ2l0LCB3aGljaGV2ZXIgaXMgbGFyZ2VyLlxyXG4gICAgICAgIHZhciBsb2cyID0gTWF0aC5jZWlsKE1hdGgubG9nKGFwcHJveCkgLyBNYXRoLkxOMiksXHJcbiAgICAgICAgICAgIGRlbHRhID0gKGxvZzIgPD0gNDgpID8gMSA6IHBvd19kYmwoMiwgbG9nMiAtIDQ4KSxcclxuXHJcbiAgICAgICAgLy8gRGVjcmVhc2UgdGhlIGFwcHJveGltYXRpb24gdW50aWwgaXQgaXMgc21hbGxlciB0aGFuIHRoZSByZW1haW5kZXIuICBOb3RlXHJcbiAgICAgICAgLy8gdGhhdCBpZiBpdCBpcyB0b28gbGFyZ2UsIHRoZSBwcm9kdWN0IG92ZXJmbG93cyBhbmQgaXMgbmVnYXRpdmUuXHJcbiAgICAgICAgICAgIGFwcHJveFJlcyA9IGZyb21OdW1iZXIoYXBwcm94KSxcclxuICAgICAgICAgICAgYXBwcm94UmVtID0gYXBwcm94UmVzLm11bChkaXZpc29yKTtcclxuICAgICAgICB3aGlsZSAoYXBwcm94UmVtLmlzTmVnYXRpdmUoKSB8fCBhcHByb3hSZW0uZ3QocmVtKSkge1xyXG4gICAgICAgICAgICBhcHByb3ggLT0gZGVsdGE7XHJcbiAgICAgICAgICAgIGFwcHJveFJlcyA9IGZyb21OdW1iZXIoYXBwcm94LCB0aGlzLnVuc2lnbmVkKTtcclxuICAgICAgICAgICAgYXBwcm94UmVtID0gYXBwcm94UmVzLm11bChkaXZpc29yKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFdlIGtub3cgdGhlIGFuc3dlciBjYW4ndCBiZSB6ZXJvLi4uIGFuZCBhY3R1YWxseSwgemVybyB3b3VsZCBjYXVzZVxyXG4gICAgICAgIC8vIGluZmluaXRlIHJlY3Vyc2lvbiBzaW5jZSB3ZSB3b3VsZCBtYWtlIG5vIHByb2dyZXNzLlxyXG4gICAgICAgIGlmIChhcHByb3hSZXMuaXNaZXJvKCkpXHJcbiAgICAgICAgICAgIGFwcHJveFJlcyA9IE9ORTtcclxuXHJcbiAgICAgICAgcmVzID0gcmVzLmFkZChhcHByb3hSZXMpO1xyXG4gICAgICAgIHJlbSA9IHJlbS5zdWIoYXBwcm94UmVtKTtcclxuICAgIH1cclxuICAgIHJldHVybiByZXM7XHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGlzIExvbmcgZGl2aWRlZCBieSB0aGUgc3BlY2lmaWVkLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2RpdmlkZX0uXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IGRpdmlzb3IgRGl2aXNvclxyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFF1b3RpZW50XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmRpdiA9IExvbmdQcm90b3R5cGUuZGl2aWRlO1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhpcyBMb25nIG1vZHVsbyB0aGUgc3BlY2lmaWVkLlxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IGRpdmlzb3IgRGl2aXNvclxyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFJlbWFpbmRlclxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5tb2R1bG8gPSBmdW5jdGlvbiBtb2R1bG8oZGl2aXNvcikge1xyXG4gICAgaWYgKCFpc0xvbmcoZGl2aXNvcikpXHJcbiAgICAgICAgZGl2aXNvciA9IGZyb21WYWx1ZShkaXZpc29yKTtcclxuXHJcbiAgICAvLyB1c2Ugd2FzbSBzdXBwb3J0IGlmIHByZXNlbnRcclxuICAgIGlmICh3YXNtKSB7XHJcbiAgICAgICAgdmFyIGxvdyA9ICh0aGlzLnVuc2lnbmVkID8gd2FzbS5yZW1fdSA6IHdhc20ucmVtX3MpKFxyXG4gICAgICAgICAgICB0aGlzLmxvdyxcclxuICAgICAgICAgICAgdGhpcy5oaWdoLFxyXG4gICAgICAgICAgICBkaXZpc29yLmxvdyxcclxuICAgICAgICAgICAgZGl2aXNvci5oaWdoXHJcbiAgICAgICAgKTtcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHMobG93LCB3YXNtLmdldF9oaWdoKCksIHRoaXMudW5zaWduZWQpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzLnN1Yih0aGlzLmRpdihkaXZpc29yKS5tdWwoZGl2aXNvcikpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhpcyBMb25nIG1vZHVsbyB0aGUgc3BlY2lmaWVkLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI21vZHVsb30uXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IGRpdmlzb3IgRGl2aXNvclxyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFJlbWFpbmRlclxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5tb2QgPSBMb25nUHJvdG90eXBlLm1vZHVsbztcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyBtb2R1bG8gdGhlIHNwZWNpZmllZC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNtb2R1bG99LlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBkaXZpc29yIERpdmlzb3JcclxuICogQHJldHVybnMgeyFMb25nfSBSZW1haW5kZXJcclxuICovXHJcbkxvbmdQcm90b3R5cGUucmVtID0gTG9uZ1Byb3RvdHlwZS5tb2R1bG87XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGUgYml0d2lzZSBOT1Qgb2YgdGhpcyBMb25nLlxyXG4gKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLm5vdCA9IGZ1bmN0aW9uIG5vdCgpIHtcclxuICAgIHJldHVybiBmcm9tQml0cyh+dGhpcy5sb3csIH50aGlzLmhpZ2gsIHRoaXMudW5zaWduZWQpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhlIGJpdHdpc2UgQU5EIG9mIHRoaXMgTG9uZyBhbmQgdGhlIHNwZWNpZmllZC5cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciBMb25nXHJcbiAqIEByZXR1cm5zIHshTG9uZ31cclxuICovXHJcbkxvbmdQcm90b3R5cGUuYW5kID0gZnVuY3Rpb24gYW5kKG90aGVyKSB7XHJcbiAgICBpZiAoIWlzTG9uZyhvdGhlcikpXHJcbiAgICAgICAgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xyXG4gICAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93ICYgb3RoZXIubG93LCB0aGlzLmhpZ2ggJiBvdGhlci5oaWdoLCB0aGlzLnVuc2lnbmVkKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBiaXR3aXNlIE9SIG9mIHRoaXMgTG9uZyBhbmQgdGhlIHNwZWNpZmllZC5cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciBMb25nXHJcbiAqIEByZXR1cm5zIHshTG9uZ31cclxuICovXHJcbkxvbmdQcm90b3R5cGUub3IgPSBmdW5jdGlvbiBvcihvdGhlcikge1xyXG4gICAgaWYgKCFpc0xvbmcob3RoZXIpKVxyXG4gICAgICAgIG90aGVyID0gZnJvbVZhbHVlKG90aGVyKTtcclxuICAgIHJldHVybiBmcm9tQml0cyh0aGlzLmxvdyB8IG90aGVyLmxvdywgdGhpcy5oaWdoIHwgb3RoZXIuaGlnaCwgdGhpcy51bnNpZ25lZCk7XHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGUgYml0d2lzZSBYT1Igb2YgdGhpcyBMb25nIGFuZCB0aGUgZ2l2ZW4gb25lLlxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIExvbmdcclxuICogQHJldHVybnMgeyFMb25nfVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS54b3IgPSBmdW5jdGlvbiB4b3Iob3RoZXIpIHtcclxuICAgIGlmICghaXNMb25nKG90aGVyKSlcclxuICAgICAgICBvdGhlciA9IGZyb21WYWx1ZShvdGhlcik7XHJcbiAgICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3cgXiBvdGhlci5sb3csIHRoaXMuaGlnaCBeIG90aGVyLmhpZ2gsIHRoaXMudW5zaWduZWQpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBzaGlmdGVkIHRvIHRoZSBsZWZ0IGJ5IHRoZSBnaXZlbiBhbW91bnQuXHJcbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnNoaWZ0TGVmdCA9IGZ1bmN0aW9uIHNoaWZ0TGVmdChudW1CaXRzKSB7XHJcbiAgICBpZiAoaXNMb25nKG51bUJpdHMpKVxyXG4gICAgICAgIG51bUJpdHMgPSBudW1CaXRzLnRvSW50KCk7XHJcbiAgICBpZiAoKG51bUJpdHMgJj0gNjMpID09PSAwKVxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgZWxzZSBpZiAobnVtQml0cyA8IDMyKVxyXG4gICAgICAgIHJldHVybiBmcm9tQml0cyh0aGlzLmxvdyA8PCBudW1CaXRzLCAodGhpcy5oaWdoIDw8IG51bUJpdHMpIHwgKHRoaXMubG93ID4+PiAoMzIgLSBudW1CaXRzKSksIHRoaXMudW5zaWduZWQpO1xyXG4gICAgZWxzZVxyXG4gICAgICAgIHJldHVybiBmcm9tQml0cygwLCB0aGlzLmxvdyA8PCAobnVtQml0cyAtIDMyKSwgdGhpcy51bnNpZ25lZCk7XHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIHNoaWZ0ZWQgdG8gdGhlIGxlZnQgYnkgdGhlIGdpdmVuIGFtb3VudC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNzaGlmdExlZnR9LlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcclxuICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcclxuICovXHJcbkxvbmdQcm90b3R5cGUuc2hsID0gTG9uZ1Byb3RvdHlwZS5zaGlmdExlZnQ7XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIGFyaXRobWV0aWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuXHJcbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnNoaWZ0UmlnaHQgPSBmdW5jdGlvbiBzaGlmdFJpZ2h0KG51bUJpdHMpIHtcclxuICAgIGlmIChpc0xvbmcobnVtQml0cykpXHJcbiAgICAgICAgbnVtQml0cyA9IG51bUJpdHMudG9JbnQoKTtcclxuICAgIGlmICgobnVtQml0cyAmPSA2MykgPT09IDApXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICBlbHNlIGlmIChudW1CaXRzIDwgMzIpXHJcbiAgICAgICAgcmV0dXJuIGZyb21CaXRzKCh0aGlzLmxvdyA+Pj4gbnVtQml0cykgfCAodGhpcy5oaWdoIDw8ICgzMiAtIG51bUJpdHMpKSwgdGhpcy5oaWdoID4+IG51bUJpdHMsIHRoaXMudW5zaWduZWQpO1xyXG4gICAgZWxzZVxyXG4gICAgICAgIHJldHVybiBmcm9tQml0cyh0aGlzLmhpZ2ggPj4gKG51bUJpdHMgLSAzMiksIHRoaXMuaGlnaCA+PSAwID8gMCA6IC0xLCB0aGlzLnVuc2lnbmVkKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgYXJpdGhtZXRpY2FsbHkgc2hpZnRlZCB0byB0aGUgcmlnaHQgYnkgdGhlIGdpdmVuIGFtb3VudC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNzaGlmdFJpZ2h0fS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnNociA9IExvbmdQcm90b3R5cGUuc2hpZnRSaWdodDtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgbG9naWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuXHJcbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnNoaWZ0UmlnaHRVbnNpZ25lZCA9IGZ1bmN0aW9uIHNoaWZ0UmlnaHRVbnNpZ25lZChudW1CaXRzKSB7XHJcbiAgICBpZiAoaXNMb25nKG51bUJpdHMpKVxyXG4gICAgICAgIG51bUJpdHMgPSBudW1CaXRzLnRvSW50KCk7XHJcbiAgICBudW1CaXRzICY9IDYzO1xyXG4gICAgaWYgKG51bUJpdHMgPT09IDApXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICBlbHNlIHtcclxuICAgICAgICB2YXIgaGlnaCA9IHRoaXMuaGlnaDtcclxuICAgICAgICBpZiAobnVtQml0cyA8IDMyKSB7XHJcbiAgICAgICAgICAgIHZhciBsb3cgPSB0aGlzLmxvdztcclxuICAgICAgICAgICAgcmV0dXJuIGZyb21CaXRzKChsb3cgPj4+IG51bUJpdHMpIHwgKGhpZ2ggPDwgKDMyIC0gbnVtQml0cykpLCBoaWdoID4+PiBudW1CaXRzLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgICAgICB9IGVsc2UgaWYgKG51bUJpdHMgPT09IDMyKVxyXG4gICAgICAgICAgICByZXR1cm4gZnJvbUJpdHMoaGlnaCwgMCwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICByZXR1cm4gZnJvbUJpdHMoaGlnaCA+Pj4gKG51bUJpdHMgLSAzMiksIDAsIHRoaXMudW5zaWduZWQpO1xyXG4gICAgfVxyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBsb2dpY2FsbHkgc2hpZnRlZCB0byB0aGUgcmlnaHQgYnkgdGhlIGdpdmVuIGFtb3VudC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNzaGlmdFJpZ2h0VW5zaWduZWR9LlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcclxuICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcclxuICovXHJcbkxvbmdQcm90b3R5cGUuc2hydSA9IExvbmdQcm90b3R5cGUuc2hpZnRSaWdodFVuc2lnbmVkO1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBsb2dpY2FsbHkgc2hpZnRlZCB0byB0aGUgcmlnaHQgYnkgdGhlIGdpdmVuIGFtb3VudC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNzaGlmdFJpZ2h0VW5zaWduZWR9LlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcclxuICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcclxuICovXHJcbkxvbmdQcm90b3R5cGUuc2hyX3UgPSBMb25nUHJvdG90eXBlLnNoaWZ0UmlnaHRVbnNpZ25lZDtcclxuXHJcbi8qKlxyXG4gKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gc2lnbmVkLlxyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFNpZ25lZCBsb25nXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnRvU2lnbmVkID0gZnVuY3Rpb24gdG9TaWduZWQoKSB7XHJcbiAgICBpZiAoIXRoaXMudW5zaWduZWQpXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3csIHRoaXMuaGlnaCwgZmFsc2UpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIENvbnZlcnRzIHRoaXMgTG9uZyB0byB1bnNpZ25lZC5cclxuICogQHJldHVybnMgeyFMb25nfSBVbnNpZ25lZCBsb25nXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnRvVW5zaWduZWQgPSBmdW5jdGlvbiB0b1Vuc2lnbmVkKCkge1xyXG4gICAgaWYgKHRoaXMudW5zaWduZWQpXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3csIHRoaXMuaGlnaCwgdHJ1ZSk7XHJcbn07XHJcblxyXG4vKipcclxuICogQ29udmVydHMgdGhpcyBMb25nIHRvIGl0cyBieXRlIHJlcHJlc2VudGF0aW9uLlxyXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSBsZSBXaGV0aGVyIGxpdHRsZSBvciBiaWcgZW5kaWFuLCBkZWZhdWx0cyB0byBiaWcgZW5kaWFuXHJcbiAqIEByZXR1cm5zIHshQXJyYXkuPG51bWJlcj59IEJ5dGUgcmVwcmVzZW50YXRpb25cclxuICovXHJcbkxvbmdQcm90b3R5cGUudG9CeXRlcyA9IGZ1bmN0aW9uIHRvQnl0ZXMobGUpIHtcclxuICAgIHJldHVybiBsZSA/IHRoaXMudG9CeXRlc0xFKCkgOiB0aGlzLnRvQnl0ZXNCRSgpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIENvbnZlcnRzIHRoaXMgTG9uZyB0byBpdHMgbGl0dGxlIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uLlxyXG4gKiBAcmV0dXJucyB7IUFycmF5LjxudW1iZXI+fSBMaXR0bGUgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb25cclxuICovXHJcbkxvbmdQcm90b3R5cGUudG9CeXRlc0xFID0gZnVuY3Rpb24gdG9CeXRlc0xFKCkge1xyXG4gICAgdmFyIGhpID0gdGhpcy5oaWdoLFxyXG4gICAgICAgIGxvID0gdGhpcy5sb3c7XHJcbiAgICByZXR1cm4gW1xyXG4gICAgICAgIGxvICAgICAgICAmIDB4ZmYsXHJcbiAgICAgICAgbG8gPj4+ICA4ICYgMHhmZixcclxuICAgICAgICBsbyA+Pj4gMTYgJiAweGZmLFxyXG4gICAgICAgIGxvID4+PiAyNCAgICAgICAsXHJcbiAgICAgICAgaGkgICAgICAgICYgMHhmZixcclxuICAgICAgICBoaSA+Pj4gIDggJiAweGZmLFxyXG4gICAgICAgIGhpID4+PiAxNiAmIDB4ZmYsXHJcbiAgICAgICAgaGkgPj4+IDI0XHJcbiAgICBdO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIENvbnZlcnRzIHRoaXMgTG9uZyB0byBpdHMgYmlnIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uLlxyXG4gKiBAcmV0dXJucyB7IUFycmF5LjxudW1iZXI+fSBCaWcgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb25cclxuICovXHJcbkxvbmdQcm90b3R5cGUudG9CeXRlc0JFID0gZnVuY3Rpb24gdG9CeXRlc0JFKCkge1xyXG4gICAgdmFyIGhpID0gdGhpcy5oaWdoLFxyXG4gICAgICAgIGxvID0gdGhpcy5sb3c7XHJcbiAgICByZXR1cm4gW1xyXG4gICAgICAgIGhpID4+PiAyNCAgICAgICAsXHJcbiAgICAgICAgaGkgPj4+IDE2ICYgMHhmZixcclxuICAgICAgICBoaSA+Pj4gIDggJiAweGZmLFxyXG4gICAgICAgIGhpICAgICAgICAmIDB4ZmYsXHJcbiAgICAgICAgbG8gPj4+IDI0ICAgICAgICxcclxuICAgICAgICBsbyA+Pj4gMTYgJiAweGZmLFxyXG4gICAgICAgIGxvID4+PiAgOCAmIDB4ZmYsXHJcbiAgICAgICAgbG8gICAgICAgICYgMHhmZlxyXG4gICAgXTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBDcmVhdGVzIGEgTG9uZyBmcm9tIGl0cyBieXRlIHJlcHJlc2VudGF0aW9uLlxyXG4gKiBAcGFyYW0geyFBcnJheS48bnVtYmVyPn0gYnl0ZXMgQnl0ZSByZXByZXNlbnRhdGlvblxyXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXHJcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IGxlIFdoZXRoZXIgbGl0dGxlIG9yIGJpZyBlbmRpYW4sIGRlZmF1bHRzIHRvIGJpZyBlbmRpYW5cclxuICogQHJldHVybnMge0xvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcclxuICovXHJcbkxvbmcuZnJvbUJ5dGVzID0gZnVuY3Rpb24gZnJvbUJ5dGVzKGJ5dGVzLCB1bnNpZ25lZCwgbGUpIHtcclxuICAgIHJldHVybiBsZSA/IExvbmcuZnJvbUJ5dGVzTEUoYnl0ZXMsIHVuc2lnbmVkKSA6IExvbmcuZnJvbUJ5dGVzQkUoYnl0ZXMsIHVuc2lnbmVkKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBDcmVhdGVzIGEgTG9uZyBmcm9tIGl0cyBsaXR0bGUgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb24uXHJcbiAqIEBwYXJhbSB7IUFycmF5LjxudW1iZXI+fSBieXRlcyBMaXR0bGUgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb25cclxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxyXG4gKiBAcmV0dXJucyB7TG9uZ30gVGhlIGNvcnJlc3BvbmRpbmcgTG9uZyB2YWx1ZVxyXG4gKi9cclxuTG9uZy5mcm9tQnl0ZXNMRSA9IGZ1bmN0aW9uIGZyb21CeXRlc0xFKGJ5dGVzLCB1bnNpZ25lZCkge1xyXG4gICAgcmV0dXJuIG5ldyBMb25nKFxyXG4gICAgICAgIGJ5dGVzWzBdICAgICAgIHxcclxuICAgICAgICBieXRlc1sxXSA8PCAgOCB8XHJcbiAgICAgICAgYnl0ZXNbMl0gPDwgMTYgfFxyXG4gICAgICAgIGJ5dGVzWzNdIDw8IDI0LFxyXG4gICAgICAgIGJ5dGVzWzRdICAgICAgIHxcclxuICAgICAgICBieXRlc1s1XSA8PCAgOCB8XHJcbiAgICAgICAgYnl0ZXNbNl0gPDwgMTYgfFxyXG4gICAgICAgIGJ5dGVzWzddIDw8IDI0LFxyXG4gICAgICAgIHVuc2lnbmVkXHJcbiAgICApO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIENyZWF0ZXMgYSBMb25nIGZyb20gaXRzIGJpZyBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvbi5cclxuICogQHBhcmFtIHshQXJyYXkuPG51bWJlcj59IGJ5dGVzIEJpZyBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvblxyXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXHJcbiAqIEByZXR1cm5zIHtMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXHJcbiAqL1xyXG5Mb25nLmZyb21CeXRlc0JFID0gZnVuY3Rpb24gZnJvbUJ5dGVzQkUoYnl0ZXMsIHVuc2lnbmVkKSB7XHJcbiAgICByZXR1cm4gbmV3IExvbmcoXHJcbiAgICAgICAgYnl0ZXNbNF0gPDwgMjQgfFxyXG4gICAgICAgIGJ5dGVzWzVdIDw8IDE2IHxcclxuICAgICAgICBieXRlc1s2XSA8PCAgOCB8XHJcbiAgICAgICAgYnl0ZXNbN10sXHJcbiAgICAgICAgYnl0ZXNbMF0gPDwgMjQgfFxyXG4gICAgICAgIGJ5dGVzWzFdIDw8IDE2IHxcclxuICAgICAgICBieXRlc1syXSA8PCAgOCB8XHJcbiAgICAgICAgYnl0ZXNbM10sXHJcbiAgICAgICAgdW5zaWduZWRcclxuICAgICk7XHJcbn07XHJcblxuXG4vKioqLyB9KVxuLyoqKioqKi8gXSk7IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCBCU09OIGZyb20gJy4vLi4vLi4vLi4vLi4vdGhpcmRfcGFydHkvYnNvbi5jb21tb24uanMnO1xuXG5jb25zdCBic29uID0gQlNPTi5ic29uO1xuXG5jbGFzcyBCc29uIHtcbiAgICAvKipcbiAgICAgKiBTZXJpYWxpemUgYSBKYXZhc2NyaXB0IG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBvYmplY3QgVGhlIEphdmFzY3JpcHQgb2JqZWN0IHRvIHNlcmlhbGl6ZS5cbiAgICAgKiBAcmV0dXJuIFRoZSBCdWZmZXIgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIHNlcmlhbGl6ZWQgb2JqZWN0LlxuICAgICAqL1xuICAgIHN0YXRpYyBzZXJpYWxpemUgKG9iamVjdCkge1xuICAgICAgICByZXR1cm4gYnNvbi5zZXJpYWxpemUob2JqZWN0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZXNlcmlhbGl6ZSBkYXRhIGFzIEJTT04uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYnVmZmVyIFRoZSBidWZmZXIgY29udGFpbmluZyB0aGUgc2VyaWFsaXplZCBzZXQgb2YgQlNPTiBkb2N1bWVudHMuXG4gICAgICogQHJldHVybnMgVGhlIGRlc2VyaWFsaXplZCBKYXZhc2NyaXB0IE9iamVjdC5cbiAgICAgKi9cbiAgICBzdGF0aWMgZGVzZXJpYWxpemUgKG9iamVjdCkge1xuICAgICAgICByZXR1cm4gYnNvbi5kZXNlcmlhbGl6ZShvYmplY3QpO1xuICAgIH1cbn1cblxuZXhwb3J0IHsgQnNvbiB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBGcmFtZVR5cGUgfSBmcm9tICcuL2VudW1zL0ZyYW1lVHlwZS5qcyc7XG5pbXBvcnQgIHsgQnNvbiB9IGZyb20gJy4vLi4vdXRpbC9Cc29uLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBTZGxQYWNrZXRcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBFWFRSQV9QQVJDRUxfREFUQV9MRU5HVEhcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBIRUFERVJfU0laRVxuICogQHByb3BlcnR5IHtudW1iZXJ9IEhFQURFUl9TSVpFX1YxXG4gKiBAcHJvcGVydHkge251bWJlcn0gRU5DUllQVElPTl9NQVNLXG4gKiBAcHJvcGVydHkge251bWJlcn0gU0VSVklDRV9UWVBFX0NPTlRST0xcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBTRVJWSUNFX1RZUEVfUlBDXG4gKiBAcHJvcGVydHkge251bWJlcn0gU0VSVklDRV9UWVBFX1BDTVxuICogQHByb3BlcnR5IHtudW1iZXJ9IFNFUlZJQ0VfVFlQRV9WSURFT1xuICogQHByb3BlcnR5IHtudW1iZXJ9IFNFUlZJQ0VfVFlQRV9CVUxLX0RBVEFcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGUkFNRV9JTkZPX0hFQVJUX0JFQVRcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGUkFNRV9JTkZPX1NUQVJUX1NFUlZJQ0VcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGUkFNRV9JTkZPX1NUQVJUX1NFUlZJQ0VfQUNLXG4gKiBAcHJvcGVydHkge251bWJlcn0gRlJBTUVfSU5GT19TVEFSVF9TRVJWSUNFX05BS1xuICogQHByb3BlcnR5IHtudW1iZXJ9IEZSQU1FX0lORk9fRU5EX1NFUlZJQ0VcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGUkFNRV9JTkZPX0VORF9TRVJWSUNFX0FDS1xuICogQHByb3BlcnR5IHtudW1iZXJ9IEZSQU1FX0lORk9fRU5EX1NFUlZJQ0VfTkFLXG4gKiBAcHJvcGVydHkge251bWJlcn0gRlJBTUVfSU5GT19SRUdJU1RFUl9TRUNPTkRBUllfVFJBTlNQT1JUXG4gKiBAcHJvcGVydHkge251bWJlcn0gRlJBTUVfSU5GT19SRUdJU1RFUl9TRUNPTkRBUllfVFJBTlNQT1JUX0FDS1xuICogQHByb3BlcnR5IHtudW1iZXJ9IEZSQU1FX0lORk9fUkVHSVNURVJfU0VDT05EQVJZX1RSQU5TUE9SVF9OQUtcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGUkFNRV9JTkZPX1RSQU5TUE9SVF9FVkVOVF9VUERBVEVcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGUkFNRV9JTkZPX1NFUlZJQ0VfREFUQV9BQ0tcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGUkFNRV9JTkZPX0hFQVJUX0JFQVRfQUNLXG4gKiBAcHJvcGVydHkge251bWJlcn0gRlJBTUVfSU5GT19GSU5BTF9DT05ORVNDVVRJVkVfRlJBTUVcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGUkFNRV9JTkZPX1JFU0VSVkVEXG5cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IGdldFZlcnNpb25cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IGdldEVuY3J5cHRpb25cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IGdldFNlcnZpY2VUeXBlXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBnZXRGcmFtZUluZm9cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IGdldFNlc3Npb25JRFxuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gZ2V0TWVzc2FnZUlEXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBnZXREYXRhU2l6ZVxuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gc2V0UGF5bG9hZFxuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gZ2V0UGF5bG9hZFxuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gZ2V0RW5jcnlwdGlvbkJpdFxuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gZ2V0RnJhbWVUeXBlXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSB0b1VpbnQ4QXJyYXlcbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IHRvU3RyaW5nXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBjb25zdHJ1Y3RQYWNrZXRcbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IHB1dFRhZ1xuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gZ2V0VGFnXG4gKi9cblxuY2xhc3MgU2RsUGFja2V0IHtcbiAgICAvKipcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICogQHBhcmFtIHtOdW1iZXJ9IHZlcnNpb24gLSBQcm90b2NvbCB2ZXJzaW9uIHRvIHVzZVxuICAgICogQHBhcmFtIHtCb29sZWFufSBlbmNyeXB0aW9uIC0gV2hldGhlciBvciBub3QgdGhlIHBheWxvYWQgaW4gdGhpcyBwYWNrZXQgaXMgZW5jcnlwdGVkXG4gICAgKiBAcGFyYW0ge0ZyYW1lVHlwZX0gZnJhbWVUeXBlIC0gQSBudW1iZXIgcmVwcmVzZW50aW5nIHRoZSBwYWNrZXQgZnJhbWUgdHlwZVxuICAgICogQHBhcmFtIHtTZXJ2aWNlVHlwZX0gc2VydmljZVR5cGUgLSBUaGUgc2VydmljZSB0aGF0IHRoaXMgcGFja2V0IGlzIGFzc29jaWF0ZWQgd2l0aFxuICAgICogQHBhcmFtIHtOdW1iZXJ9IGZyYW1lSW5mbyAtIFNwZWNpZmljIGZyYW1lIGluZm8gcmVsYXRlZCB0byB0aGlzIHBhY2tldFxuICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlc3Npb25JRCAtIElEIHRoaXMgcGFja2V0IGlzIGFzc29jaWF0ZWQgd2l0aFxuICAgICogQHBhcmFtIHtOdW1iZXJ9IGRhdGFTaXplIC0gU2l6ZSBvZiB0aGUgcGF5bG9hZCB0aGF0IHdpbGwgYmUgYWRkZWRcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSBtZXNzYWdlSUQgLSBJRCBvZiB0aGlzIHNwZWNpZmljIHBhY2tldFxuICAgICogQHBhcmFtIHtVaW50OEFycmF5fSBwYXlsb2FkIC0gUmF3IGRhdGEgdGhhdCB3aWxsIGJlIGF0dGFjaGVkIHRvIHRoZSBwYWNrZXQgKFJQQyBtZXNzYWdlLCByYXcgYnl0ZXMsIGV0YylcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSBvZmZzZXRcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSBieXRlc1RvV3JpdGVcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yICh2ZXJzaW9uID0gMSwgZW5jcnlwdGlvbiA9IGZhbHNlLCBmcmFtZVR5cGUgPSAtMSwgc2VydmljZVR5cGUgPSAtMSwgZnJhbWVJbmZvID0gLTEsIHNlc3Npb25JRCA9IDAsIGRhdGFTaXplID0gMCwgbWVzc2FnZUlEID0gMCwgcGF5bG9hZCA9IG51bGwsIG9mZnNldCA9IDAsIGJ5dGVzVG9Xcml0ZSA9IDApIHtcbiAgICAgICAgdGhpcy5fdmVyc2lvbiA9IHZlcnNpb247XG4gICAgICAgIHRoaXMuX2VuY3J5cHRpb24gPSBlbmNyeXB0aW9uO1xuICAgICAgICB0aGlzLl9mcmFtZVR5cGUgPSBmcmFtZVR5cGU7XG4gICAgICAgIHRoaXMuX3NlcnZpY2VUeXBlID0gc2VydmljZVR5cGU7XG4gICAgICAgIHRoaXMuX2ZyYW1lSW5mbyA9IGZyYW1lSW5mbztcbiAgICAgICAgdGhpcy5fc2Vzc2lvbklEID0gc2Vzc2lvbklEO1xuICAgICAgICB0aGlzLl9kYXRhU2l6ZSA9IGRhdGFTaXplO1xuICAgICAgICB0aGlzLl9tZXNzYWdlSUQgPSBtZXNzYWdlSUQ7XG4gICAgICAgIHRoaXMuX3BheWxvYWQgPSBwYXlsb2FkO1xuICAgICAgICB0aGlzLl9vZmZzZXQgPSBvZmZzZXQ7XG4gICAgICAgIHRoaXMuX2J5dGVzVG9Xcml0ZSA9IGJ5dGVzVG9Xcml0ZTtcblxuICAgICAgICB0aGlzLl9ic29uUGF5bG9hZCA9IHVuZGVmaW5lZDtcblxuICAgICAgICBpZiAocGF5bG9hZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fcGF5bG9hZCA9IG5ldyBVaW50OEFycmF5KHBheWxvYWQuc2xpY2Uob2Zmc2V0LCBieXRlc1RvV3JpdGUgKyBvZmZzZXQpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfSAtIFByb3RvY29sIHZlcnNpb24gdXNlZCBieSB0aGlzIHBhY2tldFxuICAgICovXG4gICAgZ2V0VmVyc2lvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl92ZXJzaW9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7Qm9vbGVhbn0gLSBXaGV0aGVyIG9yIG5vdCB0aGUgcGF5bG9hZCBpbiB0aGlzIHBhY2tldCBpcyBlbmNyeXB0ZWRcbiAgICAqL1xuICAgIGdldEVuY3J5cHRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5jcnlwdGlvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1NlcnZpY2VUeXBlfSAtIFRoZSBzZXJ2aWNlIHRoYXQgdGhpcyBwYWNrZXQgaXMgYXNzb2NpYXRlZCB3aXRoXG4gICAgKi9cbiAgICBnZXRTZXJ2aWNlVHlwZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zZXJ2aWNlVHlwZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn0gLSBTcGVjaWZpYyBmcmFtZSBpbmZvIHJlbGF0ZWQgdG8gdGhpcyBwYWNrZXRcbiAgICAqL1xuICAgIGdldEZyYW1lSW5mbyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mcmFtZUluZm87XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9IC0gSUQgdGhpcyBwYWNrZXQgaXMgYXNzb2NpYXRlZCB3aXRoXG4gICAgKi9cbiAgICBnZXRTZXNzaW9uSUQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2Vzc2lvbklEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfSAtIElEIG9mIHRoaXMgc3BlY2lmaWMgcGFja2V0XG4gICAgKi9cbiAgICBnZXRNZXNzYWdlSUQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWVzc2FnZUlEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfSAtIFNpemUgb2YgdGhlIHBheWxvYWQgdGhhdCB3aWxsIGJlIGFkZGVkXG4gICAgKi9cbiAgICBnZXREYXRhU2l6ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kYXRhU2l6ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7VWludDhBcnJheX0gcGF5bG9hZFxuICAgICogQHJldHVybiB7U2RsUGFja2V0fVxuICAgICovXG4gICAgc2V0UGF5bG9hZCAocGF5bG9hZCkge1xuICAgICAgICB0aGlzLl9wYXlsb2FkID0gcGF5bG9hZDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtVaW50OEFycmF5fSAtIFJhdyBkYXRhIHRoYXQgd2lsbCBiZSBhdHRhY2hlZCB0byB0aGUgcGFja2V0IChSUEMgbWVzc2FnZSwgcmF3IGJ5dGVzLCBldGMpXG4gICAgKi9cbiAgICBnZXRQYXlsb2FkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BheWxvYWQ7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gZW5jcnlwdGlvblxuICAgICAqIEByZXR1cm4ge051bWJlcn0gLSBSZXR1cm5zIGEgbnVtYmVyIHJlcHJlc2VudGluZyBhIGJ5dGUgbWFzayBkZXBlbmRpbmcgb24gdGhlIGJvb2xlYW4gdmFsdWVcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0RW5jcnlwdGlvbkJpdCAoZW5jcnlwdGlvbikge1xuICAgICAgICByZXR1cm4gZW5jcnlwdGlvbiA/IFNkbFBhY2tldC5FTkNSWVBUSU9OX01BU0sgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7RnJhbWVUeXBlfSAtIEEgbnVtYmVyIHJlcHJlc2VudGluZyB0aGUgcGFja2V0IGZyYW1lIHR5cGVcbiAgICAqL1xuICAgIGdldEZyYW1lVHlwZSAoKSB7XG4gICAgICAgIGlmIChGcmFtZVR5cGUua2V5Rm9yVmFsdWUodGhpcy5fZnJhbWVUeXBlKSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2ZyYW1lVHlwZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBGcmFtZVR5cGUuU0lOR0xFO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9IC0gU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwYWNrZXRcbiAgICAqL1xuICAgIHRvU3RyaW5nICgpIHtcbiAgICAgICAgbGV0IG91dHB1dCA9ICcqKioqKiBTZGwgUGFja2V0ICoqKioqJztcbiAgICAgICAgb3V0cHV0ICs9IGBcXG5WZXJzaW9uOiAke3RoaXMuX3ZlcnNpb259YDtcbiAgICAgICAgb3V0cHV0ICs9IGBcXG5FbmNyeXB0aW9uOiAke3RoaXMuX2VuY3J5cHRpb259YDtcbiAgICAgICAgb3V0cHV0ICs9IGBcXG5GcmFtZVR5cGU6ICR7dGhpcy5fZnJhbWVUeXBlfWA7XG4gICAgICAgIG91dHB1dCArPSBgXFxuU2VydmljZVR5cGU6ICR7dGhpcy5fc2VydmljZVR5cGV9YDtcbiAgICAgICAgb3V0cHV0ICs9IGBcXG5GcmFtZUluZm86ICR7dGhpcy5fZnJhbWVJbmZvfWA7XG4gICAgICAgIG91dHB1dCArPSBgXFxuU2Vzc2lvbklEOiAke3RoaXMuX3Nlc3Npb25JRH1gO1xuICAgICAgICBvdXRwdXQgKz0gYFxcbkRhdGFTaXplOiAke3RoaXMuX2RhdGFTaXplfWA7XG5cbiAgICAgICAgaWYgKHRoaXMuX3ZlcnNpb24gPiAxKSB7XG4gICAgICAgICAgICBvdXRwdXQgKz0gYFxcbk1lc3NhZ2VJRDogJHt0aGlzLl9tZXNzYWdlSUR9YDtcbiAgICAgICAgfVxuXG4gICAgICAgIG91dHB1dCArPSAnXFxuKioqKiogU2RsIFBhY2tldCBFbmQgKioqKionO1xuXG4gICAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgfVxuXG4gICAgLyoqXG5cdCAqIFRoaXMgbWV0aG9kIHRha2VzIGluIHRoZSB2YXJpb3VzIGNvbXBvbmVudHMgdG8gdGhlIFNETCBwYWNrZXQgc3RydWN0dXJlIGFuZCBjcmVhdGVzIGEgbmV3IGJ5dGUgYXJyYXkgdGhhdCBjYW4gYmUgc2VudCB2aWEgdGhlIHRyYW5zcG9ydFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB2ZXJzaW9uIC0gUHJvdG9jb2wgdmVyc2lvbiB0byB1c2VcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGVuY3J5cHRpb24gLSBXaGV0aGVyIG9yIG5vdCB0aGUgcGF5bG9hZCBpbiB0aGlzIHBhY2tldCBpcyBlbmNyeXB0ZWRcbiAgICAgKiBAcGFyYW0ge0ZyYW1lVHlwZX0gZnJhbWVUeXBlIC0gQSBudW1iZXIgcmVwcmVzZW50aW5nIHRoZSBwYWNrZXQgZnJhbWUgdHlwZVxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlIC0gVGhlIHNlcnZpY2UgdGhhdCB0aGlzIHBhY2tldCBpcyBhc3NvY2lhdGVkIHdpdGhcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gY29udHJvbEZyYW1lSW5mbyAtIFNwZWNpZmljIGZyYW1lIGluZm8gcmVsYXRlZCB0byB0aGlzIHBhY2tldFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzZXNzaW9uSUQgLSBJRCB0aGlzIHBhY2tldCBpcyBhc3NvY2lhdGVkIHdpdGhcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZGF0YVNpemUgLSBTaXplIG9mIHRoZSBwYXlsb2FkIHRoYXQgd2lsbCBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBtZXNzYWdlSUQgLSBJRCBvZiB0aGlzIHNwZWNpZmljIHBhY2tldFxuICAgICAqIEBwYXJhbSB7VWludDhBcnJheX0gcGF5bG9hZCAtIFJhdyBkYXRhIHRoYXQgd2lsbCBiZSBhdHRhY2hlZCB0byB0aGUgcGFja2V0IChSUEMgbWVzc2FnZSwgcmF3IGJ5dGVzLCBldGMpXG5cdCAqIEByZXR1cm4ge1VpbnQ4QXJyYXl9IC0gQSBieXRlW10gcmVwcmVzZW50YXRpb24gb2YgYW4gU2RsUGFja2V0IGJ1aWx0IHVzaW5nIHRoZSBzdXBwbGllZCBwYXJhbXNcblx0ICovXG4gICAgc3RhdGljIGNvbnN0cnVjdFBhY2tldCAodmVyc2lvbiwgZW5jcnlwdGlvbiwgZnJhbWVUeXBlLCBzZXJ2aWNlVHlwZSwgY29udHJvbEZyYW1lSW5mbywgc2Vzc2lvbklELCBkYXRhU2l6ZSwgbWVzc2FnZUlELCBwYXlsb2FkKSB7XG4gICAgICAgIGxldCBkYXRhVmlldyA9IG51bGw7XG4gICAgICAgIGxldCBkYXRhVmlld0luZGV4ID0gMDtcblxuICAgICAgICBpZiAodmVyc2lvbiA+IDEpIHtcbiAgICAgICAgICAgIGRhdGFWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoU2RsUGFja2V0LkhFQURFUl9TSVpFICsgZGF0YVNpemUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGF0YVZpZXcgPSBuZXcgVWludDhBcnJheShTZGxQYWNrZXQuSEVBREVSX1NJWkVfVjEgKyBkYXRhU2l6ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBkYXRhVmlld1tkYXRhVmlld0luZGV4KytdID0gKHZlcnNpb24gPDwgNCkgKyBTZGxQYWNrZXQuZ2V0RW5jcnlwdGlvbkJpdChlbmNyeXB0aW9uKSArIGZyYW1lVHlwZTtcbiAgICAgICAgZGF0YVZpZXdbZGF0YVZpZXdJbmRleCsrXSA9IHNlcnZpY2VUeXBlO1xuICAgICAgICBkYXRhVmlld1tkYXRhVmlld0luZGV4KytdID0gY29udHJvbEZyYW1lSW5mbztcbiAgICAgICAgZGF0YVZpZXdbZGF0YVZpZXdJbmRleCsrXSA9IHNlc3Npb25JRDtcbiAgICAgICAgZGF0YVZpZXdbZGF0YVZpZXdJbmRleCsrXSA9IChkYXRhU2l6ZSAmIDB4RkYwMDAwMDApID4+IDI0O1xuICAgICAgICBkYXRhVmlld1tkYXRhVmlld0luZGV4KytdID0gKGRhdGFTaXplICYgMHgwMEZGMDAwMCkgPj4gMTY7XG4gICAgICAgIGRhdGFWaWV3W2RhdGFWaWV3SW5kZXgrK10gPSAoZGF0YVNpemUgJiAweDAwMDBGRjAwKSA+PiA4O1xuICAgICAgICBkYXRhVmlld1tkYXRhVmlld0luZGV4KytdID0gZGF0YVNpemUgJiAweDAwMDAwMEZGO1xuXG4gICAgICAgIGlmICh2ZXJzaW9uID4gMSkge1xuICAgICAgICAgICAgZGF0YVZpZXdbZGF0YVZpZXdJbmRleCsrXSA9IChtZXNzYWdlSUQgJiAweEZGMDAwMDAwKSA+PiAyNDtcbiAgICAgICAgICAgIGRhdGFWaWV3W2RhdGFWaWV3SW5kZXgrK10gPSAobWVzc2FnZUlEICYgMHgwMEZGMDAwMCkgPj4gMTY7XG4gICAgICAgICAgICBkYXRhVmlld1tkYXRhVmlld0luZGV4KytdID0gKG1lc3NhZ2VJRCAmIDB4MDAwMEZGMDApID4+IDg7XG4gICAgICAgICAgICBkYXRhVmlld1tkYXRhVmlld0luZGV4KytdID0gbWVzc2FnZUlEICYgMHgwMDAwMDBGRjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXlsb2FkICE9PSBudWxsICYmIHBheWxvYWQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgZGF0YVZpZXcuc2V0KHBheWxvYWQsIGRhdGFWaWV3SW5kZXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRhdGFWaWV3O1xuICAgIH1cblxuICAgIC8qKlxuXHQgKiBUaGlzIG1ldGhvZCBjb252ZXJ0cyBhbiBTZGxQYWNrZXQgaW5zdGFuY2UgdG8gYSBuZXcgYnl0ZSBhcnJheSB0aGF0IGNhbiBiZSBzZW50IHZpYSB0aGUgdHJhbnNwb3J0XG5cdCAqIEByZXR1cm4ge1VpbnQ4QXJyYXl9IC0gQSBieXRlW10gcmVwcmVzZW50YXRpb24gb2YgYW4gU2RsUGFja2V0IGJ1aWx0IHVzaW5nIHRoZSBzdXBwbGllZCBwYXJhbXNcblx0ICovXG4gICAgdG9QYWNrZXQgKCkge1xuICAgICAgICBpZiAodGhpcy5fYnNvblBheWxvYWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3BheWxvYWQgPSBCc29uLnNlcmlhbGl6ZSh0aGlzLl9ic29uUGF5bG9hZCk7XG4gICAgICAgICAgICB0aGlzLl9kYXRhU2l6ZSA9IHRoaXMuX3BheWxvYWQubGVuZ3RoO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFNkbFBhY2tldC5jb25zdHJ1Y3RQYWNrZXQodGhpcy5fdmVyc2lvbiwgdGhpcy5fZW5jcnlwdGlvbiwgdGhpcy5fZnJhbWVUeXBlLCB0aGlzLl9zZXJ2aWNlVHlwZSwgdGhpcy5fZnJhbWVJbmZvLCB0aGlzLl9zZXNzaW9uSUQsIHRoaXMuX2RhdGFTaXplLCB0aGlzLl9tZXNzYWdlSUQsIHRoaXMuX3BheWxvYWQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0YWcgLSBTdHJpbmcga2V5IHRvIGFkZCBhcyBhIHByb3BlcnR5IHRvIHRoZSBCU09OIG1hcFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhIC0gT2JqZWN0IHRvIGFkZCBhcyBhIHZhbHVlIHRvIHRoZSBCU09OIG1hcFxuICAgICAqL1xuICAgIHB1dFRhZyAodGFnLCBkYXRhKSB7XG4gICAgICAgIGlmICghdGhpcy5fYnNvblBheWxvYWQpIHtcbiAgICAgICAgICAgIHRoaXMuX2Jzb25QYXlsb2FkID0ge307XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fYnNvblBheWxvYWRbdGFnXSA9IGRhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHRhZyAtIFN0cmluZyBrZXkgdG8gYWRkIGFzIGEgcHJvcGVydHkgdG8gdGhlIEJTT04gbWFwXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBkYXRhIC0gT2JqZWN0IGFzIGEgdmFsdWUgZm91bmQgZnJvbSB0aGUgdGhlIEJTT04gbWFwXG4gICAgICovXG5cbiAgICBnZXRUYWcgKHRhZykge1xuICAgICAgICBpZiAoIXRoaXMuX2Jzb25QYXlsb2FkKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuX3BheWxvYWQgfHwgdGhpcy5fcGF5bG9hZC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX2Jzb25QYXlsb2FkID0gQnNvbi5kZXNlcmlhbGl6ZSh0aGlzLl9wYXlsb2FkKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9ic29uUGF5bG9hZFt0YWddO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2Jzb25QYXlsb2FkW3RhZ107XG4gICAgICAgIH1cbiAgICB9XG59XG5cblNkbFBhY2tldC5FWFRSQV9QQVJDRUxfREFUQV9MRU5HVEggICAgICAgICAgICAgICAgICAgICAgPSAyNDtcblNkbFBhY2tldC5IRUFERVJfU0laRSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAxMjtcblNkbFBhY2tldC5IRUFERVJfU0laRV9WMSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSA4O1xuXG5TZGxQYWNrZXQuRU5DUllQVElPTl9NQVNLICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwODtcblxuLyoqXG4gKiBTZXJ2aWNlIFR5cGVcbiAqL1xuU2RsUGFja2V0LlNFUlZJQ0VfVFlQRV9DT05UUk9MICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDA7XG4vLyBSRVNFUlZFRCAweDAxIC0gMHgwNlxuU2RsUGFja2V0LlNFUlZJQ0VfVFlQRV9SUEMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDc7XG4vLyBSRVNFUlZFRCAweDA4IC0gMHgwOVxuU2RsUGFja2V0LlNFUlZJQ0VfVFlQRV9QQ00gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEE7XG5TZGxQYWNrZXQuU0VSVklDRV9UWVBFX1ZJREVPICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwQjtcbi8vIFJFU0VSVkVEIDB4MEMgLSAweDBFXG5TZGxQYWNrZXQuU0VSVklDRV9UWVBFX0JVTEtfREFUQSAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwRjtcbi8vIFJFU0VSVkVEIDB4MTAgLSAweEZGXG5cbi8qKlxuICogRnJhbWUgSW5mb1xuICovXG5TZGxQYWNrZXQuRlJBTUVfSU5GT19IRUFSVF9CRUFUICAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwMDtcblNkbFBhY2tldC5GUkFNRV9JTkZPX1NUQVJUX1NFUlZJQ0UgICAgICAgICAgICAgICAgICAgICAgPSAweDAxO1xuU2RsUGFja2V0LkZSQU1FX0lORk9fU1RBUlRfU0VSVklDRV9BQ0sgICAgICAgICAgICAgICAgICA9IDB4MDI7XG5TZGxQYWNrZXQuRlJBTUVfSU5GT19TVEFSVF9TRVJWSUNFX05BSyAgICAgICAgICAgICAgICAgID0gMHgwMztcblNkbFBhY2tldC5GUkFNRV9JTkZPX0VORF9TRVJWSUNFICAgICAgICAgICAgICAgICAgICAgICAgPSAweDA0O1xuU2RsUGFja2V0LkZSQU1FX0lORk9fRU5EX1NFUlZJQ0VfQUNLICAgICAgICAgICAgICAgICAgICA9IDB4MDU7XG5TZGxQYWNrZXQuRlJBTUVfSU5GT19FTkRfU0VSVklDRV9OQUsgICAgICAgICAgICAgICAgICAgID0gMHgwNjtcblNkbFBhY2tldC5GUkFNRV9JTkZPX1JFR0lTVEVSX1NFQ09OREFSWV9UUkFOU1BPUlQgICAgICAgPSAweDA3O1xuU2RsUGFja2V0LkZSQU1FX0lORk9fUkVHSVNURVJfU0VDT05EQVJZX1RSQU5TUE9SVF9BQ0sgICA9IDB4MDg7XG5TZGxQYWNrZXQuRlJBTUVfSU5GT19SRUdJU1RFUl9TRUNPTkRBUllfVFJBTlNQT1JUX05BSyAgID0gMHgwOTtcbi8vIDB4MEEtMHhGQyBhcmUgcmVzZXJ2ZWRcblNkbFBhY2tldC5GUkFNRV9JTkZPX1RSQU5TUE9SVF9FVkVOVF9VUERBVEUgICAgICAgICAgICAgPSAweEZEO1xuU2RsUGFja2V0LkZSQU1FX0lORk9fU0VSVklDRV9EQVRBX0FDSyAgICAgICAgICAgICAgICAgICA9IDB4RkU7XG5TZGxQYWNrZXQuRlJBTUVfSU5GT19IRUFSVF9CRUFUX0FDSyAgICAgICAgICAgICAgICAgICAgID0gMHhGRjtcblNkbFBhY2tldC5GUkFNRV9JTkZPX0ZJTkFMX0NPTk5FU0NVVElWRV9GUkFNRSAgICAgICAgICAgPSAweDAwO1xuU2RsUGFja2V0LkZSQU1FX0lORk9fUkVTRVJWRUQgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDA7XG5cbmV4cG9ydCB7IFNkbFBhY2tldCB9O1xuIiwiZXhwb3J0IGRlZmF1bHQgKHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOlxuICAgICAgICAgICAgdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDpcbiAgICAgICAgICAgIHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSk7XG4iLCJcbnZhciBsb29rdXAgPSBbXVxudmFyIHJldkxvb2t1cCA9IFtdXG52YXIgQXJyID0gdHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnID8gVWludDhBcnJheSA6IEFycmF5XG52YXIgaW5pdGVkID0gZmFsc2U7XG5mdW5jdGlvbiBpbml0ICgpIHtcbiAgaW5pdGVkID0gdHJ1ZTtcbiAgdmFyIGNvZGUgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLydcbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGNvZGUubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICBsb29rdXBbaV0gPSBjb2RlW2ldXG4gICAgcmV2TG9va3VwW2NvZGUuY2hhckNvZGVBdChpKV0gPSBpXG4gIH1cblxuICByZXZMb29rdXBbJy0nLmNoYXJDb2RlQXQoMCldID0gNjJcbiAgcmV2TG9va3VwWydfJy5jaGFyQ29kZUF0KDApXSA9IDYzXG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0b0J5dGVBcnJheSAoYjY0KSB7XG4gIGlmICghaW5pdGVkKSB7XG4gICAgaW5pdCgpO1xuICB9XG4gIHZhciBpLCBqLCBsLCB0bXAsIHBsYWNlSG9sZGVycywgYXJyXG4gIHZhciBsZW4gPSBiNjQubGVuZ3RoXG5cbiAgaWYgKGxlbiAlIDQgPiAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHN0cmluZy4gTGVuZ3RoIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA0JylcbiAgfVxuXG4gIC8vIHRoZSBudW1iZXIgb2YgZXF1YWwgc2lnbnMgKHBsYWNlIGhvbGRlcnMpXG4gIC8vIGlmIHRoZXJlIGFyZSB0d28gcGxhY2Vob2xkZXJzLCB0aGFuIHRoZSB0d28gY2hhcmFjdGVycyBiZWZvcmUgaXRcbiAgLy8gcmVwcmVzZW50IG9uZSBieXRlXG4gIC8vIGlmIHRoZXJlIGlzIG9ubHkgb25lLCB0aGVuIHRoZSB0aHJlZSBjaGFyYWN0ZXJzIGJlZm9yZSBpdCByZXByZXNlbnQgMiBieXRlc1xuICAvLyB0aGlzIGlzIGp1c3QgYSBjaGVhcCBoYWNrIHRvIG5vdCBkbyBpbmRleE9mIHR3aWNlXG4gIHBsYWNlSG9sZGVycyA9IGI2NFtsZW4gLSAyXSA9PT0gJz0nID8gMiA6IGI2NFtsZW4gLSAxXSA9PT0gJz0nID8gMSA6IDBcblxuICAvLyBiYXNlNjQgaXMgNC8zICsgdXAgdG8gdHdvIGNoYXJhY3RlcnMgb2YgdGhlIG9yaWdpbmFsIGRhdGFcbiAgYXJyID0gbmV3IEFycihsZW4gKiAzIC8gNCAtIHBsYWNlSG9sZGVycylcblxuICAvLyBpZiB0aGVyZSBhcmUgcGxhY2Vob2xkZXJzLCBvbmx5IGdldCB1cCB0byB0aGUgbGFzdCBjb21wbGV0ZSA0IGNoYXJzXG4gIGwgPSBwbGFjZUhvbGRlcnMgPiAwID8gbGVuIC0gNCA6IGxlblxuXG4gIHZhciBMID0gMFxuXG4gIGZvciAoaSA9IDAsIGogPSAwOyBpIDwgbDsgaSArPSA0LCBqICs9IDMpIHtcbiAgICB0bXAgPSAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAxOCkgfCAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPDwgMTIpIHwgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMildIDw8IDYpIHwgcmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAzKV1cbiAgICBhcnJbTCsrXSA9ICh0bXAgPj4gMTYpICYgMHhGRlxuICAgIGFycltMKytdID0gKHRtcCA+PiA4KSAmIDB4RkZcbiAgICBhcnJbTCsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIGlmIChwbGFjZUhvbGRlcnMgPT09IDIpIHtcbiAgICB0bXAgPSAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAyKSB8IChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA+PiA0KVxuICAgIGFycltMKytdID0gdG1wICYgMHhGRlxuICB9IGVsc2UgaWYgKHBsYWNlSG9sZGVycyA9PT0gMSkge1xuICAgIHRtcCA9IChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDEwKSB8IChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCA0KSB8IChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA+PiAyKVxuICAgIGFycltMKytdID0gKHRtcCA+PiA4KSAmIDB4RkZcbiAgICBhcnJbTCsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBhcnJcbn1cblxuZnVuY3Rpb24gdHJpcGxldFRvQmFzZTY0IChudW0pIHtcbiAgcmV0dXJuIGxvb2t1cFtudW0gPj4gMTggJiAweDNGXSArIGxvb2t1cFtudW0gPj4gMTIgJiAweDNGXSArIGxvb2t1cFtudW0gPj4gNiAmIDB4M0ZdICsgbG9va3VwW251bSAmIDB4M0ZdXG59XG5cbmZ1bmN0aW9uIGVuY29kZUNodW5rICh1aW50OCwgc3RhcnQsIGVuZCkge1xuICB2YXIgdG1wXG4gIHZhciBvdXRwdXQgPSBbXVxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkgKz0gMykge1xuICAgIHRtcCA9ICh1aW50OFtpXSA8PCAxNikgKyAodWludDhbaSArIDFdIDw8IDgpICsgKHVpbnQ4W2kgKyAyXSlcbiAgICBvdXRwdXQucHVzaCh0cmlwbGV0VG9CYXNlNjQodG1wKSlcbiAgfVxuICByZXR1cm4gb3V0cHV0LmpvaW4oJycpXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tQnl0ZUFycmF5ICh1aW50OCkge1xuICBpZiAoIWluaXRlZCkge1xuICAgIGluaXQoKTtcbiAgfVxuICB2YXIgdG1wXG4gIHZhciBsZW4gPSB1aW50OC5sZW5ndGhcbiAgdmFyIGV4dHJhQnl0ZXMgPSBsZW4gJSAzIC8vIGlmIHdlIGhhdmUgMSBieXRlIGxlZnQsIHBhZCAyIGJ5dGVzXG4gIHZhciBvdXRwdXQgPSAnJ1xuICB2YXIgcGFydHMgPSBbXVxuICB2YXIgbWF4Q2h1bmtMZW5ndGggPSAxNjM4MyAvLyBtdXN0IGJlIG11bHRpcGxlIG9mIDNcblxuICAvLyBnbyB0aHJvdWdoIHRoZSBhcnJheSBldmVyeSB0aHJlZSBieXRlcywgd2UnbGwgZGVhbCB3aXRoIHRyYWlsaW5nIHN0dWZmIGxhdGVyXG4gIGZvciAodmFyIGkgPSAwLCBsZW4yID0gbGVuIC0gZXh0cmFCeXRlczsgaSA8IGxlbjI7IGkgKz0gbWF4Q2h1bmtMZW5ndGgpIHtcbiAgICBwYXJ0cy5wdXNoKGVuY29kZUNodW5rKHVpbnQ4LCBpLCAoaSArIG1heENodW5rTGVuZ3RoKSA+IGxlbjIgPyBsZW4yIDogKGkgKyBtYXhDaHVua0xlbmd0aCkpKVxuICB9XG5cbiAgLy8gcGFkIHRoZSBlbmQgd2l0aCB6ZXJvcywgYnV0IG1ha2Ugc3VyZSB0byBub3QgZm9yZ2V0IHRoZSBleHRyYSBieXRlc1xuICBpZiAoZXh0cmFCeXRlcyA9PT0gMSkge1xuICAgIHRtcCA9IHVpbnQ4W2xlbiAtIDFdXG4gICAgb3V0cHV0ICs9IGxvb2t1cFt0bXAgPj4gMl1cbiAgICBvdXRwdXQgKz0gbG9va3VwWyh0bXAgPDwgNCkgJiAweDNGXVxuICAgIG91dHB1dCArPSAnPT0nXG4gIH0gZWxzZSBpZiAoZXh0cmFCeXRlcyA9PT0gMikge1xuICAgIHRtcCA9ICh1aW50OFtsZW4gLSAyXSA8PCA4KSArICh1aW50OFtsZW4gLSAxXSlcbiAgICBvdXRwdXQgKz0gbG9va3VwW3RtcCA+PiAxMF1cbiAgICBvdXRwdXQgKz0gbG9va3VwWyh0bXAgPj4gNCkgJiAweDNGXVxuICAgIG91dHB1dCArPSBsb29rdXBbKHRtcCA8PCAyKSAmIDB4M0ZdXG4gICAgb3V0cHV0ICs9ICc9J1xuICB9XG5cbiAgcGFydHMucHVzaChvdXRwdXQpXG5cbiAgcmV0dXJuIHBhcnRzLmpvaW4oJycpXG59XG4iLCJcbmV4cG9ydCBmdW5jdGlvbiByZWFkIChidWZmZXIsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtXG4gIHZhciBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgbkJpdHMgPSAtN1xuICB2YXIgaSA9IGlzTEUgPyAobkJ5dGVzIC0gMSkgOiAwXG4gIHZhciBkID0gaXNMRSA/IC0xIDogMVxuICB2YXIgcyA9IGJ1ZmZlcltvZmZzZXQgKyBpXVxuXG4gIGkgKz0gZFxuXG4gIGUgPSBzICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIHMgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IGVMZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IGUgKiAyNTYgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBtID0gZSAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBlID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBtTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IG0gPSBtICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgaWYgKGUgPT09IDApIHtcbiAgICBlID0gMSAtIGVCaWFzXG4gIH0gZWxzZSBpZiAoZSA9PT0gZU1heCkge1xuICAgIHJldHVybiBtID8gTmFOIDogKChzID8gLTEgOiAxKSAqIEluZmluaXR5KVxuICB9IGVsc2Uge1xuICAgIG0gPSBtICsgTWF0aC5wb3coMiwgbUxlbilcbiAgICBlID0gZSAtIGVCaWFzXG4gIH1cbiAgcmV0dXJuIChzID8gLTEgOiAxKSAqIG0gKiBNYXRoLnBvdygyLCBlIC0gbUxlbilcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHdyaXRlIChidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbSwgY1xuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIHJ0ID0gKG1MZW4gPT09IDIzID8gTWF0aC5wb3coMiwgLTI0KSAtIE1hdGgucG93KDIsIC03NykgOiAwKVxuICB2YXIgaSA9IGlzTEUgPyAwIDogKG5CeXRlcyAtIDEpXG4gIHZhciBkID0gaXNMRSA/IDEgOiAtMVxuICB2YXIgcyA9IHZhbHVlIDwgMCB8fCAodmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCkgPyAxIDogMFxuXG4gIHZhbHVlID0gTWF0aC5hYnModmFsdWUpXG5cbiAgaWYgKGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA9PT0gSW5maW5pdHkpIHtcbiAgICBtID0gaXNOYU4odmFsdWUpID8gMSA6IDBcbiAgICBlID0gZU1heFxuICB9IGVsc2Uge1xuICAgIGUgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbHVlKSAvIE1hdGguTE4yKVxuICAgIGlmICh2YWx1ZSAqIChjID0gTWF0aC5wb3coMiwgLWUpKSA8IDEpIHtcbiAgICAgIGUtLVxuICAgICAgYyAqPSAyXG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgdmFsdWUgKz0gcnQgLyBjXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlICs9IHJ0ICogTWF0aC5wb3coMiwgMSAtIGVCaWFzKVxuICAgIH1cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrK1xuICAgICAgYyAvPSAyXG4gICAgfVxuXG4gICAgaWYgKGUgKyBlQmlhcyA+PSBlTWF4KSB7XG4gICAgICBtID0gMFxuICAgICAgZSA9IGVNYXhcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKHZhbHVlICogYyAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSBlICsgZUJpYXNcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gMFxuICAgIH1cbiAgfVxuXG4gIGZvciAoOyBtTGVuID49IDg7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IG0gJiAweGZmLCBpICs9IGQsIG0gLz0gMjU2LCBtTGVuIC09IDgpIHt9XG5cbiAgZSA9IChlIDw8IG1MZW4pIHwgbVxuICBlTGVuICs9IG1MZW5cbiAgZm9yICg7IGVMZW4gPiAwOyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBlICYgMHhmZiwgaSArPSBkLCBlIC89IDI1NiwgZUxlbiAtPSA4KSB7fVxuXG4gIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyOFxufVxuIiwidmFyIHRvU3RyaW5nID0ge30udG9TdHJpbmc7XG5cbmV4cG9ydCBkZWZhdWx0IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKGFycikge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChhcnIpID09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIiwiLyohXG4gKiBUaGUgYnVmZmVyIG1vZHVsZSBmcm9tIG5vZGUuanMsIGZvciB0aGUgYnJvd3Nlci5cbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8ZmVyb3NzQGZlcm9zcy5vcmc+IDxodHRwOi8vZmVyb3NzLm9yZz5cbiAqIEBsaWNlbnNlICBNSVRcbiAqL1xuLyogZXNsaW50LWRpc2FibGUgbm8tcHJvdG8gKi9cblxuXG5pbXBvcnQgKiBhcyBiYXNlNjQgZnJvbSAnLi9iYXNlNjQnXG5pbXBvcnQgKiBhcyBpZWVlNzU0IGZyb20gJy4vaWVlZTc1NCdcbmltcG9ydCBpc0FycmF5IGZyb20gJy4vaXNBcnJheSdcblxuZXhwb3J0IHZhciBJTlNQRUNUX01BWF9CWVRFUyA9IDUwXG5cbi8qKlxuICogSWYgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYDpcbiAqICAgPT09IHRydWUgICAgVXNlIFVpbnQ4QXJyYXkgaW1wbGVtZW50YXRpb24gKGZhc3Rlc3QpXG4gKiAgID09PSBmYWxzZSAgIFVzZSBPYmplY3QgaW1wbGVtZW50YXRpb24gKG1vc3QgY29tcGF0aWJsZSwgZXZlbiBJRTYpXG4gKlxuICogQnJvd3NlcnMgdGhhdCBzdXBwb3J0IHR5cGVkIGFycmF5cyBhcmUgSUUgMTArLCBGaXJlZm94IDQrLCBDaHJvbWUgNyssIFNhZmFyaSA1LjErLFxuICogT3BlcmEgMTEuNissIGlPUyA0LjIrLlxuICpcbiAqIER1ZSB0byB2YXJpb3VzIGJyb3dzZXIgYnVncywgc29tZXRpbWVzIHRoZSBPYmplY3QgaW1wbGVtZW50YXRpb24gd2lsbCBiZSB1c2VkIGV2ZW5cbiAqIHdoZW4gdGhlIGJyb3dzZXIgc3VwcG9ydHMgdHlwZWQgYXJyYXlzLlxuICpcbiAqIE5vdGU6XG4gKlxuICogICAtIEZpcmVmb3ggNC0yOSBsYWNrcyBzdXBwb3J0IGZvciBhZGRpbmcgbmV3IHByb3BlcnRpZXMgdG8gYFVpbnQ4QXJyYXlgIGluc3RhbmNlcyxcbiAqICAgICBTZWU6IGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTY5NTQzOC5cbiAqXG4gKiAgIC0gQ2hyb21lIDktMTAgaXMgbWlzc2luZyB0aGUgYFR5cGVkQXJyYXkucHJvdG90eXBlLnN1YmFycmF5YCBmdW5jdGlvbi5cbiAqXG4gKiAgIC0gSUUxMCBoYXMgYSBicm9rZW4gYFR5cGVkQXJyYXkucHJvdG90eXBlLnN1YmFycmF5YCBmdW5jdGlvbiB3aGljaCByZXR1cm5zIGFycmF5cyBvZlxuICogICAgIGluY29ycmVjdCBsZW5ndGggaW4gc29tZSBzaXR1YXRpb25zLlxuXG4gKiBXZSBkZXRlY3QgdGhlc2UgYnVnZ3kgYnJvd3NlcnMgYW5kIHNldCBgQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRgIHRvIGBmYWxzZWAgc28gdGhleVxuICogZ2V0IHRoZSBPYmplY3QgaW1wbGVtZW50YXRpb24sIHdoaWNoIGlzIHNsb3dlciBidXQgYmVoYXZlcyBjb3JyZWN0bHkuXG4gKi9cbkJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUID0gZ2xvYmFsLlRZUEVEX0FSUkFZX1NVUFBPUlQgIT09IHVuZGVmaW5lZFxuICA/IGdsb2JhbC5UWVBFRF9BUlJBWV9TVVBQT1JUXG4gIDogdHJ1ZVxuXG4vKlxuICogRXhwb3J0IGtNYXhMZW5ndGggYWZ0ZXIgdHlwZWQgYXJyYXkgc3VwcG9ydCBpcyBkZXRlcm1pbmVkLlxuICovXG52YXIgX2tNYXhMZW5ndGggPSBrTWF4TGVuZ3RoKClcbmV4cG9ydCB7X2tNYXhMZW5ndGggYXMga01heExlbmd0aH07XG5mdW5jdGlvbiB0eXBlZEFycmF5U3VwcG9ydCAoKSB7XG4gIHJldHVybiB0cnVlO1xuICAvLyByb2xsdXAgaXNzdWVzXG4gIC8vIHRyeSB7XG4gIC8vICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KDEpXG4gIC8vICAgYXJyLl9fcHJvdG9fXyA9IHtcbiAgLy8gICAgIF9fcHJvdG9fXzogVWludDhBcnJheS5wcm90b3R5cGUsXG4gIC8vICAgICBmb286IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDQyIH1cbiAgLy8gICB9XG4gIC8vICAgcmV0dXJuIGFyci5mb28oKSA9PT0gNDIgJiYgLy8gdHlwZWQgYXJyYXkgaW5zdGFuY2VzIGNhbiBiZSBhdWdtZW50ZWRcbiAgLy8gICAgICAgdHlwZW9mIGFyci5zdWJhcnJheSA9PT0gJ2Z1bmN0aW9uJyAmJiAvLyBjaHJvbWUgOS0xMCBsYWNrIGBzdWJhcnJheWBcbiAgLy8gICAgICAgYXJyLnN1YmFycmF5KDEsIDEpLmJ5dGVMZW5ndGggPT09IDAgLy8gaWUxMCBoYXMgYnJva2VuIGBzdWJhcnJheWBcbiAgLy8gfSBjYXRjaCAoZSkge1xuICAvLyAgIHJldHVybiBmYWxzZVxuICAvLyB9XG59XG5cbmZ1bmN0aW9uIGtNYXhMZW5ndGggKCkge1xuICByZXR1cm4gQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRcbiAgICA/IDB4N2ZmZmZmZmZcbiAgICA6IDB4M2ZmZmZmZmZcbn1cblxuZnVuY3Rpb24gY3JlYXRlQnVmZmVyICh0aGF0LCBsZW5ndGgpIHtcbiAgaWYgKGtNYXhMZW5ndGgoKSA8IGxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbnZhbGlkIHR5cGVkIGFycmF5IGxlbmd0aCcpXG4gIH1cbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UsIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgdGhhdCA9IG5ldyBVaW50OEFycmF5KGxlbmd0aClcbiAgICB0aGF0Ll9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgfSBlbHNlIHtcbiAgICAvLyBGYWxsYmFjazogUmV0dXJuIGFuIG9iamVjdCBpbnN0YW5jZSBvZiB0aGUgQnVmZmVyIGNsYXNzXG4gICAgaWYgKHRoYXQgPT09IG51bGwpIHtcbiAgICAgIHRoYXQgPSBuZXcgQnVmZmVyKGxlbmd0aClcbiAgICB9XG4gICAgdGhhdC5sZW5ndGggPSBsZW5ndGhcbiAgfVxuXG4gIHJldHVybiB0aGF0XG59XG5cbi8qKlxuICogVGhlIEJ1ZmZlciBjb25zdHJ1Y3RvciByZXR1cm5zIGluc3RhbmNlcyBvZiBgVWludDhBcnJheWAgdGhhdCBoYXZlIHRoZWlyXG4gKiBwcm90b3R5cGUgY2hhbmdlZCB0byBgQnVmZmVyLnByb3RvdHlwZWAuIEZ1cnRoZXJtb3JlLCBgQnVmZmVyYCBpcyBhIHN1YmNsYXNzIG9mXG4gKiBgVWludDhBcnJheWAsIHNvIHRoZSByZXR1cm5lZCBpbnN0YW5jZXMgd2lsbCBoYXZlIGFsbCB0aGUgbm9kZSBgQnVmZmVyYCBtZXRob2RzXG4gKiBhbmQgdGhlIGBVaW50OEFycmF5YCBtZXRob2RzLiBTcXVhcmUgYnJhY2tldCBub3RhdGlvbiB3b3JrcyBhcyBleHBlY3RlZCAtLSBpdFxuICogcmV0dXJucyBhIHNpbmdsZSBvY3RldC5cbiAqXG4gKiBUaGUgYFVpbnQ4QXJyYXlgIHByb3RvdHlwZSByZW1haW5zIHVubW9kaWZpZWQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIEJ1ZmZlciAoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJiAhKHRoaXMgaW5zdGFuY2VvZiBCdWZmZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBCdWZmZXIoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICAvLyBDb21tb24gY2FzZS5cbiAgaWYgKHR5cGVvZiBhcmcgPT09ICdudW1iZXInKSB7XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZ09yT2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnSWYgZW5jb2RpbmcgaXMgc3BlY2lmaWVkIHRoZW4gdGhlIGZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcnXG4gICAgICApXG4gICAgfVxuICAgIHJldHVybiBhbGxvY1Vuc2FmZSh0aGlzLCBhcmcpXG4gIH1cbiAgcmV0dXJuIGZyb20odGhpcywgYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbkJ1ZmZlci5wb29sU2l6ZSA9IDgxOTIgLy8gbm90IHVzZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvblxuXG4vLyBUT0RPOiBMZWdhY3ksIG5vdCBuZWVkZWQgYW55bW9yZS4gUmVtb3ZlIGluIG5leHQgbWFqb3IgdmVyc2lvbi5cbkJ1ZmZlci5fYXVnbWVudCA9IGZ1bmN0aW9uIChhcnIpIHtcbiAgYXJyLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgcmV0dXJuIGFyclxufVxuXG5mdW5jdGlvbiBmcm9tICh0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIGEgbnVtYmVyJylcbiAgfVxuXG4gIGlmICh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmIHZhbHVlIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICByZXR1cm4gZnJvbUFycmF5QnVmZmVyKHRoYXQsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmcm9tU3RyaW5nKHRoYXQsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0KVxuICB9XG5cbiAgcmV0dXJuIGZyb21PYmplY3QodGhhdCwgdmFsdWUpXG59XG5cbi8qKlxuICogRnVuY3Rpb25hbGx5IGVxdWl2YWxlbnQgdG8gQnVmZmVyKGFyZywgZW5jb2RpbmcpIGJ1dCB0aHJvd3MgYSBUeXBlRXJyb3JcbiAqIGlmIHZhbHVlIGlzIGEgbnVtYmVyLlxuICogQnVmZmVyLmZyb20oc3RyWywgZW5jb2RpbmddKVxuICogQnVmZmVyLmZyb20oYXJyYXkpXG4gKiBCdWZmZXIuZnJvbShidWZmZXIpXG4gKiBCdWZmZXIuZnJvbShhcnJheUJ1ZmZlclssIGJ5dGVPZmZzZXRbLCBsZW5ndGhdXSlcbiAqKi9cbkJ1ZmZlci5mcm9tID0gZnVuY3Rpb24gKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGZyb20obnVsbCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gIEJ1ZmZlci5wcm90b3R5cGUuX19wcm90b19fID0gVWludDhBcnJheS5wcm90b3R5cGVcbiAgQnVmZmVyLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXlcbiAgaWYgKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC5zcGVjaWVzICYmXG4gICAgICBCdWZmZXJbU3ltYm9sLnNwZWNpZXNdID09PSBCdWZmZXIpIHtcbiAgICAvLyBGaXggc3ViYXJyYXkoKSBpbiBFUzIwMTYuIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIvcHVsbC85N1xuICAgIC8vIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShCdWZmZXIsIFN5bWJvbC5zcGVjaWVzLCB7XG4gICAgLy8gICB2YWx1ZTogbnVsbCxcbiAgICAvLyAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIC8vIH0pXG4gIH1cbn1cblxuZnVuY3Rpb24gYXNzZXJ0U2l6ZSAoc2l6ZSkge1xuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBiZSBhIG51bWJlcicpXG4gIH0gZWxzZSBpZiAoc2l6ZSA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgbmVnYXRpdmUnKVxuICB9XG59XG5cbmZ1bmN0aW9uIGFsbG9jICh0aGF0LCBzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICBhc3NlcnRTaXplKHNpemUpXG4gIGlmIChzaXplIDw9IDApIHtcbiAgICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpXG4gIH1cbiAgaWYgKGZpbGwgIT09IHVuZGVmaW5lZCkge1xuICAgIC8vIE9ubHkgcGF5IGF0dGVudGlvbiB0byBlbmNvZGluZyBpZiBpdCdzIGEgc3RyaW5nLiBUaGlzXG4gICAgLy8gcHJldmVudHMgYWNjaWRlbnRhbGx5IHNlbmRpbmcgaW4gYSBudW1iZXIgdGhhdCB3b3VsZFxuICAgIC8vIGJlIGludGVycHJldHRlZCBhcyBhIHN0YXJ0IG9mZnNldC5cbiAgICByZXR1cm4gdHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJ1xuICAgICAgPyBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSkuZmlsbChmaWxsLCBlbmNvZGluZylcbiAgICAgIDogY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpLmZpbGwoZmlsbClcbiAgfVxuICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpXG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBmaWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICogYWxsb2Moc2l6ZVssIGZpbGxbLCBlbmNvZGluZ11dKVxuICoqL1xuQnVmZmVyLmFsbG9jID0gZnVuY3Rpb24gKHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIHJldHVybiBhbGxvYyhudWxsLCBzaXplLCBmaWxsLCBlbmNvZGluZylcbn1cblxuZnVuY3Rpb24gYWxsb2NVbnNhZmUgKHRoYXQsIHNpemUpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUgPCAwID8gMCA6IGNoZWNrZWQoc2l6ZSkgfCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaXplOyArK2kpIHtcbiAgICAgIHRoYXRbaV0gPSAwXG4gICAgfVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbi8qKlxuICogRXF1aXZhbGVudCB0byBCdWZmZXIobnVtKSwgYnkgZGVmYXVsdCBjcmVhdGVzIGEgbm9uLXplcm8tZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqICovXG5CdWZmZXIuYWxsb2NVbnNhZmUgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICByZXR1cm4gYWxsb2NVbnNhZmUobnVsbCwgc2l6ZSlcbn1cbi8qKlxuICogRXF1aXZhbGVudCB0byBTbG93QnVmZmVyKG51bSksIGJ5IGRlZmF1bHQgY3JlYXRlcyBhIG5vbi16ZXJvLWZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKi9cbkJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3cgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICByZXR1cm4gYWxsb2NVbnNhZmUobnVsbCwgc2l6ZSlcbn1cblxuZnVuY3Rpb24gZnJvbVN0cmluZyAodGhhdCwgc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJyB8fCBlbmNvZGluZyA9PT0gJycpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICB9XG5cbiAgaWYgKCFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImVuY29kaW5nXCIgbXVzdCBiZSBhIHZhbGlkIHN0cmluZyBlbmNvZGluZycpXG4gIH1cblxuICB2YXIgbGVuZ3RoID0gYnl0ZUxlbmd0aChzdHJpbmcsIGVuY29kaW5nKSB8IDBcbiAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW5ndGgpXG5cbiAgdmFyIGFjdHVhbCA9IHRoYXQud3JpdGUoc3RyaW5nLCBlbmNvZGluZylcblxuICBpZiAoYWN0dWFsICE9PSBsZW5ndGgpIHtcbiAgICAvLyBXcml0aW5nIGEgaGV4IHN0cmluZywgZm9yIGV4YW1wbGUsIHRoYXQgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXJzIHdpbGxcbiAgICAvLyBjYXVzZSBldmVyeXRoaW5nIGFmdGVyIHRoZSBmaXJzdCBpbnZhbGlkIGNoYXJhY3RlciB0byBiZSBpZ25vcmVkLiAoZS5nLlxuICAgIC8vICdhYnh4Y2QnIHdpbGwgYmUgdHJlYXRlZCBhcyAnYWInKVxuICAgIHRoYXQgPSB0aGF0LnNsaWNlKDAsIGFjdHVhbClcbiAgfVxuXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUxpa2UgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGggPCAwID8gMCA6IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW5ndGgpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICB0aGF0W2ldID0gYXJyYXlbaV0gJiAyNTVcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tQXJyYXlCdWZmZXIgKHRoYXQsIGFycmF5LCBieXRlT2Zmc2V0LCBsZW5ndGgpIHtcbiAgYXJyYXkuYnl0ZUxlbmd0aCAvLyB0aGlzIHRocm93cyBpZiBgYXJyYXlgIGlzIG5vdCBhIHZhbGlkIEFycmF5QnVmZmVyXG5cbiAgaWYgKGJ5dGVPZmZzZXQgPCAwIHx8IGFycmF5LmJ5dGVMZW5ndGggPCBieXRlT2Zmc2V0KSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1xcJ29mZnNldFxcJyBpcyBvdXQgb2YgYm91bmRzJylcbiAgfVxuXG4gIGlmIChhcnJheS5ieXRlTGVuZ3RoIDwgYnl0ZU9mZnNldCArIChsZW5ndGggfHwgMCkpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXFwnbGVuZ3RoXFwnIGlzIG91dCBvZiBib3VuZHMnKVxuICB9XG5cbiAgaWYgKGJ5dGVPZmZzZXQgPT09IHVuZGVmaW5lZCAmJiBsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXkpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBhcnJheSA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0KVxuICB9IGVsc2Uge1xuICAgIGFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlLCBmb3IgYmVzdCBwZXJmb3JtYW5jZVxuICAgIHRoYXQgPSBhcnJheVxuICAgIHRoYXQuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICB0aGF0ID0gZnJvbUFycmF5TGlrZSh0aGF0LCBhcnJheSlcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tT2JqZWN0ICh0aGF0LCBvYmopIHtcbiAgaWYgKGludGVybmFsSXNCdWZmZXIob2JqKSkge1xuICAgIHZhciBsZW4gPSBjaGVja2VkKG9iai5sZW5ndGgpIHwgMFxuICAgIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgbGVuKVxuXG4gICAgaWYgKHRoYXQubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gdGhhdFxuICAgIH1cblxuICAgIG9iai5jb3B5KHRoYXQsIDAsIDAsIGxlbilcbiAgICByZXR1cm4gdGhhdFxuICB9XG5cbiAgaWYgKG9iaikge1xuICAgIGlmICgodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICBvYmouYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHx8ICdsZW5ndGgnIGluIG9iaikge1xuICAgICAgaWYgKHR5cGVvZiBvYmoubGVuZ3RoICE9PSAnbnVtYmVyJyB8fCBpc25hbihvYmoubGVuZ3RoKSkge1xuICAgICAgICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIDApXG4gICAgICB9XG4gICAgICByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmopXG4gICAgfVxuXG4gICAgaWYgKG9iai50eXBlID09PSAnQnVmZmVyJyAmJiBpc0FycmF5KG9iai5kYXRhKSkge1xuICAgICAgcmV0dXJuIGZyb21BcnJheUxpa2UodGhhdCwgb2JqLmRhdGEpXG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcignRmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZywgQnVmZmVyLCBBcnJheUJ1ZmZlciwgQXJyYXksIG9yIGFycmF5LWxpa2Ugb2JqZWN0LicpXG59XG5cbmZ1bmN0aW9uIGNoZWNrZWQgKGxlbmd0aCkge1xuICAvLyBOb3RlOiBjYW5ub3QgdXNlIGBsZW5ndGggPCBrTWF4TGVuZ3RoKClgIGhlcmUgYmVjYXVzZSB0aGF0IGZhaWxzIHdoZW5cbiAgLy8gbGVuZ3RoIGlzIE5hTiAod2hpY2ggaXMgb3RoZXJ3aXNlIGNvZXJjZWQgdG8gemVyby4pXG4gIGlmIChsZW5ndGggPj0ga01heExlbmd0aCgpKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gYWxsb2NhdGUgQnVmZmVyIGxhcmdlciB0aGFuIG1heGltdW0gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgJ3NpemU6IDB4JyArIGtNYXhMZW5ndGgoKS50b1N0cmluZygxNikgKyAnIGJ5dGVzJylcbiAgfVxuICByZXR1cm4gbGVuZ3RoIHwgMFxufVxuXG5leHBvcnQgZnVuY3Rpb24gU2xvd0J1ZmZlciAobGVuZ3RoKSB7XG4gIGlmICgrbGVuZ3RoICE9IGxlbmd0aCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGVxZXFlcVxuICAgIGxlbmd0aCA9IDBcbiAgfVxuICByZXR1cm4gQnVmZmVyLmFsbG9jKCtsZW5ndGgpXG59XG5CdWZmZXIuaXNCdWZmZXIgPSBpc0J1ZmZlcjtcbmZ1bmN0aW9uIGludGVybmFsSXNCdWZmZXIgKGIpIHtcbiAgcmV0dXJuICEhKGIgIT0gbnVsbCAmJiBiLl9pc0J1ZmZlcilcbn1cblxuQnVmZmVyLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChhLCBiKSB7XG4gIGlmICghaW50ZXJuYWxJc0J1ZmZlcihhKSB8fCAhaW50ZXJuYWxJc0J1ZmZlcihiKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50cyBtdXN0IGJlIEJ1ZmZlcnMnKVxuICB9XG5cbiAgaWYgKGEgPT09IGIpIHJldHVybiAwXG5cbiAgdmFyIHggPSBhLmxlbmd0aFxuICB2YXIgeSA9IGIubGVuZ3RoXG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IE1hdGgubWluKHgsIHkpOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAoYVtpXSAhPT0gYltpXSkge1xuICAgICAgeCA9IGFbaV1cbiAgICAgIHkgPSBiW2ldXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuQnVmZmVyLmlzRW5jb2RpbmcgPSBmdW5jdGlvbiBpc0VuY29kaW5nIChlbmNvZGluZykge1xuICBzd2l0Y2ggKFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdsYXRpbjEnOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0dXJuIHRydWVcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uIGNvbmNhdCAobGlzdCwgbGVuZ3RoKSB7XG4gIGlmICghaXNBcnJheShsaXN0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpXG4gIH1cblxuICBpZiAobGlzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gQnVmZmVyLmFsbG9jKDApXG4gIH1cblxuICB2YXIgaVxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBsZW5ndGggPSAwXG4gICAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyArK2kpIHtcbiAgICAgIGxlbmd0aCArPSBsaXN0W2ldLmxlbmd0aFxuICAgIH1cbiAgfVxuXG4gIHZhciBidWZmZXIgPSBCdWZmZXIuYWxsb2NVbnNhZmUobGVuZ3RoKVxuICB2YXIgcG9zID0gMFxuICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgIHZhciBidWYgPSBsaXN0W2ldXG4gICAgaWYgKCFpbnRlcm5hbElzQnVmZmVyKGJ1ZikpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpXG4gICAgfVxuICAgIGJ1Zi5jb3B5KGJ1ZmZlciwgcG9zKVxuICAgIHBvcyArPSBidWYubGVuZ3RoXG4gIH1cbiAgcmV0dXJuIGJ1ZmZlclxufVxuXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChzdHJpbmcsIGVuY29kaW5nKSB7XG4gIGlmIChpbnRlcm5hbElzQnVmZmVyKHN0cmluZykpIHtcbiAgICByZXR1cm4gc3RyaW5nLmxlbmd0aFxuICB9XG4gIGlmICh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBBcnJheUJ1ZmZlci5pc1ZpZXcgPT09ICdmdW5jdGlvbicgJiZcbiAgICAgIChBcnJheUJ1ZmZlci5pc1ZpZXcoc3RyaW5nKSB8fCBzdHJpbmcgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikpIHtcbiAgICByZXR1cm4gc3RyaW5nLmJ5dGVMZW5ndGhcbiAgfVxuICBpZiAodHlwZW9mIHN0cmluZyAhPT0gJ3N0cmluZycpIHtcbiAgICBzdHJpbmcgPSAnJyArIHN0cmluZ1xuICB9XG5cbiAgdmFyIGxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKGxlbiA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBVc2UgYSBmb3IgbG9vcCB0byBhdm9pZCByZWN1cnNpb25cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGVuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgIGNhc2UgdW5kZWZpbmVkOlxuICAgICAgICByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiBsZW4gKiAyXG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gbGVuID4+PiAxXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGggLy8gYXNzdW1lIHV0ZjhcbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cbkJ1ZmZlci5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuXG5mdW5jdGlvbiBzbG93VG9TdHJpbmcgKGVuY29kaW5nLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG5cbiAgLy8gTm8gbmVlZCB0byB2ZXJpZnkgdGhhdCBcInRoaXMubGVuZ3RoIDw9IE1BWF9VSU5UMzJcIiBzaW5jZSBpdCdzIGEgcmVhZC1vbmx5XG4gIC8vIHByb3BlcnR5IG9mIGEgdHlwZWQgYXJyYXkuXG5cbiAgLy8gVGhpcyBiZWhhdmVzIG5laXRoZXIgbGlrZSBTdHJpbmcgbm9yIFVpbnQ4QXJyYXkgaW4gdGhhdCB3ZSBzZXQgc3RhcnQvZW5kXG4gIC8vIHRvIHRoZWlyIHVwcGVyL2xvd2VyIGJvdW5kcyBpZiB0aGUgdmFsdWUgcGFzc2VkIGlzIG91dCBvZiByYW5nZS5cbiAgLy8gdW5kZWZpbmVkIGlzIGhhbmRsZWQgc3BlY2lhbGx5IGFzIHBlciBFQ01BLTI2MiA2dGggRWRpdGlvbixcbiAgLy8gU2VjdGlvbiAxMy4zLjMuNyBSdW50aW1lIFNlbWFudGljczogS2V5ZWRCaW5kaW5nSW5pdGlhbGl6YXRpb24uXG4gIGlmIChzdGFydCA9PT0gdW5kZWZpbmVkIHx8IHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ID0gMFxuICB9XG4gIC8vIFJldHVybiBlYXJseSBpZiBzdGFydCA+IHRoaXMubGVuZ3RoLiBEb25lIGhlcmUgdG8gcHJldmVudCBwb3RlbnRpYWwgdWludDMyXG4gIC8vIGNvZXJjaW9uIGZhaWwgYmVsb3cuXG4gIGlmIChzdGFydCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBpZiAoZW5kID09PSB1bmRlZmluZWQgfHwgZW5kID4gdGhpcy5sZW5ndGgpIHtcbiAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICB9XG5cbiAgaWYgKGVuZCA8PSAwKSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICAvLyBGb3JjZSBjb2Vyc2lvbiB0byB1aW50MzIuIFRoaXMgd2lsbCBhbHNvIGNvZXJjZSBmYWxzZXkvTmFOIHZhbHVlcyB0byAwLlxuICBlbmQgPj4+PSAwXG4gIHN0YXJ0ID4+Pj0gMFxuXG4gIGlmIChlbmQgPD0gc3RhcnQpIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxhdGluMVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdXRmMTZsZVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9IChlbmNvZGluZyArICcnKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG4vLyBUaGUgcHJvcGVydHkgaXMgdXNlZCBieSBgQnVmZmVyLmlzQnVmZmVyYCBhbmQgYGlzLWJ1ZmZlcmAgKGluIFNhZmFyaSA1LTcpIHRvIGRldGVjdFxuLy8gQnVmZmVyIGluc3RhbmNlcy5cbkJ1ZmZlci5wcm90b3R5cGUuX2lzQnVmZmVyID0gdHJ1ZVxuXG5mdW5jdGlvbiBzd2FwIChiLCBuLCBtKSB7XG4gIHZhciBpID0gYltuXVxuICBiW25dID0gYlttXVxuICBiW21dID0gaVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXAxNiA9IGZ1bmN0aW9uIHN3YXAxNiAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgMiAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgMTYtYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gMikge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDEpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwMzIgPSBmdW5jdGlvbiBzd2FwMzIgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDQgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDMyLWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDQpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyAzKVxuICAgIHN3YXAodGhpcywgaSArIDEsIGkgKyAyKVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDY0ID0gZnVuY3Rpb24gc3dhcDY0ICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSA4ICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA2NC1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA4KSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgNylcbiAgICBzd2FwKHRoaXMsIGkgKyAxLCBpICsgNilcbiAgICBzd2FwKHRoaXMsIGkgKyAyLCBpICsgNSlcbiAgICBzd2FwKHRoaXMsIGkgKyAzLCBpICsgNClcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcgKCkge1xuICB2YXIgbGVuZ3RoID0gdGhpcy5sZW5ndGggfCAwXG4gIGlmIChsZW5ndGggPT09IDApIHJldHVybiAnJ1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCAwLCBsZW5ndGgpXG4gIHJldHVybiBzbG93VG9TdHJpbmcuYXBwbHkodGhpcywgYXJndW1lbnRzKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIGVxdWFscyAoYikge1xuICBpZiAoIWludGVybmFsSXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICBpZiAodGhpcyA9PT0gYikgcmV0dXJuIHRydWVcbiAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsIGIpID09PSAwXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QgKCkge1xuICB2YXIgc3RyID0gJydcbiAgdmFyIG1heCA9IElOU1BFQ1RfTUFYX0JZVEVTXG4gIGlmICh0aGlzLmxlbmd0aCA+IDApIHtcbiAgICBzdHIgPSB0aGlzLnRvU3RyaW5nKCdoZXgnLCAwLCBtYXgpLm1hdGNoKC8uezJ9L2cpLmpvaW4oJyAnKVxuICAgIGlmICh0aGlzLmxlbmd0aCA+IG1heCkgc3RyICs9ICcgLi4uICdcbiAgfVxuICByZXR1cm4gJzxCdWZmZXIgJyArIHN0ciArICc+J1xufVxuXG5CdWZmZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlICh0YXJnZXQsIHN0YXJ0LCBlbmQsIHRoaXNTdGFydCwgdGhpc0VuZCkge1xuICBpZiAoIWludGVybmFsSXNCdWZmZXIodGFyZ2V0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICB9XG5cbiAgaWYgKHN0YXJ0ID09PSB1bmRlZmluZWQpIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICBpZiAoZW5kID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmQgPSB0YXJnZXQgPyB0YXJnZXQubGVuZ3RoIDogMFxuICB9XG4gIGlmICh0aGlzU3RhcnQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRoaXNTdGFydCA9IDBcbiAgfVxuICBpZiAodGhpc0VuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhpc0VuZCA9IHRoaXMubGVuZ3RoXG4gIH1cblxuICBpZiAoc3RhcnQgPCAwIHx8IGVuZCA+IHRhcmdldC5sZW5ndGggfHwgdGhpc1N0YXJ0IDwgMCB8fCB0aGlzRW5kID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb3V0IG9mIHJhbmdlIGluZGV4JylcbiAgfVxuXG4gIGlmICh0aGlzU3RhcnQgPj0gdGhpc0VuZCAmJiBzdGFydCA+PSBlbmQpIHtcbiAgICByZXR1cm4gMFxuICB9XG4gIGlmICh0aGlzU3RhcnQgPj0gdGhpc0VuZCkge1xuICAgIHJldHVybiAtMVxuICB9XG4gIGlmIChzdGFydCA+PSBlbmQpIHtcbiAgICByZXR1cm4gMVxuICB9XG5cbiAgc3RhcnQgPj4+PSAwXG4gIGVuZCA+Pj49IDBcbiAgdGhpc1N0YXJ0ID4+Pj0gMFxuICB0aGlzRW5kID4+Pj0gMFxuXG4gIGlmICh0aGlzID09PSB0YXJnZXQpIHJldHVybiAwXG5cbiAgdmFyIHggPSB0aGlzRW5kIC0gdGhpc1N0YXJ0XG4gIHZhciB5ID0gZW5kIC0gc3RhcnRcbiAgdmFyIGxlbiA9IE1hdGgubWluKHgsIHkpXG5cbiAgdmFyIHRoaXNDb3B5ID0gdGhpcy5zbGljZSh0aGlzU3RhcnQsIHRoaXNFbmQpXG4gIHZhciB0YXJnZXRDb3B5ID0gdGFyZ2V0LnNsaWNlKHN0YXJ0LCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgIGlmICh0aGlzQ29weVtpXSAhPT0gdGFyZ2V0Q29weVtpXSkge1xuICAgICAgeCA9IHRoaXNDb3B5W2ldXG4gICAgICB5ID0gdGFyZ2V0Q29weVtpXVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbi8vIEZpbmRzIGVpdGhlciB0aGUgZmlyc3QgaW5kZXggb2YgYHZhbGAgaW4gYGJ1ZmZlcmAgYXQgb2Zmc2V0ID49IGBieXRlT2Zmc2V0YCxcbi8vIE9SIHRoZSBsYXN0IGluZGV4IG9mIGB2YWxgIGluIGBidWZmZXJgIGF0IG9mZnNldCA8PSBgYnl0ZU9mZnNldGAuXG4vL1xuLy8gQXJndW1lbnRzOlxuLy8gLSBidWZmZXIgLSBhIEJ1ZmZlciB0byBzZWFyY2hcbi8vIC0gdmFsIC0gYSBzdHJpbmcsIEJ1ZmZlciwgb3IgbnVtYmVyXG4vLyAtIGJ5dGVPZmZzZXQgLSBhbiBpbmRleCBpbnRvIGBidWZmZXJgOyB3aWxsIGJlIGNsYW1wZWQgdG8gYW4gaW50MzJcbi8vIC0gZW5jb2RpbmcgLSBhbiBvcHRpb25hbCBlbmNvZGluZywgcmVsZXZhbnQgaXMgdmFsIGlzIGEgc3RyaW5nXG4vLyAtIGRpciAtIHRydWUgZm9yIGluZGV4T2YsIGZhbHNlIGZvciBsYXN0SW5kZXhPZlxuZnVuY3Rpb24gYmlkaXJlY3Rpb25hbEluZGV4T2YgKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKSB7XG4gIC8vIEVtcHR5IGJ1ZmZlciBtZWFucyBubyBtYXRjaFxuICBpZiAoYnVmZmVyLmxlbmd0aCA9PT0gMCkgcmV0dXJuIC0xXG5cbiAgLy8gTm9ybWFsaXplIGJ5dGVPZmZzZXRcbiAgaWYgKHR5cGVvZiBieXRlT2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gYnl0ZU9mZnNldFxuICAgIGJ5dGVPZmZzZXQgPSAwXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA+IDB4N2ZmZmZmZmYpIHtcbiAgICBieXRlT2Zmc2V0ID0gMHg3ZmZmZmZmZlxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAtMHg4MDAwMDAwMCkge1xuICAgIGJ5dGVPZmZzZXQgPSAtMHg4MDAwMDAwMFxuICB9XG4gIGJ5dGVPZmZzZXQgPSArYnl0ZU9mZnNldCAgLy8gQ29lcmNlIHRvIE51bWJlci5cbiAgaWYgKGlzTmFOKGJ5dGVPZmZzZXQpKSB7XG4gICAgLy8gYnl0ZU9mZnNldDogaXQgaXQncyB1bmRlZmluZWQsIG51bGwsIE5hTiwgXCJmb29cIiwgZXRjLCBzZWFyY2ggd2hvbGUgYnVmZmVyXG4gICAgYnl0ZU9mZnNldCA9IGRpciA/IDAgOiAoYnVmZmVyLmxlbmd0aCAtIDEpXG4gIH1cblxuICAvLyBOb3JtYWxpemUgYnl0ZU9mZnNldDogbmVnYXRpdmUgb2Zmc2V0cyBzdGFydCBmcm9tIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlclxuICBpZiAoYnl0ZU9mZnNldCA8IDApIGJ5dGVPZmZzZXQgPSBidWZmZXIubGVuZ3RoICsgYnl0ZU9mZnNldFxuICBpZiAoYnl0ZU9mZnNldCA+PSBidWZmZXIubGVuZ3RoKSB7XG4gICAgaWYgKGRpcikgcmV0dXJuIC0xXG4gICAgZWxzZSBieXRlT2Zmc2V0ID0gYnVmZmVyLmxlbmd0aCAtIDFcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0IDwgMCkge1xuICAgIGlmIChkaXIpIGJ5dGVPZmZzZXQgPSAwXG4gICAgZWxzZSByZXR1cm4gLTFcbiAgfVxuXG4gIC8vIE5vcm1hbGl6ZSB2YWxcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFsID0gQnVmZmVyLmZyb20odmFsLCBlbmNvZGluZylcbiAgfVxuXG4gIC8vIEZpbmFsbHksIHNlYXJjaCBlaXRoZXIgaW5kZXhPZiAoaWYgZGlyIGlzIHRydWUpIG9yIGxhc3RJbmRleE9mXG4gIGlmIChpbnRlcm5hbElzQnVmZmVyKHZhbCkpIHtcbiAgICAvLyBTcGVjaWFsIGNhc2U6IGxvb2tpbmcgZm9yIGVtcHR5IHN0cmluZy9idWZmZXIgYWx3YXlzIGZhaWxzXG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiAtMVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgdmFsID0gdmFsICYgMHhGRiAvLyBTZWFyY2ggZm9yIGEgYnl0ZSB2YWx1ZSBbMC0yNTVdXG4gICAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUICYmXG4gICAgICAgIHR5cGVvZiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpZiAoZGlyKSB7XG4gICAgICAgIHJldHVybiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mLmNhbGwoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUubGFzdEluZGV4T2YuY2FsbChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldClcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZihidWZmZXIsIFsgdmFsIF0sIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpXG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCd2YWwgbXVzdCBiZSBzdHJpbmcsIG51bWJlciBvciBCdWZmZXInKVxufVxuXG5mdW5jdGlvbiBhcnJheUluZGV4T2YgKGFyciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKSB7XG4gIHZhciBpbmRleFNpemUgPSAxXG4gIHZhciBhcnJMZW5ndGggPSBhcnIubGVuZ3RoXG4gIHZhciB2YWxMZW5ndGggPSB2YWwubGVuZ3RoXG5cbiAgaWYgKGVuY29kaW5nICE9PSB1bmRlZmluZWQpIHtcbiAgICBlbmNvZGluZyA9IFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgIGlmIChlbmNvZGluZyA9PT0gJ3VjczInIHx8IGVuY29kaW5nID09PSAndWNzLTInIHx8XG4gICAgICAgIGVuY29kaW5nID09PSAndXRmMTZsZScgfHwgZW5jb2RpbmcgPT09ICd1dGYtMTZsZScpIHtcbiAgICAgIGlmIChhcnIubGVuZ3RoIDwgMiB8fCB2YWwubGVuZ3RoIDwgMikge1xuICAgICAgICByZXR1cm4gLTFcbiAgICAgIH1cbiAgICAgIGluZGV4U2l6ZSA9IDJcbiAgICAgIGFyckxlbmd0aCAvPSAyXG4gICAgICB2YWxMZW5ndGggLz0gMlxuICAgICAgYnl0ZU9mZnNldCAvPSAyXG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVhZCAoYnVmLCBpKSB7XG4gICAgaWYgKGluZGV4U2l6ZSA9PT0gMSkge1xuICAgICAgcmV0dXJuIGJ1ZltpXVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYnVmLnJlYWRVSW50MTZCRShpICogaW5kZXhTaXplKVxuICAgIH1cbiAgfVxuXG4gIHZhciBpXG4gIGlmIChkaXIpIHtcbiAgICB2YXIgZm91bmRJbmRleCA9IC0xXG4gICAgZm9yIChpID0gYnl0ZU9mZnNldDsgaSA8IGFyckxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAocmVhZChhcnIsIGkpID09PSByZWFkKHZhbCwgZm91bmRJbmRleCA9PT0gLTEgPyAwIDogaSAtIGZvdW5kSW5kZXgpKSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ID09PSAtMSkgZm91bmRJbmRleCA9IGlcbiAgICAgICAgaWYgKGkgLSBmb3VuZEluZGV4ICsgMSA9PT0gdmFsTGVuZ3RoKSByZXR1cm4gZm91bmRJbmRleCAqIGluZGV4U2l6ZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGZvdW5kSW5kZXggIT09IC0xKSBpIC09IGkgLSBmb3VuZEluZGV4XG4gICAgICAgIGZvdW5kSW5kZXggPSAtMVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoYnl0ZU9mZnNldCArIHZhbExlbmd0aCA+IGFyckxlbmd0aCkgYnl0ZU9mZnNldCA9IGFyckxlbmd0aCAtIHZhbExlbmd0aFxuICAgIGZvciAoaSA9IGJ5dGVPZmZzZXQ7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB2YXIgZm91bmQgPSB0cnVlXG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHZhbExlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmIChyZWFkKGFyciwgaSArIGopICE9PSByZWFkKHZhbCwgaikpIHtcbiAgICAgICAgICBmb3VuZCA9IGZhbHNlXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZvdW5kKSByZXR1cm4gaVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiAtMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluY2x1ZGVzID0gZnVuY3Rpb24gaW5jbHVkZXMgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIHRoaXMuaW5kZXhPZih2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSAhPT0gLTFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbmRleE9mID0gZnVuY3Rpb24gaW5kZXhPZiAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgdHJ1ZSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5sYXN0SW5kZXhPZiA9IGZ1bmN0aW9uIGxhc3RJbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiBiaWRpcmVjdGlvbmFsSW5kZXhPZih0aGlzLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBmYWxzZSlcbn1cblxuZnVuY3Rpb24gaGV4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICBvZmZzZXQgPSBOdW1iZXIob2Zmc2V0KSB8fCAwXG4gIHZhciByZW1haW5pbmcgPSBidWYubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gTnVtYmVyKGxlbmd0aClcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgICB9XG4gIH1cblxuICAvLyBtdXN0IGJlIGFuIGV2ZW4gbnVtYmVyIG9mIGRpZ2l0c1xuICB2YXIgc3RyTGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAoc3RyTGVuICUgMiAhPT0gMCkgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBoZXggc3RyaW5nJylcblxuICBpZiAobGVuZ3RoID4gc3RyTGVuIC8gMikge1xuICAgIGxlbmd0aCA9IHN0ckxlbiAvIDJcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgdmFyIHBhcnNlZCA9IHBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSAqIDIsIDIpLCAxNilcbiAgICBpZiAoaXNOYU4ocGFyc2VkKSkgcmV0dXJuIGlcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSBwYXJzZWRcbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiB1dGY4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGY4VG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBhc2NpaVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYXNjaWlUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGxhdGluMVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGFzY2lpV3JpdGUoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBiYXNlNjRXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGJhc2U2NFRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gdWNzMldyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmMTZsZVRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIHdyaXRlIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZykge1xuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nKVxuICBpZiAob2Zmc2V0ID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBlbmNvZGluZylcbiAgfSBlbHNlIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gb2Zmc2V0XG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIG9mZnNldFssIGxlbmd0aF1bLCBlbmNvZGluZ10pXG4gIH0gZWxzZSBpZiAoaXNGaW5pdGUob2Zmc2V0KSkge1xuICAgIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgICBpZiAoaXNGaW5pdGUobGVuZ3RoKSkge1xuICAgICAgbGVuZ3RoID0gbGVuZ3RoIHwgMFxuICAgICAgaWYgKGVuY29kaW5nID09PSB1bmRlZmluZWQpIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgfSBlbHNlIHtcbiAgICAgIGVuY29kaW5nID0gbGVuZ3RoXG4gICAgICBsZW5ndGggPSB1bmRlZmluZWRcbiAgICB9XG4gIC8vIGxlZ2FjeSB3cml0ZShzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXQsIGxlbmd0aCkgLSByZW1vdmUgaW4gdjAuMTNcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnQnVmZmVyLndyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldFssIGxlbmd0aF0pIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQnXG4gICAgKVxuICB9XG5cbiAgdmFyIHJlbWFpbmluZyA9IHRoaXMubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCB8fCBsZW5ndGggPiByZW1haW5pbmcpIGxlbmd0aCA9IHJlbWFpbmluZ1xuXG4gIGlmICgoc3RyaW5nLmxlbmd0aCA+IDAgJiYgKGxlbmd0aCA8IDAgfHwgb2Zmc2V0IDwgMCkpIHx8IG9mZnNldCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gd3JpdGUgb3V0c2lkZSBidWZmZXIgYm91bmRzJylcbiAgfVxuXG4gIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGF0aW4xV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgLy8gV2FybmluZzogbWF4TGVuZ3RoIG5vdCB0YWtlbiBpbnRvIGFjY291bnQgaW4gYmFzZTY0V3JpdGVcbiAgICAgICAgcmV0dXJuIGJhc2U2NFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1Y3MyV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OICgpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnQnVmZmVyJyxcbiAgICBkYXRhOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLl9hcnIgfHwgdGhpcywgMClcbiAgfVxufVxuXG5mdW5jdGlvbiBiYXNlNjRTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGlmIChzdGFydCA9PT0gMCAmJiBlbmQgPT09IGJ1Zi5sZW5ndGgpIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYuc2xpY2Uoc3RhcnQsIGVuZCkpXG4gIH1cbn1cblxuZnVuY3Rpb24gdXRmOFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuICB2YXIgcmVzID0gW11cblxuICB2YXIgaSA9IHN0YXJ0XG4gIHdoaWxlIChpIDwgZW5kKSB7XG4gICAgdmFyIGZpcnN0Qnl0ZSA9IGJ1ZltpXVxuICAgIHZhciBjb2RlUG9pbnQgPSBudWxsXG4gICAgdmFyIGJ5dGVzUGVyU2VxdWVuY2UgPSAoZmlyc3RCeXRlID4gMHhFRikgPyA0XG4gICAgICA6IChmaXJzdEJ5dGUgPiAweERGKSA/IDNcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4QkYpID8gMlxuICAgICAgOiAxXG5cbiAgICBpZiAoaSArIGJ5dGVzUGVyU2VxdWVuY2UgPD0gZW5kKSB7XG4gICAgICB2YXIgc2Vjb25kQnl0ZSwgdGhpcmRCeXRlLCBmb3VydGhCeXRlLCB0ZW1wQ29kZVBvaW50XG5cbiAgICAgIHN3aXRjaCAoYnl0ZXNQZXJTZXF1ZW5jZSkge1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgaWYgKGZpcnN0Qnl0ZSA8IDB4ODApIHtcbiAgICAgICAgICAgIGNvZGVQb2ludCA9IGZpcnN0Qnl0ZVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweDFGKSA8PCAweDYgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0YpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHhDIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAodGhpcmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3RkYgJiYgKHRlbXBDb2RlUG9pbnQgPCAweEQ4MDAgfHwgdGVtcENvZGVQb2ludCA+IDB4REZGRikpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgZm91cnRoQnl0ZSA9IGJ1ZltpICsgM11cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKGZvdXJ0aEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4MTIgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4QyB8ICh0aGlyZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAoZm91cnRoQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4RkZGRiAmJiB0ZW1wQ29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY29kZVBvaW50ID09PSBudWxsKSB7XG4gICAgICAvLyB3ZSBkaWQgbm90IGdlbmVyYXRlIGEgdmFsaWQgY29kZVBvaW50IHNvIGluc2VydCBhXG4gICAgICAvLyByZXBsYWNlbWVudCBjaGFyIChVK0ZGRkQpIGFuZCBhZHZhbmNlIG9ubHkgMSBieXRlXG4gICAgICBjb2RlUG9pbnQgPSAweEZGRkRcbiAgICAgIGJ5dGVzUGVyU2VxdWVuY2UgPSAxXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPiAweEZGRkYpIHtcbiAgICAgIC8vIGVuY29kZSB0byB1dGYxNiAoc3Vycm9nYXRlIHBhaXIgZGFuY2UpXG4gICAgICBjb2RlUG9pbnQgLT0gMHgxMDAwMFxuICAgICAgcmVzLnB1c2goY29kZVBvaW50ID4+PiAxMCAmIDB4M0ZGIHwgMHhEODAwKVxuICAgICAgY29kZVBvaW50ID0gMHhEQzAwIHwgY29kZVBvaW50ICYgMHgzRkZcbiAgICB9XG5cbiAgICByZXMucHVzaChjb2RlUG9pbnQpXG4gICAgaSArPSBieXRlc1BlclNlcXVlbmNlXG4gIH1cblxuICByZXR1cm4gZGVjb2RlQ29kZVBvaW50c0FycmF5KHJlcylcbn1cblxuLy8gQmFzZWQgb24gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjI3NDcyNzIvNjgwNzQyLCB0aGUgYnJvd3NlciB3aXRoXG4vLyB0aGUgbG93ZXN0IGxpbWl0IGlzIENocm9tZSwgd2l0aCAweDEwMDAwIGFyZ3MuXG4vLyBXZSBnbyAxIG1hZ25pdHVkZSBsZXNzLCBmb3Igc2FmZXR5XG52YXIgTUFYX0FSR1VNRU5UU19MRU5HVEggPSAweDEwMDBcblxuZnVuY3Rpb24gZGVjb2RlQ29kZVBvaW50c0FycmF5IChjb2RlUG9pbnRzKSB7XG4gIHZhciBsZW4gPSBjb2RlUG9pbnRzLmxlbmd0aFxuICBpZiAobGVuIDw9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjb2RlUG9pbnRzKSAvLyBhdm9pZCBleHRyYSBzbGljZSgpXG4gIH1cblxuICAvLyBEZWNvZGUgaW4gY2h1bmtzIHRvIGF2b2lkIFwiY2FsbCBzdGFjayBzaXplIGV4Y2VlZGVkXCIuXG4gIHZhciByZXMgPSAnJ1xuICB2YXIgaSA9IDBcbiAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShcbiAgICAgIFN0cmluZyxcbiAgICAgIGNvZGVQb2ludHMuc2xpY2UoaSwgaSArPSBNQVhfQVJHVU1FTlRTX0xFTkdUSClcbiAgICApXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSAmIDB4N0YpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBsYXRpbjFTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBoZXhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG5cbiAgaWYgKCFzdGFydCB8fCBzdGFydCA8IDApIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCB8fCBlbmQgPCAwIHx8IGVuZCA+IGxlbikgZW5kID0gbGVuXG5cbiAgdmFyIG91dCA9ICcnXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgb3V0ICs9IHRvSGV4KGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBieXRlcyA9IGJ1Zi5zbGljZShzdGFydCwgZW5kKVxuICB2YXIgcmVzID0gJydcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldICsgYnl0ZXNbaSArIDFdICogMjU2KVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uIHNsaWNlIChzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBzdGFydCA9IH5+c3RhcnRcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB+fmVuZFxuXG4gIGlmIChzdGFydCA8IDApIHtcbiAgICBzdGFydCArPSBsZW5cbiAgICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgfSBlbHNlIGlmIChzdGFydCA+IGxlbikge1xuICAgIHN0YXJ0ID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgMCkge1xuICAgIGVuZCArPSBsZW5cbiAgICBpZiAoZW5kIDwgMCkgZW5kID0gMFxuICB9IGVsc2UgaWYgKGVuZCA+IGxlbikge1xuICAgIGVuZCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIHZhciBuZXdCdWZcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgbmV3QnVmID0gdGhpcy5zdWJhcnJheShzdGFydCwgZW5kKVxuICAgIG5ld0J1Zi5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIH0gZWxzZSB7XG4gICAgdmFyIHNsaWNlTGVuID0gZW5kIC0gc3RhcnRcbiAgICBuZXdCdWYgPSBuZXcgQnVmZmVyKHNsaWNlTGVuLCB1bmRlZmluZWQpXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzbGljZUxlbjsgKytpKSB7XG4gICAgICBuZXdCdWZbaV0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3QnVmXG59XG5cbi8qXG4gKiBOZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IGJ1ZmZlciBpc24ndCB0cnlpbmcgdG8gd3JpdGUgb3V0IG9mIGJvdW5kcy5cbiAqL1xuZnVuY3Rpb24gY2hlY2tPZmZzZXQgKG9mZnNldCwgZXh0LCBsZW5ndGgpIHtcbiAgaWYgKChvZmZzZXQgJSAxKSAhPT0gMCB8fCBvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb2Zmc2V0IGlzIG5vdCB1aW50JylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RyeWluZyB0byBhY2Nlc3MgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50TEUgPSBmdW5jdGlvbiByZWFkVUludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50QkUgPSBmdW5jdGlvbiByZWFkVUludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuICB9XG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXVxuICB2YXIgbXVsID0gMVxuICB3aGlsZSAoYnl0ZUxlbmd0aCA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4ID0gZnVuY3Rpb24gcmVhZFVJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2TEUgPSBmdW5jdGlvbiByZWFkVUludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkJFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDgpIHwgdGhpc1tvZmZzZXQgKyAxXVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAoKHRoaXNbb2Zmc2V0XSkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpKSArXG4gICAgICAodGhpc1tvZmZzZXQgKyAzXSAqIDB4MTAwMDAwMClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyQkUgPSBmdW5jdGlvbiByZWFkVUludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSAqIDB4MTAwMDAwMCkgK1xuICAgICgodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICB0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRMRSA9IGZ1bmN0aW9uIHJlYWRJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRCRSA9IGZ1bmN0aW9uIHJlYWRJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aFxuICB2YXIgbXVsID0gMVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWldXG4gIHdoaWxlIChpID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0taV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24gcmVhZEludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgaWYgKCEodGhpc1tvZmZzZXRdICYgMHg4MCkpIHJldHVybiAodGhpc1tvZmZzZXRdKVxuICByZXR1cm4gKCgweGZmIC0gdGhpc1tvZmZzZXRdICsgMSkgKiAtMSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2QkUgPSBmdW5jdGlvbiByZWFkSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAxXSB8ICh0aGlzW29mZnNldF0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkxFID0gZnVuY3Rpb24gcmVhZEludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDNdIDw8IDI0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkJFID0gZnVuY3Rpb24gcmVhZEludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCAyNCkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdExFID0gZnVuY3Rpb24gcmVhZEZsb2F0TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdEJFID0gZnVuY3Rpb24gcmVhZEZsb2F0QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlTEUgPSBmdW5jdGlvbiByZWFkRG91YmxlTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDUyLCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVCRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDUyLCA4KVxufVxuXG5mdW5jdGlvbiBjaGVja0ludCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmICghaW50ZXJuYWxJc0J1ZmZlcihidWYpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImJ1ZmZlclwiIGFyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXIgaW5zdGFuY2UnKVxuICBpZiAodmFsdWUgPiBtYXggfHwgdmFsdWUgPCBtaW4pIHRocm93IG5ldyBSYW5nZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgaXMgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlVUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIG1heEJ5dGVzID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpIC0gMVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG1heEJ5dGVzLCAwKVxuICB9XG5cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlVUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIG1heEJ5dGVzID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpIC0gMVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG1heEJ5dGVzLCAwKVxuICB9XG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVVSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweGZmLCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDE2IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZiArIHZhbHVlICsgMVxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGJ1Zi5sZW5ndGggLSBvZmZzZXQsIDIpOyBpIDwgajsgKytpKSB7XG4gICAgYnVmW29mZnNldCArIGldID0gKHZhbHVlICYgKDB4ZmYgPDwgKDggKiAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSkpKSA+Pj5cbiAgICAgIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpICogOFxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDMyIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCA0KTsgaSA8IGo7ICsraSkge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSA+Pj4gKGxpdHRsZUVuZGlhbiA/IGkgOiAzIC0gaSkgKiA4KSAmIDB4ZmZcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSAwXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIGlmICh2YWx1ZSA8IDAgJiYgc3ViID09PSAwICYmIHRoaXNbb2Zmc2V0ICsgaSAtIDFdICE9PSAwKSB7XG4gICAgICBzdWIgPSAxXG4gICAgfVxuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlSW50QkUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gMFxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIGlmICh2YWx1ZSA8IDAgJiYgc3ViID09PSAwICYmIHRoaXNbb2Zmc2V0ICsgaSArIDFdICE9PSAwKSB7XG4gICAgICBzdWIgPSAxXG4gICAgfVxuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4N2YsIC0weDgwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZiArIHZhbHVlICsgMVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5mdW5jdGlvbiBjaGVja0lFRUU3NTQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG4gIGlmIChvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuZnVuY3Rpb24gd3JpdGVGbG9hdCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA0LCAzLjQwMjgyMzQ2NjM4NTI4ODZlKzM4LCAtMy40MDI4MjM0NjYzODUyODg2ZSszOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCAyMywgNClcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0TEUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRCRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiB3cml0ZURvdWJsZSAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA4LCAxLjc5NzY5MzEzNDg2MjMxNTdFKzMwOCwgLTEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDUyLCA4KVxuICByZXR1cm4gb2Zmc2V0ICsgOFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlTEUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVCRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbi8vIGNvcHkodGFyZ2V0QnVmZmVyLCB0YXJnZXRTdGFydD0wLCBzb3VyY2VTdGFydD0wLCBzb3VyY2VFbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uIGNvcHkgKHRhcmdldCwgdGFyZ2V0U3RhcnQsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kICYmIGVuZCAhPT0gMCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldFN0YXJ0ID49IHRhcmdldC5sZW5ndGgpIHRhcmdldFN0YXJ0ID0gdGFyZ2V0Lmxlbmd0aFxuICBpZiAoIXRhcmdldFN0YXJ0KSB0YXJnZXRTdGFydCA9IDBcbiAgaWYgKGVuZCA+IDAgJiYgZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgLy8gQ29weSAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm4gMFxuICBpZiAodGFyZ2V0Lmxlbmd0aCA9PT0gMCB8fCB0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBGYXRhbCBlcnJvciBjb25kaXRpb25zXG4gIGlmICh0YXJnZXRTdGFydCA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigndGFyZ2V0U3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIH1cbiAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+PSB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZVN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICBpZiAoZW5kIDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZUVuZCBvdXQgb2YgYm91bmRzJylcblxuICAvLyBBcmUgd2Ugb29iP1xuICBpZiAoZW5kID4gdGhpcy5sZW5ndGgpIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgPCBlbmQgLSBzdGFydCkge1xuICAgIGVuZCA9IHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCArIHN0YXJ0XG4gIH1cblxuICB2YXIgbGVuID0gZW5kIC0gc3RhcnRcbiAgdmFyIGlcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0ICYmIHN0YXJ0IDwgdGFyZ2V0U3RhcnQgJiYgdGFyZ2V0U3RhcnQgPCBlbmQpIHtcbiAgICAvLyBkZXNjZW5kaW5nIGNvcHkgZnJvbSBlbmRcbiAgICBmb3IgKGkgPSBsZW4gLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSBpZiAobGVuIDwgMTAwMCB8fCAhQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBhc2NlbmRpbmcgY29weSBmcm9tIHN0YXJ0XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICB0YXJnZXRbaSArIHRhcmdldFN0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBVaW50OEFycmF5LnByb3RvdHlwZS5zZXQuY2FsbChcbiAgICAgIHRhcmdldCxcbiAgICAgIHRoaXMuc3ViYXJyYXkoc3RhcnQsIHN0YXJ0ICsgbGVuKSxcbiAgICAgIHRhcmdldFN0YXJ0XG4gICAgKVxuICB9XG5cbiAgcmV0dXJuIGxlblxufVxuXG4vLyBVc2FnZTpcbi8vICAgIGJ1ZmZlci5maWxsKG51bWJlclssIG9mZnNldFssIGVuZF1dKVxuLy8gICAgYnVmZmVyLmZpbGwoYnVmZmVyWywgb2Zmc2V0WywgZW5kXV0pXG4vLyAgICBidWZmZXIuZmlsbChzdHJpbmdbLCBvZmZzZXRbLCBlbmRdXVssIGVuY29kaW5nXSlcbkJ1ZmZlci5wcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uIGZpbGwgKHZhbCwgc3RhcnQsIGVuZCwgZW5jb2RpbmcpIHtcbiAgLy8gSGFuZGxlIHN0cmluZyBjYXNlczpcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKHR5cGVvZiBzdGFydCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVuY29kaW5nID0gc3RhcnRcbiAgICAgIHN0YXJ0ID0gMFxuICAgICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBlbmQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IGVuZFxuICAgICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgICB9XG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDEpIHtcbiAgICAgIHZhciBjb2RlID0gdmFsLmNoYXJDb2RlQXQoMClcbiAgICAgIGlmIChjb2RlIDwgMjU2KSB7XG4gICAgICAgIHZhbCA9IGNvZGVcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVuY29kaW5nICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZW5jb2RpbmcgbXVzdCBiZSBhIHN0cmluZycpXG4gICAgfVxuICAgIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnICYmICFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICB2YWwgPSB2YWwgJiAyNTVcbiAgfVxuXG4gIC8vIEludmFsaWQgcmFuZ2VzIGFyZSBub3Qgc2V0IHRvIGEgZGVmYXVsdCwgc28gY2FuIHJhbmdlIGNoZWNrIGVhcmx5LlxuICBpZiAoc3RhcnQgPCAwIHx8IHRoaXMubGVuZ3RoIDwgc3RhcnQgfHwgdGhpcy5sZW5ndGggPCBlbmQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignT3V0IG9mIHJhbmdlIGluZGV4JylcbiAgfVxuXG4gIGlmIChlbmQgPD0gc3RhcnQpIHtcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgc3RhcnQgPSBzdGFydCA+Pj4gMFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IHRoaXMubGVuZ3RoIDogZW5kID4+PiAwXG5cbiAgaWYgKCF2YWwpIHZhbCA9IDBcblxuICB2YXIgaVxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgICB0aGlzW2ldID0gdmFsXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciBieXRlcyA9IGludGVybmFsSXNCdWZmZXIodmFsKVxuICAgICAgPyB2YWxcbiAgICAgIDogdXRmOFRvQnl0ZXMobmV3IEJ1ZmZlcih2YWwsIGVuY29kaW5nKS50b1N0cmluZygpKVxuICAgIHZhciBsZW4gPSBieXRlcy5sZW5ndGhcbiAgICBmb3IgKGkgPSAwOyBpIDwgZW5kIC0gc3RhcnQ7ICsraSkge1xuICAgICAgdGhpc1tpICsgc3RhcnRdID0gYnl0ZXNbaSAlIGxlbl1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpc1xufVxuXG4vLyBIRUxQRVIgRlVOQ1RJT05TXG4vLyA9PT09PT09PT09PT09PT09XG5cbnZhciBJTlZBTElEX0JBU0U2NF9SRSA9IC9bXitcXC8wLTlBLVphLXotX10vZ1xuXG5mdW5jdGlvbiBiYXNlNjRjbGVhbiAoc3RyKSB7XG4gIC8vIE5vZGUgc3RyaXBzIG91dCBpbnZhbGlkIGNoYXJhY3RlcnMgbGlrZSBcXG4gYW5kIFxcdCBmcm9tIHRoZSBzdHJpbmcsIGJhc2U2NC1qcyBkb2VzIG5vdFxuICBzdHIgPSBzdHJpbmd0cmltKHN0cikucmVwbGFjZShJTlZBTElEX0JBU0U2NF9SRSwgJycpXG4gIC8vIE5vZGUgY29udmVydHMgc3RyaW5ncyB3aXRoIGxlbmd0aCA8IDIgdG8gJydcbiAgaWYgKHN0ci5sZW5ndGggPCAyKSByZXR1cm4gJydcbiAgLy8gTm9kZSBhbGxvd3MgZm9yIG5vbi1wYWRkZWQgYmFzZTY0IHN0cmluZ3MgKG1pc3NpbmcgdHJhaWxpbmcgPT09KSwgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHdoaWxlIChzdHIubGVuZ3RoICUgNCAhPT0gMCkge1xuICAgIHN0ciA9IHN0ciArICc9J1xuICB9XG4gIHJldHVybiBzdHJcbn1cblxuZnVuY3Rpb24gc3RyaW5ndHJpbSAoc3RyKSB7XG4gIGlmIChzdHIudHJpbSkgcmV0dXJuIHN0ci50cmltKClcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCAnJylcbn1cblxuZnVuY3Rpb24gdG9IZXggKG4pIHtcbiAgaWYgKG4gPCAxNikgcmV0dXJuICcwJyArIG4udG9TdHJpbmcoMTYpXG4gIHJldHVybiBuLnRvU3RyaW5nKDE2KVxufVxuXG5mdW5jdGlvbiB1dGY4VG9CeXRlcyAoc3RyaW5nLCB1bml0cykge1xuICB1bml0cyA9IHVuaXRzIHx8IEluZmluaXR5XG4gIHZhciBjb2RlUG9pbnRcbiAgdmFyIGxlbmd0aCA9IHN0cmluZy5sZW5ndGhcbiAgdmFyIGxlYWRTdXJyb2dhdGUgPSBudWxsXG4gIHZhciBieXRlcyA9IFtdXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGNvZGVQb2ludCA9IHN0cmluZy5jaGFyQ29kZUF0KGkpXG5cbiAgICAvLyBpcyBzdXJyb2dhdGUgY29tcG9uZW50XG4gICAgaWYgKGNvZGVQb2ludCA+IDB4RDdGRiAmJiBjb2RlUG9pbnQgPCAweEUwMDApIHtcbiAgICAgIC8vIGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoIWxlYWRTdXJyb2dhdGUpIHtcbiAgICAgICAgLy8gbm8gbGVhZCB5ZXRcbiAgICAgICAgaWYgKGNvZGVQb2ludCA+IDB4REJGRikge1xuICAgICAgICAgIC8vIHVuZXhwZWN0ZWQgdHJhaWxcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9IGVsc2UgaWYgKGkgKyAxID09PSBsZW5ndGgpIHtcbiAgICAgICAgICAvLyB1bnBhaXJlZCBsZWFkXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHZhbGlkIGxlYWRcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIDIgbGVhZHMgaW4gYSByb3dcbiAgICAgIGlmIChjb2RlUG9pbnQgPCAweERDMDApIHtcbiAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gdmFsaWQgc3Vycm9nYXRlIHBhaXJcbiAgICAgIGNvZGVQb2ludCA9IChsZWFkU3Vycm9nYXRlIC0gMHhEODAwIDw8IDEwIHwgY29kZVBvaW50IC0gMHhEQzAwKSArIDB4MTAwMDBcbiAgICB9IGVsc2UgaWYgKGxlYWRTdXJyb2dhdGUpIHtcbiAgICAgIC8vIHZhbGlkIGJtcCBjaGFyLCBidXQgbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgIH1cblxuICAgIGxlYWRTdXJyb2dhdGUgPSBudWxsXG5cbiAgICAvLyBlbmNvZGUgdXRmOFxuICAgIGlmIChjb2RlUG9pbnQgPCAweDgwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDEpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goY29kZVBvaW50KVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHg4MDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiB8IDB4QzAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDMpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgfCAweEUwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSA0KSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHgxMiB8IDB4RjAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29kZSBwb2ludCcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7ICsraSkge1xuICAgIC8vIE5vZGUncyBjb2RlIHNlZW1zIHRvIGJlIGRvaW5nIHRoaXMgYW5kIG5vdCAmIDB4N0YuLlxuICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpICYgMHhGRilcbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVUb0J5dGVzIChzdHIsIHVuaXRzKSB7XG4gIHZhciBjLCBoaSwgbG9cbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG5cbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSlcbiAgICBoaSA9IGMgPj4gOFxuICAgIGxvID0gYyAlIDI1NlxuICAgIGJ5dGVBcnJheS5wdXNoKGxvKVxuICAgIGJ5dGVBcnJheS5wdXNoKGhpKVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5cbmZ1bmN0aW9uIGJhc2U2NFRvQnl0ZXMgKHN0cikge1xuICByZXR1cm4gYmFzZTY0LnRvQnl0ZUFycmF5KGJhc2U2NGNsZWFuKHN0cikpXG59XG5cbmZ1bmN0aW9uIGJsaXRCdWZmZXIgKHNyYywgZHN0LCBvZmZzZXQsIGxlbmd0aCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgaWYgKChpICsgb2Zmc2V0ID49IGRzdC5sZW5ndGgpIHx8IChpID49IHNyYy5sZW5ndGgpKSBicmVha1xuICAgIGRzdFtpICsgb2Zmc2V0XSA9IHNyY1tpXVxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIGlzbmFuICh2YWwpIHtcbiAgcmV0dXJuIHZhbCAhPT0gdmFsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlXG59XG5cblxuLy8gdGhlIGZvbGxvd2luZyBpcyBmcm9tIGlzLWJ1ZmZlciwgYWxzbyBieSBGZXJvc3MgQWJvdWtoYWRpamVoIGFuZCB3aXRoIHNhbWUgbGlzZW5jZVxuLy8gVGhlIF9pc0J1ZmZlciBjaGVjayBpcyBmb3IgU2FmYXJpIDUtNyBzdXBwb3J0LCBiZWNhdXNlIGl0J3MgbWlzc2luZ1xuLy8gT2JqZWN0LnByb3RvdHlwZS5jb25zdHJ1Y3Rvci4gUmVtb3ZlIHRoaXMgZXZlbnR1YWxseVxuZXhwb3J0IGZ1bmN0aW9uIGlzQnVmZmVyKG9iaikge1xuICByZXR1cm4gb2JqICE9IG51bGwgJiYgKCEhb2JqLl9pc0J1ZmZlciB8fCBpc0Zhc3RCdWZmZXIob2JqKSB8fCBpc1Nsb3dCdWZmZXIob2JqKSlcbn1cblxuZnVuY3Rpb24gaXNGYXN0QnVmZmVyIChvYmopIHtcbiAgcmV0dXJuICEhb2JqLmNvbnN0cnVjdG9yICYmIHR5cGVvZiBvYmouY29uc3RydWN0b3IuaXNCdWZmZXIgPT09ICdmdW5jdGlvbicgJiYgb2JqLmNvbnN0cnVjdG9yLmlzQnVmZmVyKG9iailcbn1cblxuLy8gRm9yIE5vZGUgdjAuMTAgc3VwcG9ydC4gUmVtb3ZlIHRoaXMgZXZlbnR1YWxseS5cbmZ1bmN0aW9uIGlzU2xvd0J1ZmZlciAob2JqKSB7XG4gIHJldHVybiB0eXBlb2Ygb2JqLnJlYWRGbG9hdExFID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBvYmouc2xpY2UgPT09ICdmdW5jdGlvbicgJiYgaXNGYXN0QnVmZmVyKG9iai5zbGljZSgwLCAwKSlcbn1cbiIsImNsYXNzIFRleHRFbmNvZGVyIHtcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvVGV4dEVuY29kZXIjUG9seWZpbGxcbiAgICBzdGF0aWMgZW5jb2RlIChzdHIpIHtcbiAgICAgICAgY29uc3QgTGVuID0gc3RyLmxlbmd0aDtcbiAgICAgICAgbGV0IHJlc1BvcyA9IC0xO1xuICAgICAgICAvLyBUaGUgVWludDhBcnJheSdzIGxlbmd0aCBtdXN0IGJlIGF0IGxlYXN0IDN4IHRoZSBsZW5ndGggb2YgdGhlIHN0cmluZyBiZWNhdXNlIGFuIGludmFsaWQgVVRGLTE2XG4gICAgICAgIC8vICB0YWtlcyB1cCB0aGUgZXF1aXZlbGVudCBzcGFjZSBvZiAzIFVURi04IGNoYXJhY3RlcnMgdG8gZW5jb2RlIGl0IHByb3Blcmx5LiBIb3dldmVyLCBBcnJheSdzXG4gICAgICAgIC8vICBoYXZlIGFuIGF1dG8gZXhwYW5kaW5nIGxlbmd0aCBhbmQgMS41eCBzaG91bGQgYmUganVzdCB0aGUgcmlnaHQgYmFsYW5jZSBmb3IgbW9zdCB1c2VzLlxuICAgICAgICBjb25zdCByZXNBcnIgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgcG9pbnQgPSAwLCBuZXh0Y29kZSA9IDAsIGlkeCA9IDA7IGlkeCAhPT0gTGVuOykge1xuICAgICAgICAgICAgcG9pbnQgPSBzdHIuY2hhckNvZGVBdChpZHgpLCBpZHggKz0gMTtcbiAgICAgICAgICAgIGlmIChwb2ludCA+PSAweEQ4MDAgJiYgcG9pbnQgPD0gMHhEQkZGKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlkeCA9PT0gTGVuKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc0FycltyZXNQb3MgKz0gMV0gPSAweGVmO1xuICAgICAgICAgICAgICAgICAgICByZXNBcnJbcmVzUG9zICs9IDFdID0gMHhiZjtcbiAgICAgICAgICAgICAgICAgICAgcmVzQXJyW3Jlc1BvcyArPSAxXSA9IDB4YmQ7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBodHRwczovL21hdGhpYXNieW5lbnMuYmUvbm90ZXMvamF2YXNjcmlwdC1lbmNvZGluZyNzdXJyb2dhdGUtZm9ybXVsYWVcbiAgICAgICAgICAgICAgICBuZXh0Y29kZSA9IHN0ci5jaGFyQ29kZUF0KGlkeCk7XG4gICAgICAgICAgICAgICAgaWYgKG5leHRjb2RlID49IDB4REMwMCAmJiBuZXh0Y29kZSA8PSAweERGRkYpIHtcbiAgICAgICAgICAgICAgICAgICAgcG9pbnQgPSAoKHBvaW50IC0gMHhEODAwKSAqIDB4NDAwKSArIG5leHRjb2RlIC0gMHhEQzAwICsgMHgxMDAwMDtcbiAgICAgICAgICAgICAgICAgICAgaWR4ICs9IDE7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwb2ludCA+IDB4ZmZmZikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzQXJyW3Jlc1BvcyArPSAxXSA9ICgweDFlIDw8IDMpIHwgKHBvaW50ID4+PiAxOCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNBcnJbcmVzUG9zICs9IDFdID0gKDB4MiA8PCA2KSB8ICgocG9pbnQgPj4+IDEyKSAmIDB4M2YpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzQXJyW3Jlc1BvcyArPSAxXSA9ICgweDIgPDwgNikgfCAoKHBvaW50ID4+PiA2KSAmIDB4M2YpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzQXJyW3Jlc1BvcyArPSAxXSA9ICgweDIgPDwgNikgfCAocG9pbnQgJiAweDNmKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzQXJyW3Jlc1BvcyArPSAxXSA9IDB4ZWY7IHJlc0FycltyZXNQb3MgKz0gMV0gPSAweGJmO1xuICAgICAgICAgICAgICAgICAgICByZXNBcnJbcmVzUG9zICs9IDFdID0gMHhiZDsgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBvaW50IDw9IDB4MDA3Zikge1xuICAgICAgICAgICAgICAgIHJlc0FycltyZXNQb3MgKz0gMV0gPSAoMHgwIDw8IDcpIHwgcG9pbnQ7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHBvaW50IDw9IDB4MDdmZikge1xuICAgICAgICAgICAgICAgIHJlc0FycltyZXNQb3MgKz0gMV0gPSAoMHg2IDw8IDUpIHwgKHBvaW50ID4+PiA2KTtcbiAgICAgICAgICAgICAgICByZXNBcnJbcmVzUG9zICs9IDFdID0gKDB4MiA8PCA2KSB8IChwb2ludCAmIDB4M2YpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXNBcnJbcmVzUG9zICs9IDFdID0gKDB4ZSA8PCA0KSB8IChwb2ludCA+Pj4gMTIpO1xuICAgICAgICAgICAgICAgIHJlc0FycltyZXNQb3MgKz0gMV0gPSAoMHgyIDw8IDYpIHwgKChwb2ludCA+Pj4gNikgJiAweDNmKTtcbiAgICAgICAgICAgICAgICByZXNBcnJbcmVzUG9zICs9IDFdID0gKDB4MiA8PCA2KSB8IChwb2ludCAmIDB4M2YpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIGVsc2UgLy8gSUUgNi05XG4gICAgICAgIHJlc0Fyci5sZW5ndGggPSByZXNQb3MgKyAxOyAvLyB0cmltIG9mZiBleHRyYSB3ZWlnaHRcbiAgICAgICAgcmV0dXJuIHJlc0FycjtcbiAgICB9XG59XG5cbmV4cG9ydCB7IFRleHRFbmNvZGVyIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFRleHRFbmNvZGVyIH0gZnJvbSAnLi9UZXh0RW5jb2Rlci5qcyc7XG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ycGMvUnBjU3RydWN0LmpzJztcblxuY2xhc3MgSnNvblJwY01hcnNoYWxsZXIge1xuICAgIC8qKlxuICAgICAqIFRha2VzIGFuIFJQQyBtZXNzYWdlIGFuZCBjb252ZXJ0cyBpdFxuICAgICAqIGludG8gYSBieXRlIGFycmF5IHRoYXQgY2FuIGJlIGFkZGVkXG4gICAgICogYXMgcGFydCBvZiB0aGUgU2RsUGFja2V0LlxuICAgICAqIEBwYXJhbSB7UnBjU3RydWN0fSBycGNTdHJ1Y3QgLSBUaGlzIHBhcmFtIGNvbnRhaW5zIHRoZSBqc29uIG9iamVjdCB0byB0cmFuc2Zvcm1cbiAgICAgKiBiYXNlZCBvbiB0aGUgZ2V0UGFyYW1ldGVycyBtZXRob2QuIFRoaXMgY2FuIGJlIGFuIFJwY1N0cnVjdCBvciBzb21ldGhpbmcgbGlrZSBScGNNZXNzYWdlXG4gICAgICogd2hpY2ggZXh0ZW5kcyBScGNTdHJ1Y3QuXG4gICAgICogQHJldHVybnMge251bGx8VWludDhBcnJheX0gLSBFaXRoZXIgdGhlIGJ5dGUgYXJyYXkgb3IgbnVsbCBvbiBlcnJvci5cbiAgICAgKi9cbiAgICBzdGF0aWMgbWFyc2hhbGwgKHJwY1N0cnVjdCkge1xuICAgICAgICBsZXQganNvbkJ5dGVzID0gbnVsbDtcbiAgICAgICAgZnVuY3Rpb24gcGFyYW1pZnkgKHJwY1N0cnVjdCkge1xuICAgICAgICAgICAgY29uc3QgcGFyYW1zID0gcnBjU3RydWN0LmdldFBhcmFtZXRlcnMoKTtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHBhcmFtcykge1xuICAgICAgICAgICAgICAgIGlmIChwYXJhbXNba2V5XSBpbnN0YW5jZW9mIFJwY1N0cnVjdCkge1xuICAgICAgICAgICAgICAgICAgICBwYXJhbXNba2V5XSA9IHBhcmFtaWZ5KHBhcmFtc1trZXldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcGFyYW1zO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGpzb25PYmplY3QgPSBwYXJhbWlmeShycGNTdHJ1Y3QpO1xuICAgICAgICAgICAgY29uc3Qgc3RyaW5nVmVyc2lvbiA9IEpTT04uc3RyaW5naWZ5KGpzb25PYmplY3QpO1xuICAgICAgICAgICAganNvbkJ5dGVzID0gdGhpcy5fZW5jb2RlKHN0cmluZ1ZlcnNpb24pO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIGVuY29kZSBtZXNzYWdlcyB0byBKU09OLicsIGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ganNvbkJ5dGVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRha2VzIGEgYnl0ZSBhcnJheSBhbmQgdHJhbnNmb3JtcyBpdCBpbnRvIGEganNvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHtVaW50OEFycmF5fSBieXRlcyAtIEJ5dGUgYXJyYXkgY29udGFpbmluZyB0aGUganNvbiBzdHJpbmcgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxPYmplY3R9IC0gRWl0aGVyIGEganNvbiBvYmplY3Qgb3IgbnVsbCBvbiBlcnJvciBpbiBwYXJzaW5nLlxuICAgICAqL1xuICAgIHN0YXRpYyB1bm1hcnNoYWxsIChieXRlcykge1xuICAgICAgICBsZXQgcmV0ID0gbnVsbDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGpzb25TdHJpbmcgPSB0aGlzLl9kZWNvZGUoYnl0ZXMpO1xuICAgICAgICAgICAgcmV0ID0gSlNPTi5wYXJzZShqc29uU3RyaW5nKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBwYXJzZSBKU09OJywgZXJyb3IpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJhbnNmb3JtIGEgc3RyaW5nIGludG8gYSBieXRlIGFycmF5LlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgLSBTdHJpbmcgdG8gdHJhbnNmb3JtLlxuICAgICAqIEByZXR1cm5zIHtVaW50OEFycmF5fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIF9lbmNvZGUgKHN0cikge1xuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoVGV4dEVuY29kZXIuZW5jb2RlKHN0cikpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyYW5zZm9ybSBhIGJ5dGUgYXJyYXkgaW50byBhIHN0cmluZy5cbiAgICAgKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ5dGVzIC0gQnl0ZSBhcnJheSB0byB0cmFuc2Zvcm0uXG4gICAgICogQHJldHVybnMge1N0cmluZ31cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBfZGVjb2RlIChieXRlcykge1xuICAgICAgICByZXR1cm4gQnVmZmVyLmZyb20oYnl0ZXMpLnRvU3RyaW5nKCk7XG4gICAgfVxufVxuXG5leHBvcnQgeyBKc29uUnBjTWFyc2hhbGxlciB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG4vKipcbiAqIENvbnRhaW5zIHRoZSByYXcganNvbiBkYXRhIGFuZCBidWxrIGRhdGEgZm9yIGFuIFJQQyByZXF1ZXN0L3Jlc3BvbnNlIGFsb25nIHdpdGggdGhlIGJhc2ljIGhlYWRlciBpbmZvXG4gKiBycGMgdHlwZSwgZnVuY3Rpb24gaWQsIGFuZCBjb3JyZWxhdGlvbiBpZC5cbiAqXG4gKiBUaGlzIGNsYXNzIGNhbiBwYXJzZSBpbmNvbWluZyBkYXRhIGZyb20gc2RsIGNvcmUgYW5kIGFzc2VtYmxlIGEgYmluYXJ5IGhlYWRlciB0byBzZW5kIHRvIHNkbCBjb3JlLlxuICpcbiAqXG4gKiAgQHByaXZhdGUge251bWJlcn0gX3JwY1R5cGUgLSBSZXF1ZXN0ID0gMCwgUmVzcG9uc2UgPSAxLCBOb3RpZmljYXRpb24gPSAyLlxuICogIEBwcml2YXRlIHtudW1iZXJ9IF9mdW5jdGlvbklkIC0gTWF0Y2hlcyBhIGZ1bmN0aW9uIElkIGluIHRoZSBtb2JpbGUgYXBpIHNwZWMgaHR0cHM6Ly9naXRodWIuY29tL3NtYXJ0ZGV2aWNlbGluay9ycGNfc3BlYy9ibG9iL21hc3Rlci9NT0JJTEVfQVBJLnhtbFxuICogIEBwcml2YXRlIHtudW1iZXJ9IF9jb3JyZWxhdGlvbklkIC0gRm9yIGEgcmVxdWVzdCB0aGlzIGlkIGlzIHByb3ZpZGVkIGFuZCB0aGUgbWF0Y2hpbmcgcmVzcG9uc2Ugd2lsbCBoYXZlIHRoaXMgc2FtZSBpZC5cbiAqICBAcHJpdmF0ZSB7bnVtYmVyfSBfanNvblNpemUgLSBTaXplIG9mIGpzb24uXG4gKiAgQHByaXZhdGUge1VpbnQ4QXJyYXl9IF9qc29uRGF0YSAtIFJhdyBqc29uIGRhdGEuIFRoaXMgY2FuIGJlIHBhcnNlZCB1c2luZyB0aGUgSnNvblJwY01hcnNoYWxsZXIuXG4gKiAgQHByaXZhdGUge1VpbnQ4QXJyYXl9IF9idWxrRGF0YSAtIEJ1bGsgZGF0YSAob3B0aW9uYWwpLiBJZiBzb21ldGhpbmcgY2Fubm90IGJlIGV4cHJlc3NlZCBhcyBhIGpzb24gb2JqZWN0IGl0IHdpbGwgYmUgaW4gdGhlIGJ1bGsgZGF0YSAoZWcgUHV0RmlsZS9HZXRGaWxlIGhhcyB0aGUgZnVsbCBmaWxlIGluIGJ1bGsgZGF0YS4pXG4gKi9cbmNsYXNzIEJpbmFyeUZyYW1lSGVhZGVyIHtcbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBycGNUeXBlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGZ1bmN0aW9uSWRcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gY29ycmVsYXRpb25JZFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBqc29uU2l6ZVxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChycGNUeXBlLCBmdW5jdGlvbklkLCBjb3JyZWxhdGlvbklkLCBqc29uU2l6ZSkge1xuICAgICAgICB0aGlzLl9ycGNUeXBlID0gcnBjVHlwZTtcbiAgICAgICAgdGhpcy5fZnVuY3Rpb25JZCA9IGZ1bmN0aW9uSWQ7XG4gICAgICAgIHRoaXMuX2NvcnJlbGF0aW9uSWQgPSBjb3JyZWxhdGlvbklkO1xuICAgICAgICB0aGlzLl9qc29uU2l6ZSA9IGpzb25TaXplO1xuICAgICAgICB0aGlzLl9idWxrRGF0YSA9IG51bGw7XG4gICAgICAgIHRoaXMuX2pzb25EYXRhID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHaXZlbiBhIGJ5dGUgYXJyYXkgd2l0aCB1aW50OCB2YWx1ZXMsIGEgQmluYXJ5RnJhbWVIZWFkZXIgaW5zdGFuY2UgaXMgY3JlYXRlZC5cbiAgICAgKiBAcGFyYW0ge2FycmF5fSBiaW5hcnlGcmFtZUhlYWRlckRhdGEgLSBCeXRlIGFycmF5IGNvbnRhaW5pbmcgYmFzaWMgaW5mb3JtYXRpb24gb24gdGhlIGZyYW1lcyB0eXBlLCBsZW5ndGgsIGFuZCByZWxhdGVkIGlkcy5cbiAgICAgKiBAcmV0dXJucyB7QmluYXJ5RnJhbWVIZWFkZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGZyb21CaW5hcnlIZWFkZXIgKGJpbmFyeUZyYW1lSGVhZGVyRGF0YSkge1xuICAgICAgICBjb25zdCBycGNUeXBlID0gYmluYXJ5RnJhbWVIZWFkZXJEYXRhWzBdID4+IDQ7XG5cbiAgICAgICAgbGV0IGZ1bmN0aW9uSWQgPSAoYmluYXJ5RnJhbWVIZWFkZXJEYXRhWzBdICYgMHgwRikgPDwgMjQ7XG4gICAgICAgIGZ1bmN0aW9uSWQgKz0gKGJpbmFyeUZyYW1lSGVhZGVyRGF0YVsxXSAmIDB4RkYpIDw8IDE2O1xuICAgICAgICBmdW5jdGlvbklkICs9IChiaW5hcnlGcmFtZUhlYWRlckRhdGFbMl0gJiAweEZGKSA8PCA4O1xuICAgICAgICBmdW5jdGlvbklkICs9IGJpbmFyeUZyYW1lSGVhZGVyRGF0YVszXSAmIDB4RkY7XG5cbiAgICAgICAgbGV0IGNvcnJlbGF0aW9uSWQgPSAoYmluYXJ5RnJhbWVIZWFkZXJEYXRhWzRdICYgMHhGRikgPDwgMjQ7XG4gICAgICAgIGNvcnJlbGF0aW9uSWQgKz0gKGJpbmFyeUZyYW1lSGVhZGVyRGF0YVs1XSAmIDB4RkYpIDw8IDE2O1xuICAgICAgICBjb3JyZWxhdGlvbklkICs9IChiaW5hcnlGcmFtZUhlYWRlckRhdGFbNl0gJiAweEZGKSA8PCA4O1xuICAgICAgICBjb3JyZWxhdGlvbklkICs9IGJpbmFyeUZyYW1lSGVhZGVyRGF0YVs3XSAmIDB4RkY7XG5cbiAgICAgICAgbGV0IGpzb25TaXplID0gKGJpbmFyeUZyYW1lSGVhZGVyRGF0YVs4XSAmIDB4RkYpIDw8IDI0O1xuICAgICAgICBqc29uU2l6ZSArPSAoYmluYXJ5RnJhbWVIZWFkZXJEYXRhWzldICYgMHhGRikgPDwgMTY7XG4gICAgICAgIGpzb25TaXplICs9IChiaW5hcnlGcmFtZUhlYWRlckRhdGFbMTBdICYgMHhGRikgPDwgODtcbiAgICAgICAganNvblNpemUgKz0gYmluYXJ5RnJhbWVIZWFkZXJEYXRhWzExXSAmIDB4RkY7XG5cbiAgICAgICAgY29uc3QgYmluYXJ5RnJhbWVIZWFkZXIgPSBuZXcgQmluYXJ5RnJhbWVIZWFkZXIocnBjVHlwZSwgZnVuY3Rpb25JZCwgY29ycmVsYXRpb25JZCwganNvblNpemUpO1xuXG4gICAgICAgIGNvbnN0IGpzb25EYXRhU3RhcnQgPSBCaW5hcnlGcmFtZUhlYWRlci5IRUFERVJfU0laRTtcbiAgICAgICAgY29uc3QganNvbkRhdGFFbmQgPSBCaW5hcnlGcmFtZUhlYWRlci5IRUFERVJfU0laRSArIGpzb25TaXplO1xuXG4gICAgICAgIGJpbmFyeUZyYW1lSGVhZGVyLnNldEpzb25EYXRhKGJpbmFyeUZyYW1lSGVhZGVyRGF0YS5zbGljZShqc29uRGF0YVN0YXJ0LCBqc29uRGF0YUVuZCkpO1xuXG4gICAgICAgIC8vIGFueSBkYXRhIGFmdGVyIHRoZSBKU09OIGRhdGEgaXMgdGhlIGJ1bGsgZGF0YSAoZWcgUHV0RmlsZSBjb250YWlucyB0aGUgZmlsZSBhZnRlciB0aGUgbWFpbiBqc29uKVxuICAgICAgICBpZiAoYmluYXJ5RnJhbWVIZWFkZXJEYXRhLmxlbmd0aCA+IGpzb25EYXRhRW5kKSB7XG4gICAgICAgICAgICBjb25zdCBidWxrRGF0YSA9IGJpbmFyeUZyYW1lSGVhZGVyRGF0YS5zbGljZShqc29uRGF0YUVuZCk7XG4gICAgICAgICAgICBiaW5hcnlGcmFtZUhlYWRlci5zZXRCdWxrRGF0YShidWxrRGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJpbmFyeUZyYW1lSGVhZGVyO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogQXNzZW1ibGVzIGJpbmFyeSBoZWFkZXIgZGF0YS5cbiAgICAgKiBAcmV0dXJucyB7YXJyYXl9XG4gICAgICovXG4gICAgYXNzZW1ibGVIZWFkZXJCeXRlcyAoKSB7XG4gICAgICAgIGNvbnN0IGJ1ZmZlciA9IFtdO1xuICAgICAgICBjb25zdCBmdW5jdGlvbklkID0gdGhpcy5fZnVuY3Rpb25JZDtcbiAgICAgICAgY29uc3QgY29ycmVsYXRpb25JZCA9IHRoaXMuX2NvcnJlbGF0aW9uSWQ7XG4gICAgICAgIGNvbnN0IHJwY1R5cGUgPSB0aGlzLl9ycGNUeXBlO1xuXG4gICAgICAgIGJ1ZmZlci5wdXNoKChmdW5jdGlvbklkICYgMHgwRjAwMDAwMCkgPj4gMjQpICsgKHJwY1R5cGUgPDwgNCk7XG4gICAgICAgIGJ1ZmZlci5wdXNoKChmdW5jdGlvbklkICYgMHgwMEZGMDAwMCkgPj4gMTYpO1xuICAgICAgICBidWZmZXIucHVzaCgoZnVuY3Rpb25JZCAmIDB4MDAwMEZGMDApID4+IDgpO1xuICAgICAgICBidWZmZXIucHVzaChmdW5jdGlvbklkICYgMHgwMDAwMDBGRik7XG5cbiAgICAgICAgYnVmZmVyLnB1c2goKGNvcnJlbGF0aW9uSWQgJiAweEZGMDAwMDAwKSA+PiAyNCk7XG4gICAgICAgIGJ1ZmZlci5wdXNoKChjb3JyZWxhdGlvbklkICYgMHgwMEZGMDAwMCkgPj4gMTYpO1xuICAgICAgICBidWZmZXIucHVzaCgoY29ycmVsYXRpb25JZCAmIDB4MDAwMEZGMDApID4+IDgpO1xuICAgICAgICBidWZmZXIucHVzaChjb3JyZWxhdGlvbklkICYgMHgwMDAwMDBGRik7XG5cbiAgICAgICAgY29uc3QganNvblNpemUgPSB0aGlzLl9qc29uU2l6ZTtcbiAgICAgICAgYnVmZmVyLnB1c2goKGpzb25TaXplICYgMHhGRjAwMDAwMCkgPj4gMjQpO1xuICAgICAgICBidWZmZXIucHVzaCgoanNvblNpemUgJiAweDAwRkYwMDAwKSA+PiAxNik7XG4gICAgICAgIGJ1ZmZlci5wdXNoKChqc29uU2l6ZSAmIDB4MDAwMEZGMDApID4+IDgpO1xuICAgICAgICBidWZmZXIucHVzaChqc29uU2l6ZSAmIDB4MDAwMDAwRkYpO1xuXG4gICAgICAgIHJldHVybiBidWZmZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgcnBjIHR5cGUgb2YgdGhlIGJpbmFyeSBoZWFkZXIuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHR5cGVcbiAgICAgKiBAcmV0dXJucyB7QmluYXJ5RnJhbWVIZWFkZXJ9XG4gICAgICovXG4gICAgc2V0UnBjVHlwZSAodHlwZSkge1xuICAgICAgICB0aGlzLl9ycGNUeXBlID0gdHlwZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcnBjIHR5cGUgb2YgdGhlIGJpbmFyeSBoZWFkZXJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxuICAgICAqL1xuICAgIGdldFJwY1R5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcnBjVHlwZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBmdW5jdGlvbiBpZCBvZiB0aGUgYmluYXJ5IGhlYWRlci5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gaWRcbiAgICAgKiBAcmV0dXJucyB7QmluYXJ5RnJhbWVIZWFkZXJ9XG4gICAgICovXG4gICAgc2V0RnVuY3Rpb25JZCAoaWQpIHtcbiAgICAgICAgdGhpcy5fZnVuY3Rpb25JZCA9IGlkO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBmdW5jdGlvbiBJZCBvZiB0aGUgYmluYXJ5IGhlYWRlci5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxuICAgICAqL1xuICAgIGdldEZ1bmN0aW9uSWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZnVuY3Rpb25JZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBjb3JyZWxhdGlvbiBJZCBvZiB0aGUgYmluYXJ5IGhlYWRlci5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gaWRcbiAgICAgKiBAcmV0dXJucyB7QmluYXJ5RnJhbWVIZWFkZXJ9XG4gICAgICovXG4gICAgc2V0Q29ycmVsYXRpb25JZCAoaWQpIHtcbiAgICAgICAgdGhpcy5fY29ycmVsYXRpb25JZCA9IGlkO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBjb3JyZWxhdGlvbiBJZCBvZiB0aGUgYmluYXJ5IGhlYWRlci5cbiAgICAgKi9cbiAgICBnZXRDb3JyZWxhdGlvbklkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvcnJlbGF0aW9uSWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUganNvbiBzaXplIG9mIHRoZSBiaW5hcnkgaGVhZGVyLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzaXplXG4gICAgICogQHJldHVybnMge0JpbmFyeUZyYW1lSGVhZGVyfVxuICAgICAqL1xuICAgIHNldEpzb25TaXplIChzaXplKSB7XG4gICAgICAgIHRoaXMuX2pzb25TaXplID0gc2l6ZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2VzdCB0aGUganNvbiBzaXplIG9mIHRoZSBiaW5hcnkgaGVhZGVyLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9XG4gICAgICovXG4gICAgZ2V0SnNvblNpemUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fanNvblNpemU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUganNvbiBkYXRhIGFzIGEgYnl0ZSBhcnJheS5cbiAgICAgKiBAcmV0dXJucyB7YXJyYXl9IC0gQnl0ZSBhcnJheSBvZiBqc29uIGRhdGEuXG4gICAgICovXG4gICAgZ2V0SnNvbkRhdGEgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fanNvbkRhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUganNvbiBkYXRhIG9mIHRoZSBiaW5hcnkgaGVhZGVyLlxuICAgICAqIEBwYXJhbSB7YXJyYXl9IGRhdGEgLSBCeXRlIGFycmF5IG9mIGpzb24gZGF0YVxuICAgICAqIEByZXR1cm5zIHtCaW5hcnlGcmFtZUhlYWRlcn1cbiAgICAgKi9cbiAgICBzZXRKc29uRGF0YSAoZGF0YSkge1xuICAgICAgICB0aGlzLl9qc29uRGF0YSA9IGRhdGE7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGJ1bGsgZGF0YSBvZiB0aGUgYmluYXJ5IGhlYWRlci5cbiAgICAgKiBTdXBwb3J0ZWQgYnkgcHJvdGNvbCAyIGFuZCB1cC5cbiAgICAgKiBAcGFyYW0ge2FycmF5fSBkYXRhIC0gQnl0ZSBhcnJheSBvZiBidWxrIGRhdGFcbiAgICAgKi9cbiAgICBzZXRCdWxrRGF0YSAoZGF0YSkge1xuICAgICAgICB0aGlzLl9idWxrRGF0YSA9IGRhdGE7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGJ1bGsgZGF0YSBvZiB0aGUgYmluYXJ5IGhlYWRlci5cbiAgICAgKiBTdXBwb3J0ZWQgYnkgcHJvdGNvbCAyIGFuZCB1cC5cbiAgICAgKiBAcmV0dXJucyB7YXJyYXl9IC0gQnl0ZSBhcnJheSBvZiBidWxrIGRhdGFcbiAgICAgKi9cbiAgICBnZXRCdWxrRGF0YSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9idWxrRGF0YTtcbiAgICB9XG59XG5cbkJpbmFyeUZyYW1lSGVhZGVyLkhFQURFUl9TSVpFID0gMTI7XG5cbmV4cG9ydCB7IEJpbmFyeUZyYW1lSGVhZGVyIH07XG5cblxuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5pbXBvcnQgeyBGcmFtZVR5cGUgfSBmcm9tICcuL2VudW1zL0ZyYW1lVHlwZS5qcyc7XG5pbXBvcnQgeyBTZGxQYWNrZXQgfSBmcm9tICcuL1NkbFBhY2tldC5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi8uLi9ycGMvZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBKc29uUnBjTWFyc2hhbGxlciB9IGZyb20gJy4vLi4vdXRpbC9Kc29uUnBjTWFyc2hhbGxlci5qcyc7XG5pbXBvcnQgeyBCaW5hcnlGcmFtZUhlYWRlciB9IGZyb20gJy4vQmluYXJ5RnJhbWVIZWFkZXIuanMnO1xuXG5cbi8qKlxuICogVGFrZXMgYW4gcnBjIG1lc3NhZ2UgYW5kIGNvbnZlcnRzIGl0IGludG8gcGFja2V0cyByZWFkeSB0byBzZW5kLlxuICovXG5jbGFzcyBNZXNzYWdlRnJhbWVEaXNhc3NlbWJsZXIge1xuICAgIC8qKlxuICAgICAgKlxuICAgICAgKiBAcGFyYW0ge1JwY1JlcXVlc3R9IHJwY1JlcXVlc3QgLSBSUEMgbWVzc2FnZSB0aGF0IHdpbGwgc3BsaXQgaW50byBzbWFsbGVyIHNkbCBwYWNrZXRzLlxuICAgICAgKiBAcGFyYW0ge051bWJlcn0gc2Vzc2lvbklkIC0gc2Vzc2lvbklkIGZvciBwYWNrZXRzXG4gICAgICAqIEBwYXJhbSB7TnVtYmVyfSBtZXNzYWdlSWQgLSBtZXNzYWdlSWQgZm9yIHBhY2tldHMuXG4gICAgICAqIEBwYXJhbSB7TnVtYmVyfSBtdHUgLSBtYXggdHJhbnNwb3J0IHVuaXQsIHVzZWQgdG8gZGV0ZXJtaW5lIHBhY2tldCBzaXplIHRvIHNlbmQuXG4gICAgICAqIEBwYXJhbSB7TnVtYmVyfSB2ZXJzaW9uIC0gbWFqb3IgdmVyc2lvblxuICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGlzRW5jcnlwdGVkIC0gcGFja2V0IGlzIGVuY3J5cHRlZFxuICAgICAgKiBAcGFyYW0ge2NifSBwYWNrZXRDYWxsYmFjayAtIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgd2hlbiBhIHBhY2tldCBpcyByZWFkeSB0byBzZW5kLlxuICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICovXG4gICAgY29uc3RydWN0b3IgKHJwY1JlcXVlc3QsIHNlc3Npb25JZCwgbWVzc2FnZUlkLCBtdHUsIHZlcnNpb24sIGlzRW5jcnlwdGVkLCBwYWNrZXRDYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9ycGNSZXF1ZXN0ID0gcnBjUmVxdWVzdDtcbiAgICAgICAgdGhpcy5fc2Vzc2lvbklkID0gc2Vzc2lvbklkO1xuICAgICAgICB0aGlzLl9tZXNzYWdlSWQgPSBtZXNzYWdlSWQ7XG4gICAgICAgIHRoaXMuX2lzRW5jcnlwdGVkID0gaXNFbmNyeXB0ZWQ7XG5cbiAgICAgICAgaWYgKCFtdHUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTVRVIG11c3QgYmUgc3BlY2lmaWVkLicpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX210dSA9IG10dTtcblxuICAgICAgICBpZiAoIXZlcnNpb24pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVmVyc2lvbiBtdXN0IGJlIHNwZWNpZmllZC4nKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl92ZXJzaW9uID0gdmVyc2lvbjtcbiAgICAgICAgdGhpcy5fcGFja2V0Q2FsbGJhY2sgPSBwYWNrZXRDYWxsYmFjaztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgICogSW1tZWRpYXRlbHkgYnVpbGQgcnBjIGFuZCByZXNwb25kIHRvIHBhY2tldGNhbGxiYWNrIHdpdGggcGFja2V0cyB0byBzZW5kLlxuICAgICAgKiBAcGFyYW0ge1JwY1JlcXVlc3R9IHJwY01lc3NhZ2UgLSBSUEMgbWVzc2FnZSB0aGF0IHdpbGwgc3BsaXQgaW50byBzbWFsbGVyIHNkbCBwYWNrZXRzLlxuICAgICAgKiBAcGFyYW0ge051bWJlcn0gc2Vzc2lvbklkIC0gc2Vzc2lvbklkIGZvciBwYWNrZXRzXG4gICAgICAqIEBwYXJhbSB7TnVtYmVyfSBtZXNzYWdlSWQgLSBtZXNzYWdlSWQgZm9yIHBhY2tldHMuXG4gICAgICAqIEBwYXJhbSB7TnVtYmVyfSBtdHUgLSBtYXggdHJhbnNwb3J0IHVuaXQsIHVzZWQgdG8gZGV0ZXJtaW5lIHBhY2tldCBzaXplIHRvIHNlbmQuXG4gICAgICAqIEBwYXJhbSB7TnVtYmVyfSB2ZXJzaW9uIC0gbWFqb3IgdmVyc2lvblxuICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGlzRW5jcnlwdGVkIC0gcGFja2V0IGlzIGVuY3J5cHRlZFxuICAgICAgKiBAcGFyYW0ge2NifSBwYWNrZXRDYWxsYmFjayAtIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgd2hlbiBhIHBhY2tldCBpcyByZWFkeSB0byBzZW5kLlxuICAgICAgKi9cbiAgICBzdGF0aWMgYnVpbGRSUEMgKHJwY1JlcXVlc3QsIHNlc3Npb25JZCwgbWVzc2FnZUlkLCBtdHUsIHZlcnNpb24sIGlzRW5jcnlwdGVkLCBjYikge1xuICAgICAgICBjb25zdCBvYmogPSBuZXcgTWVzc2FnZUZyYW1lRGlzYXNzZW1ibGVyKHJwY1JlcXVlc3QsIHNlc3Npb25JZCwgbWVzc2FnZUlkLCBtdHUsIHZlcnNpb24sIGlzRW5jcnlwdGVkLCBjYik7XG4gICAgICAgIG9iai5kb1JlcXVlc3QoKTtcbiAgICAgICAgcmV0dXJuIG9iajtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgdGhlIG1haW4gQmluYXJ5RnJhbWVIZWFkZXIgYnVmZmVyLlxuICAgICAqIEByZXR1cm5zIHtVbml0OEFycmF5fVxuICAgICAqL1xuICAgIF9idWlsZFJQQ01haW5CdWZmZXIgKCkge1xuICAgICAgICBjb25zdCBycGNCdWxrRGF0YSA9IHRoaXMuX3JwY1JlcXVlc3QuZ2V0QnVsa0RhdGEoKTtcbiAgICAgICAgY29uc3QgY29ycmVsYXRpb25JZCA9IHRoaXMuX3JwY1JlcXVlc3QuZ2V0Q29ycmVsYXRpb25JZCgpO1xuICAgICAgICBjb25zdCBycGNUeXBlID0gIHRoaXMuX3JwY1JlcXVlc3QuZ2V0UlBDVHlwZSgpO1xuXG4gICAgICAgIGNvbnN0IGZ1bmN0aW9uTmFtZSA9IHRoaXMuX3JwY1JlcXVlc3QuZ2V0RnVuY3Rpb25OYW1lKCk7XG4gICAgICAgIGNvbnN0IGZ1bmN0aW9uSWQgPSBGdW5jdGlvbklELnZhbHVlRm9yS2V5KGZ1bmN0aW9uTmFtZSk7XG4gICAgICAgIGlmICghZnVuY3Rpb25JZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gZmluZCBmdW5jdGlvbiAke2Z1bmN0aW9uTmFtZX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGpzb25CdWZmZXIgPSBKc29uUnBjTWFyc2hhbGxlci5tYXJzaGFsbCh0aGlzLl9ycGNSZXF1ZXN0KTtcbiAgICAgICAgY29uc3QganNvblNpemUgPSBqc29uQnVmZmVyLmxlbmd0aDtcblxuICAgICAgICBjb25zdCBiZmggPSBuZXcgQmluYXJ5RnJhbWVIZWFkZXIocnBjVHlwZSwgZnVuY3Rpb25JZCwgY29ycmVsYXRpb25JZCk7XG4gICAgICAgIGJmaC5zZXRKc29uRGF0YShqc29uQnVmZmVyKTtcbiAgICAgICAgYmZoLnNldEpzb25TaXplKGpzb25TaXplKTtcbiAgICAgICAgYmZoLnNldEJ1bGtEYXRhKHJwY0J1bGtEYXRhKTtcbiAgICAgICAgY29uc3QgaGVhZGVyU2l6ZSA9IDEyO1xuICAgICAgICBjb25zdCBidWxrRGF0YSA9IGJmaC5nZXRCdWxrRGF0YSgpO1xuICAgICAgICBsZXQgYnVsa0RhdGFTaXplID0gMDtcbiAgICAgICAgaWYgKGJ1bGtEYXRhKSB7XG4gICAgICAgICAgICBidWxrRGF0YVNpemUgPSBidWxrRGF0YS5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdG90YWxNZXNzYWdlU2l6ZSA9IGhlYWRlclNpemUgKyBqc29uU2l6ZSArIGJ1bGtEYXRhU2l6ZTtcbiAgICAgICAgY29uc3QgZGF0YSA9IG5ldyBVaW50OEFycmF5KHRvdGFsTWVzc2FnZVNpemUpO1xuICAgICAgICBkYXRhLnNldChiZmguYXNzZW1ibGVIZWFkZXJCeXRlcygpLCAwKTtcbiAgICAgICAgZGF0YS5zZXQoanNvbkJ1ZmZlciwgaGVhZGVyU2l6ZSk7XG4gICAgICAgIGlmIChidWxrRGF0YSkge1xuICAgICAgICAgICAgZGF0YS5zZXQoYnVsa0RhdGEsIGhlYWRlclNpemUgKyBqc29uU2l6ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgUlBDIHJlcXVlc3QgYW5kIHVzZSBjYWxsYmFjayB0byBzZW5kXG4gICAgICogc2RsIHBhY2tldHMgb2YgdGhlIGFwcHJvcHJpYXRlIHNpemUuXG4gICAgICovXG4gICAgZG9SZXF1ZXN0ICgpIHtcbiAgICAgICAgY29uc3QgdmVyc2lvbiA9IHRoaXMuX3ZlcnNpb247XG4gICAgICAgIGNvbnN0IGZyYW1lSW5mbyA9IDA7XG4gICAgICAgIGNvbnN0IGZyYW1lVHlwZSA9IEZyYW1lVHlwZS5TSU5HTEU7XG5cbiAgICAgICAgY29uc3Qgc2VydmljZVR5cGUgPSBTZGxQYWNrZXQuU0VSVklDRV9UWVBFX1JQQztcbiAgICAgICAgY29uc3Qgc2Vzc2lvbklkID0gdGhpcy5fc2Vzc2lvbklkO1xuICAgICAgICBjb25zdCBtZXNzYWdlSWQgPSB0aGlzLl9tZXNzYWdlSWQ7XG5cbiAgICAgICAgY29uc3QgaXNFbmNyeXB0ZWQgPSB0aGlzLl9pc0VuY3J5cHRlZDtcbiAgICAgICAgY29uc3QgbWFpbkJ1ZmZlciA9IHRoaXMuX2J1aWxkUlBDTWFpbkJ1ZmZlcigpO1xuICAgICAgICBjb25zdCBtdHUgPSB0aGlzLl9tdHU7XG5cbiAgICAgICAgY29uc3QgZnJhbWVDb3VudCA9IE1hdGguY2VpbChtYWluQnVmZmVyLmxlbmd0aCAvIG10dSk7XG5cbiAgICAgICAgaWYgKGZyYW1lQ291bnQgPD0gMSkge1xuICAgICAgICAgICAgY29uc3QgZnVsbFBhY2tldCA9IHRoaXMuX2NvbnN0cnVjdFBhY2tldChcbiAgICAgICAgICAgICAgICB2ZXJzaW9uLFxuICAgICAgICAgICAgICAgIHNlcnZpY2VUeXBlLFxuICAgICAgICAgICAgICAgIGZyYW1lSW5mbyxcbiAgICAgICAgICAgICAgICBzZXNzaW9uSWQsXG4gICAgICAgICAgICAgICAgbWVzc2FnZUlkLFxuICAgICAgICAgICAgICAgIGZyYW1lVHlwZSxcbiAgICAgICAgICAgICAgICBtYWluQnVmZmVyLFxuICAgICAgICAgICAgICAgIGlzRW5jcnlwdGVkXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5fcGFja2V0Q2FsbGJhY2soZnVsbFBhY2tldCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoOCk7IC8vIEludDMyIGhhcyA4IGJ5dGVzXG4gICAgICAgICAgICBjb25zdCB2aWV3ID0gbmV3IERhdGFWaWV3KGJ1ZmZlcik7XG4gICAgICAgICAgICB2aWV3LnNldFVpbnQzMigwLCBtYWluQnVmZmVyLmxlbmd0aCwgZmFsc2UpO1xuICAgICAgICAgICAgdmlldy5zZXRVaW50MzIoNCwgZnJhbWVDb3VudCwgZmFsc2UpO1xuICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XG5cbiAgICAgICAgICAgIGNvbnN0IGZpcnN0SGVhZGVyID0gdGhpcy5fY29uc3RydWN0UGFja2V0KHZlcnNpb24sIHNlcnZpY2VUeXBlLCBmcmFtZUluZm8sIHNlc3Npb25JZCwgbWVzc2FnZUlkLCBGcmFtZVR5cGUuRklSU1QsIHBheWxvYWQsIGlzRW5jcnlwdGVkKTtcbiAgICAgICAgICAgIHRoaXMuX3BhY2tldENhbGxiYWNrKGZpcnN0SGVhZGVyKTtcblxuICAgICAgICAgICAgdGhpcy5fYnVpbGRDb25zZWN1dGl2ZUZyYW1lcyhcbiAgICAgICAgICAgICAgICB2ZXJzaW9uLFxuICAgICAgICAgICAgICAgIHNlcnZpY2VUeXBlLFxuICAgICAgICAgICAgICAgIHNlc3Npb25JZCxcbiAgICAgICAgICAgICAgICBtZXNzYWdlSWQsXG4gICAgICAgICAgICAgICAgbWFpbkJ1ZmZlcixcbiAgICAgICAgICAgICAgICBtdHUsXG4gICAgICAgICAgICAgICAgaXNFbmNyeXB0ZWRcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gc2RsIHBhY2tldC5cbiAgICAgKiBAcGFyYW0ge051bWJlcn0gdmVyc2lvblxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGZyYW1lSW5mb1xuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzZXNzaW9uSWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbWVzc2FnZUlkXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGZyYW1lVHlwZVxuICAgICAqIEBwYXJhbSB7VW5pdDhBcnJheX0gcGF5bG9hZFxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNFbmNyeXB0ZWRcbiAgICAgKiBAcmV0dXJucyB7U2RsUGFja2V0fVxuICAgICAqL1xuICAgIF9jb25zdHJ1Y3RQYWNrZXQgKHZlcnNpb24sIHNlcnZpY2VUeXBlLCBmcmFtZUluZm8sIHNlc3Npb25JZCwgbWVzc2FnZUlkLCBmcmFtZVR5cGUsIHBheWxvYWQsIGlzRW5jcnlwdGVkKSB7XG4gICAgICAgIGNvbnN0IGRhdGFTaXplID0gcGF5bG9hZC5sZW5ndGg7XG4gICAgICAgIGNvbnN0IG9mZnNldCA9IDA7XG4gICAgICAgIGNvbnN0IGJ5dGVzVG9Xcml0ZSA9IGRhdGFTaXplO1xuICAgICAgICBjb25zdCBzZGxQYWNrZXQgPSBuZXcgU2RsUGFja2V0KHZlcnNpb24sIGlzRW5jcnlwdGVkLCBmcmFtZVR5cGUsIHNlcnZpY2VUeXBlLCBmcmFtZUluZm8sIHNlc3Npb25JZCwgZGF0YVNpemUsIG1lc3NhZ2VJZCwgcGF5bG9hZCwgb2Zmc2V0LCBieXRlc1RvV3JpdGUpO1xuICAgICAgICByZXR1cm4gc2RsUGFja2V0O1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogQnVpbGRzIGNvbnNlY3V0aXZlIGZyYW1lcyBhZnRlciB0aGUgaW5pdGFsIGZyYW1lIGlzIHNlbnQgZm9yIGEgbXVsdGktZnJhbWUgbWVzc2FnZS5cbiAgICAgKiBAcGFyYW0ge051bWJlcn0gdmVyc2lvblxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlc3Npb25JZFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBtZXNzYWdlSWRcbiAgICAgKiBAcGFyYW0ge0J1ZmZlcn0gYnVmZmVyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGxlbmd0aFxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNFbmNyeXB0ZWRcbiAgICAgKi9cbiAgICBfYnVpbGRDb25zZWN1dGl2ZUZyYW1lcyAodmVyc2lvbiwgc2VydmljZVR5cGUsIHNlc3Npb25JZCwgbWVzc2FnZUlkLCBidWZmZXIsIGxlbmd0aCwgaXNFbmNyeXB0ZWQpIHtcbiAgICAgICAgbGV0IGZyYW1lU2VxdWVuY2VOdW1iZXI7XG4gICAgICAgIGxldCBjb3VudCA9IDA7XG4gICAgICAgIGxldCBvZmZzZXQgPSAwO1xuXG4gICAgICAgIHdoaWxlIChmcmFtZVNlcXVlbmNlTnVtYmVyICE9PSAwKSB7XG4gICAgICAgICAgICBpZiAob2Zmc2V0ICsgbGVuZ3RoID49IGJ1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBmcmFtZVNlcXVlbmNlTnVtYmVyID0gMDsgLy8gbGFzdCBmcmFtZVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBmcmFtZVNlcXVlbmNlTnVtYmVyID0gKGNvdW50ICUgMjU1KSArIDE7IC8vIDEsMiwzLC4uLiwyNTUsMVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBoZWFkZXIgPSB0aGlzLl9jb25zdHJ1Y3RQYWNrZXQoXG4gICAgICAgICAgICAgICAgdmVyc2lvbixcbiAgICAgICAgICAgICAgICBzZXJ2aWNlVHlwZSxcbiAgICAgICAgICAgICAgICBmcmFtZVNlcXVlbmNlTnVtYmVyLFxuICAgICAgICAgICAgICAgIHNlc3Npb25JZCxcbiAgICAgICAgICAgICAgICBtZXNzYWdlSWQsXG4gICAgICAgICAgICAgICAgRnJhbWVUeXBlLkNPTlNFQ1VUSVZFLFxuICAgICAgICAgICAgICAgIGJ1ZmZlci5zbGljZShvZmZzZXQsIG9mZnNldCArIGxlbmd0aCksXG4gICAgICAgICAgICAgICAgaXNFbmNyeXB0ZWRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLl9wYWNrZXRDYWxsYmFjayhoZWFkZXIpO1xuICAgICAgICAgICAgY291bnQrKztcbiAgICAgICAgICAgIG9mZnNldCArPSBsZW5ndGg7XG4gICAgICAgIH1cbiAgICB9XG59XG5cblxuXG5leHBvcnQgeyBNZXNzYWdlRnJhbWVEaXNhc3NlbWJsZXIgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuY2xhc3MgVHJhbnNwb3J0TGlzdGVuZXIge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgdGhpcy5fb25UcmFuc3BvcnRDb25uZWN0ZWQgPSBudWxsO1xuICAgICAgICB0aGlzLl9vblRyYW5zcG9ydERpc2Nvbm5lY3RlZCA9IG51bGw7XG4gICAgICAgIHRoaXMuX29uRXJyb3IgPSBudWxsO1xuICAgICAgICB0aGlzLl9vblBhY2tldFJlY2VpdmVkID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jXG4gICAgICogQHJldHVybiB7VHJhbnNwb3J0TGlzdGVuZXJ9XG4gICAgICovXG4gICAgc2V0T25UcmFuc3BvcnRDb25uZWN0ZWQgKGZ1bmMpIHtcbiAgICAgICAgdGhpcy5fb25UcmFuc3BvcnRDb25uZWN0ZWQgPSBmdW5jO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmNcbiAgICAgKiBAcmV0dXJuIHtUcmFuc3BvcnRMaXN0ZW5lcn1cbiAgICAgKi9cbiAgICBzZXRPblRyYW5zcG9ydERpc2Nvbm5lY3RlZCAoZnVuYykge1xuICAgICAgICB0aGlzLl9vblRyYW5zcG9ydERpc2Nvbm5lY3RlZCA9IGZ1bmM7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuY1xuICAgICAqIEByZXR1cm4ge1RyYW5zcG9ydExpc3RlbmVyfVxuICAgICAqL1xuICAgIHNldE9uRXJyb3IgKGZ1bmMpIHtcbiAgICAgICAgdGhpcy5fb25FcnJvciA9IGZ1bmM7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuY1xuICAgICAqIEByZXR1cm4ge1RyYW5zcG9ydExpc3RlbmVyfVxuICAgICAqL1xuICAgIHNldE9uUGFja2V0UmVjZWl2ZWQgKGZ1bmMpIHtcbiAgICAgICAgdGhpcy5fb25QYWNrZXRSZWNlaXZlZCA9IGZ1bmM7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG5cbiAgICBvblRyYW5zcG9ydENvbm5lY3RlZCAoKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fb25UcmFuc3BvcnRDb25uZWN0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuX29uVHJhbnNwb3J0Q29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvblRyYW5zcG9ydERpc2Nvbm5lY3RlZCAoKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fb25UcmFuc3BvcnREaXNjb25uZWN0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuX29uVHJhbnNwb3J0RGlzY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbkVycm9yIChlcnJvciA9IG51bGwpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9vbkVycm9yID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9vbkVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uUGFja2V0UmVjZWl2ZWQgKHNkbFBhY2tldCkge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX29uUGFja2V0UmVjZWl2ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuX29uUGFja2V0UmVjZWl2ZWQoc2RsUGFja2V0KTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IHsgVHJhbnNwb3J0TGlzdGVuZXIgfTtcbiIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5jbGFzcyBWZXJzaW9uIHtcbiAgICAvKipcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICovXG4gICAgY29uc3RydWN0b3IgKG1ham9yLCBtaW5vciwgcGF0Y2gpIHtcbiAgICAgICAgdGhpcy5zZXRNYWpvcihtYWpvcik7XG4gICAgICAgIHRoaXMuc2V0TWlub3IobWlub3IpO1xuICAgICAgICB0aGlzLnNldFBhdGNoKHBhdGNoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSBtYWpvclxuICAgICogQHJldHVybiB7VmVyc2lvbn1cbiAgICAqL1xuICAgIHNldE1ham9yIChtYWpvcikge1xuICAgICAgICB0aGlzLl9tYWpvciA9IHBhcnNlSW50KG1ham9yKSB8fCAwO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgZ2V0TWFqb3IgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFqb3I7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge051bWJlcn0gbWlub3JcbiAgICAqIEByZXR1cm4ge1ZlcnNpb259XG4gICAgKi9cbiAgICBzZXRNaW5vciAobWlub3IpIHtcbiAgICAgICAgdGhpcy5fbWlub3IgPSBwYXJzZUludChtaW5vcikgfHwgMDtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIGdldE1pbm9yICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21pbm9yO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtOdW1iZXJ9IHBhdGNoXG4gICAgKiBAcmV0dXJuIHtWZXJzaW9ufVxuICAgICovXG4gICAgc2V0UGF0Y2ggKHBhdGNoKSB7XG4gICAgICAgIHRoaXMuX3BhdGNoID0gcGFyc2VJbnQocGF0Y2gpIHx8IDA7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBnZXRQYXRjaCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXRjaDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSB2ZXJzaW9uIC0gUGFyc2UgdGhpcyBzdHJpbmcgdG8gYSBWZXJzaW9uIG9iamVjdFxuICAgICogQHJldHVybiB7VmVyc2lvbn1cbiAgICAqL1xuICAgIGZyb21TdHJpbmcgKHZlcnNpb24pIHtcbiAgICAgICAgY29uc3QgdmVyc2lvbnMgPSB2ZXJzaW9uLnNwbGl0KCcuJyk7XG4gICAgICAgIGlmICh2ZXJzaW9ucy5sZW5ndGggIT09IDMpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW5jb3JyZWN0IHZlcnNpb24gc3RyaW5nIGZvcm1hdCcpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0TWFqb3IodmVyc2lvbnNbMF0pO1xuICAgICAgICB0aGlzLnNldE1pbm9yKHZlcnNpb25zWzFdKTtcbiAgICAgICAgdGhpcy5zZXRQYXRjaCh2ZXJzaW9uc1syXSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICB0b1N0cmluZyAoKSB7XG4gICAgICAgIHJldHVybiBgJHt0aGlzLmdldE1ham9yKCl9LiR7dGhpcy5nZXRNaW5vcigpfS4ke3RoaXMuZ2V0UGF0Y2goKX1gO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogTWV0aG9kIHRvIHRlc3QgaWYgdGhpcyBpbnN0YW5jZSBvZiBWZXJzaW9uIGlzIG5ld2VyIHRoYW4gdGhlIHN1cHBsaWVkIG9uZS5cbiAgICAqIEBwYXJhbSB2ZXJzaW9uIC0gdGhlIHZlcnNpb24gdG8gY2hlY2sgYWdhaW5zdFxuICAgICogQHJldHVybiB7TnVtYmVyfSAtIDEgaWYgdGhpcyBpbnN0YW5jZSBpcyBuZXdlciwgLTEgaWYgc3VwcGxpZWQgdmVyc2lvbiBpcyBuZXdlciwgYW5kIDAgaWYgdGhleSBhcmUgZXF1YWxcbiAgICAqL1xuICAgIGlzTmV3ZXJUaGFuICh2ZXJzaW9uKSB7XG4gICAgICAgIGlmICh0aGlzLmdldE1ham9yKCkgPiB2ZXJzaW9uLmdldE1ham9yKCkpIHtcbiAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZ2V0TWFqb3IoKSA9PT0gdmVyc2lvbi5nZXRNYWpvcigpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5nZXRNaW5vcigpID4gdmVyc2lvbi5nZXRNaW5vcigpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZ2V0TWlub3IoKSA9PT0gdmVyc2lvbi5nZXRNaW5vcigpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZ2V0UGF0Y2goKSA+IHZlcnNpb24uZ2V0UGF0Y2goKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZ2V0UGF0Y2goKSA9PT0gdmVyc2lvbi5nZXRQYXRjaCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxufVxuXG5leHBvcnQgeyBWZXJzaW9uIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBTZXJ2aWNlVHlwZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgU2VydmljZVR5cGUgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBDT05UUk9MICgpIHtcbiAgICAgICAgcmV0dXJuIFNlcnZpY2VUeXBlLl9NQVAuQ09OVFJPTDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgUlBDICgpIHtcbiAgICAgICAgcmV0dXJuIFNlcnZpY2VUeXBlLl9NQVAuUlBDO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBBVURJTyAoKSB7XG4gICAgICAgIHJldHVybiBTZXJ2aWNlVHlwZS5fTUFQLkFVRElPO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBWSURFTyAoKSB7XG4gICAgICAgIHJldHVybiBTZXJ2aWNlVHlwZS5fTUFQLlZJREVPO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBIWUJSSUQgKCkge1xuICAgICAgICByZXR1cm4gU2VydmljZVR5cGUuX01BUC5IWUJSSUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFNlcnZpY2VUeXBlLl92YWx1ZUZvcktleShrZXksIFNlcnZpY2VUeXBlLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBTZXJ2aWNlVHlwZS5fa2V5Rm9yVmFsdWUodmFsdWUsIFNlcnZpY2VUeXBlLl9NQVApO1xuICAgIH1cbn1cblxuU2VydmljZVR5cGUuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdDT05UUk9MJzogMHgwMCxcbiAgICAnUlBDJzogMHgwNyxcbiAgICAnQVVESU8nOiAweDBBLFxuICAgICdWSURFTyc6IDB4MEIsXG4gICAgJ0hZQlJJRCc6MHgwRixcbn0pO1xuXG5leHBvcnQgeyBTZXJ2aWNlVHlwZSB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZyYW1lVHlwZSB9IGZyb20gJy4vZW51bXMvRnJhbWVUeXBlLmpzJztcbmltcG9ydCB7IFNkbFBhY2tldCB9IGZyb20gJy4vU2RsUGFja2V0LmpzJztcblxuLyoqXG4gKiBDYWxsYmFjayBmb3IgZmluaXNoZWQgcGFja2V0LlxuICogQGNhbGxiYWNrIGNiXG4gKiBAcGFyYW0ge3N0cmluZ30gZXJyb3IgLSBJZiB0aGVyZSBpcyBhbiBlcnJvciB0aGF0IGNhbm5vdCBiZSByZWNvdmVyZWQgZnJvbSBpdCB3aWxsIGJlIHJldHVybmVkLlxuICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldCAtIEZpbmlzaGVkIHNkbCBwYWNrZXQuXG4gKi9cblxuLyoqXG4gKiBBc3NlbWJsZXMgc2RsIHBhY2tldHMgd2hpY2ggbWF5IGNvbWUgaW4gc2VwZXJhdGUgY2h1bmtzIGlmIHRoZSBkYXRhIGV4Y2VlZHMgdGhlXG4gKiBtYXggdHJhbnNwb3J0IHVuaXQgYWxsb3dlZCBieSBzZGwgY29yZS5cbiAqXG4gKiBAcHJpdmF0ZSB7Y2J9IF9jYWxsYmFjayAtIENhbGxiYWNrIGZvciBjb21iaW5lZCBwYWNrZXQuXG4gKiBAcHJpdmF0ZSB7bnVtYmVyfSBfdG90YWxDb25zZWN1dGl2ZUZyYW1lcyAtIFRvdGFsIGNvbnNlY3V0aXZlIGZyYW1lcyBleHBlY3RlZCBmb3IgYSBtdWx0aWZyYW1lIHBhY2tldC5cbiAqIEBwcml2YXRlIHtudW1iZXJ9IF9jb25zZWN1dGl2ZUZyYW1lc0RhdGFMZW5ndGggLSBFeHBlY3RlZCBkYXRhIGxlbmd0aCBvZiBmaW5pc2hlZCBtdWx0aWZyYW1lIHBhY2tldC5cbiAqIEBwcml2YXRlIHtudW1iZXJ9IF9jb25zZWN1dGl2ZUZyYW1lc0hhbmRsZWRDb3VudCAtIFJ1bm5pbmcgdG90YWwgb2YgY29uc2VjdXRpdmUgZnJhbWVzIHJlY2VpdmVkIGFuZCBoYW5kbGVkLlxuICogQHByaXZhdGUge2FycmF5fSBfYWNjdW11bGF0b3IgQ29tYmluZXMgaW5jb21pbmcgYnl0ZXMgZnJvbSBjb25zZWN1dGl2ZSBmcmFtZXMuXG4gKi9cbmNsYXNzIE1lc3NhZ2VGcmFtZUFzc2VtYmxlciB7XG4gICAgLyoqXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAqIEBwYXJhbSB7Y2J9IGNhbGxiYWNrXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYWxsYmFjayBub3Qgb2YgZXhwZWN0ZWQgdHlwZSAoZnVuY3Rpb24pIGZvciBNZXNzYWdlRnJhbWVBc3NlbWJsZXInKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2NhbGxiYWNrID0gY2FsbGJhY2s7XG5cbiAgICAgICAgdGhpcy5fYWNjdW11bGF0b3IgPSBbXTtcbiAgICAgICAgdGhpcy5fdG90YWxDb25zZWN1dGl2ZUZyYW1lcyA9IDA7XG4gICAgICAgIHRoaXMuX2NvbnNlY3V0aXZlRnJhbWVzSGFuZGxlZENvdW50ID0gMDtcbiAgICAgICAgdGhpcy5fY29uc2VjdXRpdmVGcmFtZXNEYXRhTGVuZ3RoID0gMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBY2NlcHRzIGEgc2luZ2xlIGZyYW1lIG9yIG11bHRpZnJhbWUgcGFja2V0LiBUaGUgY2FsbGJhY2sgaXMgdXNlZCB3aGVuIHRoZSBwYWNrZXRcbiAgICAgKiBpcyBjb21wbGV0ZWx5IHJlYWQuIEZvciBhIHNpbmdsZSBmcmFtZSB0aGlzIGlzIGltbWVkaWF0ZWx5LiBGb3IgYSBtdWx0aSBmcmFtZSBwYWNrZXRcbiAgICAgKiBAcGFyYW0ge1NkbFBhY2tldH0gc2RsUGFja2V0IC0gSW5jb21pbmcgc2RsIHBhY2tldCB0byBiZSByZWFkLlxuICAgICovXG4gICAgaGFuZGxlRnJhbWUgKHNkbFBhY2tldCkge1xuICAgICAgICBjb25zdCBmcmFtZVR5cGUgPSBzZGxQYWNrZXQuZ2V0RnJhbWVUeXBlKCk7XG4gICAgICAgIC8vIElmIHRoZSBzZGwgcGFja2V0IGlzIGEgc2luZ2xlIGZyYW1lIG5vdGhpbmcgbmVlZHMgdG8gYmUgYXNzZW1ibGVkIGFuZCB0aGlzIGNhbiBiZSByZXR1cm5lZCBpbW1lZGlhdGVseS5cbiAgICAgICAgaWYgKGZyYW1lVHlwZSAhPT0gRnJhbWVUeXBlLkZJUlNUICYmIGZyYW1lVHlwZSAhPT0gRnJhbWVUeXBlLkNPTlNFQ1VUSVZFKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY2FsbGJhY2sobnVsbCwgc2RsUGFja2V0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5faGFuZGxlTXVsdGlGcmFtZU1lc3NhZ2Uoc2RsUGFja2V0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGVzIHRoZSBmaXJzdCBkYXRhIGZyYW1lLiBTZXRzIHRoZSBleHBlY3RlZCBmcmFtZSBjb3VudCBhbmQgZGF0YSBsZW5ndGguXG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldFxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgX2hhbmRsZUZpcnN0RGF0YUZyYW1lIChzZGxQYWNrZXQpIHtcbiAgICAgICAgLyoqIEB0eXBlIHthcnJheX0gQXJyYXkgb2YgdWludDggKi9cbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IHNkbFBhY2tldC5nZXRQYXlsb2FkKCk7XG5cbiAgICAgICAgaWYgKHBheWxvYWQgaW5zdGFuY2VvZiBVaW50OEFycmF5ICE9PSB0cnVlIHx8IHBheWxvYWQubGVuZ3RoICE9PSA4KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Vycm9yIGhhbmRsaW5nIGZpcnN0IGZyYW1lLiBQYXlsb2FkIGlzIGFuIGludmFsaWQgbGVuZ3RoIHNob3VsZCBiZSBsZW5ndGggOC4nKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IGJ5dGUgaW4gcGF5bG9hZCkge1xuICAgICAgICAgICAgaWYgKGJ5dGUgPCAweDAwIHx8IGJ5dGUgPiAweEZGKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHBheWxvYWQuIE11c3QgYmUgYW4gYXJyYXkgb2YgdWludDggYnl0ZXMuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBmaXJzdCA0IDgtYml0IGludGVnZXJzIGNvbnRhaW4gdGhlIGRhdGEgbGVuZ3RoLlxuICAgICAgICBsZXQgZGF0YUxlbmd0aCA9IChwYXlsb2FkWzBdICYgMHgwRikgPDwgMjQ7IC8vIDgtYml0IHggM1xuICAgICAgICBkYXRhTGVuZ3RoICs9IChwYXlsb2FkWzFdICYgMHhGRikgPDwgMTY7IC8vIDggeCAyXG4gICAgICAgIGRhdGFMZW5ndGggKz0gKHBheWxvYWRbMl0gJiAweEZGKSA8PCA4OyAvLyA4IHggMVxuICAgICAgICBkYXRhTGVuZ3RoICs9IHBheWxvYWRbM10gJiAweEZGOyAvLyA4IHggMFxuXG4gICAgICAgIGxldCBmcmFtZUNvdW50ID0gKHBheWxvYWRbNF0gJiAweEZGKSA8PCAyNDtcbiAgICAgICAgZnJhbWVDb3VudCArPSAocGF5bG9hZFs1XSAmIDB4RkYpIDw8IDE2O1xuICAgICAgICBmcmFtZUNvdW50ICs9IChwYXlsb2FkWzZdICYgMHhGRikgPDwgODtcbiAgICAgICAgZnJhbWVDb3VudCArPSBwYXlsb2FkWzddICYgMHhGRjtcblxuICAgICAgICB0aGlzLl90b3RhbENvbnNlY3V0aXZlRnJhbWVzID0gZnJhbWVDb3VudDtcbiAgICAgICAgdGhpcy5fY29uc2VjdXRpdmVGcmFtZXNEYXRhTGVuZ3RoID0gZGF0YUxlbmd0aDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGaXJzdCBmcmFtZSBzaG91bGQgYmUgcmVhZCBpbiBiZWZvcmUgdGhpcyBpcyBjYWxsZWQuIE9uY2UgdGhlIGxhc3RcbiAgICAgKiBmcmFtZSBpcyByZWFkLCBjYWxsYmFjayBpcyB1c2VkLlxuICAgICAqIEBwYXJhbSB7U2RsUGFja2V0fSBzZGxQYWNrZXRcbiAgICAgKi9cbiAgICBfaGFuZGxlQ29uc2VjdXRpdmVGcmFtZSAoc2RsUGFja2V0KSB7XG4gICAgICAgIHRoaXMuX2NvbnNlY3V0aXZlRnJhbWVzSGFuZGxlZENvdW50Kys7XG5cbiAgICAgICAgY29uc3QgZnJhbWVUeXBlID0gc2RsUGFja2V0LmdldEZyYW1lVHlwZSgpO1xuICAgICAgICAvKipcbiAgICAgICAgICogZnJhbWVTZXF1ZW5jZSBudGggZnJhbWUsIG9yIDAgZm9yIGxhc3QgZnJhbWUsXG4gICAgICAgICAqIDggYml0cyBhcmUgdXNlZCB0byBzdG9yZSB0aGlzIGluZm8gc28gdGhlIGNvdW50IHJldmVydHMgdG8gMSBhZnRlciAyNTVcbiAgICAgICAgICogVGhpcyBkb2Vzbid0IGFmZmVjdCByZWFkaW5nIHRoZSBwYWNrZXQgYnV0IGl0IGlzIG5vdGFibGUgaWYgZnJhbWUgc2VxdWVuY2UgaXMgcmVsaWVkIG9uLlxuICAgICAgICAgKi9cbiAgICAgICAgY29uc3QgZnJhbWVTZXF1ZW5jZSA9IHNkbFBhY2tldC5nZXRGcmFtZUluZm8oKTtcblxuICAgICAgICBjb25zdCBwYXlsb2FkID0gc2RsUGFja2V0LmdldFBheWxvYWQoKTtcblxuICAgICAgICBmb3IgKGNvbnN0IGJ5dGUgb2YgcGF5bG9hZCkge1xuICAgICAgICAgICAgdGhpcy5fYWNjdW11bGF0b3IucHVzaChieXRlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRoaXMgaXMgdGhlIGxhc3QgZnJhbWUsIGZpbmlzaCB0aGluZ3MgdXAgYW5kIHVzZSBjYWxsYmFjay5cbiAgICAgICAgaWYgKGZyYW1lU2VxdWVuY2UgPT09IDApIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9jb25zZWN1dGl2ZUZyYW1lc0hhbmRsZWRDb3VudCAhPT0gdGhpcy5fdG90YWxDb25zZWN1dGl2ZUZyYW1lcykge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgVG90YWwgZnJhbWVzIGV4cGVjdGVkICR7dGhpcy5fdG90YWxDb25zZWN1dGl2ZUZyYW1lc30gZG9lcyBub3QgbWF0Y2ggdG90YWwgZnJhbWVzIHJlY2VpdmVkICR7dGhpcy5fY29uc2VjdXRpdmVGcmFtZXNIYW5kbGVkQ291bnR9YCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLl9jb25zZWN1dGl2ZUZyYW1lc0RhdGFMZW5ndGggIT09IHRoaXMuX2FjY3VtdWxhdG9yLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgVG90YWwgZGF0YSBleHBlY3RlZCAke3RoaXMuX2NvbnNlY3V0aXZlRnJhbWVzRGF0YUxlbmd0aH0gZG9lcyBub3QgbWF0Y2ggdG90YWwgZGF0YSByZWNlaXZlZCAke3RoaXMuX2FjY3VtdWxhdG9yLmxlbmd0aH1gKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZmluaXNoZWRTZGxQYWNrZXQgPSBuZXcgU2RsUGFja2V0KFxuICAgICAgICAgICAgICAgIHNkbFBhY2tldC5nZXRWZXJzaW9uKCksXG4gICAgICAgICAgICAgICAgc2RsUGFja2V0LmdldEVuY3J5cHRpb24oKSxcbiAgICAgICAgICAgICAgICBmcmFtZVR5cGUsXG4gICAgICAgICAgICAgICAgc2RsUGFja2V0LmdldFNlcnZpY2VUeXBlKCksXG4gICAgICAgICAgICAgICAgZnJhbWVTZXF1ZW5jZSxcbiAgICAgICAgICAgICAgICBzZGxQYWNrZXQuZ2V0U2Vzc2lvbklEKCksXG4gICAgICAgICAgICAgICAgdGhpcy5fYWNjdW11bGF0b3IubGVuZ3RoLFxuICAgICAgICAgICAgICAgIHNkbFBhY2tldC5nZXRNZXNzYWdlSUQoKSxcbiAgICAgICAgICAgICAgICB0aGlzLl9hY2N1bXVsYXRvcixcbiAgICAgICAgICAgICAgICAwLCAvLyBubyBvZmZzZXRcbiAgICAgICAgICAgICAgICB0aGlzLl9hY2N1bXVsYXRvci5sZW5ndGggLy8gcmVhZCB0aGUgZW50aXJlIGJ1ZmZlclxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgdGhpcy5fY2FsbGJhY2sobnVsbCwgZmluaXNoZWRTZGxQYWNrZXQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlIHRoZSBzZGwgcGFja2V0IGJhc2VkIG9uIGl0cyBmcmFtZSB0eXBlLCBGSVJTVCBvciBDT05TRUNVVElWRS5cbiAgICAgKiBDYWxsYmFjayBpcyB1c2VkIHdoZW4gZmluYWwgcGFja2V0IGlzIHJlYWQuXG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldCAtIFNkbCBwYWNrZXQgdG8gYmUgcmVhZC5cbiAgICAgKi9cbiAgICBfaGFuZGxlTXVsdGlGcmFtZU1lc3NhZ2UgKHNkbFBhY2tldCkge1xuICAgICAgICBjb25zdCBmcmFtZVR5cGUgPSBzZGxQYWNrZXQuZ2V0RnJhbWVUeXBlKCk7XG4gICAgICAgIGlmIChmcmFtZVR5cGUgPT09IEZyYW1lVHlwZS5GSVJTVCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2hhbmRsZUZpcnN0RGF0YUZyYW1lKHNkbFBhY2tldCk7XG4gICAgICAgIH0gZWxzZSB7IC8vIEZyYW1lVHlwZS5Db25zZWN1dGl2ZVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2hhbmRsZUNvbnNlY3V0aXZlRnJhbWUoc2RsUGFja2V0KTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuXG5cbmV4cG9ydCB7IE1lc3NhZ2VGcmFtZUFzc2VtYmxlciB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5jbGFzcyBDb250cm9sRnJhbWVUYWdzIHtcbn1cblxuLy8gaGlkZGVuIGlubmVyIG9iamVjdHNcblxuY29uc3QgU3RhcnRTZXJ2aWNlQUNLQmFzZSA9IHtcbiAgICBNVFU6ICdtdHUnLFxufTtcblxuY29uc3QgTkFLQmFzZSA9IHtcbiAgICBSRUpFQ1RFRF9QQVJBTVM6ICdyZWplY3RlZFBhcmFtcycsXG59O1xuXG5jb25zdCBTdGFydFNlcnZpY2VQcm90b2NvbFZlcnNpb24gPSB7XG4gICAgLyoqIFRoZSBuZWdvdGlhdGVkIHZlcnNpb24gb2YgdGhlIHByb3RvY29sLiBNdXN0IGJlIGluIHRoZSBmb3JtYXQgXCJNYWpvci5NaW5vci5QYXRjaFwiKi9cbiAgICBQUk9UT0NPTF9WRVJTSU9OOiAncHJvdG9jb2xWZXJzaW9uJyxcbn07XG5cbmNvbnN0IFN0YXJ0U2VydmljZUhhc2hJZCA9IHtcbiAgICAvKiogSGFzaCBJRCB0byBpZGVudGlmeSB0aGlzIHNlcnZpY2UgYW5kIHVzZWQgd2hlbiBzZW5kaW5nIGFuIEVuZFNlcnZpY2UgY29udHJvbCBmcmFtZSovXG4gICAgSEFTSF9JRDogJ2hhc2hJZCcsXG59O1xuXG5jb25zdCBTdGFydFNlcnZpY2VEaW1lbnNpb25zID0ge1xuICAgIEhFSUdIVDogJ2hlaWdodCcsXG4gICAgV0lEVEg6ICd3aWR0aCcsXG59O1xuXG4vLyBzdGF0aWMgbWVtYmVyc1xuXG5Db250cm9sRnJhbWVUYWdzLlJQQyA9IE9iamVjdC5mcmVlemUoe1xuICAgIFN0YXJ0U2VydmljZTogU3RhcnRTZXJ2aWNlUHJvdG9jb2xWZXJzaW9uLFxuXG4gICAgU3RhcnRTZXJ2aWNlQUNLOiBPYmplY3QuYXNzaWduKHtcbiAgICAgICAgLyoqIEhVIGFsbG93ZWQgdHJhbnNwb3J0IGZvciBzZWNvbmRhcnkgY29ubmVjdGlvbiAqL1xuICAgICAgICBTRUNPTkRBUllfVFJBTlNQT1JUUzogJ3NlY29uZGFyeVRyYW5zcG9ydHMnLFxuICAgICAgICAvKiogSFUgYWxsb3dlZCB0cmFuc3BvcnRzIGZvciBhdWRpbyBhbmQgdmlkZW8gc2VydmljZXMgKDEgPT0gUHJpbWFyeSwgMiA9PSBTZWNvbmRhcnkpICovXG4gICAgICAgIEFVRElPX1NFUlZJQ0VfVFJBTlNQT1JUUzogJ2F1ZGlvU2VydmljZVRyYW5zcG9ydHMnLFxuICAgICAgICBWSURFT19TRVJWSUNFX1RSQU5TUE9SVFM6ICd2aWRlb1NlcnZpY2VUcmFuc3BvcnRzJyxcbiAgICAgICAgLyoqIEF1dGggdG9rZW4gdG8gYmUgdXNlZCBmb3IgbG9nIGluIGludG8gc2VydmljZXMgKiovXG4gICAgICAgIEFVVEhfVE9LRU46ICdhdXRoVG9rZW4nLFxuICAgIH0sIFN0YXJ0U2VydmljZUFDS0Jhc2UsIFN0YXJ0U2VydmljZVByb3RvY29sVmVyc2lvbiwgU3RhcnRTZXJ2aWNlSGFzaElkKSxcblxuICAgIFN0YXJ0U2VydmljZU5BSzogTkFLQmFzZSxcblxuICAgIEVuZFNlcnZpY2U6IFN0YXJ0U2VydmljZUhhc2hJZCxcblxuICAgIEVuZFNlcnZpY2VBQ0s6IHt9LFxuXG4gICAgRW5kU2VydmljZU5BSzogTkFLQmFzZSxcblxuICAgIFRyYW5zcG9ydEV2ZW50VXBkYXRlOiB7XG4gICAgICAgIFRDUF9JUF9BRERSRVNTOiAndGNwSXBBZGRyZXNzJyxcbiAgICAgICAgVENQX1BPUlQ6ICd0Y3BQb3J0JyxcbiAgICB9LFxuXG4gICAgUmVnaXN0ZXJTZWNvbmRhcnlUcmFuc3BvcnQ6IHt9LFxuXG4gICAgUmVnaXN0ZXJTZWNvbmRhcnlUcmFuc3BvcnRBQ0s6IHt9LFxuXG4gICAgUmVnaXN0ZXJTZWNvbmRhcnlUcmFuc3BvcnROQUs6IE9iamVjdC5hc3NpZ24oe1xuICAgICAgICBSRUFTT046ICdyZWFzb24nLFxuICAgIH0sIE5BS0Jhc2UpLFxufSk7XG5cbkNvbnRyb2xGcmFtZVRhZ3MuQXVkaW8gPSBPYmplY3QuZnJlZXplKHtcbiAgICBTdGFydFNlcnZpY2U6IHt9LFxuXG4gICAgU3RhcnRTZXJ2aWNlQUNLOiBTdGFydFNlcnZpY2VBQ0tCYXNlLFxuXG4gICAgU3RhcnRTZXJ2aWNlTkFLOiBOQUtCYXNlLFxuXG4gICAgRW5kU2VydmljZToge30sXG5cbiAgICBFbmRTZXJ2aWNlQUNLOiB7fSxcblxuICAgIEVuZFNlcnZpY2VOQUs6IE5BS0Jhc2UsXG59KTtcblxuQ29udHJvbEZyYW1lVGFncy5WaWRlbyA9IE9iamVjdC5mcmVlemUoe1xuICAgIFN0YXJ0U2VydmljZTogT2JqZWN0LmFzc2lnbih7XG4gICAgICAgIFZJREVPX1BST1RPQ09MOiAndmlkZW9Qcm90b2NvbCcsXG4gICAgICAgIFZJREVPX0NPREVDOiAndmlkZW9Db2RlYycsXG4gICAgfSwgU3RhcnRTZXJ2aWNlRGltZW5zaW9ucyksXG5cbiAgICBTdGFydFNlcnZpY2VBQ0s6IE9iamVjdC5hc3NpZ24oe1xuICAgICAgICBWSURFT19QUk9UT0NPTDogJ3ZpZGVvUHJvdG9jb2wnLFxuICAgICAgICBWSURFT19DT0RFQzogJ3ZpZGVvQ29kZWMnLFxuICAgIH0sIFN0YXJ0U2VydmljZUFDS0Jhc2UsIFN0YXJ0U2VydmljZURpbWVuc2lvbnMpLFxuXG4gICAgU3RhcnRTZXJ2aWNlTkFLOiBOQUtCYXNlLFxuXG4gICAgRW5kU2VydmljZToge30sXG5cbiAgICBFbmRTZXJ2aWNlQUNLOiB7fSxcblxuICAgIEVuZFNlcnZpY2VOQUs6IE5BS0Jhc2UsXG59KTtcblxuZXhwb3J0IHsgQ29udHJvbEZyYW1lVGFncyB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5jbGFzcyBCaXRDb252ZXJ0ZXIge1xuICAgIC8qKlxuXHQgKiBAcGFyYW0ge0FycmF5QnVmZmVyfSBidWZmZXIgLSBidWZmZXIgdGhhdCB3aWxsIGJlIGNvbnZlcnRlZCB0byBpbnRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gb2Zmc2V0IC0gaW50IG9wdGlvbmFsLCB0aGUgb2Zmc2V0IHNoaWZ0XG5cdCAqIEByZXR1cm4ge051bWJlcn0gaW50IGNvbnZlcnRlZCBmcm9tIGJ1ZmZlciBvciAtMSBpZiBidWZmZXIgaXMgbnVsbFxuXHQgKi9cbiAgICBzdGF0aWMgYXJyYXlCdWZmZXJUb0ludDMyIChidWZmZXIsIG9mZnNldCA9IDApIHtcbiAgICAgICAgaWYgKCFidWZmZXIpIHtcbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB2aWV3ID0gbmV3IERhdGFWaWV3KGJ1ZmZlcik7XG4gICAgICAgIHJldHVybiB2aWV3LmdldFVpbnQzMihvZmZzZXQpO1xuICAgIH1cblxuICAgIC8qKlxuXHQgKiBAcGFyYW0ge051bWJlcn0gdmFsdWUgLSB0aGUgaW50ZWdlciB0byBiZSBjb252ZXJ0ZWRcblx0ICogQHJldHVybiB7QXJyYXlCdWZmZXJ9IGJ1ZmZlciBjb252ZXJ0ZWQgZnJvbSBpbnB1dCB2YWx1ZVxuXHQgKi9cbiAgICBzdGF0aWMgaW50MzJUb0FycmF5QnVmZmVyICh2YWx1ZSkge1xuICAgICAgICBjb25zdCBidWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoNCk7IC8vIEludDMyIGhhcyA0IGJ5dGVzXG4gICAgICAgIGNvbnN0IHZpZXcgPSBuZXcgRGF0YVZpZXcoYnVmZmVyKTtcbiAgICAgICAgdmlldy5zZXRVaW50MzIoMCwgdmFsdWUsIGZhbHNlKTtcbiAgICAgICAgcmV0dXJuIGJ1ZmZlcjtcbiAgICB9XG59XG5cbmV4cG9ydCB7IEJpdENvbnZlcnRlciB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBTZGxQYWNrZXQgfSBmcm9tICcuL1NkbFBhY2tldC5qcyc7XG5pbXBvcnQgeyBDb250cm9sRnJhbWVUYWdzIH0gZnJvbSAnLi9lbnVtcy9Db250cm9sRnJhbWVUYWdzLmpzJztcbmltcG9ydCB7IEJpdENvbnZlcnRlciB9IGZyb20gJy4vLi4vdXRpbC9CaXRDb252ZXJ0ZXIuanMnO1xuaW1wb3J0IHsgRnJhbWVUeXBlIH0gZnJvbSAnLi9lbnVtcy9GcmFtZVR5cGUuanMnO1xuXG4vKipcbiAqIENyZWF0ZXMgY29udHJvbCBwYWNrZXRzLlxuICogRm9yIHJlZ3VsYXIgUlBDIFJQQ01lc3NhZ2Ugc2hvdWxkIGJlIHVzZWQuXG4gKi9cbmNsYXNzIFNkbFBhY2tldEZhY3Rvcnkge1xuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBoZWFydGJlYXQgYWNrbm93bGVnZW1lbnQgcGFja2V0LlxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlc3Npb25JRFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB2ZXJzaW9uXG4gICAgICogQHJldHVybnMge1NkbFBhY2tldH1cbiAgICAgKi9cbiAgICBzdGF0aWMgY3JlYXRlSGVhcnRiZWF0QUNLIChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklELCB2ZXJzaW9uKSB7XG4gICAgICAgIHJldHVybiBuZXcgU2RsUGFja2V0KHZlcnNpb24sIGZhbHNlLCBGcmFtZVR5cGUuQ09OVFJPTCxcbiAgICAgICAgICAgIHNlcnZpY2VUeXBlLCBTZGxQYWNrZXQuRlJBTUVfSU5GT19IRUFSVF9CRUFUX0FDSywgc2Vzc2lvbklELFxuICAgICAgICAgICAgMCwgMCwgbnVsbCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBlbmQgc2Vzc2lvbiBwYWNrZXQuXG4gICAgICogQHBhcmFtIHtTZXJ2aWNlVHlwZX0gc2VydmljZVR5cGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc2Vzc2lvbklEXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG1lc3NhZ2VJRFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB2ZXJzaW9uXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGhhc2hJRFxuICAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGVFbmRTZXNzaW9uIChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklELCBtZXNzYWdlSUQsIHZlcnNpb24sIGhhc2hJRCkge1xuICAgICAgICBpZiAodmVyc2lvbiA8IDUpIHtcbiAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBuZXcgVWludDhBcnJheShCaXRDb252ZXJ0ZXIuaW50MzJUb0FycmF5QnVmZmVyKGhhc2hJRCkpO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBTZGxQYWNrZXQodmVyc2lvbiwgZmFsc2UsIEZyYW1lVHlwZS5DT05UUk9MLFxuICAgICAgICAgICAgICAgIHNlcnZpY2VUeXBlLCBTZGxQYWNrZXQuRlJBTUVfSU5GT19FTkRfU0VSVklDRSwgc2Vzc2lvbklELFxuICAgICAgICAgICAgICAgIHBheWxvYWQubGVuZ3RoLCBtZXNzYWdlSUQsIHBheWxvYWQsIDAsIHBheWxvYWQubGVuZ3RoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGVuZFNlc3Npb24gPSBuZXcgU2RsUGFja2V0KHZlcnNpb24sIGZhbHNlLCBGcmFtZVR5cGUuQ09OVFJPTCxcbiAgICAgICAgICAgICAgICBzZXJ2aWNlVHlwZSwgU2RsUGFja2V0LkZSQU1FX0lORk9fRU5EX1NFUlZJQ0UsIHNlc3Npb25JRCxcbiAgICAgICAgICAgICAgICAwLCBtZXNzYWdlSUQsIG51bGwpO1xuICAgICAgICAgICAgZW5kU2Vzc2lvbi5wdXRUYWcoQ29udHJvbEZyYW1lVGFncy5SUEMuRW5kU2VydmljZS5IQVNIX0lELCBoYXNoSUQpO1xuICAgICAgICAgICAgcmV0dXJuIGVuZFNlc3Npb247XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCB7IFNkbFBhY2tldEZhY3RvcnkgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYge0VudW19IEltYWdlVHlwZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgSW1hZ2VUeXBlIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTVEFUSUMgKCkge1xuICAgICAgICByZXR1cm4gSW1hZ2VUeXBlLl9NQVAuU1RBVElDO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IERZTkFNSUMgKCkge1xuICAgICAgICByZXR1cm4gSW1hZ2VUeXBlLl9NQVAuRFlOQU1JQztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gSW1hZ2VUeXBlLl92YWx1ZUZvcktleShrZXksIEltYWdlVHlwZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gSW1hZ2VUeXBlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgSW1hZ2VUeXBlLl9NQVApO1xuICAgIH1cbn1cblxuSW1hZ2VUeXBlLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnU1RBVElDJzogJ1NUQVRJQycsXG4gICAgJ0RZTkFNSUMnOiAnRFlOQU1JQycsXG59KTtcblxuZXhwb3J0IHsgSW1hZ2VUeXBlIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBJbWFnZVR5cGUgfSBmcm9tICcuLi9lbnVtcy9JbWFnZVR5cGUuanMnO1xuXG5jbGFzcyBJbWFnZSBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlXG4gICAgKiBAcmV0dXJuIHtJbWFnZX1cbiAgICAqL1xuICAgIHNldFZhbHVlICh2YWx1ZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihJbWFnZS5LRVlfVkFMVUUsIHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBnZXRWYWx1ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihJbWFnZS5LRVlfVkFMVUUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtJbWFnZVR5cGV9IHR5cGVcbiAgICAqIEByZXR1cm4ge0ltYWdlfVxuICAgICovXG4gICAgc2V0SW1hZ2VUeXBlICh0eXBlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEltYWdlVHlwZSwgdHlwZSk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoSW1hZ2UuS0VZX0lNQUdFX1RZUEUsIHR5cGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0ltYWdlVHlwZX1cbiAgICAqL1xuICAgIGdldEltYWdlVHlwZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChJbWFnZVR5cGUsIEltYWdlLktFWV9JTUFHRV9UWVBFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNUZW1wbGF0ZVxuICAgICogQHJldHVybiB7SW1hZ2V9XG4gICAgKi9cbiAgICBzZXRJc1RlbXBsYXRlIChpc1RlbXBsYXRlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEltYWdlLktFWV9JU19URU1QTEFURSwgaXNUZW1wbGF0ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAqL1xuICAgIGdldElzVGVtcGxhdGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoSW1hZ2UuS0VZX0lTX1RFTVBMQVRFKTtcbiAgICB9XG59XG5cbkltYWdlLktFWV9WQUxVRSA9ICd2YWx1ZSc7XG5JbWFnZS5LRVlfSU1BR0VfVFlQRSA9ICdpbWFnZVR5cGUnO1xuSW1hZ2UuS0VZX0lTX1RFTVBMQVRFID0gJ2lzVGVtcGxhdGUnO1xuXG5leHBvcnQgeyBJbWFnZSB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5cbmNsYXNzIE1lbnVQYXJhbXMgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSBpZFxuICAgICogQHJldHVybiB7TWVudVBhcmFtc31cbiAgICAqL1xuICAgIHNldFBhcmVudElEIChpZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihNZW51UGFyYW1zLktFWV9QQVJFTlRfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBnZXRQYXJlbnRJRCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihNZW51UGFyYW1zLktFWV9QQVJFTlRfSUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtOdW1iZXJ9IHBvc2l0aW9uXG4gICAgKiBAcmV0dXJuIHtNZW51UGFyYW1zfVxuICAgICovXG4gICAgc2V0UG9zaXRpb24gKHBvc2l0aW9uKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE1lbnVQYXJhbXMuS0VZX1BPU0lUSU9OLCBwb3NpdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgZ2V0UG9zaXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoTWVudVBhcmFtcy5LRVlfUE9TSVRJT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IG1lbnVOYW1lXG4gICAgKiBAcmV0dXJuIHtNZW51UGFyYW1zfVxuICAgICovXG4gICAgc2V0TWVudU5hbWUgKG1lbnVOYW1lKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE1lbnVQYXJhbXMuS0VZX01FTlVfTkFNRSwgbWVudU5hbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7U3RyaW5nfVxuICAgICovXG4gICAgZ2V0TWVudU5hbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoTWVudVBhcmFtcy5LRVlfTUVOVV9OQU1FKTtcbiAgICB9XG59XG5cbk1lbnVQYXJhbXMuS0VZX1BBUkVOVF9JRCA9ICdwYXJlbnRJRCc7XG5NZW51UGFyYW1zLktFWV9QT1NJVElPTiAgPSAncG9zaXRpb24nO1xuTWVudVBhcmFtcy5LRVlfTUVOVV9OQU1FID0gJ21lbnVOYW1lJztcblxuZXhwb3J0IHsgTWVudVBhcmFtcyB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1JlcXVlc3QgfSBmcm9tICcuLi9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IEltYWdlIH0gZnJvbSAnLi4vc3RydWN0cy9JbWFnZS5qcyc7XG5pbXBvcnQgeyBNZW51UGFyYW1zIH0gZnJvbSAnLi4vc3RydWN0cy9NZW51UGFyYW1zLmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcblxuY2xhc3MgQWRkQ29tbWFuZCBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkFkZENvbW1hbmQpO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge051bWJlcn0gaWRcbiAgICAqIEByZXR1cm4ge0FkZENvbW1hbmR9XG4gICAgKi9cbiAgICBzZXRDbWRJRCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQWRkQ29tbWFuZC5LRVlfQ01EX0lELCBpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgZ2V0Q21kSUQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQWRkQ29tbWFuZC5LRVlfQ01EX0lEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7TWVudVBhcmFtc30gbWVudVBhcmFtc1xuICAgICogQHJldHVybiB7QWRkQ29tbWFuZH1cbiAgICAqL1xuICAgIHNldE1lbnVQYXJhbXMgKG1lbnVQYXJhbXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTWVudVBhcmFtcywgbWVudVBhcmFtcyk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQWRkQ29tbWFuZC5LRVlfTUVOVV9QQVJBTVMsIG1lbnVQYXJhbXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge01lbnVQYXJhbXN9XG4gICAgKi9cbiAgICBnZXRNZW51UGFyYW1zICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KE1lbnVQYXJhbXMsIEFkZENvbW1hbmQuS0VZX01FTlVfUEFSQU1TKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7QXJyYXk8U3RyaW5nPn0gdnJDb21tYW5kc1xuICAgICogQHJldHVybiB7QWRkQ29tbWFuZH1cbiAgICAqL1xuICAgIHNldFZyQ29tbWFuZHMgKHZyQ29tbWFuZHMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQWRkQ29tbWFuZC5LRVlfVlJfQ09NTUFORFMsIHZyQ29tbWFuZHMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0FycmF5PFN0cmluZz59XG4gICAgKi9cbiAgICBnZXRWckNvbW1hbmRzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEFkZENvbW1hbmQuS0VZX1ZSX0NPTU1BTkRTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7SW1hZ2V9IGljb25cbiAgICAqIEByZXR1cm4ge0FkZENvbW1hbmR9XG4gICAgKi9cbiAgICBzZXRDbWRJY29uIChpY29uKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEltYWdlLCBpY29uKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBZGRDb21tYW5kLktFWV9DTURfSUNPTiwgaWNvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7SW1hZ2V9XG4gICAgKi9cbiAgICBnZXRDbWRJY29uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEltYWdlLCBBZGRDb21tYW5kLktFWV9DTURfSUNPTik7XG4gICAgfVxufVxuXG5BZGRDb21tYW5kLktFWV9DTURfSUNPTiA9ICdjbWRJY29uJztcbkFkZENvbW1hbmQuS0VZX01FTlVfUEFSQU1TID0gJ21lbnVQYXJhbXMnO1xuQWRkQ29tbWFuZC5LRVlfQ01EX0lEID0gJ2NtZElEJztcbkFkZENvbW1hbmQuS0VZX1ZSX0NPTU1BTkRTID0gJ3ZyQ29tbWFuZHMnO1xuXG5leHBvcnQgeyBBZGRDb21tYW5kIH07XG4iLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5cbmNsYXNzIEFkZENvbW1hbmRSZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5BZGRDb21tYW5kKTtcbiAgICB9XG59XG5cbmV4cG9ydCB7IEFkZENvbW1hbmRSZXNwb25zZSB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY01lc3NhZ2UgfSBmcm9tICcuL1JwY01lc3NhZ2UuanMnO1xuaW1wb3J0IHsgUnBjVHlwZSB9IGZyb20gJy4vZW51bXMvUnBjVHlwZS5qcyc7XG5cbmNsYXNzIFJwY05vdGlmaWNhdGlvbiBleHRlbmRzIFJwY01lc3NhZ2Uge1xuICAgIC8qKlxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldFJQQ1R5cGUoUnBjVHlwZS5OT1RJRklDQVRJT04pO1xuICAgIH1cbn1cblxuZXhwb3J0IHsgUnBjTm90aWZpY2F0aW9uIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBITUlMZXZlbFxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgSE1JTGV2ZWwgZXh0ZW5kcyBFbnVtIHtcbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSE1JX0ZVTEwgKCkge1xuICAgICAgICByZXR1cm4gSE1JTGV2ZWwuX01BUC5ITUlfRlVMTDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBITUlfTElNSVRFRCAoKSB7XG4gICAgICAgIHJldHVybiBITUlMZXZlbC5fTUFQLkhNSV9MSU1JVEVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEhNSV9CQUNLR1JPVU5EICgpIHtcbiAgICAgICAgcmV0dXJuIEhNSUxldmVsLl9NQVAuSE1JX0JBQ0tHUk9VTkQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSE1JX05PTkUgKCkge1xuICAgICAgICByZXR1cm4gSE1JTGV2ZWwuX01BUC5ITUlfTk9ORTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gSE1JTGV2ZWwuX3ZhbHVlRm9yS2V5KGtleSwgSE1JTGV2ZWwuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIEhNSUxldmVsLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgSE1JTGV2ZWwuX01BUCk7XG4gICAgfVxufVxuXG5ITUlMZXZlbC5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0hNSV9GVUxMJzogJ0ZVTEwnLFxuICAgICdITUlfTElNSVRFRCc6ICdMSU1JVEVEJyxcbiAgICAnSE1JX0JBQ0tHUk9VTkQnOiAnQkFDS0dST1VORCcsXG4gICAgJ0hNSV9OT05FJzogJ05PTkUnLFxuXG59KTtcblxuZXhwb3J0IHsgSE1JTGV2ZWwgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYge0VudW19IEF1ZGlvU3RyZWFtaW5nU3RhdGVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIEF1ZGlvU3RyZWFtaW5nU3RhdGUgZXh0ZW5kcyBFbnVtIHtcbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQVVESUJMRSAoKSB7XG4gICAgICAgIHJldHVybiBBdWRpb1N0cmVhbWluZ1N0YXRlLl9NQVAuQVVESUJMRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBBVFRFTlVBVEVEICgpIHtcbiAgICAgICAgcmV0dXJuIEF1ZGlvU3RyZWFtaW5nU3RhdGUuX01BUC5BVFRFTlVBVEVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5PVF9BVURJQkxFICgpIHtcbiAgICAgICAgcmV0dXJuIEF1ZGlvU3RyZWFtaW5nU3RhdGUuX01BUC5OT1RfQVVESUJMRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gQXVkaW9TdHJlYW1pbmdTdGF0ZS5fdmFsdWVGb3JLZXkoa2V5LCBBdWRpb1N0cmVhbWluZ1N0YXRlLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBBdWRpb1N0cmVhbWluZ1N0YXRlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgQXVkaW9TdHJlYW1pbmdTdGF0ZS5fTUFQKTtcbiAgICB9XG59XG5cbkF1ZGlvU3RyZWFtaW5nU3RhdGUuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdBVURJQkxFJzogJ0FVRElCTEUnLFxuICAgICdBVFRFTlVBVEVEJzogJ0FUVEVOVUFURUQnLFxuICAgICdOT1RfQVVESUJMRSc6ICdOT1RfQVVESUJMRScsXG5cbn0pO1xuXG5leHBvcnQgeyBBdWRpb1N0cmVhbWluZ1N0YXRlIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBWaWRlb1N0cmVhbWluZ1N0YXRlXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBWaWRlb1N0cmVhbWluZ1N0YXRlIGV4dGVuZHMgRW51bSB7XG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNUUkVBTUFCTEUgKCkge1xuICAgICAgICByZXR1cm4gVmlkZW9TdHJlYW1pbmdTdGF0ZS5fTUFQLlNUUkVBTUFCTEU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTk9UX1NUUkVBTUFCTEUgKCkge1xuICAgICAgICByZXR1cm4gVmlkZW9TdHJlYW1pbmdTdGF0ZS5fTUFQLk5PVF9TVFJFQU1BQkxFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgKiBAcGFyYW0gdmFsdWUgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBWaWRlb1N0cmVhbWluZ1N0YXRlLl92YWx1ZUZvcktleShrZXksIFZpZGVvU3RyZWFtaW5nU3RhdGUuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFZpZGVvU3RyZWFtaW5nU3RhdGUuX2tleUZvclZhbHVlKHZhbHVlLCBWaWRlb1N0cmVhbWluZ1N0YXRlLl9NQVApO1xuICAgIH1cbn1cblxuVmlkZW9TdHJlYW1pbmdTdGF0ZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1NUUkVBTUFCTEUnOiAnU1RSRUFNQUJMRScsXG4gICAgJ05PVF9TVFJFQU1BQkxFJzogJ05PVF9TVFJFQU1BQkxFJyxcblxufSk7XG5cbmV4cG9ydCB7IFZpZGVvU3RyZWFtaW5nU3RhdGUgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYge0VudW19IFN5c3RlbUNvbnRleHRcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIFN5c3RlbUNvbnRleHQgZXh0ZW5kcyBFbnVtIHtcbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU1lTQ1RYVF9NQUlOICgpIHtcbiAgICAgICAgcmV0dXJuIFN5c3RlbUNvbnRleHQuX01BUC5TWVNDVFhUX01BSU47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU1lTQ1RYVF9WUlNFU1NJT04gKCkge1xuICAgICAgICByZXR1cm4gU3lzdGVtQ29udGV4dC5fTUFQLlNZU0NUWFRfVlJTRVNTSU9OO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNZU0NUWFRfTUVOVSAoKSB7XG4gICAgICAgIHJldHVybiBTeXN0ZW1Db250ZXh0Ll9NQVAuU1lTQ1RYVF9NRU5VO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNZU0NUWFRfSE1JX09CU0NVUkVEICgpIHtcbiAgICAgICAgcmV0dXJuIFN5c3RlbUNvbnRleHQuX01BUC5TWVNDVFhUX0hNSV9PQlNDVVJFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTWVNDVFhUX0FMRVJUICgpIHtcbiAgICAgICAgcmV0dXJuIFN5c3RlbUNvbnRleHQuX01BUC5TWVNDVFhUX0FMRVJUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgKiBAcGFyYW0gdmFsdWUgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBTeXN0ZW1Db250ZXh0Ll92YWx1ZUZvcktleShrZXksIFN5c3RlbUNvbnRleHQuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFN5c3RlbUNvbnRleHQuX2tleUZvclZhbHVlKHZhbHVlLCBTeXN0ZW1Db250ZXh0Ll9NQVApO1xuICAgIH1cbn1cblxuU3lzdGVtQ29udGV4dC5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1NZU0NUWFRfTUFJTic6ICdNQUlOJyxcbiAgICAnU1lTQ1RYVF9WUlNFU1NJT04nOiAnVlJTRVNTSU9OJyxcbiAgICAnU1lTQ1RYVF9NRU5VJzogJ01FTlUnLFxuICAgICdTWVNDVFhUX0hNSV9PQlNDVVJFRCc6ICdITUlfT0JTQ1VSRUQnLFxuICAgICdTWVNDVFhUX0FMRVJUJzogJ0FMRVJUJyxcblxufSk7XG5cbmV4cG9ydCB7IFN5c3RlbUNvbnRleHQgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjTm90aWZpY2F0aW9uIH0gZnJvbSAnLi4vUnBjTm90aWZpY2F0aW9uLmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IEhNSUxldmVsIH0gZnJvbSAnLi4vZW51bXMvSE1JTGV2ZWwuanMnO1xuaW1wb3J0IHsgQXVkaW9TdHJlYW1pbmdTdGF0ZSB9IGZyb20gJy4uL2VudW1zL0F1ZGlvU3RyZWFtaW5nU3RhdGUuanMnO1xuaW1wb3J0IHsgVmlkZW9TdHJlYW1pbmdTdGF0ZSB9IGZyb20gJy4uL2VudW1zL1ZpZGVvU3RyZWFtaW5nU3RhdGUuanMnO1xuaW1wb3J0IHsgU3lzdGVtQ29udGV4dCB9IGZyb20gJy4uL2VudW1zL1N5c3RlbUNvbnRleHQuanMnO1xuXG5jbGFzcyBPbkhtaVN0YXR1cyBleHRlbmRzIFJwY05vdGlmaWNhdGlvbiB7XG4gICAgLyoqXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuT25ITUlTdGF0dXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtITUlMZXZlbH0gaG1pTGV2ZWxcbiAgICAqIEByZXR1cm4ge09uSG1pU3RhdHVzfVxuICAgICovXG4gICAgc2V0SE1JTGV2ZWwgKGhtaUxldmVsKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEhNSUxldmVsLCBobWlMZXZlbCk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25IbWlTdGF0dXMuS0VZX0hNSV9MRVZFTCwgaG1pTGV2ZWwpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0hNSUxldmVsfVxuICAgICovXG4gICAgZ2V0SE1JTGV2ZWwgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoSE1JTGV2ZWwsIE9uSG1pU3RhdHVzLktFWV9ITUlfTEVWRUwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtBdWRpb1N0cmVhbWluZ1N0YXRlfSBhdWRpb1N0cmVhbWluZ1N0YXRlXG4gICAgKiBAcmV0dXJuIHtPbkhtaVN0YXR1c31cbiAgICAqL1xuICAgIHNldEF1ZGlvU3RyZWFtaW5nU3RhdGUgKGF1ZGlvU3RyZWFtaW5nU3RhdGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQXVkaW9TdHJlYW1pbmdTdGF0ZSwgYXVkaW9TdHJlYW1pbmdTdGF0ZSk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25IbWlTdGF0dXMuS0VZX0FVRElPX1NUUkVBTUlOR19TVEFURSwgYXVkaW9TdHJlYW1pbmdTdGF0ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7QXVkaW9TdHJlYW1pbmdTdGF0ZX1cbiAgICAqL1xuICAgIGdldEF1ZGlvU3RyZWFtaW5nU3RhdGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQXVkaW9TdHJlYW1pbmdTdGF0ZSwgT25IbWlTdGF0dXMuS0VZX0FVRElPX1NUUkVBTUlOR19TVEFURSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N5c3RlbUNvbnRleHR9IHN5c3RlbUNvbnRleHRcbiAgICAqIEByZXR1cm4ge09uSG1pU3RhdHVzfVxuICAgICovXG4gICAgc2V0U3lzdGVtQ29udGV4dCAoc3lzdGVtQ29udGV4dCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShTeXN0ZW1Db250ZXh0LCBzeXN0ZW1Db250ZXh0KTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPbkhtaVN0YXR1cy5LRVlfU1lTVEVNX0NPTlRFWFQsIHN5c3RlbUNvbnRleHQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N5c3RlbUNvbnRleHR9XG4gICAgKi9cbiAgICBnZXRTeXN0ZW1Db250ZXh0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFN5c3RlbUNvbnRleHQsIE9uSG1pU3RhdHVzLktFWV9TWVNURU1fQ09OVEVYVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1ZpZGVvU3RyZWFtaW5nU3RhdGV9IHZpZGVvU3RyZWFtaW5nU3RhdGVcbiAgICAqIEByZXR1cm4ge09uSG1pU3RhdHVzfVxuICAgICovXG4gICAgc2V0VmlkZW9TdHJlYW1pbmdTdGF0ZSAodmlkZW9TdHJlYW1pbmdTdGF0ZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWaWRlb1N0cmVhbWluZ1N0YXRlLCB2aWRlb1N0cmVhbWluZ1N0YXRlKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPbkhtaVN0YXR1cy5LRVlfVklERU9fU1RSRUFNSU5HX1NUQVRFLCB2aWRlb1N0cmVhbWluZ1N0YXRlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtWaWRlb1N0cmVhbWluZ1N0YXRlfVxuICAgICovXG4gICAgZ2V0VmlkZW9TdHJlYW1pbmdTdGF0ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWaWRlb1N0cmVhbWluZ1N0YXRlLCBPbkhtaVN0YXR1cy5LRVlfVklERU9fU1RSRUFNSU5HX1NUQVRFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSB3aW5kb3dJRFxuICAgICogQHJldHVybiB7U2hvd31cbiAgICAqL1xuICAgIHNldFdpbmRvd0lEICh3aW5kb3dJRCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPbkhtaVN0YXR1cy5LRVlfV0lORE9XX0lELCB3aW5kb3dJRCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgZ2V0V2luZG93SUQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoT25IbWlTdGF0dXMuS0VZX1dJTkRPV19JRCk7XG4gICAgfVxufVxuXG5PbkhtaVN0YXR1cy5LRVlfSE1JX0xFVkVMID0gJ2htaUxldmVsJztcbk9uSG1pU3RhdHVzLktFWV9BVURJT19TVFJFQU1JTkdfU1RBVEUgPSAnYXVkaW9TdHJlYW1pbmdTdGF0ZSc7XG5PbkhtaVN0YXR1cy5LRVlfU1lTVEVNX0NPTlRFWFQgPSAnc3lzdGVtQ29udGV4dCc7XG5PbkhtaVN0YXR1cy5LRVlfVklERU9fU1RSRUFNSU5HX1NUQVRFID0gJ3ZpZGVvU3RyZWFtaW5nU3RhdGUnO1xuT25IbWlTdGF0dXMuS0VZX1dJTkRPV19JRCA9ICd3aW5kb3dJRCc7XG5cbmV4cG9ydCB7IE9uSG1pU3RhdHVzIH07XG4iLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjTm90aWZpY2F0aW9uIH0gZnJvbSAnLi4vUnBjTm90aWZpY2F0aW9uLmpzJztcbmltcG9ydCB7IExhbmd1YWdlIH0gZnJvbSAnLi4vZW51bXMvTGFuZ3VhZ2UuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG5jbGFzcyBPbkxhbmd1YWdlQ2hhbmdlIGV4dGVuZHMgUnBjTm90aWZpY2F0aW9uIHtcbiAgICAvKipcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5Pbkxhbmd1YWdlQ2hhbmdlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7TGFuZ3VhZ2V9IGxhbmd1YWdlXG4gICAgKiBAcmV0dXJuIHtPbkxhbmd1YWdlQ2hhbmdlfVxuICAgICovXG4gICAgc2V0TGFuZ3VhZ2UgKGxhbmd1YWdlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKExhbmd1YWdlLCBsYW5ndWFnZSk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25MYW5ndWFnZUNoYW5nZS5LRVlfTEFOR1VBR0UsIGxhbmd1YWdlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtMYW5ndWFnZX1cbiAgICAqL1xuICAgIGdldExhbmd1YWdlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KExhbmd1YWdlLCBPbkxhbmd1YWdlQ2hhbmdlLktFWV9MQU5HVUFHRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0xhbmd1YWdlfSBsYW5ndWFnZVxuICAgICogQHJldHVybiB7T25MYW5ndWFnZUNoYW5nZX1cbiAgICAqL1xuICAgIHNldEhNSURpc3BsYXlMYW5ndWFnZSAobGFuZ3VhZ2UpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTGFuZ3VhZ2UsIGxhbmd1YWdlKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPbkxhbmd1YWdlQ2hhbmdlLktFWV9ITUlfRElTUExBWV9MQU5HVUFHRSwgbGFuZ3VhZ2UpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0xhbmd1YWdlfVxuICAgICovXG4gICAgZ2V0SE1JRGlzcGxheUxhbmd1YWdlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KExhbmd1YWdlLCBPbkxhbmd1YWdlQ2hhbmdlLktFWV9ITUlfRElTUExBWV9MQU5HVUFHRSk7XG4gICAgfVxufVxuXG5Pbkxhbmd1YWdlQ2hhbmdlLktFWV9MQU5HVUFHRSA9ICdsYW5ndWFnZSc7XG5Pbkxhbmd1YWdlQ2hhbmdlLktFWV9ITUlfRElTUExBWV9MQU5HVUFHRSA9ICdobWlEaXNwbGF5TGFuZ3VhZ2UnO1xuXG5leHBvcnQgeyBPbkxhbmd1YWdlQ2hhbmdlIH07XG4iLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYge0VudW19IEZpbGVUeXBlXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBGaWxlVHlwZSBleHRlbmRzIEVudW0ge1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBHUkFQSElDX0JNUCAoKSB7XG4gICAgICAgIHJldHVybiBGaWxlVHlwZS5fTUFQLkdSQVBISUNfQk1QO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEdSQVBISUNfSlBFRyAoKSB7XG4gICAgICAgIHJldHVybiBGaWxlVHlwZS5fTUFQLkdSQVBISUNfSlBFRztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBHUkFQSElDX1BORyAoKSB7XG4gICAgICAgIHJldHVybiBGaWxlVHlwZS5fTUFQLkdSQVBISUNfUE5HO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFVRElPX1dBVkUgKCkge1xuICAgICAgICByZXR1cm4gRmlsZVR5cGUuX01BUC5BVURJT19XQVZFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFVRElPX0FBQyAoKSB7XG4gICAgICAgIHJldHVybiBGaWxlVHlwZS5fTUFQLkFVRElPX0FBQztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBCSU5BUlkgKCkge1xuICAgICAgICByZXR1cm4gRmlsZVR5cGUuX01BUC5CSU5BUlk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSlNPTiAoKSB7XG4gICAgICAgIHJldHVybiBGaWxlVHlwZS5fTUFQLkpTT047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIEZpbGVUeXBlLl92YWx1ZUZvcktleShrZXksIEZpbGVUeXBlLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBGaWxlVHlwZS5fa2V5Rm9yVmFsdWUodmFsdWUsIEZpbGVUeXBlLl9NQVApO1xuICAgIH1cbn1cblxuRmlsZVR5cGUuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdHUkFQSElDX0JNUCc6ICdHUkFQSElDX0JNUCcsXG4gICAgJ0dSQVBISUNfSlBFRyc6ICdHUkFQSElDX0pQRUcnLFxuICAgICdHUkFQSElDX1BORyc6ICdHUkFQSElDX1BORycsXG4gICAgJ0FVRElPX1dBVkUnOiAnQVVESU9fV0FWRScsXG4gICAgJ0FVRElPX01QMyc6ICdBVURJT19NUDMnLFxuICAgICdBVURJT19BQUMnOiAnQVVESU9fQUFDJyxcbiAgICAnQklOQVJZJzogJ0JJTkFSWScsXG4gICAgJ0pTT04nOiAnSlNPTicsXG5cbn0pO1xuXG5leHBvcnQgeyBGaWxlVHlwZSB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBGaWxlVHlwZSB9IGZyb20gJy4uL2VudW1zL0ZpbGVUeXBlLmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcblxuY2xhc3MgUHV0RmlsZSBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlB1dEZpbGUpO1xuICAgIH1cblxuICAgIC8vIC0tLS0tLSBOb3QgcGFydCBvZiB0aGUgUlBDIHNwZWMgaXRzZWxmIC0tLS0tXG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7VWludDhBcnJheX0gZmlsZURhdGFcbiAgICAqIEByZXR1cm4ge1B1dEZpbGV9XG4gICAgKi9cbiAgICBzZXRGaWxlRGF0YSAoZmlsZURhdGEpIHtcbiAgICAgICAgdGhpcy5zZXRCdWxrRGF0YShmaWxlRGF0YSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1VpbnQ4QXJyYXl9XG4gICAgKi9cbiAgICBnZXRGaWxlRGF0YSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEJ1bGtEYXRhKCk7XG4gICAgfVxuXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0gRU5EIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IGZpbGVOYW1lXG4gICAgKiBAcmV0dXJuIHtQdXRGaWxlfVxuICAgICovXG4gICAgc2V0RmlsZU5hbWUgKGZpbGVOYW1lKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFB1dEZpbGUuS0VZX0ZJTEVfTkFNRSwgZmlsZU5hbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIGdldEZpbGVOYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFB1dEZpbGUuS0VZX0ZJTEVfTkFNRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0ZpbGVUeXBlfSBmaWxlVHlwZVxuICAgICogQHJldHVybiB7UHV0RmlsZX1cbiAgICAqL1xuICAgIHNldEZpbGVUeXBlIChmaWxlVHlwZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShGaWxlVHlwZSwgZmlsZVR5cGUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihQdXRGaWxlLktFWV9GSUxFX1RZUEUsIGZpbGVUeXBlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtGaWxlVHlwZX1cbiAgICAqL1xuICAgIGdldEZpbGVUeXBlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEZpbGVUeXBlLCBQdXRGaWxlLktFWV9NRU5VX1BBUkFNUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0Jvb2xlYW59IHBlcnNpc3RlbnRGaWxlXG4gICAgKiBAcmV0dXJuIHtQdXRGaWxlfVxuICAgICovXG4gICAgc2V0UGVyc2lzdGVudEZpbGUgKHBlcnNpc3RlbnRGaWxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFB1dEZpbGUuS0VZX1BFUlNJU1RFTlRfRklMRSwgcGVyc2lzdGVudEZpbGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgKi9cbiAgICBnZXRQZXJzaXN0ZW50RmlsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihQdXRGaWxlLktFWV9QRVJTSVNURU5UX0ZJTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtCb29sZWFufSBzeXN0ZW1GaWxlXG4gICAgKiBAcmV0dXJuIHtQdXRGaWxlfVxuICAgICovXG4gICAgc2V0U3lzdGVtRmlsZSAoc3lzdGVtRmlsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihQdXRGaWxlLktFWV9TWVNURU1fRklMRSwgc3lzdGVtRmlsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAqL1xuICAgIGdldFN5c3RlbUZpbGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUHV0RmlsZS5LRVlfU1lTVEVNX0ZJTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtOdW1iZXJ9IG9mZnNldFxuICAgICogQHJldHVybiB7UHV0RmlsZX1cbiAgICAqL1xuICAgIHNldE9mZnNldCAob2Zmc2V0KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFB1dEZpbGUuS0VZX09GRlNFVCwgb2Zmc2V0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBnZXRPZmZzZXQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUHV0RmlsZS5LRVlfT0ZGU0VUKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSBsZW5ndGhcbiAgICAqIEByZXR1cm4ge1B1dEZpbGV9XG4gICAgKi9cbiAgICBzZXRMZW5ndGggKGxlbmd0aCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihQdXRGaWxlLktFWV9MRU5HVEgsIGxlbmd0aCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgZ2V0TGVuZ3RoICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFB1dEZpbGUuS0VZX0xFTkdUSCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge051bWJlcn0gY3JjXG4gICAgKiBAcmV0dXJuIHtQdXRGaWxlfVxuICAgICovXG4gICAgc2V0Q1JDIChjcmMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUHV0RmlsZS5LRVlfQ1JDLCBjcmMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIGdldENSQyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihQdXRGaWxlLktFWV9DUkMpO1xuICAgIH1cbn1cblxuUHV0RmlsZS5LRVlfRklMRV9OQU1FID0gJ3N5bmNGaWxlTmFtZSc7XG5QdXRGaWxlLktFWV9GSUxFX1RZUEUgPSAnZmlsZVR5cGUnO1xuUHV0RmlsZS5LRVlfUEVSU0lTVEVOVF9GSUxFID0gJ3BlcnNpc3RlbnRGaWxlJztcblB1dEZpbGUuS0VZX1NZU1RFTV9GSUxFID0gJ3N5c3RlbUZpbGUnO1xuUHV0RmlsZS5LRVlfT0ZGU0VUID0gJ29mZnNldCc7XG5QdXRGaWxlLktFWV9MRU5HVEggPSAnbGVuZ3RoJztcblB1dEZpbGUuS0VZX0NSQyA9ICdjcmMnO1xuXG5leHBvcnQgeyBQdXRGaWxlIH07XG4iLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5cbmNsYXNzIFB1dEZpbGVSZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5QdXRGaWxlKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtOdW1iZXJ9IHNwYWNlQXZhaWxhYmxlXG4gICAgKiBAcmV0dXJuIHtQdXRGaWxlUmVzcG9uc2V9XG4gICAgKi9cbiAgICBzZXRTcGFjZUF2YWlsYWJsZSAoc3BhY2VBdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUHV0RmlsZVJlc3BvbnNlLktFWV9TUEFDRV9BVkFJTEFCTEUsIHNwYWNlQXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBnZXRTcGFjZUF2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihQdXRGaWxlUmVzcG9uc2UuS0VZX1NQQUNFX0FWQUlMQUJMRSk7XG4gICAgfVxufVxuXG5QdXRGaWxlUmVzcG9uc2UuS0VZX1NQQUNFX0FWQUlMQUJMRSA9ICdzcGFjZUF2YWlsYWJsZSc7XG5cbmV4cG9ydCB7IFB1dEZpbGVSZXNwb25zZSB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBUZXh0RmllbGROYW1lXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBUZXh0RmllbGROYW1lIGV4dGVuZHMgRW51bSB7XG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBtYWluRmllbGQxICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5tYWluRmllbGQxO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBtYWluRmllbGQyICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5tYWluRmllbGQyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBtYWluRmllbGQzICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5tYWluRmllbGQzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBtYWluRmllbGQ0ICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5tYWluRmllbGQ0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBzdGF0dXNCYXIgKCkge1xuICAgICAgICByZXR1cm4gVGV4dEZpZWxkTmFtZS5fTUFQLnN0YXR1c0JhcjtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBtZWRpYUNsb2NrICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5tZWRpYUNsb2NrO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBtZWRpYVRyYWNrICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5tZWRpYVRyYWNrO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCB0ZW1wbGF0ZVRpdGxlICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC50ZW1wbGF0ZVRpdGxlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBhbGVydFRleHQxICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5hbGVydFRleHQxO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBhbGVydFRleHQyICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5hbGVydFRleHQyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBhbGVydFRleHQzICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5hbGVydFRleHQzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBzY3JvbGxhYmxlTWVzc2FnZUJvZHkgKCkge1xuICAgICAgICByZXR1cm4gVGV4dEZpZWxkTmFtZS5fTUFQLnNjcm9sbGFibGVNZXNzYWdlQm9keTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBpbml0aWFsSW50ZXJhY3Rpb25UZXh0ICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5pbml0aWFsSW50ZXJhY3Rpb25UZXh0O1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IG5hdmlnYXRpb25UZXh0MSAoKSB7XG4gICAgICAgIHJldHVybiBUZXh0RmllbGROYW1lLl9NQVAubmF2aWdhdGlvblRleHQxO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IG5hdmlnYXRpb25UZXh0MiAoKSB7XG4gICAgICAgIHJldHVybiBUZXh0RmllbGROYW1lLl9NQVAubmF2aWdhdGlvblRleHQyO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IEVUQSAoKSB7XG4gICAgICAgIHJldHVybiBUZXh0RmllbGROYW1lLl9NQVAuRVRBO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IHRvdGFsRGlzdGFuY2UgKCkge1xuICAgICAgICByZXR1cm4gVGV4dEZpZWxkTmFtZS5fTUFQLnRvdGFsRGlzdGFuY2U7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgYXVkaW9QYXNzVGhydURpc3BsYXlUZXh0MSAoKSB7XG4gICAgICAgIHJldHVybiBUZXh0RmllbGROYW1lLl9NQVAuYXVkaW9QYXNzVGhydURpc3BsYXlUZXh0MTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBhdWRpb1Bhc3NUaHJ1RGlzcGxheVRleHQyICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5hdWRpb1Bhc3NUaHJ1RGlzcGxheVRleHQyO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IHNsaWRlckhlYWRlciAoKSB7XG4gICAgICAgIHJldHVybiBUZXh0RmllbGROYW1lLl9NQVAuc2xpZGVySGVhZGVyO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IHNsaWRlckZvb3RlciAoKSB7XG4gICAgICAgIHJldHVybiBUZXh0RmllbGROYW1lLl9NQVAuc2xpZGVyRm9vdGVyO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IG1lbnVOYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5tZW51TmFtZTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBzZWNvbmRhcnlUZXh0ICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5zZWNvbmRhcnlUZXh0O1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IHRlcnRpYXJ5VGV4dCAoKSB7XG4gICAgICAgIHJldHVybiBUZXh0RmllbGROYW1lLl9NQVAudGVydGlhcnlUZXh0O1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IG1lbnVUaXRsZSAoKSB7XG4gICAgICAgIHJldHVybiBUZXh0RmllbGROYW1lLl9NQVAubWVudVRpdGxlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBsb2NhdGlvbk5hbWUgKCkge1xuICAgICAgICByZXR1cm4gVGV4dEZpZWxkTmFtZS5fTUFQLmxvY2F0aW9uTmFtZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgbG9jYXRpb25EZXNjcmlwdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBUZXh0RmllbGROYW1lLl9NQVAubG9jYXRpb25EZXNjcmlwdGlvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgYWRkcmVzc0xpbmVzICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5hZGRyZXNzTGluZXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IHBob25lTnVtYmVyICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5waG9uZU51bWJlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gVGV4dEZpZWxkTmFtZS5fdmFsdWVGb3JLZXkoa2V5LCBUZXh0RmllbGROYW1lLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBUZXh0RmllbGROYW1lLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgVGV4dEZpZWxkTmFtZS5fTUFQKTtcbiAgICB9XG59XG5cblRleHRGaWVsZE5hbWUuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdtYWluRmllbGQxJzogJ21haW5GaWVsZDEnLFxuICAgICdtYWluRmllbGQyJzogJ21haW5GaWVsZDInLFxuICAgICdtYWluRmllbGQzJzogJ21haW5GaWVsZDMnLFxuICAgICdtYWluRmllbGQ0JzogJ21haW5GaWVsZDQnLFxuICAgICdzdGF0dXNCYXInOiAnc3RhdHVzQmFyJyxcbiAgICAnbWVkaWFDbG9jayc6ICdtZWRpYUNsb2NrJyxcbiAgICAnbWVkaWFUcmFjayc6ICdtZWRpYVRyYWNrJyxcbiAgICAndGVtcGxhdGVUaXRsZSc6ICd0ZW1wbGF0ZVRpdGxlJyxcbiAgICAnYWxlcnRUZXh0MSc6ICdhbGVydFRleHQxJyxcbiAgICAnYWxlcnRUZXh0Mic6ICdhbGVydFRleHQyJyxcbiAgICAnYWxlcnRUZXh0Myc6ICdhbGVydFRleHQzJyxcbiAgICAnc2Nyb2xsYWJsZU1lc3NhZ2VCb2R5JzogJ3Njcm9sbGFibGVNZXNzYWdlQm9keScsXG4gICAgJ2luaXRpYWxJbnRlcmFjdGlvblRleHQnOiAnaW5pdGlhbEludGVyYWN0aW9uVGV4dCcsXG4gICAgJ25hdmlnYXRpb25UZXh0MSc6ICduYXZpZ2F0aW9uVGV4dDEnLFxuICAgICduYXZpZ2F0aW9uVGV4dDInOiAnbmF2aWdhdGlvblRleHQyJyxcbiAgICAnRVRBJzogJ0VUQScsXG4gICAgJ3RvdGFsRGlzdGFuY2UnOiAndG90YWxEaXN0YW5jZScsXG4gICAgJ2F1ZGlvUGFzc1RocnVEaXNwbGF5VGV4dDEnOiAnYXVkaW9QYXNzVGhydURpc3BsYXlUZXh0MScsXG4gICAgJ2F1ZGlvUGFzc1RocnVEaXNwbGF5VGV4dDInOiAnYXVkaW9QYXNzVGhydURpc3BsYXlUZXh0MicsXG4gICAgJ3NsaWRlckhlYWRlcic6ICdzbGlkZXJIZWFkZXInLFxuICAgICdzbGlkZXJGb290ZXInOiAnc2xpZGVyRm9vdGVyJyxcbiAgICAnbWVudU5hbWUnOiAnbWVudU5hbWUnLFxuICAgICdzZWNvbmRhcnlUZXh0JzogJ3NlY29uZGFyeVRleHQnLFxuICAgICd0ZXJ0aWFyeVRleHQnOiAndGVydGlhcnlUZXh0JyxcbiAgICAnbWVudVRpdGxlJzogJ21lbnVUaXRsZScsXG4gICAgJ2xvY2F0aW9uTmFtZSc6ICdsb2NhdGlvbk5hbWUnLFxuICAgICdsb2NhdGlvbkRlc2NyaXB0aW9uJzogJ2xvY2F0aW9uRGVzY3JpcHRpb24nLFxuICAgICdhZGRyZXNzTGluZXMnOiAnYWRkcmVzc0xpbmVzJyxcbiAgICAncGhvbmVOdW1iZXInOiAncGhvbmVOdW1iZXInLFxuXG59KTtcblxuZXhwb3J0IHsgVGV4dEZpZWxkTmFtZSB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gQ2hhcmFjdGVyU2V0XG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBDaGFyYWN0ZXJTZXQgZXh0ZW5kcyBFbnVtIHtcbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IFRZUEUyU0VUICgpIHtcbiAgICAgICAgcmV0dXJuIENoYXJhY3RlclNldC5fTUFQLlRZUEUyU0VUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBUWVBFNVNFVCAoKSB7XG4gICAgICAgIHJldHVybiBDaGFyYWN0ZXJTZXQuX01BUC5UWVBFNVNFVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ0lEMVNFVCAoKSB7XG4gICAgICAgIHJldHVybiBDaGFyYWN0ZXJTZXQuX01BUC5DSUQxU0VUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBDSUQyU0VUICgpIHtcbiAgICAgICAgcmV0dXJuIENoYXJhY3RlclNldC5fTUFQLkNJRDJTRVQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIENoYXJhY3RlclNldC5fdmFsdWVGb3JLZXkoa2V5LCBDaGFyYWN0ZXJTZXQuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIENoYXJhY3RlclNldC5fa2V5Rm9yVmFsdWUodmFsdWUsIENoYXJhY3RlclNldC5fTUFQKTtcbiAgICB9XG59XG5cbkNoYXJhY3RlclNldC5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1RZUEUyU0VUJzogJ1RZUEUyU0VUJyxcbiAgICAnVFlQRTVTRVQnOiAnVFlQRTVTRVQnLFxuICAgICdDSUQxU0VUJzogJ0NJRDFTRVQnLFxuICAgICdDSUQyU0VUJzogJ0NJRDJTRVQnLFxuXG59KTtcblxuZXhwb3J0IHsgQ2hhcmFjdGVyU2V0IH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBUZXh0RmllbGROYW1lIH0gZnJvbSAnLi4vZW51bXMvVGV4dEZpZWxkTmFtZS5qcyc7XG5pbXBvcnQgeyBDaGFyYWN0ZXJTZXQgfSBmcm9tICcuLi9lbnVtcy9DaGFyYWN0ZXJTZXQuanMnO1xuXG5jbGFzcyBUZXh0RmllbGQgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtUZXh0RmllbGROYW1lfSB0ZXh0RmllbGROYW1lXG4gICAgKiBAcmV0dXJuIHtUZXh0RmllbGR9XG4gICAgKi9cbiAgICBzZXRUZXh0RmllbGROYW1lICh0ZXh0RmllbGROYW1lKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFRleHRGaWVsZE5hbWUsIHRleHRGaWVsZE5hbWUpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFRleHRGaWVsZC5LRVlfTkFNRSwgdGV4dEZpZWxkTmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7VGV4dEZpZWxkTmFtZX1cbiAgICAqL1xuICAgIGdldFRleHRGaWVsZE5hbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVGV4dEZpZWxkTmFtZSwgVGV4dEZpZWxkLktFWV9OQU1FKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtDaGFyYWN0ZXJTZXR9IHRleHRGaWVsZE5hbWVcbiAgICAqIEByZXR1cm4ge1RleHRGaWVsZH1cbiAgICAqL1xuICAgIHNldENoYXJhY3RlclNldCAoY2hhcmFjdGVyU2V0KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKENoYXJhY3RlclNldCwgY2hhcmFjdGVyU2V0KTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihUZXh0RmllbGQuS0VZX0NIQVJBQ1RFUl9TRVQsIGNoYXJhY3RlclNldCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7Q2hhcmFjdGVyU2V0fVxuICAgICovXG4gICAgZ2V0Q2hhcmFjdGVyU2V0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KENoYXJhY3RlclNldCwgVGV4dEZpZWxkLktFWV9DSEFSQUNURVJfU0VUKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSB3aWR0aFxuICAgICogQHJldHVybiB7VGV4dEZpZWxkfVxuICAgICovXG4gICAgc2V0V2lkdGggKHdpZHRoKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFRleHRGaWVsZC5LRVlfV0lEVEgsIHdpZHRoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBnZXRXaWR0aCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihUZXh0RmllbGQuS0VZX1dJRFRIKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSByb3dzXG4gICAgKiBAcmV0dXJuIHtUZXh0RmllbGR9XG4gICAgKi9cbiAgICBzZXRSb3dzIChyb3dzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFRleHRGaWVsZC5LRVlfUk9XUywgcm93cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgZ2V0Um93cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihUZXh0RmllbGQuS0VZX1JPV1MpO1xuICAgIH1cbn1cblxuVGV4dEZpZWxkLktFWV9OQU1FID0gJ25hbWUnO1xuVGV4dEZpZWxkLktFWV9DSEFSQUNURVJfU0VUID0gJ2NoYXJhY3RlclNldCc7XG5UZXh0RmllbGQuS0VZX1dJRFRIID0gJ3dpZHRoJztcblRleHRGaWVsZC5LRVlfUk9XUyA9ICdyb3dzJztcblxuZXhwb3J0IHsgVGV4dEZpZWxkIH07XG4iLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcblxuY2xhc3MgSW1hZ2VSZXNvbHV0aW9uIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSByZXNvbHV0aW9uV2lkdGhcbiAgICAqIEByZXR1cm4ge0ltYWdlUmVzb2x1dGlvbn1cbiAgICAqL1xuICAgIHNldFJlc29sdXRpb25XaWR0aCAocmVzb2x1dGlvbldpZHRoKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEltYWdlUmVzb2x1dGlvbi5LRVlfUkVTT0xVVElPTl9XSURUSCwgcmVzb2x1dGlvbldpZHRoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBnZXRSZXNvbHV0aW9uV2lkdGggKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoSW1hZ2VSZXNvbHV0aW9uLktFWV9SRVNPTFVUSU9OX1dJRFRIKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSByZXNvbHV0aW9uSGVpZ2h0XG4gICAgKiBAcmV0dXJuIHtJbWFnZVJlc29sdXRpb259XG4gICAgKi9cbiAgICBzZXRSZXNvbHV0aW9uSGVpZ2h0IChyZXNvbHV0aW9uSGVpZ2h0KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEltYWdlUmVzb2x1dGlvbi5LRVlfUkVTT0xVVElPTl9IRUlHSFQsIHJlc29sdXRpb25IZWlnaHQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIGdldFJlc29sdXRpb25IZWlnaHQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoSW1hZ2VSZXNvbHV0aW9uLktFWV9SRVNPTFVUSU9OX0hFSUdIVCk7XG4gICAgfVxufVxuXG5JbWFnZVJlc29sdXRpb24uS0VZX1JFU09MVVRJT05fV0lEVEggPSAncmVzb2x1dGlvbldpZHRoJztcbkltYWdlUmVzb2x1dGlvbi5LRVlfUkVTT0xVVElPTl9IRUlHSFQgPSAncmVzb2x1dGlvbkhlaWdodCc7XG5cbmV4cG9ydCB7IEltYWdlUmVzb2x1dGlvbiB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBJbWFnZUZpZWxkTmFtZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgSW1hZ2VGaWVsZE5hbWUgZXh0ZW5kcyBFbnVtIHtcbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IHNvZnRCdXR0b25JbWFnZSAoKSB7XG4gICAgICAgIHJldHVybiBJbWFnZUZpZWxkTmFtZS5fTUFQLnNvZnRCdXR0b25JbWFnZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgY2hvaWNlSW1hZ2UgKCkge1xuICAgICAgICByZXR1cm4gSW1hZ2VGaWVsZE5hbWUuX01BUC5jaG9pY2VJbWFnZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgY2hvaWNlU2Vjb25kYXJ5SW1hZ2UgKCkge1xuICAgICAgICByZXR1cm4gSW1hZ2VGaWVsZE5hbWUuX01BUC5jaG9pY2VTZWNvbmRhcnlJbWFnZTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCB2ckhlbHBJdGVtICgpIHtcbiAgICAgICAgcmV0dXJuIEltYWdlRmllbGROYW1lLl9NQVAudnJIZWxwSXRlbTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCB0dXJuSWNvbiAoKSB7XG4gICAgICAgIHJldHVybiBJbWFnZUZpZWxkTmFtZS5fTUFQLnR1cm5JY29uO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IG1lbnVJY29uICgpIHtcbiAgICAgICAgcmV0dXJuIEltYWdlRmllbGROYW1lLl9NQVAubWVudUljb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IGNtZEljb24gKCkge1xuICAgICAgICByZXR1cm4gSW1hZ2VGaWVsZE5hbWUuX01BUC5jbWRJY29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBhcHBJY29uICgpIHtcbiAgICAgICAgcmV0dXJuIEltYWdlRmllbGROYW1lLl9NQVAuYXBwSWNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgZ3JhcGhpYyAoKSB7XG4gICAgICAgIHJldHVybiBJbWFnZUZpZWxkTmFtZS5fTUFQLmdyYXBoaWM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IHNlY29uZGFyeUdyYXBoaWMgKCkge1xuICAgICAgICByZXR1cm4gSW1hZ2VGaWVsZE5hbWUuX01BUC5zZWNvbmRhcnlHcmFwaGljO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBzaG93Q29uc3RhbnRUQlRJY29uICgpIHtcbiAgICAgICAgcmV0dXJuIEltYWdlRmllbGROYW1lLl9NQVAuc2hvd0NvbnN0YW50VEJUSWNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgc2hvd0NvbnN0YW50VEJUTmV4dFR1cm5JY29uICgpIHtcbiAgICAgICAgcmV0dXJuIEltYWdlRmllbGROYW1lLl9NQVAuc2hvd0NvbnN0YW50VEJUTmV4dFR1cm5JY29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBsb2NhdGlvbkltYWdlICgpIHtcbiAgICAgICAgcmV0dXJuIEltYWdlRmllbGROYW1lLl9NQVAubG9jYXRpb25JbWFnZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgYWxlcnRJY29uICgpIHtcbiAgICAgICAgcmV0dXJuIEltYWdlRmllbGROYW1lLl9NQVAuYWxlcnRJY29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgKiBAcGFyYW0gdmFsdWUgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBJbWFnZUZpZWxkTmFtZS5fdmFsdWVGb3JLZXkoa2V5LCBJbWFnZUZpZWxkTmFtZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gSW1hZ2VGaWVsZE5hbWUuX2tleUZvclZhbHVlKHZhbHVlLCBJbWFnZUZpZWxkTmFtZS5fTUFQKTtcbiAgICB9XG59XG5cbkltYWdlRmllbGROYW1lLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnc29mdEJ1dHRvbkltYWdlJzogJ3NvZnRCdXR0b25JbWFnZScsXG4gICAgJ2Nob2ljZUltYWdlJzogJ2Nob2ljZUltYWdlJyxcbiAgICAnY2hvaWNlU2Vjb25kYXJ5SW1hZ2UnOiAnY2hvaWNlU2Vjb25kYXJ5SW1hZ2UnLFxuICAgICd2ckhlbHBJdGVtJzogJ3ZySGVscEl0ZW0nLFxuICAgICd0dXJuSWNvbic6ICd0dXJuSWNvbicsXG4gICAgJ21lbnVJY29uJzogJ21lbnVJY29uJyxcbiAgICAnY21kSWNvbic6ICdjbWRJY29uJyxcbiAgICAnYXBwSWNvbic6ICdhcHBJY29uJyxcbiAgICAnZ3JhcGhpYyc6ICdncmFwaGljJyxcbiAgICAnc2Vjb25kYXJ5R3JhcGhpYyc6ICdzZWNvbmRhcnlHcmFwaGljJyxcbiAgICAnc2hvd0NvbnN0YW50VEJUSWNvbic6ICdzaG93Q29uc3RhbnRUQlRJY29uJyxcbiAgICAnc2hvd0NvbnN0YW50VEJUTmV4dFR1cm5JY29uJzogJ3Nob3dDb25zdGFudFRCVE5leHRUdXJuSWNvbicsXG4gICAgJ2xvY2F0aW9uSW1hZ2UnOiAnbG9jYXRpb25JbWFnZScsXG4gICAgJ2FsZXJ0SWNvbic6ICdhbGVydEljb24nLFxuXG59KTtcblxuZXhwb3J0IHsgSW1hZ2VGaWVsZE5hbWUgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IEltYWdlUmVzb2x1dGlvbiB9IGZyb20gJy4vSW1hZ2VSZXNvbHV0aW9uLmpzJztcbmltcG9ydCB7IEZpbGVUeXBlIH0gZnJvbSAnLi4vZW51bXMvRmlsZVR5cGUuanMnO1xuaW1wb3J0IHsgSW1hZ2VGaWVsZE5hbWUgfSBmcm9tICcuLi9lbnVtcy9JbWFnZUZpZWxkTmFtZS5qcyc7XG5cbmNsYXNzIEltYWdlRmllbGQgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtJbWFnZUZpZWxkTmFtZX0gaW1hZ2VGaWVsZE5hbWVcbiAgICAqIEByZXR1cm4ge0ltYWdlRmllbGR9XG4gICAgKi9cbiAgICBzZXRJbWFnZUZpZWxkTmFtZSAoaW1hZ2VGaWVsZE5hbWUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoSW1hZ2VGaWVsZE5hbWUsIGltYWdlRmllbGROYW1lKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihJbWFnZUZpZWxkLktFWV9OQU1FLCBpbWFnZUZpZWxkTmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7SW1hZ2VGaWVsZE5hbWV9XG4gICAgKi9cbiAgICBnZXRJbWFnZUZpZWxkTmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChJbWFnZUZpZWxkTmFtZSwgSW1hZ2VGaWVsZC5LRVlfTkFNRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0ZpbGVUeXBlW119IGltYWdlVHlwZVN1cHBvcnRlZFxuICAgICogQHJldHVybiB7SW1hZ2VGaWVsZH1cbiAgICAqL1xuICAgIHNldEltYWdlVHlwZVN1cHBvcnRlZCAoaW1hZ2VUeXBlU3VwcG9ydGVkKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEZpbGVUeXBlLCBpbWFnZVR5cGVTdXBwb3J0ZWQsIHRydWUpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEltYWdlRmllbGQuS0VZX0lNQUdFX1RZUEVfU1VQUE9SVEVELCBpbWFnZVR5cGVTdXBwb3J0ZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0ZpbGVUeXBlfVxuICAgICovXG4gICAgZ2V0SW1hZ2VUeXBlU3VwcG9ydGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEZpbGVUeXBlLCBJbWFnZUZpZWxkLktFWV9JTUFHRV9UWVBFX1NVUFBPUlRFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0ltYWdlUmVzb2x1dGlvbn0gaW1hZ2VSZXNvbHV0aW9uXG4gICAgKiBAcmV0dXJuIHtJbWFnZUZpZWxkfVxuICAgICovXG4gICAgc2V0SW1hZ2VSZXNvbHV0aW9uIChpbWFnZVJlc29sdXRpb24pIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoSW1hZ2VSZXNvbHV0aW9uLCBpbWFnZVJlc29sdXRpb24pO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEltYWdlRmllbGQuS0VZX0lNQUdFX1JFU09MVVRJT04sIGltYWdlUmVzb2x1dGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7SW1hZ2VSZXNvbHV0aW9ufVxuICAgICovXG4gICAgZ2V0SW1hZ2VSZXNvbHV0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEltYWdlUmVzb2x1dGlvbiwgSW1hZ2VGaWVsZC5LRVlfSU1BR0VfUkVTT0xVVElPTik7XG4gICAgfVxufVxuXG5JbWFnZUZpZWxkLktFWV9OQU1FID0gJ25hbWUnO1xuSW1hZ2VGaWVsZC5LRVlfSU1BR0VfVFlQRV9TVVBQT1JURUQgPSAnaW1hZ2VUeXBlU3VwcG9ydGVkJztcbkltYWdlRmllbGQuS0VZX0lNQUdFX1JFU09MVVRJT04gPSAnaW1hZ2VSZXNvbHV0aW9uJztcblxuZXhwb3J0IHsgSW1hZ2VGaWVsZCB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5cbmNsYXNzIFRvdWNoRXZlbnRDYXBhYmlsaXRpZXMgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0Jvb2xlYW59IHByZXNzQXZhaWxhYmxlXG4gICAgKiBAcmV0dXJuIHtUb3VjaEV2ZW50Q2FwYWJpbGl0aWVzfVxuICAgICovXG4gICAgc2V0UHJlc3NBdmFpbGFibGUgKHByZXNzQXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFRvdWNoRXZlbnRDYXBhYmlsaXRpZXMuS0VZX1BSRVNTX0FWQUlMQUJMRSwgcHJlc3NBdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgKi9cbiAgICBnZXRQcmVzc0F2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihUb3VjaEV2ZW50Q2FwYWJpbGl0aWVzLktFWV9QUkVTU19BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtCb29sZWFufSBtdWx0aVRvdWNoQXZhaWxhYmxlXG4gICAgKiBAcmV0dXJuIHtUb3VjaEV2ZW50Q2FwYWJpbGl0aWVzfVxuICAgICovXG4gICAgc2V0TXVsdGlUb3VjaEF2YWlsYWJsZSAobXVsdGlUb3VjaEF2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihUb3VjaEV2ZW50Q2FwYWJpbGl0aWVzLktFWV9NVUxUSV9UT1VDSF9BVkFJTEFCTEUsIG11bHRpVG91Y2hBdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgKi9cbiAgICBnZXRNdWx0aVRvdWNoQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFRvdWNoRXZlbnRDYXBhYmlsaXRpZXMuS0VZX01VTFRJX1RPVUNIX0FWQUlMQUJMRSk7XG4gICAgfVxuXG5cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtCb29sZWFufSBkb3VibGVQcmVzc0F2YWlsYWJsZVxuICAgICogQHJldHVybiB7VG91Y2hFdmVudENhcGFiaWxpdGllc31cbiAgICAqL1xuICAgIHNldERvdWJsZVByZXNzQXZhaWxhYmxlIChkb3VibGVQcmVzc0F2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihUb3VjaEV2ZW50Q2FwYWJpbGl0aWVzLktFWV9ET1VCTEVfUFJFU1NfQVZBSUxBQkxFLCBkb3VibGVQcmVzc0F2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAqL1xuICAgIGdldERvdWJsZVByZXNzQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFRvdWNoRXZlbnRDYXBhYmlsaXRpZXMuS0VZX0RPVUJMRV9QUkVTU19BVkFJTEFCTEUpO1xuICAgIH1cbn1cblxuVG91Y2hFdmVudENhcGFiaWxpdGllcy5LRVlfUFJFU1NfQVZBSUxBQkxFID0gJ3ByZXNzQXZhaWxhYmxlJztcblRvdWNoRXZlbnRDYXBhYmlsaXRpZXMuS0VZX01VTFRJX1RPVUNIX0FWQUlMQUJMRSA9ICdtdWx0aVRvdWNoQXZhaWxhYmxlJztcblRvdWNoRXZlbnRDYXBhYmlsaXRpZXMuS0VZX0RPVUJMRV9QUkVTU19BVkFJTEFCTEUgPSAnZG91YmxlUHJlc3NBdmFpbGFibGUnO1xuXG5leHBvcnQgeyBUb3VjaEV2ZW50Q2FwYWJpbGl0aWVzIH07XG4iLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IEltYWdlUmVzb2x1dGlvbiB9IGZyb20gJy4vSW1hZ2VSZXNvbHV0aW9uLmpzJztcbmltcG9ydCB7IFRvdWNoRXZlbnRDYXBhYmlsaXRpZXMgfSBmcm9tICcuL1RvdWNoRXZlbnRDYXBhYmlsaXRpZXMuanMnO1xuXG5jbGFzcyBTY3JlZW5QYXJhbXMgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0ltYWdlUmVzb2x1dGlvbn0gcmVzb2x1dGlvblxuICAgICogQHJldHVybiB7U2NyZWVuUGFyYW1zfVxuICAgICovXG4gICAgc2V0UmVzb2x1dGlvbiAocmVzb2x1dGlvbikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShJbWFnZVJlc29sdXRpb24sIHJlc29sdXRpb24pO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNjcmVlblBhcmFtcy5LRVlfUkVTT0xVVElPTiwgcmVzb2x1dGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7SW1hZ2VSZXNvbHV0aW9ufVxuICAgICovXG4gICAgZ2V0UmVzb2x1dGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChJbWFnZVJlc29sdXRpb24sIFNjcmVlblBhcmFtcy5LRVlfUkVTT0xVVElPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1RvdWNoRXZlbnRDYXBhYmlsaXRpZXN9IHRvdWNoRXZlbnRDYXBhYmlsaXRpZXNcbiAgICAqIEByZXR1cm4ge1NjcmVlblBhcmFtc31cbiAgICAqL1xuICAgIHNldFRvdWNoRXZlbnRBdmFpbGFibGUgKHRvdWNoRXZlbnRDYXBhYmlsaXRpZXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVG91Y2hFdmVudENhcGFiaWxpdGllcywgdG91Y2hFdmVudENhcGFiaWxpdGllcyk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2NyZWVuUGFyYW1zLktFWV9UT1VDSF9FVkVOVF9BVkFJTEFCTEUsIHRvdWNoRXZlbnRDYXBhYmlsaXRpZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1RvdWNoRXZlbnRDYXBhYmlsaXRpZXN9XG4gICAgKi9cbiAgICBnZXRUb3VjaEV2ZW50QXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFRvdWNoRXZlbnRDYXBhYmlsaXRpZXMsIFNjcmVlblBhcmFtcy5LRVlfVE9VQ0hfRVZFTlRfQVZBSUxBQkxFKTtcbiAgICB9XG59XG5cblNjcmVlblBhcmFtcy5LRVlfUkVTT0xVVElPTiA9ICdyZXNvbHV0aW9uJztcblNjcmVlblBhcmFtcy5LRVlfVE9VQ0hfRVZFTlRfQVZBSUxBQkxFID0gJ3RvdWNoRXZlbnRBdmFpbGFibGUnO1xuXG5leHBvcnQgeyBTY3JlZW5QYXJhbXMgfTtcbiIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gRGlzcGxheVR5cGVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIERpc3BsYXlUeXBlIGV4dGVuZHMgRW51bSB7XG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENJRCAoKSB7XG4gICAgICAgIHJldHVybiBEaXNwbGF5VHlwZS5fTUFQLkNJRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBUWVBFMiAoKSB7XG4gICAgICAgIHJldHVybiBEaXNwbGF5VHlwZS5fTUFQLlRZUEUyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFRZUEU1ICgpIHtcbiAgICAgICAgcmV0dXJuIERpc3BsYXlUeXBlLl9NQVAuVFlQRTU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTkdOICgpIHtcbiAgICAgICAgcmV0dXJuIERpc3BsYXlUeXBlLl9NQVAuTkdOO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEdFTjJfOF9ETUEgKCkge1xuICAgICAgICByZXR1cm4gRGlzcGxheVR5cGUuX01BUC5HRU4yXzhfRE1BO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEdFTjJfNl9ETUEgKCkge1xuICAgICAgICByZXR1cm4gRGlzcGxheVR5cGUuX01BUC5HRU4yXzZfRE1BO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE1GRDMgKCkge1xuICAgICAgICByZXR1cm4gRGlzcGxheVR5cGUuX01BUC5NRkQzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE1GRDQgKCkge1xuICAgICAgICByZXR1cm4gRGlzcGxheVR5cGUuX01BUC5NRkQ0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE1GRDUgKCkge1xuICAgICAgICByZXR1cm4gRGlzcGxheVR5cGUuX01BUC5NRkQ1O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEdFTjNfOF9JTkNIICgpIHtcbiAgICAgICAgcmV0dXJuIERpc3BsYXlUeXBlLl9NQVAuR0VOM184X0lOQ0g7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0RMX0dFTkVSSUMgKCkge1xuICAgICAgICByZXR1cm4gRGlzcGxheVR5cGUuX01BUC5TRExfR0VORVJJQztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gRGlzcGxheVR5cGUuX3ZhbHVlRm9yS2V5KGtleSwgRGlzcGxheVR5cGUuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIERpc3BsYXlUeXBlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgRGlzcGxheVR5cGUuX01BUCk7XG4gICAgfVxufVxuXG5EaXNwbGF5VHlwZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0NJRCc6ICdDSUQnLFxuICAgICdUWVBFMic6ICdUWVBFMicsXG4gICAgJ1RZUEU1JzogJ1RZUEU1JyxcbiAgICAnTkdOJzogJ05HTicsXG4gICAgJ0dFTjJfOF9ETUEnOiAnR0VOMl84X0RNQScsXG4gICAgJ0dFTjJfNl9ETUEnOiAnR0VOMl82X0RNQScsXG4gICAgJ01GRDMnOiAnTUZEMycsXG4gICAgJ01GRDQnOiAnTUZENCcsXG4gICAgJ1RFU1RJTkcnOiAnVEVTVElORycsXG4gICAgJ01GRDUnOiAnTUZENScsXG4gICAgJ0dFTjNfOF9JTkNIJzogJ0dFTjNfOC1JTkNIJyxcbiAgICAnU0RMX0dFTkVSSUMnOiAnU0RMX0dFTkVSSUMnLFxufSk7XG5cbmV4cG9ydCB7IERpc3BsYXlUeXBlIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBNZWRpYUNsb2NrRm9ybWF0XG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBNZWRpYUNsb2NrRm9ybWF0IGV4dGVuZHMgRW51bSB7XG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENMT0NLMSAoKSB7XG4gICAgICAgIHJldHVybiBNZWRpYUNsb2NrRm9ybWF0Ll9NQVAuQ0xPQ0sxO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENMT0NLMiAoKSB7XG4gICAgICAgIHJldHVybiBNZWRpYUNsb2NrRm9ybWF0Ll9NQVAuQ0xPQ0syO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENMT0NLMyAoKSB7XG4gICAgICAgIHJldHVybiBNZWRpYUNsb2NrRm9ybWF0Ll9NQVAuQ0xPQ0szO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENMT0NLVEVYVDEgKCkge1xuICAgICAgICByZXR1cm4gTWVkaWFDbG9ja0Zvcm1hdC5fTUFQLkNMT0NLVEVYVDE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ0xPQ0tURVhUMiAoKSB7XG4gICAgICAgIHJldHVybiBNZWRpYUNsb2NrRm9ybWF0Ll9NQVAuQ0xPQ0tURVhUMjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDTE9DS1RFWFQzICgpIHtcbiAgICAgICAgcmV0dXJuIE1lZGlhQ2xvY2tGb3JtYXQuX01BUC5DTE9DS1RFWFQzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENMT0NLVEVYVDQgKCkge1xuICAgICAgICByZXR1cm4gTWVkaWFDbG9ja0Zvcm1hdC5fTUFQLkNMT0NLVEVYVDQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIE1lZGlhQ2xvY2tGb3JtYXQuX3ZhbHVlRm9yS2V5KGtleSwgTWVkaWFDbG9ja0Zvcm1hdC5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gTWVkaWFDbG9ja0Zvcm1hdC5fa2V5Rm9yVmFsdWUodmFsdWUsIE1lZGlhQ2xvY2tGb3JtYXQuX01BUCk7XG4gICAgfVxufVxuXG5NZWRpYUNsb2NrRm9ybWF0Ll9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnQ0xPQ0sxJzogJ0NMT0NLMScsXG4gICAgJ0NMT0NLMic6ICdDTE9DSzInLFxuICAgICdDTE9DSzMnOiAnQ0xPQ0szJyxcbiAgICAnQ0xPQ0tURVhUMSc6ICdDTE9DS1RFWFQxJyxcbiAgICAnQ0xPQ0tURVhUMic6ICdDTE9DS1RFWFQyJyxcbiAgICAnQ0xPQ0tURVhUMyc6ICdDTE9DS1RFWFQzJyxcbiAgICAnQ0xPQ0tURVhUNCc6ICdDTE9DS1RFWFQ0Jyxcbn0pO1xuXG5leHBvcnQgeyBNZWRpYUNsb2NrRm9ybWF0IH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBUZXh0RmllbGQgfSBmcm9tICcuL1RleHRGaWVsZC5qcyc7XG5pbXBvcnQgeyBJbWFnZUZpZWxkIH0gZnJvbSAnLi9JbWFnZUZpZWxkLmpzJztcbmltcG9ydCB7IFNjcmVlblBhcmFtcyB9IGZyb20gJy4vU2NyZWVuUGFyYW1zLmpzJztcbmltcG9ydCB7IERpc3BsYXlUeXBlIH0gZnJvbSAnLi4vZW51bXMvRGlzcGxheVR5cGUuanMnO1xuaW1wb3J0IHsgTWVkaWFDbG9ja0Zvcm1hdCB9IGZyb20gJy4uL2VudW1zL01lZGlhQ2xvY2tGb3JtYXQuanMnO1xuXG5jbGFzcyBEaXNwbGF5Q2FwYWJpbGl0aWVzIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7RGlzcGxheVR5cGV9IGRpc3BsYXlUeXBlXG4gICAgKiBAcmV0dXJuIHtEaXNwbGF5Q2FwYWJpbGl0aWVzfVxuICAgICovXG4gICAgc2V0RGlzcGxheVR5cGUgKGRpc3BsYXlUeXBlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKERpc3BsYXlUeXBlLCBkaXNwbGF5VHlwZSk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGlzcGxheUNhcGFiaWxpdGllcy5LRVlfRElTUExBWV9UWVBFLCBkaXNwbGF5VHlwZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7RGlzcGxheVR5cGV9XG4gICAgKi9cbiAgICBnZXREaXNwbGF5VHlwZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChEaXNwbGF5VHlwZSwgRGlzcGxheUNhcGFiaWxpdGllcy5LRVlfRElTUExBWV9UWVBFKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IGRpc3BsYXlOYW1lXG4gICAgKiBAcmV0dXJuIHtEaXNwbGF5Q2FwYWJpbGl0aWVzfVxuICAgICovXG4gICAgc2V0RGlzcGxheU5hbWUgKGRpc3BsYXlOYW1lKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKERpc3BsYXlDYXBhYmlsaXRpZXMuS0VZX0RJU1BMQVlfTkFNRSwgZGlzcGxheU5hbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIGdldERpc3BsYXlOYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKERpc3BsYXlDYXBhYmlsaXRpZXMuS0VZX0RJU1BMQVlfTkFNRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0FycmF5PFRleHRGaWVsZD59IHRleHRGaWVsZHNcbiAgICAqIEByZXR1cm4ge0Rpc3BsYXlDYXBhYmlsaXRpZXN9XG4gICAgKi9cbiAgICBzZXRUZXh0RmllbGRzICh0ZXh0RmllbGRzKSB7XG4gICAgICAgIC8vIFRPRE8gbWFrZSB3b3JrIHdpdGggYXJyYXlzXG4gICAgICAgIC8vIHRoaXMudmFsaWRhdGVUeXBlKFRleHRGaWVsZCwgdGV4dEZpZWxkcyk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGlzcGxheUNhcGFiaWxpdGllcy5LRVlfVEVYVF9GSUVMRFMsIHRleHRGaWVsZHMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0FycmF5PFRleHRGaWVsZD59XG4gICAgKi9cbiAgICBnZXRUZXh0RmllbGRzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFRleHRGaWVsZCwgRGlzcGxheUNhcGFiaWxpdGllcy5LRVlfVEVYVF9GSUVMRFMpO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0FycmF5PEltYWdlRmllbGQ+fSBpbWFnZUZpZWxkc1xuICAgICogQHJldHVybiB7RGlzcGxheUNhcGFiaWxpdGllc31cbiAgICAqL1xuICAgIHNldEltYWdlRmllbGRzIChpbWFnZUZpZWxkcykge1xuICAgICAgICAvLyBUT0RPIG1ha2Ugd29yayB3aXRoIGFycmF5c1xuICAgICAgICAvLyB0aGlzLnZhbGlkYXRlVHlwZShJbWFnZUZpZWxkLCBpbWFnZUZpZWxkcyk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGlzcGxheUNhcGFiaWxpdGllcy5LRVlfSU1BR0VfRklFTERTLCBpbWFnZUZpZWxkcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7QXJyYXk8SW1hZ2VGaWVsZD59XG4gICAgKi9cbiAgICBnZXRJbWFnZUZpZWxkcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChJbWFnZUZpZWxkLCBEaXNwbGF5Q2FwYWJpbGl0aWVzLktFWV9JTUFHRV9GSUVMRFMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtBcnJheTxNZWRpYUNsb2NrRm9ybWF0Pn0gbWVkaWFDbG9ja0Zvcm1hdHNcbiAgICAqIEByZXR1cm4ge0Rpc3BsYXlDYXBhYmlsaXRpZXN9XG4gICAgKi9cbiAgICBzZXRNZWRpYUNsb2NrRm9ybWF0cyAobWVkaWFDbG9ja0Zvcm1hdHMpIHtcbiAgICAgICAgLy8gVE9ETyBtYWtlIHdvcmsgd2l0aCBhcnJheXNcbiAgICAgICAgLy8gdGhpcy52YWxpZGF0ZVR5cGUoSW1hZ2VGaWVsZCwgbWVkaWFDbG9ja0Zvcm1hdHMpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKERpc3BsYXlDYXBhYmlsaXRpZXMuS0VZX01FRElBX0NMT0NLX0ZPUk1BVFMsIG1lZGlhQ2xvY2tGb3JtYXRzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtBcnJheTxNZWRpYUNsb2NrRm9ybWF0Pn1cbiAgICAqL1xuICAgIGdldE1lZGlhQ2xvY2tGb3JtYXRzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KE1lZGlhQ2xvY2tGb3JtYXQsIERpc3BsYXlDYXBhYmlsaXRpZXMuS0VZX01FRElBX0NMT0NLX0ZPUk1BVFMpO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0Jvb2xlYW59IGdyYXBoaWNTdXBwb3J0ZWRcbiAgICAqIEByZXR1cm4ge0Rpc3BsYXlDYXBhYmlsaXRpZXN9XG4gICAgKi9cbiAgICBzZXRHcmFwaGljc1N1cHBvcnRlZCAoZ3JhcGhpY1N1cHBvcnRlZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihEaXNwbGF5Q2FwYWJpbGl0aWVzLktFWV9HUkFQSElDU19TVVBQT1JURUQsIGdyYXBoaWNTdXBwb3J0ZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgKi9cbiAgICBnZXRHcmFwaGljc1N1cHBvcnRlZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihEaXNwbGF5Q2FwYWJpbGl0aWVzLktFWV9HUkFQSElDU19TVVBQT1JURUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtBcnJheTxTdHJpbmc+fSB0ZW1wbGF0ZXNBdmFpbGFibGVcbiAgICAqIEByZXR1cm4ge0Rpc3BsYXlDYXBhYmlsaXRpZXN9XG4gICAgKi9cbiAgICBzZXRUZW1wbGF0ZXNBdmFpbGFibGUgKHRlbXBsYXRlc0F2YWlsYWJsZSkge1xuICAgICAgICAvLyBUT0RPIG1ha2Ugd29yayB3aXRoIGFycmF5c1xuICAgICAgICAvLyB0aGlzLnZhbGlkYXRlVHlwZShTdHJpbmcsIHRlbXBsYXRlc0F2YWlsYWJsZSk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGlzcGxheUNhcGFiaWxpdGllcy5LRVlfVEVNUExBVEVTX0FWQUlMQUJMRSwgdGVtcGxhdGVzQXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtBcnJheTxTdHJpbmc+fVxuICAgICovXG4gICAgZ2V0VGVtcGxhdGVzQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKERpc3BsYXlDYXBhYmlsaXRpZXMuS0VZX1RFTVBMQVRFU19BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTY3JlZW5QYXJhbXN9IHNjcmVlblBhcmFtc1xuICAgICogQHJldHVybiB7RGlzcGxheUNhcGFiaWxpdGllc31cbiAgICAqL1xuICAgIHNldFNjcmVlblBhcmFtcyAoc2NyZWVuUGFyYW1zKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFNjcmVlblBhcmFtcywgc2NyZWVuUGFyYW1zKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihEaXNwbGF5Q2FwYWJpbGl0aWVzLktFWV9TQ1JFRU5fUEFSQU1TLCBzY3JlZW5QYXJhbXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1NjcmVlblBhcmFtc31cbiAgICAqL1xuICAgIGdldFNjcmVlblBhcmFtcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChTY3JlZW5QYXJhbXMsIERpc3BsYXlDYXBhYmlsaXRpZXMuS0VZX1NDUkVFTl9QQVJBTVMpO1xuICAgIH1cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7QXJyYXk8TnVtYmVyPn0gbnVtQ3VzdG9tUHJlc2V0c0F2YWlsYWJsZVxuICAgICogQHJldHVybiB7RGlzcGxheUNhcGFiaWxpdGllc31cbiAgICAqL1xuICAgIHNldE51bUN1c3RvbVByZXNldHNBdmFpbGFibGUgKG51bUN1c3RvbVByZXNldHNBdmFpbGFibGUpIHtcbiAgICAgICAgLy8gVE9ETyBtYWtlIHdvcmsgd2l0aCBhcnJheXNcbiAgICAgICAgLy8gdGhpcy52YWxpZGF0ZVR5cGUoTnVtYmVyLCBudW1DdXN0b21QcmVzZXRzQXZhaWxhYmxlKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihEaXNwbGF5Q2FwYWJpbGl0aWVzLktFWV9OVU1fQ1VTVE9NX1BSRVNFVFNfQVZBSUxBQkxFLCBudW1DdXN0b21QcmVzZXRzQXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtBcnJheTxOdW1iZXI+fVxuICAgICovXG4gICAgZ2V0TnVtQ3VzdG9tUHJlc2V0c0F2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihEaXNwbGF5Q2FwYWJpbGl0aWVzLktFWV9OVU1fQ1VTVE9NX1BSRVNFVFNfQVZBSUxBQkxFKTtcbiAgICB9XG59XG5cbkRpc3BsYXlDYXBhYmlsaXRpZXMuS0VZX0RJU1BMQVlfVFlQRSA9ICdkaXNwbGF5VHlwZSc7XG5EaXNwbGF5Q2FwYWJpbGl0aWVzLktFWV9ESVNQTEFZX05BTUUgPSAnZGlzcGxheU5hbWUnO1xuRGlzcGxheUNhcGFiaWxpdGllcy5LRVlfVEVYVF9GSUVMRFMgPSAndGV4dEZpZWxkcyc7XG5EaXNwbGF5Q2FwYWJpbGl0aWVzLktFWV9JTUFHRV9GSUVMRFMgPSAnaW1hZ2VGaWVsZHMnO1xuRGlzcGxheUNhcGFiaWxpdGllcy5LRVlfTUVESUFfQ0xPQ0tfRk9STUFUUyA9ICdtZWRpYUNsb2NrRm9ybWF0cyc7XG5EaXNwbGF5Q2FwYWJpbGl0aWVzLktFWV9HUkFQSElDU19TVVBQT1JURUQgPSAnZ3JhcGhpY1N1cHBvcnRlZCc7XG5EaXNwbGF5Q2FwYWJpbGl0aWVzLktFWV9URU1QTEFURVNfQVZBSUxBQkxFID0gJ3RlbXBsYXRlc0F2YWlsYWJsZSc7XG5EaXNwbGF5Q2FwYWJpbGl0aWVzLktFWV9TQ1JFRU5fUEFSQU1TID0gJ3NjcmVlblBhcmFtcyc7XG5EaXNwbGF5Q2FwYWJpbGl0aWVzLktFWV9OVU1fQ1VTVE9NX1BSRVNFVFNfQVZBSUxBQkxFID0gJ251bUN1c3RvbVByZXNldHNBdmFpbGFibGUnO1xuXG5leHBvcnQgeyBEaXNwbGF5Q2FwYWJpbGl0aWVzIH07XG4iLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcblxuY2xhc3MgR3JpZCBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge051bWJlcn0gY29sdW1uXG4gICAgKiBAcmV0dXJuIHtHcmlkfVxuICAgICovXG4gICAgc2V0Q29sdW1uIChjb2x1bW4pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR3JpZC5LRVlfQ09MVU1OLCBjb2x1bW4pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIGdldENvbHVtbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHcmlkLktFWV9DT0xVTU4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtOdW1iZXJ9IHJvd1xuICAgICogQHJldHVybiB7R3JpZH1cbiAgICAqL1xuICAgIHNldFJvdyAocm93KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdyaWQuS0VZX1JPVywgcm93KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBnZXRSb3cgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR3JpZC5LRVlfUk9XKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSBsZXZlbFxuICAgICogQHJldHVybiB7R3JpZH1cbiAgICAqL1xuICAgIHNldExldmVsIChsZXZlbCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHcmlkLktFWV9MRVZFTCwgbGV2ZWwpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIGdldExldmVsICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdyaWQuS0VZX0xFVkVMKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSBjb2x1bW5TcGFuXG4gICAgKiBAcmV0dXJuIHtHcmlkfVxuICAgICovXG4gICAgc2V0Q29sdW1uU3BhbiAoY29sdW1uU3Bhbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHcmlkLktFWV9DT0xVTU5fU1BBTiwgY29sdW1uU3Bhbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgZ2V0Q29sdW1uU3BhbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHcmlkLktFWV9DT0xVTU5fU1BBTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge051bWJlcn0gcm93U3BhblxuICAgICogQHJldHVybiB7R3JpZH1cbiAgICAqL1xuICAgIHNldFJvd1NwYW4gKHJvd1NwYW4pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR3JpZC5LRVlfUk9XX1NQQU4sIHJvd1NwYW4pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIGdldFJvd1NwYW4gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR3JpZC5LRVlfUk9XX1NQQU4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtOdW1iZXJ9IGxldmVsU3BhblxuICAgICogQHJldHVybiB7R3JpZH1cbiAgICAqL1xuICAgIHNldExldmVsU3BhbiAobGV2ZWxTcGFuKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdyaWQuS0VZX0xFVkVMX1NQQU4sIGxldmVsU3Bhbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgZ2V0TGV2ZWxTcGFuICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdyaWQuS0VZX0xFVkVMX1NQQU4pO1xuICAgIH1cbn1cblxuR3JpZC5LRVlfQ09MVU1OID0gJ2NvbCc7XG5HcmlkLktFWV9ST1cgPSAncm93JztcbkdyaWQuS0VZX0xFVkVMID0gJ2xldmVsJztcbkdyaWQuS0VZX0NPTFVNTl9TUEFOID0gJ2NvbHNwYW4nO1xuR3JpZC5LRVlfUk9XX1NQQU4gPSAncm93c3Bhbic7XG5HcmlkLktFWV9MRVZFTF9TUEFOID0gJ2xldmVsc3Bhbic7XG5cbmV4cG9ydCB7IEdyaWQgfTtcbiIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgR3JpZCB9IGZyb20gJy4vR3JpZC5qcyc7XG5cbmNsYXNzIE1vZHVsZUluZm8gZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IG1vZHVsZUlkXG4gICAgKiBAcmV0dXJuIHtNb2R1bGVJbmZvfVxuICAgICovXG4gICAgc2V0TW9kdWxlSWQgKG1vZHVsZUlkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE1vZHVsZUluZm8uS0VZX01PRFVMRV9JRCwgbW9kdWxlSWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIGdldE1vZHVsZUlkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE1vZHVsZUluZm8uS0VZX01PRFVMRV9JRCk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7R3JpZH0gbG9jYXRpb25cbiAgICAqIEByZXR1cm4ge01vZHVsZUluZm99XG4gICAgKi9cbiAgICBzZXRMb2NhdGlvbiAobG9jYXRpb24pIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoR3JpZCwgbG9jYXRpb24pO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE1vZHVsZUluZm8uS0VZX0xPQ0FUSU9OLCBsb2NhdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7R3JpZH1cbiAgICAqL1xuICAgIGdldExvY2F0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEdyaWQsIE1vZHVsZUluZm8uS0VZX0xPQ0FUSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7R3JpZH0gc2VydmljZUFyZWFcbiAgICAqIEByZXR1cm4ge01vZHVsZUluZm99XG4gICAgKi9cbiAgICBzZXRTZXJ2aWNlQXJlYSAoc2VydmljZUFyZWEpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoR3JpZCwgc2VydmljZUFyZWEpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE1vZHVsZUluZm8uS0VZX1NFUlZJQ0VfQVJFQSwgc2VydmljZUFyZWEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0dyaWR9XG4gICAgKi9cbiAgICBnZXRTZXJ2aWNlQXJlYSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChHcmlkLCBNb2R1bGVJbmZvLktFWV9TRVJWSUNFX0FSRUEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtCb29sZWFufSBhbGxvd011bHRpcGxlQWNjZXNzXG4gICAgKiBAcmV0dXJuIHtNb2R1bGVJbmZvfVxuICAgICovXG4gICAgc2V0QWxsb3dNdWx0aXBsZUFjY2VzcyAoYWxsb3dNdWx0aXBsZUFjY2Vzcykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihNb2R1bGVJbmZvLktFWV9BTExPV19NVUxUSVBMRV9BQ0NFU1MsIGFsbG93TXVsdGlwbGVBY2Nlc3MpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgKi9cbiAgICBnZXRBbGxvd011bHRpcGxlQWNjZXNzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE1vZHVsZUluZm8uS0VZX0FMTE9XX01VTFRJUExFX0FDQ0VTUyk7XG4gICAgfVxufVxuXG5Nb2R1bGVJbmZvLktFWV9NT0RVTEVfSUQgPSAnbW9kdWxlSWQnO1xuTW9kdWxlSW5mby5LRVlfTE9DQVRJT04gPSAnbG9jYXRpb24nO1xuTW9kdWxlSW5mby5LRVlfU0VSVklDRV9BUkVBID0gJ3NlcnZpY2VBcmVhJztcbk1vZHVsZUluZm8uS0VZX0FMTE9XX01VTFRJUExFX0FDQ0VTUyA9ICdhbGxvd011bHRpcGxlQWNjZXNzJztcblxuZXhwb3J0IHsgTW9kdWxlSW5mbyB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBCdXR0b25OYW1lXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBCdXR0b25OYW1lIGV4dGVuZHMgRW51bSB7XG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE9LICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5PSztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBQTEFZX1BBVVNFICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5QTEFZX1BBVVNFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNFRUtMRUZUICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5TRUVLTEVGVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTRUVLUklHSFQgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLlNFRUtSSUdIVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBUVU5FVVAgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLlRVTkVVUDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBUVU5FRE9XTiAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuVFVORURPV047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUFJFU0VUXzAgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLlBSRVNFVF8wO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFBSRVNFVF8xICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5QUkVTRVRfMTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBQUkVTRVRfMiAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuUFJFU0VUXzI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUFJFU0VUXzMgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLlBSRVNFVF8zO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFBSRVNFVF80ICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5QUkVTRVRfNDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBQUkVTRVRfNSAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuUFJFU0VUXzU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUFJFU0VUXzYgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLlBSRVNFVF82O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFBSRVNFVF83ICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5QUkVTRVRfNztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBQUkVTRVRfOCAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuUFJFU0VUXzg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUFJFU0VUXzkgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLlBSRVNFVF85O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENVU1RPTV9CVVRUT04gKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLkNVU1RPTV9CVVRUT047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0VBUkNIICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5TRUFSQ0g7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQUNfTUFYICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5BQ19NQVg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQUMgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLkFDO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJFQ0lSQ1VMQVRFICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5SRUNJUkNVTEFURTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBGQU5fVVAgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLkZBTl9VUDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBGQU5fRE9XTiAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuRkFOX0RPV047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVEVNUF9VUCAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuVEVNUF9VUDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBURU1QX0RPV04gKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLlRFTVBfRE9XTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBERUZST1NUX01BWCAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuREVGUk9TVF9NQVg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgREVGUk9TVCAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuREVGUk9TVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBERUZST1NUX1JFQVIgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLkRFRlJPU1RfUkVBUjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBVUFBFUl9WRU5UICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5VUFBFUl9WRU5UO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IExPV0VSX1ZFTlQgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLkxPV0VSX1ZFTlQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVk9MVU1FX1VQICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5WT0xVTUVfVVA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVk9MVU1FX0RPV04gKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLlZPTFVNRV9ET1dOO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEVKRUNUICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5FSkVDVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTT1VSQ0UgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLlNPVVJDRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTSFVGRkxFICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5TSFVGRkxFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJFUEVBVCAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuUkVQRUFUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5BVl9DRU5URVJfTE9DQVRJT04gKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLk5BVl9DRU5URVJfTE9DQVRJT047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTkFWX1pPT01fSU4gKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLk5BVl9aT09NX0lOO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5BVl9aT09NX09VVCAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuTkFWX1pPT01fT1VUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5BVl9QQU5fVVAgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLk5BVl9QQU5fVVA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTkFWX1BBTl9VUF9SSUdIVCAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuTkFWX1BBTl9VUF9SSUdIVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOQVZfUEFOX1JJR0hUICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5OQVZfUEFOX1JJR0hUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5BVl9QQU5fRE9XTl9SSUdIVCAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuTkFWX1BBTl9ET1dOX1JJR0hUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5BVl9QQU5fRE9XTiAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuTkFWX1BBTl9ET1dOO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5BVl9QQU5fRE9XTl9MRUZUICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5OQVZfUEFOX0RPV05fTEVGVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOQVZfUEFOX0xFRlQgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLk5BVl9QQU5fTEVGVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOQVZfUEFOX1VQX0xFRlQgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLk5BVl9QQU5fVVBfTEVGVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOQVZfVElMVF9UT0dHTEUgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLk5BVl9USUxUX1RPR0dMRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOQVZfUk9UQVRFX0NMT0NLV0lTRSAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuTkFWX1JPVEFURV9DTE9DS1dJU0U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTkFWX1JPVEFURV9DT1VOVEVSQ0xPQ0tXSVNFICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5OQVZfUk9UQVRFX0NPVU5URVJDTE9DS1dJU0U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTkFWX0hFQURJTkdfVE9HR0xFICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5OQVZfSEVBRElOR19UT0dHTEU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX3ZhbHVlRm9yS2V5KGtleSwgQnV0dG9uTmFtZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fa2V5Rm9yVmFsdWUodmFsdWUsIEJ1dHRvbk5hbWUuX01BUCk7XG4gICAgfVxufVxuXG5CdXR0b25OYW1lLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnT0snOiAnT0snLFxuICAgICdQTEFZX1BBVVNFJzogJ1BMQVlfUEFVU0UnLFxuICAgICdTRUVLTEVGVCc6ICdTRUVLTEVGVCcsXG4gICAgJ1NFRUtSSUdIVCc6ICdTRUVLUklHSFQnLFxuICAgICdUVU5FVVAnOiAnVFVORVVQJyxcbiAgICAnVFVORURPV04nOiAnVFVORURPV04nLFxuICAgICdQUkVTRVRfMCc6ICdQUkVTRVRfMCcsXG4gICAgJ1BSRVNFVF8xJzogJ1BSRVNFVF8xJyxcbiAgICAnUFJFU0VUXzInOiAnUFJFU0VUXzInLFxuICAgICdQUkVTRVRfMyc6ICdQUkVTRVRfMycsXG4gICAgJ1BSRVNFVF80JzogJ1BSRVNFVF80JyxcbiAgICAnUFJFU0VUXzUnOiAnUFJFU0VUXzUnLFxuICAgICdQUkVTRVRfNic6ICdQUkVTRVRfNicsXG4gICAgJ1BSRVNFVF83JzogJ1BSRVNFVF83JyxcbiAgICAnUFJFU0VUXzgnOiAnUFJFU0VUXzgnLFxuICAgICdQUkVTRVRfOSc6ICdQUkVTRVRfOScsXG4gICAgJ0NVU1RPTV9CVVRUT04nOiAnQ1VTVE9NX0JVVFRPTicsXG4gICAgJ1NFQVJDSCc6ICdTRUFSQ0gnLFxuICAgICdBQ19NQVgnOiAnQUNfTUFYJyxcbiAgICAnQUMnOiAnQUMnLFxuICAgICdSRUNJUkNVTEFURSc6ICdSRUNJUkNVTEFURScsXG4gICAgJ0ZBTl9VUCc6ICdGQU5fVVAnLFxuICAgICdGQU5fRE9XTic6ICdGQU5fRE9XTicsXG4gICAgJ1RFTVBfVVAnOiAnVEVNUF9VUCcsXG4gICAgJ1RFTVBfRE9XTic6ICdURU1QX0RPV04nLFxuICAgICdERUZST1NUX01BWCc6ICdERUZST1NUX01BWCcsXG4gICAgJ0RFRlJPU1QnOiAnREVGUk9TVCcsXG4gICAgJ0RFRlJPU1RfUkVBUic6ICdERUZST1NUX1JFQVInLFxuICAgICdVUFBFUl9WRU5UJzogJ1VQUEVSX1ZFTlQnLFxuICAgICdMT1dFUl9WRU5UJzogJ0xPV0VSX1ZFTlQnLFxuICAgICdWT0xVTUVfVVAnOiAnVk9MVU1FX1VQJyxcbiAgICAnVk9MVU1FX0RPV04nOiAnVk9MVU1FX0RPV04nLFxuICAgICdFSkVDVCc6ICdFSkVDVCcsXG4gICAgJ1NPVVJDRSc6ICdTT1VSQ0UnLFxuICAgICdTSFVGRkxFJzogJ1NIVUZGTEUnLFxuICAgICdSRVBFQVQnOiAnUkVQRUFUJyxcbiAgICAnTkFWX0NFTlRFUl9MT0NBVElPTic6ICdOQVZfQ0VOVEVSX0xPQ0FUSU9OJyxcbiAgICAnTkFWX1pPT01fSU4nOiAnTkFWX1pPT01fSU4nLFxuICAgICdOQVZfWk9PTV9PVVQnOiAnTkFWX1pPT01fT1VUJyxcbiAgICAnTkFWX1BBTl9VUCc6ICdOQVZfUEFOX1VQJyxcbiAgICAnTkFWX1BBTl9VUF9SSUdIVCc6ICdOQVZfUEFOX1VQX1JJR0hUJyxcbiAgICAnTkFWX1BBTl9SSUdIVCc6ICdOQVZfUEFOX1JJR0hUJyxcbiAgICAnTkFWX1BBTl9ET1dOX1JJR0hUJzogJ05BVl9QQU5fRE9XTl9SSUdIVCcsXG4gICAgJ05BVl9QQU5fRE9XTic6ICdOQVZfUEFOX0RPV04nLFxuICAgICdOQVZfUEFOX0RPV05fTEVGVCc6ICdOQVZfUEFOX0RPV05fTEVGVCcsXG4gICAgJ05BVl9QQU5fTEVGVCc6ICdOQVZfUEFOX0xFRlQnLFxuICAgICdOQVZfUEFOX1VQX0xFRlQnOiAnTkFWX1BBTl9VUF9MRUZUJyxcbiAgICAnTkFWX1RJTFRfVE9HR0xFJzogJ05BVl9USUxUX1RPR0dMRScsXG4gICAgJ05BVl9ST1RBVEVfQ0xPQ0tXSVNFJzogJ05BVl9ST1RBVEVfQ0xPQ0tXSVNFJyxcbiAgICAnTkFWX1JPVEFURV9DT1VOVEVSQ0xPQ0tXSVNFJzogJ05BVl9ST1RBVEVfQ09VTlRFUkNMT0NLV0lTRScsXG4gICAgJ05BVl9IRUFESU5HX1RPR0dMRSc6ICdOQVZfSEVBRElOR19UT0dHTEUnLFxuXG59KTtcblxuZXhwb3J0IHsgQnV0dG9uTmFtZSB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgTW9kdWxlSW5mbyB9IGZyb20gJy4vTW9kdWxlSW5mbyc7XG5pbXBvcnQgeyBCdXR0b25OYW1lIH0gZnJvbSAnLi4vZW51bXMvQnV0dG9uTmFtZS5qcyc7XG5cbmNsYXNzIEJ1dHRvbkNhcGFiaWxpdGllcyBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0J1dHRvbk5hbWV9IG5hbWVcbiAgICAqIEByZXR1cm4ge0J1dHRvbkNhcGFiaWxpdGllc31cbiAgICAqL1xuICAgIHNldE5hbWUgKG5hbWUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQnV0dG9uTmFtZSwgbmFtZSk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQnV0dG9uQ2FwYWJpbGl0aWVzLktFWV9OQU1FLCBuYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtCdXR0b25OYW1lfVxuICAgICovXG4gICAgZ2V0TmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChCdXR0b25OYW1lLCBCdXR0b25DYXBhYmlsaXRpZXMuS0VZX05BTUUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtNb2R1bGVJbmZvfSBtb2R1bGVJbmZvXG4gICAgKiBAcmV0dXJuIHtCdXR0b25DYXBhYmlsaXRpZXN9XG4gICAgKi9cbiAgICBzZXRNb2R1bGVJbmZvIChtb2R1bGVJbmZvKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKE1vZHVsZUluZm8sIG1vZHVsZUluZm8pO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfTU9EVUxFX0lORk8sIG1vZHVsZUluZm8pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge01vZHVsZUluZm99XG4gICAgKi9cbiAgICBnZXRNb2R1bGVJbmZvICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KE1vZHVsZUluZm8sIEJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfTU9EVUxFX0lORk8pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtCb29sZWFufSBzaG9ydFByZXNzQXZhaWxhYmxlXG4gICAgKiBAcmV0dXJuIHtCdXR0b25DYXBhYmlsaXRpZXN9XG4gICAgKi9cbiAgICBzZXRTaG9ydFByZXNzQXZhaWxhYmxlIChzaG9ydFByZXNzQXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfU0hPUlRfUFJFU1NfQVZBSUxBQkxFLCBzaG9ydFByZXNzQXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICovXG4gICAgZ2V0U2hvcnRQcmVzc0F2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihCdXR0b25DYXBhYmlsaXRpZXMuS0VZX1NIT1JUX1BSRVNTX0FWQUlMQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0Jvb2xlYW59IGxvbmdQcmVzc0F2YWlsYWJsZVxuICAgICogQHJldHVybiB7QnV0dG9uQ2FwYWJpbGl0aWVzfVxuICAgICovXG4gICAgc2V0TG9uZ1ByZXNzQXZhaWxhYmxlIChsb25nUHJlc3NBdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQnV0dG9uQ2FwYWJpbGl0aWVzLktFWV9MT05HX1BSRVNTX0FWQUlMQUJMRSwgbG9uZ1ByZXNzQXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICovXG4gICAgZ2V0TG9uZ1ByZXNzQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfTE9OR19QUkVTU19BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtCb29sZWFufSB1cERvd25BdmFpbGFibGVcbiAgICAqIEByZXR1cm4ge0J1dHRvbkNhcGFiaWxpdGllc31cbiAgICAqL1xuICAgIHNldFVwRG93bkF2YWlsYWJsZSAodXBEb3duQXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfVVBfRE9XTl9BVkFJTEFCTEUsIHVwRG93bkF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAqL1xuICAgIGdldFVwRG93bkF2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihCdXR0b25DYXBhYmlsaXRpZXMuS0VZX1VQX0RPV05fQVZBSUxBQkxFKTtcbiAgICB9XG59XG5cbkJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfTkFNRSA9ICduYW1lJztcbkJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfTU9EVUxFX0lORk8gPSAnbW9kdWxlSW5mbyc7XG5CdXR0b25DYXBhYmlsaXRpZXMuS0VZX1NIT1JUX1BSRVNTX0FWQUlMQUJMRSA9ICdzaG9ydFByZXNzQXZhaWxhYmxlJztcbkJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfTE9OR19QUkVTU19BVkFJTEFCTEUgPSAnbG9uZ1ByZXNzQXZhaWxhYmxlJztcbkJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfVVBfRE9XTl9BVkFJTEFCTEUgPSAndXBEb3duQXZhaWxhYmxlJztcblxuZXhwb3J0IHsgQnV0dG9uQ2FwYWJpbGl0aWVzIH07XG4iLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcblxuY2xhc3MgU29mdEJ1dHRvbkNhcGFiaWxpdGllcyBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0Jvb2xlYW59IHNob3J0UHJlc3NBdmFpbGFibGVcbiAgICAqIEByZXR1cm4ge1NvZnRCdXR0b25DYXBhYmlsaXRpZXN9XG4gICAgKi9cbiAgICBzZXRTaG9ydFByZXNzQXZhaWxhYmxlIChzaG9ydFByZXNzQXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNvZnRCdXR0b25DYXBhYmlsaXRpZXMuS0VZX1NIT1JUX1BSRVNTX0FWQUlMQUJMRSwgc2hvcnRQcmVzc0F2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAqL1xuICAgIGdldFNob3J0UHJlc3NBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU29mdEJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfU0hPUlRfUFJFU1NfQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gbG9uZ1ByZXNzQXZhaWxhYmxlXG4gICAgKiBAcmV0dXJuIHtTb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzfVxuICAgICovXG4gICAgc2V0TG9uZ1ByZXNzQXZhaWxhYmxlIChsb25nUHJlc3NBdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU29mdEJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfTE9OR19QUkVTU19BVkFJTEFCTEUsIGxvbmdQcmVzc0F2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAqL1xuICAgIGdldExvbmdQcmVzc0F2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzLktFWV9MT05HX1BSRVNTX0FWQUlMQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0Jvb2xlYW59IHVwRG93bkF2YWlsYWJsZVxuICAgICogQHJldHVybiB7U29mdEJ1dHRvbkNhcGFiaWxpdGllc31cbiAgICAqL1xuICAgIHNldFVwRG93bkF2YWlsYWJsZSAodXBEb3duQXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNvZnRCdXR0b25DYXBhYmlsaXRpZXMuS0VZX1VQX0RPV05fQVZBSUxBQkxFLCB1cERvd25BdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgKi9cbiAgICBnZXRVcERvd25BdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU29mdEJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfVVBfRE9XTl9BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtCb29sZWFufSBpbWFnZVN1cHBvcnRlZFxuICAgICogQHJldHVybiB7U29mdEJ1dHRvbkNhcGFiaWxpdGllc31cbiAgICAqL1xuICAgIHNldEltYWdlU3VwcG9ydGVkIChpbWFnZVN1cHBvcnRlZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzLktFWV9JTUFHRV9TVVBQT1JURUQsIGltYWdlU3VwcG9ydGVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICovXG4gICAgZ2V0SW1hZ2VTdXBwb3J0ZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU29mdEJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfSU1BR0VfU1VQUE9SVEVEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gdGV4dFN1cHBvcnRlZFxuICAgICogQHJldHVybiB7U29mdEJ1dHRvbkNhcGFiaWxpdGllc31cbiAgICAqL1xuICAgIHNldFRleHRTdXBwb3J0ZWQgKHRleHRTdXBwb3J0ZWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU29mdEJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfVEVYVF9TVVBQT1JURUQsIHRleHRTdXBwb3J0ZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgKi9cbiAgICBnZXRUZXh0U3VwcG9ydGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNvZnRCdXR0b25DYXBhYmlsaXRpZXMuS0VZX1RFWFRfU1VQUE9SVEVEKTtcbiAgICB9XG59XG5cblNvZnRCdXR0b25DYXBhYmlsaXRpZXMuS0VZX1NIT1JUX1BSRVNTX0FWQUlMQUJMRSA9ICdzaG9ydFByZXNzQXZhaWxhYmxlJztcblNvZnRCdXR0b25DYXBhYmlsaXRpZXMuS0VZX0xPTkdfUFJFU1NfQVZBSUxBQkxFID0gJ2xvbmdQcmVzc0F2YWlsYWJsZSc7XG5Tb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzLktFWV9VUF9ET1dOX0FWQUlMQUJMRSA9ICd1cERvd25BdmFpbGFibGUnO1xuU29mdEJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfSU1BR0VfU1VQUE9SVEVEID0gJ2ltYWdlU3VwcG9ydGVkJztcblNvZnRCdXR0b25DYXBhYmlsaXRpZXMuS0VZX1RFWFRfU1VQUE9SVEVEID0gJ3RleHRTdXBwb3J0ZWQnO1xuXG5leHBvcnQgeyBTb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzIH07XG4iLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcblxuY2xhc3MgUHJlc2V0QmFua0NhcGFiaWxpdGllcyBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0Jvb2xlYW59IG9uU2NyZWVuUHJlc2V0c0F2YWlsYWJsZVxuICAgICogQHJldHVybiB7UHJlc2V0QmFua0NhcGFiaWxpdGllc31cbiAgICAqL1xuICAgIHNldE9uU2NyZWVuUHJlc2V0c0F2YWlsYWJsZSAob25TY3JlZW5QcmVzZXRzQXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFByZXNldEJhbmtDYXBhYmlsaXRpZXMuS0VZX09OX1NDUkVFTl9QUkVTRVRTX0FWQUlMQUJMRSwgb25TY3JlZW5QcmVzZXRzQXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICovXG4gICAgZ2V0T25TY3JlZW5QcmVzZXRzQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFByZXNldEJhbmtDYXBhYmlsaXRpZXMuS0VZX09OX1NDUkVFTl9QUkVTRVRTX0FWQUlMQUJMRSk7XG4gICAgfVxufVxuXG5QcmVzZXRCYW5rQ2FwYWJpbGl0aWVzLktFWV9PTl9TQ1JFRU5fUFJFU0VUU19BVkFJTEFCTEUgPSAnb25TY3JlZW5QcmVzZXRzQXZhaWxhYmxlJztcblxuZXhwb3J0IHsgUHJlc2V0QmFua0NhcGFiaWxpdGllcyB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5cbmNsYXNzIFZlaGljbGVUeXBlIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBtYWtlXG4gICAgKiBAcmV0dXJuIHtWZWhpY2xlVHlwZX1cbiAgICAqL1xuICAgIHNldE1ha2UgKG1ha2UpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVmVoaWNsZVR5cGUuS0VZX01BS0UsIG1ha2UpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIGdldE1ha2UgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoVmVoaWNsZVR5cGUuS0VZX01BS0UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IG1vZGVsXG4gICAgKiBAcmV0dXJuIHtWZWhpY2xlVHlwZX1cbiAgICAqL1xuICAgIHNldE1vZGVsIChtb2RlbCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihWZWhpY2xlVHlwZS5LRVlfTU9ERUwsIG1vZGVsKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBnZXRNb2RlbCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihWZWhpY2xlVHlwZS5LRVlfTU9ERUwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IG1vZGVsWWVhclxuICAgICogQHJldHVybiB7VmVoaWNsZVR5cGV9XG4gICAgKi9cbiAgICBzZXRNb2RlbFllYXIgKG1vZGVsWWVhcikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihWZWhpY2xlVHlwZS5LRVlfTU9ERUxfWUVBUiwgbW9kZWxZZWFyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBnZXRNb2RlbFllYXIgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoVmVoaWNsZVR5cGUuS0VZX01PREVMX1lFQVIpO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gdHJpbVxuICAgICogQHJldHVybiB7VmVoaWNsZVR5cGV9XG4gICAgKi9cbiAgICBzZXRUcmltICh0cmltKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFZlaGljbGVUeXBlLktFWV9UUklNLCB0cmltKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBnZXRUcmltICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFZlaGljbGVUeXBlLktFWV9UUklNKTtcbiAgICB9XG59XG5cblZlaGljbGVUeXBlLktFWV9NQUtFID0gJ21ha2UnO1xuVmVoaWNsZVR5cGUuS0VZX01PREVMID0gJ21vZGVsJztcblZlaGljbGVUeXBlLktFWV9NT0RFTF9ZRUFSID0gJ21vZGVsWWVhcic7XG5WZWhpY2xlVHlwZS5LRVlfVFJJTSA9ICd0cmltJztcblxuZXhwb3J0IHsgVmVoaWNsZVR5cGUgfTtcbiIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gRmlsZVR5cGVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIEhtaVpvbmVDYXBhYmlsaXRpZXMgZXh0ZW5kcyBFbnVtIHtcbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRlJPTlQgKCkge1xuICAgICAgICByZXR1cm4gSG1pWm9uZUNhcGFiaWxpdGllcy5fTUFQLkZST05UO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEJBQ0sgKCkge1xuICAgICAgICByZXR1cm4gSG1pWm9uZUNhcGFiaWxpdGllcy5fTUFQLkJBQ0s7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIEhtaVpvbmVDYXBhYmlsaXRpZXMuX3ZhbHVlRm9yS2V5KGtleSwgSG1pWm9uZUNhcGFiaWxpdGllcy5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gSG1pWm9uZUNhcGFiaWxpdGllcy5fa2V5Rm9yVmFsdWUodmFsdWUsIEhtaVpvbmVDYXBhYmlsaXRpZXMuX01BUCk7XG4gICAgfVxufVxuXG5IbWlab25lQ2FwYWJpbGl0aWVzLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnRlJPTlQnOiAnRlJPTlQnLFxuICAgICdCQUNLJzogJ0JBQ0snLFxuXG59KTtcblxuZXhwb3J0IHsgSG1pWm9uZUNhcGFiaWxpdGllcyB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gUHJlcmVjb3JkZWRTcGVlY2hcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIFByZXJlY29yZGVkU3BlZWNoIGV4dGVuZHMgRW51bSB7XG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEhFTFBfSklOR0xFICgpIHtcbiAgICAgICAgcmV0dXJuIFByZXJlY29yZGVkU3BlZWNoLl9NQVAuSEVMUF9KSU5HTEU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSU5JVElBTF9KSU5HTEUgKCkge1xuICAgICAgICByZXR1cm4gUHJlcmVjb3JkZWRTcGVlY2guX01BUC5JTklUSUFMX0pJTkdMRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBMSVNURU5fSklOR0xFICgpIHtcbiAgICAgICAgcmV0dXJuIFByZXJlY29yZGVkU3BlZWNoLl9NQVAuTElTVEVOX0pJTkdMRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBQT1NJVElWRV9KSU5HTEUgKCkge1xuICAgICAgICByZXR1cm4gUHJlcmVjb3JkZWRTcGVlY2guX01BUC5QT1NJVElWRV9KSU5HTEU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTkVHQVRJVkVfSklOR0xFICgpIHtcbiAgICAgICAgcmV0dXJuIFByZXJlY29yZGVkU3BlZWNoLl9NQVAuTkVHQVRJVkVfSklOR0xFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgKiBAcGFyYW0gdmFsdWUgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBQcmVyZWNvcmRlZFNwZWVjaC5fdmFsdWVGb3JLZXkoa2V5LCBQcmVyZWNvcmRlZFNwZWVjaC5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gUHJlcmVjb3JkZWRTcGVlY2guX2tleUZvclZhbHVlKHZhbHVlLCBQcmVyZWNvcmRlZFNwZWVjaC5fTUFQKTtcbiAgICB9XG59XG5cblByZXJlY29yZGVkU3BlZWNoLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnSEVMUF9KSU5HTEUnOiAnSEVMUF9KSU5HTEUnLFxuICAgICdJTklUSUFMX0pJTkdMRSc6ICdJTklUSUFMX0pJTkdMRScsXG4gICAgJ0xJU1RFTl9KSU5HTEUnOiAnTElTVEVOX0pJTkdMRScsXG4gICAgJ1BPU0lUSVZFX0pJTkdMRSc6ICdQT1NJVElWRV9KSU5HTEUnLFxuICAgICdORUdBVElWRV9KSU5HTEUnOiAnTkVHQVRJVkVfSklOR0xFJyxcblxufSk7XG5cbmV4cG9ydCB7IFByZXJlY29yZGVkU3BlZWNoIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBTYW1wbGluZ1JhdGVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIFNhbXBsaW5nUmF0ZSBleHRlbmRzIEVudW0ge1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTYW1wbGluZ1JhdGVfOEtIWiAoKSB7XG4gICAgICAgIHJldHVybiBTYW1wbGluZ1JhdGUuX01BUC5TYW1wbGluZ1JhdGVfOEtIWjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTYW1wbGluZ1JhdGVfMTZLSFogKCkge1xuICAgICAgICByZXR1cm4gU2FtcGxpbmdSYXRlLl9NQVAuU2FtcGxpbmdSYXRlXzE2S0haO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNhbXBsaW5nUmF0ZV8yMktIWiAoKSB7XG4gICAgICAgIHJldHVybiBTYW1wbGluZ1JhdGUuX01BUC5TYW1wbGluZ1JhdGVfMjJLSFo7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU2FtcGxpbmdSYXRlXzQ0S0haICgpIHtcbiAgICAgICAgcmV0dXJuIFNhbXBsaW5nUmF0ZS5fTUFQLlNhbXBsaW5nUmF0ZV80NEtIWjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gU2FtcGxpbmdSYXRlLl92YWx1ZUZvcktleShrZXksIFNhbXBsaW5nUmF0ZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gU2FtcGxpbmdSYXRlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgU2FtcGxpbmdSYXRlLl9NQVApO1xuICAgIH1cbn1cblxuLy8gV2UgaGF2ZSB0byB1c2UgU2FtcGxpbmdSYXRlXyBwcmVmaXggaW4gdGhlIG5hbWUgYmVjYXVzZSBqYXZhc2NyaXB0IHdpbGwgbm90XG4vLyBhbGxvdyB0aGUgZW51bSB0byBzdGFydCB3aXRoIGEgbnVtYmVyXG5TYW1wbGluZ1JhdGUuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdTYW1wbGluZ1JhdGVfOEtIWic6ICc4S0haJyxcbiAgICAnU2FtcGxpbmdSYXRlXzE2S0haJzogJzE2S0haJyxcbiAgICAnU2FtcGxpbmdSYXRlXzIyS0haJzogJzIyS0haJyxcbiAgICAnU2FtcGxpbmdSYXRlXzQ0S0haJzogJzQ0S0haJyxcblxufSk7XG5cbmV4cG9ydCB7IFNhbXBsaW5nUmF0ZSB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gQml0c1BlclNhbXBsZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgQml0c1BlclNhbXBsZSBleHRlbmRzIEVudW0ge1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBCaXRzUGVyU2FtcGxlXzhfQklUICgpIHtcbiAgICAgICAgcmV0dXJuIEJpdHNQZXJTYW1wbGUuX01BUC5CaXRzUGVyU2FtcGxlXzhfQklUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEJpdHNQZXJTYW1wbGVfMTZfQklUICgpIHtcbiAgICAgICAgcmV0dXJuIEJpdHNQZXJTYW1wbGUuX01BUC5CaXRzUGVyU2FtcGxlXzE2X0JJVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gQml0c1BlclNhbXBsZS5fdmFsdWVGb3JLZXkoa2V5LCBCaXRzUGVyU2FtcGxlLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBCaXRzUGVyU2FtcGxlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgQml0c1BlclNhbXBsZS5fTUFQKTtcbiAgICB9XG59XG5cblxuLy8gV2UgaGF2ZSB0byB1c2UgQml0c1BlclNhbXBsZV8gcHJlZml4IGluIHRoZSBuYW1lIGJlY2F1c2UgamF2YXNjcmlwdCB3aWxsIG5vdFxuLy8gYWxsb3cgdGhlIGVudW0gdG8gc3RhcnQgd2l0aCBhIG51bWJlclxuQml0c1BlclNhbXBsZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0JpdHNQZXJTYW1wbGVfOF9CSVQnOiAnOF9CSVQnLFxuICAgICdCaXRzUGVyU2FtcGxlXzE2X0JJVCc6ICcxNl9CSVQnLFxuXG59KTtcblxuZXhwb3J0IHsgQml0c1BlclNhbXBsZSB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gQXVkaW9UeXBlXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBBdWRpb1R5cGUgZXh0ZW5kcyBFbnVtIHtcbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUENNICgpIHtcbiAgICAgICAgcmV0dXJuIEF1ZGlvVHlwZS5fTUFQLlBDTTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gQXVkaW9UeXBlLl92YWx1ZUZvcktleShrZXksIEF1ZGlvVHlwZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gQXVkaW9UeXBlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgQXVkaW9UeXBlLl9NQVApO1xuICAgIH1cbn1cblxuQXVkaW9UeXBlLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnUENNJzogJ1BDTScsXG5cbn0pO1xuXG5leHBvcnQgeyBBdWRpb1R5cGUgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IFNhbXBsaW5nUmF0ZSB9IGZyb20gJy4uL2VudW1zL1NhbXBsaW5nUmF0ZS5qcyc7XG5pbXBvcnQgeyBCaXRzUGVyU2FtcGxlIH0gZnJvbSAnLi4vZW51bXMvQml0c1BlclNhbXBsZS5qcyc7XG5pbXBvcnQgeyBBdWRpb1R5cGUgfSBmcm9tICcuLi9lbnVtcy9BdWRpb1R5cGUuanMnO1xuXG5jbGFzcyBBdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7U2FtcGxpbmdSYXRlfSBzYW1wbGluZ1JhdGVcbiAgICAqIEByZXR1cm4ge0F1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXN9XG4gICAgKi9cbiAgICBzZXRTYW1wbGluZ1JhdGUgKHNhbXBsaW5nUmF0ZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShTYW1wbGluZ1JhdGUsIHNhbXBsaW5nUmF0ZSk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQXVkaW9QYXNzVGhydUNhcGFiaWxpdGllcy5LRVlfU0FNUExJTkdfUkFURSwgc2FtcGxpbmdSYXRlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTYW1wbGluZ1JhdGV9XG4gICAgKi9cbiAgICBnZXRTYW1wbGluZ1JhdGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoU2FtcGxpbmdSYXRlLCBBdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzLktFWV9TQU1QTElOR19SQVRFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7Qml0c1BlclNhbXBsZX0gYml0c1BlclNhbXBsZVxuICAgICogQHJldHVybiB7QXVkaW9QYXNzVGhydUNhcGFiaWxpdGllc31cbiAgICAqL1xuICAgIHNldEJpdHNQZXJTYW1wbGUgKGJpdHNQZXJTYW1wbGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQml0c1BlclNhbXBsZSwgYml0c1BlclNhbXBsZSk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQXVkaW9QYXNzVGhydUNhcGFiaWxpdGllcy5LRVlfQklUU19QRVJfU0FNUExFLCBiaXRzUGVyU2FtcGxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtCaXRzUGVyU2FtcGxlfVxuICAgICovXG4gICAgZ2V0Qml0c1BlclNhbXBsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChCaXRzUGVyU2FtcGxlLCBBdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzLktFWV9CSVRTX1BFUl9TQU1QTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtBdWRpb1R5cGV9IGJpdHNQZXJTYW1wbGVcbiAgICAqIEByZXR1cm4ge0F1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXN9XG4gICAgKi9cbiAgICBzZXRBdWRpb1R5cGUgKGF1ZGlvVHlwZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShBdWRpb1R5cGUsIGF1ZGlvVHlwZSk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQXVkaW9QYXNzVGhydUNhcGFiaWxpdGllcy5LRVlfQVVESU9fVFlQRSwgYXVkaW9UeXBlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtBdWRpb1R5cGV9XG4gICAgKi9cbiAgICBnZXRBdWRpb1R5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQXVkaW9UeXBlLCBBdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzLktFWV9BVURJT19UWVBFKTtcbiAgICB9XG59XG5cbkF1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXMuS0VZX1NBTVBMSU5HX1JBVEUgPSAnc2FtcGxpbmdSYXRlJztcbkF1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXMuS0VZX0JJVFNfUEVSX1NBTVBMRSA9ICdiaXRzUGVyU2FtcGxlJztcbkF1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXMuS0VZX0FVRElPX1RZUEUgPSAnYXVkaW9UeXBlJztcblxuZXhwb3J0IHsgQXVkaW9QYXNzVGhydUNhcGFiaWxpdGllcyB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBWckNhcGFiaWxpdGllc1xuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgVnJDYXBhYmlsaXRpZXMgZXh0ZW5kcyBFbnVtIHtcbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVlJfVEVYVCAoKSB7XG4gICAgICAgIHJldHVybiBWckNhcGFiaWxpdGllcy5fTUFQLlZSX1RFWFQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFZyQ2FwYWJpbGl0aWVzLl92YWx1ZUZvcktleShrZXksIFZyQ2FwYWJpbGl0aWVzLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBWckNhcGFiaWxpdGllcy5fa2V5Rm9yVmFsdWUodmFsdWUsIFZyQ2FwYWJpbGl0aWVzLl9NQVApO1xuICAgIH1cbn1cblxuVnJDYXBhYmlsaXRpZXMuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdWUl9URVhUJzogJ1RFWFQnLFxufSk7XG5cbmV4cG9ydCB7IFZyQ2FwYWJpbGl0aWVzIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5cblxuY2xhc3MgSE1JQ2FwYWJpbGl0aWVzIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gbmF2aWdhdGlvblxuICAgICogQHJldHVybiB7SE1JQ2FwYWJpbGl0aWVzfVxuICAgICovXG4gICAgc2V0TmF2aWdhdGlvbiAobmF2aWdhdGlvbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihITUlDYXBhYmlsaXRpZXMuS0VZX05BVklHQVRJT04sIG5hdmlnYXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgKi9cbiAgICBnZXROYXZpZ2F0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEhNSUNhcGFiaWxpdGllcy5LRVlfTkFWSUdBVElPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0Jvb2xlYW59IHBob25lQ2FsbFxuICAgICogQHJldHVybiB7SE1JQ2FwYWJpbGl0aWVzfVxuICAgICovXG4gICAgc2V0UGhvbmVDYWxsIChwaG9uZUNhbGwpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoSE1JQ2FwYWJpbGl0aWVzLktFWV9QSE9ORV9DQUxMLCBwaG9uZUNhbGwpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgKi9cbiAgICBnZXRQaG9uZUNhbGwgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoSE1JQ2FwYWJpbGl0aWVzLktFWV9QSE9ORV9DQUxMKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gdmlkZW9TdHJlYW1pbmdcbiAgICAqIEByZXR1cm4ge0hNSUNhcGFiaWxpdGllc31cbiAgICAqL1xuICAgIHNldFZpZGVvU3RyZWFtaW5nICh2aWRlb1N0cmVhbWluZykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihITUlDYXBhYmlsaXRpZXMuS0VZX1ZJREVPX1NUUkVBTUlORywgdmlkZW9TdHJlYW1pbmcpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgKi9cbiAgICBnZXRWaWRlb1N0cmVhbWluZyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihITUlDYXBhYmlsaXRpZXMuS0VZX1ZJREVPX1NUUkVBTUlORyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0Jvb2xlYW59IHJlbW90ZUNvbnRyb2xcbiAgICAqIEByZXR1cm4ge0hNSUNhcGFiaWxpdGllc31cbiAgICAqL1xuICAgIHNldFJlbW90ZUNvbnRyb2wgKHJlbW90ZUNvbnRyb2wpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoSE1JQ2FwYWJpbGl0aWVzLktFWV9SRU1PVEVfQ09OVFJPTCwgcmVtb3RlQ29udHJvbCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAqL1xuICAgIGdldFJlbW90ZUNvbnRyb2wgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoSE1JQ2FwYWJpbGl0aWVzLktFWV9SRU1PVEVfQ09OVFJPTCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0Jvb2xlYW59IGFwcFNlcnZpY2VzXG4gICAgKiBAcmV0dXJuIHtITUlDYXBhYmlsaXRpZXN9XG4gICAgKi9cbiAgICBzZXRBcHBTZXJ2aWNlIChhcHBTZXJ2aWNlcykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihITUlDYXBhYmlsaXRpZXMuS0VZX0FQUF9TRVJWSUNFUywgYXBwU2VydmljZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgKi9cbiAgICBnZXRBcHBTZXJ2aWNlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEhNSUNhcGFiaWxpdGllcy5LRVlfQVBQX1NFUlZJQ0VTKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtCb29sZWFufSBkaXNwbGF5c1xuICAgICogQHJldHVybiB7SE1JQ2FwYWJpbGl0aWVzfVxuICAgICovXG4gICAgc2V0RGlzcGxheXMgKGRpc3BsYXlzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEhNSUNhcGFiaWxpdGllcy5LRVlfRElTUExBWVMsIGRpc3BsYXlzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICovXG4gICAgZ2V0RGlzcGxheXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoSE1JQ2FwYWJpbGl0aWVzLktFWV9ESVNQTEFZUyk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gc2VhdExvY2F0aW9uXG4gICAgKiBAcmV0dXJuIHtITUlDYXBhYmlsaXRpZXN9XG4gICAgKi9cbiAgICBzZXRTZWF0TG9jYXRpb24gKHNlYXRMb2NhdGlvbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihITUlDYXBhYmlsaXRpZXMuS0VZX1NFQVRfTE9DQVRJT04sIHNlYXRMb2NhdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAqL1xuICAgIGdldFNlYXRMb2NhdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihITUlDYXBhYmlsaXRpZXMuS0VZX1NFQVRfTE9DQVRJT04pO1xuICAgIH1cbn1cblxuSE1JQ2FwYWJpbGl0aWVzLktFWV9OQVZJR0FUSU9OID0gJ25hdmlnYXRpb24nO1xuSE1JQ2FwYWJpbGl0aWVzLktFWV9QSE9ORV9DQUxMID0gJ3Bob25lQ2FsbCc7XG5ITUlDYXBhYmlsaXRpZXMuS0VZX1ZJREVPX1NUUkVBTUlORyA9ICd2aWRlb1N0cmVhbWluZyc7XG5ITUlDYXBhYmlsaXRpZXMuS0VZX1JFTU9URV9DT05UUk9MID0gJ3JlbW90ZUNvbnRyb2wnO1xuSE1JQ2FwYWJpbGl0aWVzLktFWV9BUFBfU0VSVklDRVMgPSAnYXBwU2VydmljZXMnO1xuSE1JQ2FwYWJpbGl0aWVzLktFWV9ESVNQTEFZUyA9ICdkaXNwbGF5cyc7XG5ITUlDYXBhYmlsaXRpZXMuS0VZX1NFQVRfTE9DQVRJT04gPSAnc2VhdExvY2F0aW9uJztcblxuZXhwb3J0IHsgSE1JQ2FwYWJpbGl0aWVzIH07XG4iLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBTZGxNc2dWZXJzaW9uIH0gZnJvbSAnLi4vc3RydWN0cy9TZGxNc2dWZXJzaW9uLmpzJztcbmltcG9ydCB7IERpc3BsYXlDYXBhYmlsaXRpZXMgfSBmcm9tICcuLi9zdHJ1Y3RzL0Rpc3BsYXlDYXBhYmlsaXRpZXMuanMnO1xuaW1wb3J0IHsgQnV0dG9uQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi4vc3RydWN0cy9CdXR0b25DYXBhYmlsaXRpZXMuanMnO1xuaW1wb3J0IHsgU29mdEJ1dHRvbkNhcGFiaWxpdGllcyB9IGZyb20gJy4uL3N0cnVjdHMvU29mdEJ1dHRvbkNhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBQcmVzZXRCYW5rQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi4vc3RydWN0cy9QcmVzZXRCYW5rQ2FwYWJpbGl0aWVzLmpzJztcbmltcG9ydCB7IFZlaGljbGVUeXBlIH0gZnJvbSAnLi4vc3RydWN0cy9WZWhpY2xlVHlwZS5qcyc7XG5pbXBvcnQgeyBMYW5ndWFnZSB9IGZyb20gJy4uL2VudW1zL0xhbmd1YWdlLmpzJztcbmltcG9ydCB7IEhtaVpvbmVDYXBhYmlsaXRpZXMgfSBmcm9tICcuLi9lbnVtcy9IbWlab25lQ2FwYWJpbGl0aWVzLmpzJztcbmltcG9ydCB7IFNwZWVjaENhcGFiaWxpdGllcyB9IGZyb20gJy4uL2VudW1zL1NwZWVjaENhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBQcmVyZWNvcmRlZFNwZWVjaCB9IGZyb20gJy4uL2VudW1zL1ByZXJlY29yZGVkU3BlZWNoLmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IEF1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXMgfSBmcm9tICcuLi9zdHJ1Y3RzL0F1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXMuanMnO1xuaW1wb3J0IHsgVnJDYXBhYmlsaXRpZXMgfSBmcm9tICcuLi9lbnVtcy9WckNhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBITUlDYXBhYmlsaXRpZXMgfSBmcm9tICcuLi9zdHJ1Y3RzL0hNSUNhcGFiaWxpdGllcy5qcyc7XG5cbmNsYXNzIFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UgZXh0ZW5kcyBScGNSZXNwb25zZSB7XG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5SZWdpc3RlckFwcEludGVyZmFjZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1NkbE1zZ1ZlcnNpb259IFRoZSBtYXggUlBDIFNwZWMgdmVyc2lvbiBzdXBwb3J0ZWQgYnkgdGhpcyBsaWJyYXJ5XG4gICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlfVxuICAgICovXG4gICAgc2V0U2RsTXNnVmVyc2lvbiAoc2RsTXNnVmVyc2lvbikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShTZGxNc2dWZXJzaW9uLCBzZGxNc2dWZXJzaW9uKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9TRExfTVNHX1ZFUlNJT04sIHNkbE1zZ1ZlcnNpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1NkbE1zZ1ZlcnNpb259XG4gICAgKi9cbiAgICBnZXRTZGxNc2dWZXJzaW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFNkbE1zZ1ZlcnNpb24sIFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1NETF9NU0dfVkVSU0lPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0xhbmd1YWdlfSBsYW5ndWFnZVxuICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZX1cbiAgICAqL1xuICAgIHNldExhbmd1YWdlIChsYW5ndWFnZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShMYW5ndWFnZSwgbGFuZ3VhZ2UpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX0xBTkdVQUdFLCBsYW5ndWFnZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TGFuZ3VhZ2V9XG4gICAgKi9cbiAgICBnZXRMYW5ndWFnZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChMYW5ndWFnZSwgUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfTEFOR1VBR0UpO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0xhbmd1YWdlfSBobWlEaXNwbGF5TGFuZ3VhZ2VcbiAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2V9XG4gICAgKi9cbiAgICBzZXRIbWlEaXNwbGF5TGFuZ3VhZ2UgKGhtaURpc3BsYXlMYW5ndWFnZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShMYW5ndWFnZSwgaG1pRGlzcGxheUxhbmd1YWdlKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9ITUlfRElTUExBWV9MQU5HVUFHRSwgaG1pRGlzcGxheUxhbmd1YWdlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtMYW5ndWFnZX1cbiAgICAqL1xuICAgIGdldEhtaURpc3BsYXlMYW5ndWFnZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChMYW5ndWFnZSwgUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfSE1JX0RJU1BMQVlfTEFOR1VBR0UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtEaXNwbGF5Q2FwYWJpbGl0aWVzfSBkaXNwbGF5Q2FwYWJpbGl0aWVzXG4gICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlfVxuICAgICovXG4gICAgc2V0RGlzcGxheUNhcGFiaWxpdGllcyAoZGlzcGxheUNhcGFiaWxpdGllcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShEaXNwbGF5Q2FwYWJpbGl0aWVzLCBkaXNwbGF5Q2FwYWJpbGl0aWVzKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9ESVNQTEFZX0NBUEFCSUxJVElFUywgZGlzcGxheUNhcGFiaWxpdGllcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7RGlzcGxheUNhcGFiaWxpdGllc31cbiAgICAqL1xuICAgIGdldERpc3BsYXlDYXBhYmlsaXRpZXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoRGlzcGxheUNhcGFiaWxpdGllcywgUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfRElTUExBWV9DQVBBQklMSVRJRVMpO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0FycmF5PEJ1dHRvbkNhcGFiaWxpdGllcz59IGJ1dHRvbkNhcGFiaWxpdGllc1xuICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZX1cbiAgICAqL1xuICAgIHNldEJ1dHRvbkNhcGFiaWxpdGllcyAoYnV0dG9uQ2FwYWJpbGl0aWVzKSB7XG4gICAgICAgIC8vIFRPRE8gbWFrZSB0aGlzIHdvcmsgd2l0aCBhcnJheXNcbiAgICAgICAgLy8gdGhpcy52YWxpZGF0ZVR5cGUoTGFuZ3VhZ2UsIGJ1dHRvbkNhcGFiaWxpdGllcyk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfQlVUVE9OX0NBUEFCSUxJVElFUywgYnV0dG9uQ2FwYWJpbGl0aWVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtBcnJheTxCdXR0b25DYXBhYmlsaXRpZXM+fVxuICAgICovXG4gICAgZ2V0QnV0dG9uQ2FwYWJpbGl0aWVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEJ1dHRvbkNhcGFiaWxpdGllcywgUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfQlVUVE9OX0NBUEFCSUxJVElFUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0FycmF5PFNvZnRCdXR0b25DYXBhYmlsaXRpZXM+fSBzb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzXG4gICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlfVxuICAgICovXG4gICAgc2V0U29mdEJ1dHRvbkNhcGFiaWxpdGllcyAoc29mdEJ1dHRvbkNhcGFiaWxpdGllcykge1xuICAgICAgICAvLyBUT0RPIG1ha2UgdGhpcyB3b3JrIHdpdGggYXJyYXlzXG4gICAgICAgIC8vIHRoaXMudmFsaWRhdGVUeXBlKFNvZnRCdXR0b25DYXBhYmlsaXRpZXMsIHNvZnRCdXR0b25DYXBhYmlsaXRpZXMpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1NPRlRfQlVUVE9OX0NBUEFCSUxJVElFUywgc29mdEJ1dHRvbkNhcGFiaWxpdGllcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7QXJyYXk8U29mdEJ1dHRvbkNhcGFiaWxpdGllcz59XG4gICAgKi9cbiAgICBnZXRTb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFNvZnRCdXR0b25DYXBhYmlsaXRpZXMsIFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1NPRlRfQlVUVE9OX0NBUEFCSUxJVElFUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1ByZXNldEJhbmtDYXBhYmlsaXRpZXN9IHByZXNldEJhbmtDYXBhYmlsaXRpZXNcbiAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2V9XG4gICAgKi9cbiAgICBzZXRQcmVzZXRCYW5rQ2FwYWJpbGl0aWVzIChwcmVzZXRCYW5rQ2FwYWJpbGl0aWVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFByZXNldEJhbmtDYXBhYmlsaXRpZXMsIHByZXNldEJhbmtDYXBhYmlsaXRpZXMpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1BSRVNFVF9CQU5LX0NBUEFCSUxJVElFUywgcHJlc2V0QmFua0NhcGFiaWxpdGllcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7UHJlc2V0QmFua0NhcGFiaWxpdGllc31cbiAgICAqL1xuICAgIGdldFByZXNldEJhbmtDYXBhYmlsaXRpZXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoUHJlc2V0QmFua0NhcGFiaWxpdGllcywgUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfUFJFU0VUX0JBTktfQ0FQQUJJTElUSUVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7QXJyYXk8SG1pWm9uZUNhcGFiaWxpdGllcz59IGhtaVpvbmVDYXBhYmlsaXRpZXNcbiAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2V9XG4gICAgKi9cbiAgICBzZXRIbWlab25lQ2FwYWJpbGl0aWVzIChobWlab25lQ2FwYWJpbGl0aWVzKSB7XG4gICAgICAgIC8vIFRPRE8gbWFrZSB0aGlzIHdvcmsgZm9yIGFycmF5c1xuICAgICAgICAvLyB0aGlzLnZhbGlkYXRlVHlwZShIbWlab25lQ2FwYWJpbGl0aWVzLCBobWlab25lQ2FwYWJpbGl0aWVzKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9ITUlfWk9ORV9DQVBBQklMSVRJRVMsIGhtaVpvbmVDYXBhYmlsaXRpZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0FycmF5PEhtaVpvbmVDYXBhYmlsaXRpZXM+fVxuICAgICovXG4gICAgZ2V0SG1pWm9uZUNhcGFiaWxpdGllcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChIbWlab25lQ2FwYWJpbGl0aWVzLCBSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9ITUlfWk9ORV9DQVBBQklMSVRJRVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtBcnJheTxTcGVlY2hDYXBhYmlsaXRpZXM+fSBzcGVlY2hDYXBhYmlsaXRpZXNcbiAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2V9XG4gICAgKi9cbiAgICBzZXRTcGVlY2hDYXBhYmlsaXRpZXMgKHNwZWVjaENhcGFiaWxpdGllcykge1xuICAgICAgICAvLyBUT0RPIG1ha2UgdGhpcyB3b3JrIGZvciBhcnJheXNcbiAgICAgICAgLy8gdGhpcy52YWxpZGF0ZVR5cGUoU3BlZWNoQ2FwYWJpbGl0aWVzLCBzcGVlY2hDYXBhYmlsaXRpZXMpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1NQRUVDSF9DQVBBQklMSVRJRVMsIHNwZWVjaENhcGFiaWxpdGllcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7QXJyYXk8U3BlZWNoQ2FwYWJpbGl0aWVzPn1cbiAgICAqL1xuICAgIGdldFNwZWVjaENhcGFiaWxpdGllcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChTcGVlY2hDYXBhYmlsaXRpZXMsIFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1NQRUVDSF9DQVBBQklMSVRJRVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtBcnJheTxQcmVyZWNvcmRlZFNwZWVjaD59IHNwZWVjaENhcGFiaWxpdGllc1xuICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZX1cbiAgICAqL1xuICAgIHNldFByZXJlY29yZGVkU3BlZWNoIChzcGVlY2hDYXBhYmlsaXRpZXMpIHtcbiAgICAgICAgLy8gVE9ETyBtYWtlIHRoaXMgd29yayBmb3IgYXJyYXlzXG4gICAgICAgIC8vIHRoaXMudmFsaWRhdGVUeXBlKFByZXJlY29yZGVkU3BlZWNoLCBzcGVlY2hDYXBhYmlsaXRpZXMpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1BSRVJFQ09SREVEX1NQRUVDSCwgc3BlZWNoQ2FwYWJpbGl0aWVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtBcnJheTxQcmVyZWNvcmRlZFNwZWVjaD59XG4gICAgKi9cbiAgICBnZXRQcmVyZWNvcmRlZFNwZWVjaCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChQcmVyZWNvcmRlZFNwZWVjaCwgUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfUFJFUkVDT1JERURfU1BFRUNIKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7QXJyYXk8VnJDYXBhYmlsaXRpZXM+fSB2ckNhcGFiaWxpdGllc1xuICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZX1cbiAgICAqL1xuICAgIHNldFZyQ2FwYWJpbGl0aWVzICh2ckNhcGFiaWxpdGllcykge1xuICAgICAgICAvLyBUT0RPIG1ha2UgdGhpcyB3b3JrIGZvciBhcnJheXNcbiAgICAgICAgLy8gdGhpcy52YWxpZGF0ZVR5cGUoVnJDYXBhYmlsaXRpZXMsIHZyQ2FwYWJpbGl0aWVzKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9WUl9DQVBBQklMSVRJRVMsIHZyQ2FwYWJpbGl0aWVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtBcnJheTxWckNhcGFiaWxpdGllcz59XG4gICAgKi9cbiAgICBnZXRWckNhcGFiaWxpdGllcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWckNhcGFiaWxpdGllcywgUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfVlJfQ0FQQUJJTElUSUVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7QXJyYXk8QXVkaW9QYXNzVGhydUNhcGFiaWxpdGllcz59IGF1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXNcbiAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2V9XG4gICAgKi9cbiAgICBzZXRBdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzIChhdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzKSB7XG4gICAgICAgIC8vIFRPRE8gbWFrZSB0aGlzIHdvcmsgZm9yIGFycmF5c1xuICAgICAgICAvLyB0aGlzLnZhbGlkYXRlVHlwZShBdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzLCBhdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9BVURJT19QQVNTX1RIUlVfQ0FQQUJJTElUSUVTLCBhdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtBcnJheTxBdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzPn1cbiAgICAqL1xuICAgIGdldEF1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQXVkaW9QYXNzVGhydUNhcGFiaWxpdGllcywgUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfQVVESU9fUEFTU19USFJVX0NBUEFCSUxJVElFUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0F1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXN9IHBjbVN0cmVhbUNhcGFiaWxpdGllc1xuICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZX1cbiAgICAqL1xuICAgIHNldFBjbVN0cmVhbUNhcGFiaWxpdGllcyAocGNtU3RyZWFtQ2FwYWJpbGl0aWVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEF1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXMsIHBjbVN0cmVhbUNhcGFiaWxpdGllcyk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfUENNX1NUUkVBTV9DQVBBQklMSVRJRVMsIHBjbVN0cmVhbUNhcGFiaWxpdGllcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7QXVkaW9QYXNzVGhydUNhcGFiaWxpdGllc31cbiAgICAqL1xuICAgIGdldFBjbVN0cmVhbUNhcGFiaWxpdGllcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChBdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzLCBSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9QQ01fU1RSRUFNX0NBUEFCSUxJVElFUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1ZlaGljbGVUeXBlfSB2ZWhpY2xlVHlwZVxuICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZX1cbiAgICAqL1xuICAgIHNldFZlaGljbGVUeXBlICh2ZWhpY2xlVHlwZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlVHlwZSwgdmVoaWNsZVR5cGUpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1ZFSElDTEVfVFlQRSwgdmVoaWNsZVR5cGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1ZlaGljbGVUeXBlfVxuICAgICovXG4gICAgZ2V0VmVoaWNsZVR5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZVR5cGUsIFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1ZFSElDTEVfVFlQRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge051bWJlcn0gc3VwcG9ydGVkRGlhZ01vZGVzXG4gICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlfVxuICAgICovXG4gICAgc2V0U3VwcG9ydGVkRGlhZ01vZGVzIChzdXBwb3J0ZWREaWFnTW9kZXMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfU1VQUE9SVEVEX0RJQUdfTU9ERSwgc3VwcG9ydGVkRGlhZ01vZGVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBnZXRTdXBwb3J0ZWREaWFnTW9kZXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfU1VQUE9SVEVEX0RJQUdfTU9ERSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0hNSUNhcGFiaWxpdGllc30gaG1pQ2FwYWJpbGl0aWVzXG4gICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlfVxuICAgICovXG4gICAgc2V0SE1JQ2FwYWJpbGl0aWVzIChobWlDYXBhYmlsaXRpZXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoSE1JQ2FwYWJpbGl0aWVzLCBobWlDYXBhYmlsaXRpZXMpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX0hNSV9DQVBBQklMSVRJRVMsIGhtaUNhcGFiaWxpdGllcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7SE1JQ2FwYWJpbGl0aWVzfVxuICAgICovXG4gICAgZ2V0SE1JQ2FwYWJpbGl0aWVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEhNSUNhcGFiaWxpdGllcywgUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfSE1JX0NBUEFCSUxJVElFUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gc2RsVmVyc2lvblxuICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZX1cbiAgICAqL1xuICAgIHNldFNkbFZlcnNpb24gKHNkbFZlcnNpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfU0RMX1ZFUlNJT04sIHNkbFZlcnNpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIGdldFNkbFZlcnNpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfU0RMX1ZFUlNJT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IHN5c3RlbVNvZnR3YXJlVmVyc2lvblxuICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZX1cbiAgICAqL1xuICAgIHNldFN5c3RlbVNvZnR3YXJlVmVyc2lvbiAoc3lzdGVtU29mdHdhcmVWZXJzaW9uKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1NZU1RFTV9TT0ZUV0FSRV9WRVJTSU9OLCBzeXN0ZW1Tb2Z0d2FyZVZlcnNpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIGdldFN5c3RlbVNvZnR3YXJlVmVyc2lvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9TWVNURU1fU09GVFdBUkVfVkVSU0lPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0Jvb2xlYW59IGljb25SZXN1bWVkXG4gICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlfVxuICAgICovXG4gICAgc2V0SWNvblJlc3VtZWQgKGljb25SZXN1bWVkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX0lDT05fUkVTVU1FRCwgaWNvblJlc3VtZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgKi9cbiAgICBnZXRJY29uUmVzdW1lZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9JQ09OX1JFU1VNRUQpO1xuICAgIH1cbn1cblxuUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfU0RMX01TR19WRVJTSU9OID0gJ3N5bmNNc2dWZXJzaW9uJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX0xBTkdVQUdFID0gJ2xhbmd1YWdlJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX0hNSV9ESVNQTEFZX0xBTkdVQUdFID0gJ2htaURpc3BsYXlMYW5ndWFnZSc7XG5SZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9ESVNQTEFZX0NBUEFCSUxJVElFUyA9ICdkaXNwbGF5Q2FwYWJpbGl0aWVzJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX0JVVFRPTl9DQVBBQklMSVRJRVMgPSAnYnV0dG9uQ2FwYWJpbGl0aWVzJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1NPRlRfQlVUVE9OX0NBUEFCSUxJVElFUyA9ICdzb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1BSRVNFVF9CQU5LX0NBUEFCSUxJVElFUyA9ICdwcmVzZXRCYW5rQ2FwYWJpbGl0aWVzJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX0hNSV9aT05FX0NBUEFCSUxJVElFUyA9ICdobWlab25lQ2FwYWJpbGl0aWVzJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1NQRUVDSF9DQVBBQklMSVRJRVMgPSAnc3BlZWNoQ2FwYWJpbGl0aWVzJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1BSRVJFQ09SREVEX1NQRUVDSCA9ICdwcmVyZWNvcmRlZFNwZWVjaCc7XG5SZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9WUl9DQVBBQklMSVRJRVMgPSAndnJDYXBhYmlsaXRpZXMnO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfQVVESU9fUEFTU19USFJVX0NBUEFCSUxJVElFUyA9ICdhdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1BDTV9TVFJFQU1fQ0FQQUJJTElUSUVTID0gJ3BjbVN0cmVhbUNhcGFiaWxpdGllcyc7XG5SZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9WRUhJQ0xFX1RZUEUgPSAndmVoaWNsZVR5cGUnO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfU1VQUE9SVEVEX0RJQUdfTU9ERSA9ICdzdXBwb3J0ZWREaWFnTW9kZXMnO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfSE1JX0NBUEFCSUxJVElFUyA9ICdobWlDYXBhYmlsaXRpZXMnO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfU0RMX1ZFUlNJT04gPSAnc2RsVmVyc2lvbic7XG5SZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9TWVNURU1fU09GVFdBUkVfVkVSU0lPTiA9ICdzeXN0ZW1Tb2Z0d2FyZVZlcnNpb24nO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfSUNPTl9SRVNVTUVEID0gJ2ljb25SZXN1bWVkJztcblxuZXhwb3J0IHsgUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZSB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1JlcXVlc3QgfSBmcm9tICcuLi9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcblxuY2xhc3MgU2V0QXBwSWNvbiBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlNldEFwcEljb24pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IGZpbGVOYW1lXG4gICAgKiBAcmV0dXJuIHtTZXRBcHBJY29ufVxuICAgICovXG4gICAgc2V0RmlsZU5hbWUgKGZpbGVOYW1lKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNldEFwcEljb24uS0VZX0ZJTEVfTkFNRSwgZmlsZU5hbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIGdldEZpbGVOYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNldEFwcEljb24uS0VZX0ZJTEVfTkFNRSk7XG4gICAgfVxufVxuXG5TZXRBcHBJY29uLktFWV9GSUxFX05BTUUgPSAnc3luY0ZpbGVOYW1lJztcblxuXG5leHBvcnQgeyBTZXRBcHBJY29uIH07XG4iLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5cbmNsYXNzIFNldEFwcEljb25SZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5TZXRBcHBJY29uKTtcbiAgICB9XG59XG5cbmV4cG9ydCB7IFNldEFwcEljb25SZXNwb25zZSB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBTb2Z0QnV0dG9uVHlwZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgU29mdEJ1dHRvblR5cGUgZXh0ZW5kcyBFbnVtIHtcbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0JUX1RFWFQgKCkge1xuICAgICAgICByZXR1cm4gU29mdEJ1dHRvblR5cGUuX01BUC5TQlRfVEVYVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTQlRfSU1BR0UgKCkge1xuICAgICAgICByZXR1cm4gU29mdEJ1dHRvblR5cGUuX01BUC5TQlRfSU1BR0U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0JUX0JPVEggKCkge1xuICAgICAgICByZXR1cm4gU29mdEJ1dHRvblR5cGUuX01BUC5TQlRfQk9USDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gU29mdEJ1dHRvblR5cGUuX3ZhbHVlRm9yS2V5KGtleSwgU29mdEJ1dHRvblR5cGUuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFNvZnRCdXR0b25UeXBlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgU29mdEJ1dHRvblR5cGUuX01BUCk7XG4gICAgfVxufVxuXG5Tb2Z0QnV0dG9uVHlwZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1NCVF9URVhUJzogJ1RFWFQnLFxuICAgICdTQlRfSU1BR0UnOiAnSU1BR0UnLFxuICAgICdTQlRfQk9USCc6ICdCT1RIJyxcblxufSk7XG5cbmV4cG9ydCB7IFNvZnRCdXR0b25UeXBlIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBTeXN0ZW1BY3Rpb25cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIFN5c3RlbUFjdGlvbiBleHRlbmRzIEVudW0ge1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBERUZBVUxUX0FDVElPTiAoKSB7XG4gICAgICAgIHJldHVybiBTeXN0ZW1BY3Rpb24uX01BUC5ERUZBVUxUX0FDVElPTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTVEVBTF9GT0NVUyAoKSB7XG4gICAgICAgIHJldHVybiBTeXN0ZW1BY3Rpb24uX01BUC5TVEVBTF9GT0NVUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBLRUVQX0NPTlRFWFQgKCkge1xuICAgICAgICByZXR1cm4gU3lzdGVtQWN0aW9uLl9NQVAuS0VFUF9DT05URVhUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgKiBAcGFyYW0gdmFsdWUgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBTeXN0ZW1BY3Rpb24uX3ZhbHVlRm9yS2V5KGtleSwgU3lzdGVtQWN0aW9uLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBTeXN0ZW1BY3Rpb24uX2tleUZvclZhbHVlKHZhbHVlLCBTeXN0ZW1BY3Rpb24uX01BUCk7XG4gICAgfVxufVxuXG5TeXN0ZW1BY3Rpb24uX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdERUZBVUxUX0FDVElPTic6ICdERUZBVUxUX0FDVElPTicsXG4gICAgJ1NURUFMX0ZPQ1VTJzogJ1NURUFMX0ZPQ1VTJyxcbiAgICAnS0VFUF9DT05URVhUJzogJ0tFRVBfQ09OVEVYVCcsXG5cbn0pO1xuXG5leHBvcnQgeyBTeXN0ZW1BY3Rpb24gfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IFNvZnRCdXR0b25UeXBlIH0gZnJvbSAnLi4vZW51bXMvU29mdEJ1dHRvblR5cGUuanMnO1xuaW1wb3J0IHsgU3lzdGVtQWN0aW9uIH0gZnJvbSAnLi4vZW51bXMvU3lzdGVtQWN0aW9uLmpzJztcbmltcG9ydCB7IEltYWdlIH0gZnJvbSAnLi9JbWFnZS5qcyc7XG5cblxuY2xhc3MgU29mdEJ1dHRvbiBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1NvZnRCdXR0b25UeXBlfSB0eXBlXG4gICAgKiBAcmV0dXJuIHtTb2Z0QnV0dG9ufVxuICAgICovXG4gICAgc2V0VHlwZSAodHlwZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShTb2Z0QnV0dG9uVHlwZSwgdHlwZSk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU29mdEJ1dHRvbi5LRVlfVFlQRSwgdHlwZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U29mdEJ1dHRvblR5cGV9XG4gICAgKi9cbiAgICBnZXRUeXBlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFNvZnRCdXR0b25UeXBlLCBTb2Z0QnV0dG9uLktFWV9UWVBFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0XG4gICAgKiBAcmV0dXJuIHtTb2Z0QnV0dG9ufVxuICAgICovXG4gICAgc2V0VGV4dCAodGV4dCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTb2Z0QnV0dG9uLktFWV9URVhULCB0ZXh0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBnZXRUZXh0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNvZnRCdXR0b24uS0VZX1RFWFQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtJbWFnZX0gaW1hZ2VcbiAgICAqIEByZXR1cm4ge1NvZnRCdXR0b259XG4gICAgKi9cbiAgICBzZXRJbWFnZSAoaW1hZ2UpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoSW1hZ2UsIGltYWdlKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTb2Z0QnV0dG9uLktFWV9JTUFHRSwgaW1hZ2UpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0ltYWdlfVxuICAgICovXG4gICAgZ2V0SW1hZ2UgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoSW1hZ2UsIFNvZnRCdXR0b24uS0VZX0lNQUdFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNIaWdobGlnaHRlZFxuICAgICogQHJldHVybiB7U29mdEJ1dHRvbn1cbiAgICAqL1xuICAgIHNldElzSGlnaGxpZ2h0ZWQgKGlzSGlnaGxpZ2h0ZWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU29mdEJ1dHRvbi5LRVlfSVNfSElHSExJR0hURUQsIGlzSGlnaGxpZ2h0ZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgKi9cbiAgICBnZXRJc0hpZ2hsaWdodGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNvZnRCdXR0b24uS0VZX0lTX0hJR0hMSUdIVEVEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSBzb2Z0QnV0dG9uSURcbiAgICAqIEByZXR1cm4ge1NvZnRCdXR0b259XG4gICAgKi9cbiAgICBzZXRTb2Z0QnV0dG9uSUQgKHNvZnRCdXR0b25JRCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTb2Z0QnV0dG9uLktFWV9TT0ZUX0JVVFRPTl9JRCwgc29mdEJ1dHRvbklEKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBnZXRTb2Z0QnV0dG9uSUQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU29mdEJ1dHRvbi5LRVlfU09GVF9CVVRUT05fSUQpO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N5c3RlbUFjdGlvbn0gc3lzdGVtQWN0aW9uXG4gICAgKiBAcmV0dXJuIHtTb2Z0QnV0dG9ufVxuICAgICovXG4gICAgc2V0U3lzdGVtQWN0aW9uIChzeXN0ZW1BY3Rpb24pIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoU3lzdGVtQWN0aW9uLCBzeXN0ZW1BY3Rpb24pO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNvZnRCdXR0b24uS0VZX1NZU1RFTV9BQ1RJT04sIHN5c3RlbUFjdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3lzdGVtQWN0aW9ufVxuICAgICovXG4gICAgZ2V0U3lzdGVtQWN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFN5c3RlbUFjdGlvbiwgU29mdEJ1dHRvbi5LRVlfU1lTVEVNX0FDVElPTik7XG4gICAgfVxufVxuXG5Tb2Z0QnV0dG9uLktFWV9UWVBFID0gJ3R5cGUnO1xuU29mdEJ1dHRvbi5LRVlfVEVYVCA9ICd0ZXh0JztcblNvZnRCdXR0b24uS0VZX0lNQUdFID0gJ2ltYWdlJztcblNvZnRCdXR0b24uS0VZX0lTX0hJR0hMSUdIVEVEID0gJ2lzSGlnaGxpZ2h0ZWQnO1xuU29mdEJ1dHRvbi5LRVlfU09GVF9CVVRUT05fSUQgPSAnc29mdEJ1dHRvbklEJztcblNvZnRCdXR0b24uS0VZX1NZU1RFTV9BQ1RJT04gPSAnc3lzdGVtQWN0aW9uJztcblxuZXhwb3J0IHsgU29mdEJ1dHRvbiB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBNZXRhZGF0YVR5cGVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIE1ldGFkYXRhVHlwZSBleHRlbmRzIEVudW0ge1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBtZWRpYVRpdGxlICgpIHtcbiAgICAgICAgcmV0dXJuIE1ldGFkYXRhVHlwZS5fTUFQLm1lZGlhVGl0bGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgbWVkaWFBcnRpc3QgKCkge1xuICAgICAgICByZXR1cm4gTWV0YWRhdGFUeXBlLl9NQVAubWVkaWFBcnRpc3Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgbWVkaWFBbGJ1bSAoKSB7XG4gICAgICAgIHJldHVybiBNZXRhZGF0YVR5cGUuX01BUC5tZWRpYUFsYnVtO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IG1lZGlhWWVhciAoKSB7XG4gICAgICAgIHJldHVybiBNZXRhZGF0YVR5cGUuX01BUC5tZWRpYVllYXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgbWVkaWFHZW5yZSAoKSB7XG4gICAgICAgIHJldHVybiBNZXRhZGF0YVR5cGUuX01BUC5tZWRpYUdlbnJlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IG1lZGlhU3RhdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBNZXRhZGF0YVR5cGUuX01BUC5tZWRpYVN0YXRpb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgcmF0aW5nICgpIHtcbiAgICAgICAgcmV0dXJuIE1ldGFkYXRhVHlwZS5fTUFQLnJhdGluZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBjdXJyZW50VGVtcGVyYXR1cmUgKCkge1xuICAgICAgICByZXR1cm4gTWV0YWRhdGFUeXBlLl9NQVAuY3VycmVudFRlbXBlcmF0dXJlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IG1heGltdW1UZW1wZXJhdHVyZSAoKSB7XG4gICAgICAgIHJldHVybiBNZXRhZGF0YVR5cGUuX01BUC5tYXhpbXVtVGVtcGVyYXR1cmU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgbWluaW11bVRlbXBlcmF0dXJlICgpIHtcbiAgICAgICAgcmV0dXJuIE1ldGFkYXRhVHlwZS5fTUFQLm1pbmltdW1UZW1wZXJhdHVyZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCB3ZWF0aGVyVGVybSAoKSB7XG4gICAgICAgIHJldHVybiBNZXRhZGF0YVR5cGUuX01BUC53ZWF0aGVyVGVybTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBodW1pZGl0eSAoKSB7XG4gICAgICAgIHJldHVybiBNZXRhZGF0YVR5cGUuX01BUC5odW1pZGl0eTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gTWV0YWRhdGFUeXBlLl92YWx1ZUZvcktleShrZXksIE1ldGFkYXRhVHlwZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gTWV0YWRhdGFUeXBlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgTWV0YWRhdGFUeXBlLl9NQVApO1xuICAgIH1cbn1cblxuTWV0YWRhdGFUeXBlLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnbWVkaWFUaXRsZSc6ICdtZWRpYVRpdGxlJyxcbiAgICAnbWVkaWFBcnRpc3QnOiAnbWVkaWFBcnRpc3QnLFxuICAgICdtZWRpYUFsYnVtJzogJ21lZGlhQWxidW0nLFxuICAgICdtZWRpYVllYXInOiAnbWVkaWFZZWFyJyxcbiAgICAnbWVkaWFHZW5yZSc6ICdtZWRpYUdlbnJlJyxcbiAgICAnbWVkaWFTdGF0aW9uJzogJ21lZGlhU3RhdGlvbicsXG4gICAgJ3JhdGluZyc6ICdyYXRpbmcnLFxuICAgICdjdXJyZW50VGVtcGVyYXR1cmUnOiAnY3VycmVudFRlbXBlcmF0dXJlJyxcbiAgICAnbWF4aW11bVRlbXBlcmF0dXJlJzogJ21heGltdW1UZW1wZXJhdHVyZScsXG4gICAgJ21pbmltdW1UZW1wZXJhdHVyZSc6ICdtaW5pbXVtVGVtcGVyYXR1cmUnLFxuICAgICd3ZWF0aGVyVGVybSc6ICd3ZWF0aGVyVGVybScsXG4gICAgJ2h1bWlkaXR5JzogJ2h1bWlkaXR5JyxcblxufSk7XG5cbmV4cG9ydCB7IE1ldGFkYXRhVHlwZSB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBNZXRhZGF0YVR5cGUgfSBmcm9tICcuLi9lbnVtcy9NZXRhZGF0YVR5cGUuanMnO1xuXG5jbGFzcyBNZXRhZGF0YVRhZ3MgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7QXJyYXk8TWV0YWRhdGFUeXBlPn0gbWFpbkZpZWxkMVxuICAgICogQHJldHVybiB7TWV0YWRhdGFUYWdzfVxuICAgICovXG4gICAgc2V0TWFpbkZpZWxkMSAobWFpbkZpZWxkMSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihNZXRhZGF0YVRhZ3MuS0VZX01BSU5fRklFTERfMSwgbWFpbkZpZWxkMSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7QXJyYXk8TWV0YWRhdGFUeXBlPn1cbiAgICAqL1xuICAgIGdldE1haW5GaWVsZDEgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTWV0YWRhdGFUeXBlLCBNZXRhZGF0YVRhZ3MuS0VZX01BSU5fRklFTERfMSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0FycmF5PE1ldGFkYXRhVHlwZT59IG1haW5GaWVsZDJcbiAgICAqIEByZXR1cm4ge01ldGFkYXRhVGFnc31cbiAgICAqL1xuICAgIHNldE1haW5GaWVsZDIgKG1haW5GaWVsZDIpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTWV0YWRhdGFUYWdzLktFWV9NQUlOX0ZJRUxEXzIsIG1haW5GaWVsZDIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0FycmF5PE1ldGFkYXRhVHlwZT59XG4gICAgKi9cbiAgICBnZXRNYWluRmllbGQyICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KE1ldGFkYXRhVHlwZSwgTWV0YWRhdGFUYWdzLktFWV9NQUlOX0ZJRUxEXzIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtBcnJheTxNZXRhZGF0YVR5cGU+fSBtYWluRmllbGQzXG4gICAgKiBAcmV0dXJuIHtNZXRhZGF0YVRhZ3N9XG4gICAgKi9cbiAgICBzZXRNYWluRmllbGQzIChtYWluRmllbGQzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE1ldGFkYXRhVGFncy5LRVlfTUFJTl9GSUVMRF8zLCBtYWluRmllbGQzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtBcnJheTxNZXRhZGF0YVR5cGU+fVxuICAgICovXG4gICAgZ2V0TWFpbkZpZWxkMyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChNZXRhZGF0YVR5cGUsIE1ldGFkYXRhVGFncy5LRVlfTUFJTl9GSUVMRF8zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7QXJyYXk8TWV0YWRhdGFUeXBlPn0gbWFpbkZpZWxkNFxuICAgICogQHJldHVybiB7TWV0YWRhdGFUYWdzfVxuICAgICovXG4gICAgc2V0TWFpbkZpZWxkNCAobWFpbkZpZWxkNCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihNZXRhZGF0YVRhZ3MuS0VZX01BSU5fRklFTERfNCwgbWFpbkZpZWxkNCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7QXJyYXk8TWV0YWRhdGFUeXBlPn1cbiAgICAqL1xuICAgIGdldE1haW5GaWVsZDQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTWV0YWRhdGFUeXBlLCBNZXRhZGF0YVRhZ3MuS0VZX01BSU5fRklFTERfNCk7XG4gICAgfVxufVxuXG5NZXRhZGF0YVRhZ3MuS0VZX01BSU5fRklFTERfMSA9ICdtYWluRmllbGQxJztcbk1ldGFkYXRhVGFncy5LRVlfTUFJTl9GSUVMRF8yID0gJ21haW5GaWVsZDInO1xuTWV0YWRhdGFUYWdzLktFWV9NQUlOX0ZJRUxEXzMgPSAnbWFpbkZpZWxkMyc7XG5NZXRhZGF0YVRhZ3MuS0VZX01BSU5fRklFTERfNCA9ICdtYWluRmllbGQ0JztcblxuZXhwb3J0IHsgTWV0YWRhdGFUYWdzIH07XG4iLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYge0VudW19IFRleHRBbGlnbm1lbnRcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIFRleHRBbGlnbm1lbnQgZXh0ZW5kcyBFbnVtIHtcbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IExFRlRfQUxJR05FRCAoKSB7XG4gICAgICAgIHJldHVybiBUZXh0QWxpZ25tZW50Ll9NQVAuTEVGVF9BTElHTkVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBSSUdIVF9BTElHTkVEICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRBbGlnbm1lbnQuX01BUC5SSUdIVF9BTElHTkVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBDRU5URVJFRCAoKSB7XG4gICAgICAgIHJldHVybiBUZXh0QWxpZ25tZW50Ll9NQVAuQ0VOVEVSRUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFRleHRBbGlnbm1lbnQuX3ZhbHVlRm9yS2V5KGtleSwgVGV4dEFsaWdubWVudC5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gVGV4dEFsaWdubWVudC5fa2V5Rm9yVmFsdWUodmFsdWUsIFRleHRBbGlnbm1lbnQuX01BUCk7XG4gICAgfVxufVxuXG5UZXh0QWxpZ25tZW50Ll9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnTEVGVF9BTElHTkVEJzogJ0xFRlRfQUxJR05FRCcsXG4gICAgJ1JJR0hUX0FMSUdORUQnOiAnUklHSFRfQUxJR05FRCcsXG4gICAgJ0NFTlRFUkVEJzogJ0NFTlRFUkVEJyxcblxuXG59KTtcblxuZXhwb3J0IHsgVGV4dEFsaWdubWVudCB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBTb2Z0QnV0dG9uIH0gZnJvbSAnLi4vc3RydWN0cy9Tb2Z0QnV0dG9uLmpzJztcbmltcG9ydCB7IEltYWdlIH0gZnJvbSAnLi4vc3RydWN0cy9JbWFnZS5qcyc7XG5pbXBvcnQgeyBNZXRhZGF0YVRhZ3MgfSBmcm9tICcuLi9zdHJ1Y3RzL01ldGFkYXRhVGFncy5qcyc7XG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFRleHRBbGlnbm1lbnQgfSBmcm9tICcuLi9lbnVtcy9UZXh0QWxpZ25tZW50LmpzJztcblxuY2xhc3MgU2hvdyBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlNob3cpO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gbWFpbkZpZWxkMVxuICAgICogQHJldHVybiB7U2hvd31cbiAgICAqL1xuICAgIHNldE1haW5GaWVsZDEgKG1haW5GaWVsZDEpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2hvdy5LRVlfTUFJTl9GSUVMRF8xLCBtYWluRmllbGQxKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBnZXRNYWluRmllbGQxICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNob3cuS0VZX01BSU5fRklFTERfMSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gbWFpbkZpZWxkMlxuICAgICogQHJldHVybiB7U2hvd31cbiAgICAqL1xuICAgIHNldE1haW5GaWVsZDIgKG1haW5GaWVsZDIpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2hvdy5LRVlfTUFJTl9GSUVMRF8yLCBtYWluRmllbGQyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBnZXRNYWluRmllbGQyICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNob3cuS0VZX01BSU5fRklFTERfMik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gbWFpbkZpZWxkM1xuICAgICogQHJldHVybiB7U2hvd31cbiAgICAqL1xuICAgIHNldE1haW5GaWVsZDMgKG1haW5GaWVsZDMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2hvdy5LRVlfTUFJTl9GSUVMRF8zLCBtYWluRmllbGQzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBnZXRNYWluRmllbGQzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNob3cuS0VZX01BSU5fRklFTERfMyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gbWFpbkZpZWxkNFxuICAgICogQHJldHVybiB7U2hvd31cbiAgICAqL1xuICAgIHNldE1haW5GaWVsZDQgKG1haW5GaWVsZDQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2hvdy5LRVlfTUFJTl9GSUVMRF80LCBtYWluRmllbGQ0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBnZXRNYWluRmllbGQ0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNob3cuS0VZX01BSU5fRklFTERfNCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1RleHRBbGlnbm1lbnR9IG1lbnVQYXJhbXNcbiAgICAqIEByZXR1cm4ge1Nob3d9XG4gICAgKi9cbiAgICBzZXRBbGlnbm1lbnQgKGFsaWdubWVudCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShUZXh0QWxpZ25tZW50LCBhbGlnbm1lbnQpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNob3cuS0VZX0FMSUdOTUVOVCwgYWxpZ25tZW50KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtUZXh0QWxpZ25tZW50fVxuICAgICovXG4gICAgZ2V0QWxpZ25tZW50ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFRleHRBbGlnbm1lbnQsIFNob3cuS0VZX0FMSUdOTUVOVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gc3RhdHVzQmFyXG4gICAgKiBAcmV0dXJuIHtTaG93fVxuICAgICovXG4gICAgc2V0U3RhdHVzQmFyIChzdGF0dXNCYXIpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2hvdy5LRVlfU1RBVFVTX0JBUiwgc3RhdHVzQmFyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBnZXRTdGF0dXNCYXIgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2hvdy5LRVlfU1RBVFVTX0JBUik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gbWVkaWFDbG9ja1xuICAgICogQHJldHVybiB7U2hvd31cbiAgICAqL1xuICAgIHNldE1lZGlhQ2xvY2sgKG1lZGlhQ2xvY2spIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2hvdy5LRVlfTUVESUFfQ0xPQ0ssIG1lZGlhQ2xvY2spO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIGdldE1lZGlhQ2xvY2sgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2hvdy5LRVlfTUVESUFfQ0xPQ0spO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IG1lZGlhVHJhY2tcbiAgICAqIEByZXR1cm4ge1Nob3d9XG4gICAgKi9cbiAgICBzZXRNZWRpYVRyYWNrIChtZWRpYVRyYWNrKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNob3cuS0VZX01FRElBX1RSQUNLLCBtZWRpYVRyYWNrKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBnZXRNZWRpYVRyYWNrICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNob3cuS0VZX01FRElBX1RSQUNLKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7SW1hZ2V9IGdyYXBoaWNcbiAgICAqIEByZXR1cm4ge1Nob3d9XG4gICAgKi9cbiAgICBzZXRHcmFwaGljIChncmFwaGljKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEltYWdlLCBncmFwaGljKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTaG93LktFWV9HUkFQSElDLCBncmFwaGljKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtJbWFnZX1cbiAgICAqL1xuICAgIGdldEdyYXBoaWMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoSW1hZ2UsIFNob3cuS0VZX0dSQVBISUMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtJbWFnZX0gc2Vjb25kYXJ5R3JhcGhpY1xuICAgICogQHJldHVybiB7U2hvd31cbiAgICAqL1xuICAgIHNldFNlY29uZGFyeUdyYXBoaWMgKHNlY29uZGFyeUdyYXBoaWMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoSW1hZ2UsIHNlY29uZGFyeUdyYXBoaWMpO1xuXG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNob3cuS0VZX1NFQ09OREFSWV9HUkFQSElDLCBzZWNvbmRhcnlHcmFwaGljKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtJbWFnZX1cbiAgICAqL1xuICAgIGdldFNlY29uZGFyeUdyYXBoaWMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoSW1hZ2UsIFNob3cuS0VZX1NFQ09OREFSWV9HUkFQSElDKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7QXJyYXk8U29mdEJ1dHRvbj59IHNvZnRCdXR0b25zXG4gICAgKiBAcmV0dXJuIHtTaG93fVxuICAgICovXG4gICAgc2V0U29mdEJ1dHRvbnMgKHNvZnRCdXR0b25zKSB7XG4gICAgICAgIC8vIFRPRE8gbWFrZSB0aGlzIHdvcmsgZm9yIGFycmF5c1xuICAgICAgICAvLyB0aGlzLnZhbGlkYXRlVHlwZShTb2Z0QnV0dG9uLCBzb2Z0QnV0dG9ucyk7XG5cbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2hvdy5LRVlfU09GVF9CVVRUT05TLCBzb2Z0QnV0dG9ucyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7QXJyYXk8U29mdEJ1dHRvbj59XG4gICAgKi9cbiAgICBnZXRTb2Z0QnV0dG9ucyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChTb2Z0QnV0dG9uLCBTaG93LktFWV9TT0ZUX0JVVFRPTlMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtBcnJheTxTdHJpbmc+fSBjdXN0b21QcmVzZXRzXG4gICAgKiBAcmV0dXJuIHtTaG93fVxuICAgICovXG4gICAgc2V0Q3VzdG9tUHJlc2V0cyAoY3VzdG9tUHJlc2V0cykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTaG93LktFWV9DVVNUT01fUFJFU0VUUywgY3VzdG9tUHJlc2V0cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7QXJyYXk8U3RyaW5nPn1cbiAgICAqL1xuICAgIGdldEN1c3RvbVByZXNldHMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2hvdy5LRVlfQ1VTVE9NX1BSRVNFVFMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtNZXRhZGF0YVRhZ3N9IG1ldGFkYXRhVGFnc1xuICAgICogQHJldHVybiB7U2hvd31cbiAgICAqL1xuICAgIHNldE1ldGFkYXRhVGFncyAobWV0YWRhdGFUYWdzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKE1ldGFkYXRhVGFncywgbWV0YWRhdGFUYWdzKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTaG93LktFWV9NRVRBREFUQV9UQUdTLCBtZXRhZGF0YVRhZ3MpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge01ldGFkYXRhVGFnc31cbiAgICAqL1xuICAgIGdldE1ldGFkYXRhVGFncyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChNZXRhZGF0YVRhZ3MsIFNob3cuS0VZX01FVEFEQVRBX1RBR1MpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IHRlbXBsYXRlVGl0bGVcbiAgICAqIEByZXR1cm4ge1Nob3d9XG4gICAgKi9cbiAgICBzZXRUZW1wbGF0ZVRpdGxlICh0ZW1wbGF0ZVRpdGxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNob3cuS0VZX1RFTVBMQVRFX1RJVExFLCB0ZW1wbGF0ZVRpdGxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBnZXRUZW1wbGF0ZVRpdGxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNob3cuS0VZX1RFTVBMQVRFX1RJVExFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSB3aW5kb3dJRFxuICAgICogQHJldHVybiB7U2hvd31cbiAgICAqL1xuICAgIHNldFdpbmRvd0lEICh3aW5kb3dJRCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTaG93LktFWV9XSU5ET1dfSUQsIHdpbmRvd0lEKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBnZXRXaW5kb3dJRCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTaG93LktFWV9XSU5ET1dfSUQpO1xuICAgIH1cbn1cblxuU2hvdy5LRVlfTUFJTl9GSUVMRF8xID0gJ21haW5GaWVsZDEnO1xuU2hvdy5LRVlfTUFJTl9GSUVMRF8yID0gJ21haW5GaWVsZDInO1xuU2hvdy5LRVlfTUFJTl9GSUVMRF8zID0gJ21haW5GaWVsZDMnO1xuU2hvdy5LRVlfTUFJTl9GSUVMRF80ID0gJ21haW5GaWVsZDQnO1xuU2hvdy5LRVlfQUxJR05NRU5UID0gJ2FsaWdubWVudCc7XG5TaG93LktFWV9TVEFUVVNfQkFSID0gJ3N0YXR1c0Jhcic7XG5TaG93LktFWV9NRURJQV9DTE9DSyA9ICdtZWRpYUNsb2NrJztcblNob3cuS0VZX01FRElBX1RSQUNLID0gJ21lZGlhVHJhY2snO1xuU2hvdy5LRVlfR1JBUEhJQyA9ICdncmFwaGljJztcblNob3cuS0VZX1NFQ09OREFSWV9HUkFQSElDID0gJ3NlY29uZGFyeUdyYXBoaWMnO1xuU2hvdy5LRVlfU09GVF9CVVRUT05TID0gJ3NvZnRCdXR0b25zJztcblNob3cuS0VZX0NVU1RPTV9QUkVTRVRTID0gJ2N1c3RvbVByZXNldHMnO1xuU2hvdy5LRVlfTUVUQURBVEFfVEFHUyA9ICdtZXRhZGF0YVRhZ3MnO1xuU2hvdy5LRVlfVEVNUExBVEVfVElUTEUgPSAndGVtcGxhdGVUaXRsZSc7XG5TaG93LktFWV9XSU5ET1dfSUQgPSAnd2luZG93SUQnO1xuXG5leHBvcnQgeyBTaG93IH07XG4iLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5cbmNsYXNzIFNob3dSZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5TaG93KTtcbiAgICB9XG59XG5cbmV4cG9ydCB7IFNob3dSZXNwb25zZSB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1JlcXVlc3QgfSBmcm9tICcuLi9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcblxuY2xhc3MgVW5yZWdpc3RlckFwcEludGVyZmFjZSBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlVucmVnaXN0ZXJBcHBJbnRlcmZhY2UpO1xuICAgIH1cbn1cblxuXG5leHBvcnQgeyBVbnJlZ2lzdGVyQXBwSW50ZXJmYWNlIH07XG4iLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5cbmNsYXNzIFVucmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5VbnJlZ2lzdGVyQXBwSW50ZXJmYWNlKTtcbiAgICB9XG59XG5cbmV4cG9ydCB7IFVucmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZSB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbi8vIG1lc3NhZ2VzXG5pbXBvcnQgeyBBZGRDb21tYW5kIH0gZnJvbSAnLi9tZXNzYWdlcy9BZGRDb21tYW5kLmpzJztcbmltcG9ydCB7IEFkZENvbW1hbmRSZXNwb25zZSB9IGZyb20gJy4vbWVzc2FnZXMvQWRkQ29tbWFuZFJlc3BvbnNlLmpzJztcbmltcG9ydCB7IE9uSG1pU3RhdHVzIH0gZnJvbSAnLi9tZXNzYWdlcy9PbkhtaVN0YXR1cy5qcyc7XG5pbXBvcnQgeyBPbkxhbmd1YWdlQ2hhbmdlIH0gZnJvbSAnLi9tZXNzYWdlcy9Pbkxhbmd1YWdlQ2hhbmdlLmpzJztcbmltcG9ydCB7IFB1dEZpbGUgfSBmcm9tICcuL21lc3NhZ2VzL1B1dEZpbGUuanMnO1xuaW1wb3J0IHsgUHV0RmlsZVJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9QdXRGaWxlUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgUmVnaXN0ZXJBcHBJbnRlcmZhY2UgfSBmcm9tICcuL21lc3NhZ2VzL1JlZ2lzdGVyQXBwSW50ZXJmYWNlLmpzJztcbmltcG9ydCB7IFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL1JlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgU2V0QXBwSWNvbiB9IGZyb20gJy4vbWVzc2FnZXMvU2V0QXBwSWNvbi5qcyc7XG5pbXBvcnQgeyBTZXRBcHBJY29uUmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL1NldEFwcEljb25SZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBTaG93IH0gZnJvbSAnLi9tZXNzYWdlcy9TaG93LmpzJztcbmltcG9ydCB7IFNob3dSZXNwb25zZSB9IGZyb20gJy4vbWVzc2FnZXMvU2hvd1Jlc3BvbnNlLmpzJztcbmltcG9ydCB7IFVucmVnaXN0ZXJBcHBJbnRlcmZhY2UgfSBmcm9tICcuL21lc3NhZ2VzL1VucmVnaXN0ZXJBcHBJbnRlcmZhY2UuanMnO1xuaW1wb3J0IHsgVW5yZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9VbnJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuanMnO1xuXG4vLyBvdGhlclxuaW1wb3J0IHsgUnBjVHlwZSB9IGZyb20gJy4vZW51bXMvUnBjVHlwZS5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IEpzb25ScGNNYXJzaGFsbGVyIH0gZnJvbSAnLi8uLi91dGlsL0pzb25ScGNNYXJzaGFsbGVyLmpzJztcbmltcG9ydCB7IEJpbmFyeUZyYW1lSGVhZGVyIH0gZnJvbSAnLi8uLi9wcm90b2NvbC9CaW5hcnlGcmFtZUhlYWRlci5qcyc7XG5cbmNsYXNzIFJwY0NyZWF0b3Ige1xuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGFuIFNkbFBhY2tldCB0byBhbiBScGNNZXNzYWdlXG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldFxuICAgICAqIEByZXR1cm4ge1JwY01lc3NhZ2V9XG4gICAgICovXG4gICAgc3RhdGljIGNvbnN0cnVjdCAoc2RsUGFja2V0KSB7XG4gICAgICAgIGNvbnN0IHBheWxvYWQgPSBzZGxQYWNrZXQuZ2V0UGF5bG9hZCgpO1xuICAgICAgICBjb25zdCBiaW5hcnlGcmFtZUhlYWRlciA9IEJpbmFyeUZyYW1lSGVhZGVyLmZyb21CaW5hcnlIZWFkZXIocGF5bG9hZCk7XG5cbiAgICAgICAgbGV0IG1lc3NhZ2U7XG4gICAgICAgIGNvbnN0IHJwY1R5cGUgPSBiaW5hcnlGcmFtZUhlYWRlci5nZXRScGNUeXBlKCk7XG4gICAgICAgIGNvbnN0IHJwY05hbWUgPSBScGNUeXBlLmtleUZvclZhbHVlKHJwY1R5cGUpO1xuICAgICAgICBjb25zdCBjb3JyZWxhdGlvbklkID0gYmluYXJ5RnJhbWVIZWFkZXIuZ2V0Q29ycmVsYXRpb25JZCgpO1xuICAgICAgICBjb25zdCBmdW5jdGlvbklkID0gYmluYXJ5RnJhbWVIZWFkZXIuZ2V0RnVuY3Rpb25JZCgpO1xuICAgICAgICBjb25zdCBmdW5jdGlvbk5hbWUgPSBGdW5jdGlvbklELmtleUZvclZhbHVlKGZ1bmN0aW9uSWQpO1xuICAgICAgICBjb25zdCBidWxrRGF0YSA9IGJpbmFyeUZyYW1lSGVhZGVyLmdldEJ1bGtEYXRhKCk7XG4gICAgICAgIGNvbnN0IGpzb25EYXRhID0gYmluYXJ5RnJhbWVIZWFkZXIuZ2V0SnNvbkRhdGEoKTtcbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgcGFyYW1ldGVyczogSnNvblJwY01hcnNoYWxsZXIudW5tYXJzaGFsbChqc29uRGF0YSksXG4gICAgICAgIH07XG5cbiAgICAgICAgc3dpdGNoIChmdW5jdGlvbklkKSB7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuQWRkQ29tbWFuZDpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgQWRkQ29tbWFuZChwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IEFkZENvbW1hbmRSZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5PbkhNSVN0YXR1czogLy8gVE9ETzogc2hvdWxkIE9uSE1JU3RhdHVzIGJlIE9uSG1pU3RhdHVzLCBvciB0aGUgY2xhc3MgbmFtZSBjaGFuZ2UgdG8gT25ITUlTdGF0dXM/IG9yIGlzIHRoaXMgZmluZSBhcyBpcz9cbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5OT1RJRklDQVRJT04pIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBPbkhtaVN0YXR1cyhwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5Pbkxhbmd1YWdlQ2hhbmdlOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLk5PVElGSUNBVElPTikge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IE9uTGFuZ3VhZ2VDaGFuZ2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuUHV0RmlsZTpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgUHV0RmlsZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFB1dEZpbGVSZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5SZWdpc3RlckFwcEludGVyZmFjZTpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgUmVnaXN0ZXJBcHBJbnRlcmZhY2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELlNldEFwcEljb246XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVRVUVTVCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFNldEFwcEljb24ocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBTZXRBcHBJY29uUmVzcG9uc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuU2hvdzpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgU2hvdyhwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFNob3dSZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5VbnJlZ2lzdGVyQXBwSW50ZXJmYWNlOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBVbnJlZ2lzdGVyQXBwSW50ZXJmYWNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFU1BPTlNFKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgVW5yZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtZXNzYWdlID09PSBudWxsIHx8IG1lc3NhZ2UgPT09IHVuZGVmaW5lZCkgeyAvLyBpbmZvcm1zIG9mIG1pc3NpbmcgY2xhc3Nlc1xuICAgICAgICAgICAgY29uc29sZS53YXJuKGBScGNDcmVhdG9yIGNvdWxkbid0IGNvbnN0cnVjdCBhbiBSUEMgZm9yIHRoZSAke2Z1bmN0aW9uTmFtZX0gJHtycGNOYW1lfWApO1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUIHx8IHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgIG1lc3NhZ2Uuc2V0Q29ycmVsYXRpb25JZChjb3JyZWxhdGlvbklkKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYnVsa0RhdGEpIHtcbiAgICAgICAgICAgIG1lc3NhZ2Uuc2V0QnVsa0RhdGEoYnVsa0RhdGEpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfVxufVxuXG5leHBvcnQgeyBScGNDcmVhdG9yIH07XG4iLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYge0VudW19IFZpZGVvU3RyZWFtaW5nUHJvdG9jb2xcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIFZpZGVvU3RyZWFtaW5nUHJvdG9jb2wgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSQVcgKCkge1xuICAgICAgICByZXR1cm4gVmlkZW9TdHJlYW1pbmdQcm90b2NvbC5fTUFQLlJBVztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSVFAgKCkge1xuICAgICAgICByZXR1cm4gVmlkZW9TdHJlYW1pbmdQcm90b2NvbC5fTUFQLlJUUDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSVFNQICgpIHtcbiAgICAgICAgcmV0dXJuIFZpZGVvU3RyZWFtaW5nUHJvdG9jb2wuX01BUC5SVFNQO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJUTVAgKCkge1xuICAgICAgICByZXR1cm4gVmlkZW9TdHJlYW1pbmdQcm90b2NvbC5fTUFQLlJUTVA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgV0VCTSAoKSB7XG4gICAgICAgIHJldHVybiBWaWRlb1N0cmVhbWluZ1Byb3RvY29sLl9NQVAuV0VCTTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gVmlkZW9TdHJlYW1pbmdQcm90b2NvbC5fdmFsdWVGb3JLZXkoa2V5LCBWaWRlb1N0cmVhbWluZ1Byb3RvY29sLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBWaWRlb1N0cmVhbWluZ1Byb3RvY29sLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgVmlkZW9TdHJlYW1pbmdQcm90b2NvbC5fTUFQKTtcbiAgICB9XG59XG5cblZpZGVvU3RyZWFtaW5nUHJvdG9jb2wuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgIC8qKlxuICAgICAqIFJhdyBzdHJlYW0gYnl0ZXMgdGhhdCBjb250YWlucyBubyB0aW1lc3RhbXAgZGF0YSBhbmQgaXMgdGhlIGxvd2VzdCBzdXBwb3J0ZWQgdmlkZW8gc3RyZWFtaW5nXG4gICAgICovXG4gICAgJ1JBVyc6ICdSQVcnLFxuICAgIC8qKlxuICAgICAqIFJUUCBmYWNpbGl0YXRlcyB0aGUgdHJhbnNmZXIgb2YgcmVhbC10aW1lIGRhdGEuIEluZm9ybWF0aW9uIHByb3ZpZGVkIGJ5IHRoaXMgcHJvdG9jb2wgaW5jbHVkZVxuICAgICAqIHRpbWVzdGFtcHMgKGZvciBzeW5jaHJvbml6YXRpb24pLCBzZXF1ZW5jZSBudW1iZXJzIChmb3IgcGFja2V0IGxvc3MgYW5kIHJlb3JkZXJpbmcgZGV0ZWN0aW9uKVxuICAgICAqIGFuZCB0aGUgcGF5bG9hZCBmb3JtYXQgd2hpY2ggaW5kaWNhdGVzIHRoZSBlbmNvZGVkIGZvcm1hdCBvZiB0aGUgZGF0YS5cbiAgICAgKi9cbiAgICAnUlRQJzogJ1JUUCcsXG4gICAgLyoqXG4gICAgICogVGhlIHRyYW5zbWlzc2lvbiBvZiBzdHJlYW1pbmcgZGF0YSBpdHNlbGYgaXMgbm90IGEgdGFzayBvZiBSVFNQLiBNb3N0IFJUU1Agc2VydmVycyB1c2UgdGhlXG4gICAgICogUmVhbC10aW1lIFRyYW5zcG9ydCBQcm90b2NvbCAoUlRQKSBpbiBjb25qdW5jdGlvbiB3aXRoIFJlYWwtdGltZSBDb250cm9sIFByb3RvY29sIChSVENQKSBmb3JcbiAgICAgKiBtZWRpYSBzdHJlYW0gZGVsaXZlcnkuIEhvd2V2ZXIsIHNvbWUgdmVuZG9ycyBpbXBsZW1lbnQgcHJvcHJpZXRhcnkgdHJhbnNwb3J0IHByb3RvY29scy5cbiAgICAgKi9cbiAgICAnUlRTUCc6ICdSVFNQJyxcbiAgICAvKipcbiAgICAgKiBSZWFsLVRpbWUgTWVzc2FnaW5nIFByb3RvY29sIChSVE1QKSB3YXMgaW5pdGlhbGx5IGEgcHJvcHJpZXRhcnkgcHJvdG9jb2wgZGV2ZWxvcGVkIGJ5XG4gICAgICogTWFjcm9tZWRpYSBmb3Igc3RyZWFtaW5nIGF1ZGlvLCB2aWRlbyBhbmQgZGF0YSBvdmVyIHRoZSBJbnRlcm5ldCwgYmV0d2VlbiBhIEZsYXNoIHBsYXllciBhbmRcbiAgICAgKiBhIHNlcnZlci4gTWFjcm9tZWRpYSBpcyBub3cgb3duZWQgYnkgQWRvYmUsIHdoaWNoIGhhcyByZWxlYXNlZCBhbiBpbmNvbXBsZXRlIHZlcnNpb24gb2YgdGhlXG4gICAgICogc3BlY2lmaWNhdGlvbiBvZiB0aGUgcHJvdG9jb2wgZm9yIHB1YmxpYyB1c2UuXG4gICAgICovXG4gICAgJ1JUTVAnOiAnUlRNUCcsXG4gICAgLyoqXG4gICAgICogVGhlIFdlYk0gY29udGFpbmVyIGlzIGJhc2VkIG9uIGEgcHJvZmlsZSBvZiBNYXRyb3NrYS4gV2ViTSBpbml0aWFsbHkgc3VwcG9ydGVkIFZQOCB2aWRlbyBhbmRcbiAgICAgKiBWb3JiaXMgYXVkaW8gc3RyZWFtcy4gSW4gMjAxMyBpdCB3YXMgdXBkYXRlZCB0byBhY2NvbW1vZGF0ZSBWUDkgdmlkZW8gYW5kIE9wdXMgYXVkaW8uXG4gICAgICovXG4gICAgJ1dFQk0nOiAnV0VCTScsXG5cbn0pO1xuXG5leHBvcnQgeyBWaWRlb1N0cmVhbWluZ1Byb3RvY29sIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBWaWRlb1N0cmVhbWluZ0NvZGVjXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBWaWRlb1N0cmVhbWluZ0NvZGVjIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSDI2NCAoKSB7XG4gICAgICAgIHJldHVybiBWaWRlb1N0cmVhbWluZ0NvZGVjLl9NQVAuSDI2NDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBIMjY1ICgpIHtcbiAgICAgICAgcmV0dXJuIFZpZGVvU3RyZWFtaW5nQ29kZWMuX01BUC5IMjY1O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFRoZW9yYSAoKSB7XG4gICAgICAgIHJldHVybiBWaWRlb1N0cmVhbWluZ0NvZGVjLl9NQVAuVGhlb3JhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZQOCAoKSB7XG4gICAgICAgIHJldHVybiBWaWRlb1N0cmVhbWluZ0NvZGVjLl9NQVAuVlA4O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZQOSAoKSB7XG4gICAgICAgIHJldHVybiBWaWRlb1N0cmVhbWluZ0NvZGVjLl9NQVAuVlA5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgKiBAcGFyYW0gdmFsdWUgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBWaWRlb1N0cmVhbWluZ0NvZGVjLl92YWx1ZUZvcktleShrZXksIFZpZGVvU3RyZWFtaW5nQ29kZWMuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFZpZGVvU3RyZWFtaW5nQ29kZWMuX2tleUZvclZhbHVlKHZhbHVlLCBWaWRlb1N0cmVhbWluZ0NvZGVjLl9NQVApO1xuICAgIH1cbn1cblxuVmlkZW9TdHJlYW1pbmdDb2RlYy5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgLyoqXG4gICAgICogQSBibG9jay1vcmllbnRlZCBtb3Rpb24tY29tcGVuc2F0aW9uLWJhc2VkIHZpZGVvIGNvbXByZXNzaW9uIHN0YW5kYXJkLiBBcyBvZiAyMDE0IGl0IGlzIG9uZVxuICAgICAqIG9mIHRoZSBtb3N0IGNvbW1vbmx5IHVzZWQgZm9ybWF0cyBmb3IgdGhlIHJlY29yZGluZywgY29tcHJlc3Npb24sIGFuZCBkaXN0cmlidXRpb24gb2YgdmlkZW9cbiAgICAgKiBjb250ZW50LlxuICAgICAqL1xuICAgICdIMjY0JzogJ0gyNjQnLFxuICAgIC8qKlxuICAgICAqIEhpZ2ggRWZmaWNpZW5jeSBWaWRlbyBDb2RpbmcgKEhFVkMpLCBhbHNvIGtub3duIGFzIEguMjY1IGFuZCBNUEVHLUggUGFydCAyLCBpcyBhIHZpZGVvXG4gICAgICogY29tcHJlc3Npb24gc3RhbmRhcmQsIG9uZSBvZiBzZXZlcmFsIHBvdGVudGlhbCBzdWNjZXNzb3JzIHRvIHRoZSB3aWRlbHkgdXNlZCBBVkNcbiAgICAgKiAoSC4yNjQgb3IgTVBFRy00IFBhcnQgMTApLiBJbiBjb21wYXJpc29uIHRvIEFWQywgSEVWQyBvZmZlcnMgYWJvdXQgZG91YmxlIHRoZSBkYXRhXG4gICAgICogY29tcHJlc3Npb24gcmF0aW8gYXQgdGhlIHNhbWUgbGV2ZWwgb2YgdmlkZW8gcXVhbGl0eSwgb3Igc3Vic3RhbnRpYWxseSBpbXByb3ZlZCB2aWRlbyBxdWFsaXR5XG4gICAgICogYXQgdGhlIHNhbWUgYml0IHJhdGUuIEl0IHN1cHBvcnRzIHJlc29sdXRpb25zIHVwIHRvIDgxOTJ4NDMyMCwgaW5jbHVkaW5nIDhLIFVIRC5cbiAgICAgKi9cbiAgICAnSDI2NSc6ICdIMjY1JyxcbiAgICAvKipcbiAgICAgKiBUaGVvcmEgaXMgZGVyaXZlZCBmcm9tIHRoZSBmb3JtZXJseSBwcm9wcmlldGFyeSBWUDMgY29kZWMsIHJlbGVhc2VkIGludG8gdGhlIHB1YmxpYyBkb21haW4gYnlcbiAgICAgKiBPbjIgVGVjaG5vbG9naWVzLiBJdCBpcyBicm9hZGx5IGNvbXBhcmFibGUgaW4gZGVzaWduIGFuZCBiaXRyYXRlIGVmZmljaWVuY3kgdG8gTVBFRy00IFBhcnQgMixcbiAgICAgKiBlYXJseSB2ZXJzaW9ucyBvZiBXaW5kb3dzIE1lZGlhIFZpZGVvLCBhbmQgUmVhbFZpZGVvIHdoaWxlIGxhY2tpbmcgc29tZSBvZiB0aGUgZmVhdHVyZXNcbiAgICAgKiBwcmVzZW50IGluIHNvbWUgb2YgdGhlc2Ugb3RoZXIgY29kZWNzLiBJdCBpcyBjb21wYXJhYmxlIGluIG9wZW4gc3RhbmRhcmRzIHBoaWxvc29waHkgdG8gdGhlXG4gICAgICogQkJDJ3MgRGlyYWMgY29kZWMuXG4gICAgICovXG4gICAgJ1RoZW9yYSc6ICdUaGVvcmEnLFxuICAgIC8qKlxuICAgICAqIFZQOCBjYW4gYmUgbXVsdGlwbGV4ZWQgaW50byB0aGUgTWF0cm9za2EtYmFzZWQgY29udGFpbmVyIGZvcm1hdCBXZWJNIGFsb25nIHdpdGggVm9yYmlzIGFuZFxuICAgICAqIE9wdXMgYXVkaW8uIFRoZSBpbWFnZSBmb3JtYXQgV2ViUCBpcyBiYXNlZCBvbiBWUDgncyBpbnRyYS1mcmFtZSBjb2RpbmcuIFZQOCdzIGRpcmVjdFxuICAgICAqIHN1Y2Nlc3NvciwgVlA5LCBhbmQgdGhlIGVtZXJnaW5nIHJveWFsdHktZnJlZSBpbnRlcm5ldCB2aWRlbyBmb3JtYXQgQVYxIGZyb20gdGhlIEFsbGlhbmNlXG4gICAgICogZm9yIE9wZW4gTWVkaWEgKEFPTWVkaWEpIGFyZSBiYXNlZCBvbiBWUDguXG4gICAgICovXG4gICAgJ1ZQOCc6ICdWUDgnLFxuICAgIC8qKlxuICAgICAqIFNpbWlsYXIgdG8gVlA4LCBidXQgVlA5IGlzIGN1c3RvbWl6ZWQgZm9yIHZpZGVvIHJlc29sdXRpb25zIGJleW9uZCBoaWdoLWRlZmluaXRpb24gdmlkZW9cbiAgICAgKiAoVUhEKSBhbmQgYWxzbyBlbmFibGVzIGxvc3NsZXNzIGNvbXByZXNzaW9uLlxuICAgICAqL1xuICAgICdWUDknOiAnVlA5Jyxcbn0pO1xuXG5leHBvcnQgeyBWaWRlb1N0cmVhbWluZ0NvZGVjIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBWaWRlb1N0cmVhbWluZ1Byb3RvY29sIH0gZnJvbSAnLi4vZW51bXMvVmlkZW9TdHJlYW1pbmdQcm90b2NvbC5qcyc7XG5pbXBvcnQgeyBWaWRlb1N0cmVhbWluZ0NvZGVjIH0gZnJvbSAnLi4vZW51bXMvVmlkZW9TdHJlYW1pbmdDb2RlYy5qcyc7XG5cbmNsYXNzIFZpZGVvU3RyZWFtaW5nRm9ybWF0IGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7VmlkZW9TdHJlYW1pbmdQcm90b2NvbH0gdmFsXG4gICAgKiBAcmV0dXJuIHtWaWRlb1N0cmVhbWluZ0Zvcm1hdH1cbiAgICAqL1xuICAgIHNldFByb3RvY29sICh2YWwpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmlkZW9TdHJlYW1pbmdQcm90b2NvbCwgdmFsKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVmlkZW9TdHJlYW1pbmdGb3JtYXQuS0VZX1BST1RPQ09MLCB2YWwpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1ZpZGVvU3RyZWFtaW5nUHJvdG9jb2x9XG4gICAgKi9cbiAgICBnZXRQcm90b2NvbCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihWaWRlb1N0cmVhbWluZ0Zvcm1hdC5LRVlfUFJPVE9DT0wpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtWaWRlb1N0cmVhbWluZ0NvZGVjfSB2YWxcbiAgICAqIEByZXR1cm4ge1ZpZGVvU3RyZWFtaW5nRm9ybWF0fVxuICAgICovXG4gICAgc2V0Q29kZWMgKHZhbCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWaWRlb1N0cmVhbWluZ0NvZGVjLCB2YWwpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihWaWRlb1N0cmVhbWluZ0Zvcm1hdC5LRVlfQ09ERUMsIHZhbCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7VmlkZW9TdHJlYW1pbmdDb2RlY31cbiAgICAqL1xuICAgIGdldENvZGVjICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFZpZGVvU3RyZWFtaW5nRm9ybWF0LktFWV9DT0RFQyk7XG4gICAgfVxufVxuXG5WaWRlb1N0cmVhbWluZ0Zvcm1hdC5LRVlfUFJPVE9DT0wgPSAncHJvdG9jb2wnO1xuVmlkZW9TdHJlYW1pbmdGb3JtYXQuS0VZX0NPREVDID0gJ2NvZGVjJztcblxuZXhwb3J0IHsgVmlkZW9TdHJlYW1pbmdGb3JtYXQgfTtcbiIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBNZXNzYWdlRnJhbWVEaXNhc3NlbWJsZXIgfSBmcm9tICcuL01lc3NhZ2VGcmFtZURpc2Fzc2VtYmxlci5qcyc7XG5pbXBvcnQgeyBUcmFuc3BvcnRMaXN0ZW5lciB9IGZyb20gJy4uL3RyYW5zcG9ydC9UcmFuc3BvcnRMaXN0ZW5lci5qcyc7XG5pbXBvcnQgeyBWZXJzaW9uIH0gZnJvbSAnLi4vdXRpbC9WZXJzaW9uLmpzJztcbmltcG9ydCB7IFNlcnZpY2VUeXBlIH0gZnJvbSAnLi9lbnVtcy9TZXJ2aWNlVHlwZS5qcyc7XG5pbXBvcnQgeyBGcmFtZVR5cGUgfSBmcm9tICcuL2VudW1zL0ZyYW1lVHlwZS5qcyc7XG5pbXBvcnQgeyBNZXNzYWdlRnJhbWVBc3NlbWJsZXIgfSBmcm9tICcuL01lc3NhZ2VGcmFtZUFzc2VtYmxlci5qcyc7XG5pbXBvcnQgeyBTZGxQYWNrZXQgfSBmcm9tICcuL1NkbFBhY2tldC5qcyc7XG5pbXBvcnQgeyBDb250cm9sRnJhbWVUYWdzIH0gZnJvbSAnLi9lbnVtcy9Db250cm9sRnJhbWVUYWdzLmpzJztcbmltcG9ydCB7IEJpdENvbnZlcnRlciB9IGZyb20gJy4vLi4vdXRpbC9CaXRDb252ZXJ0ZXIuanMnO1xuXG5pbXBvcnQgeyBTZGxQYWNrZXRGYWN0b3J5IH0gZnJvbSAnLi9TZGxQYWNrZXRGYWN0b3J5LmpzJztcbmltcG9ydCB7IFJwY0NyZWF0b3IgfSBmcm9tICcuLy4uL3JwYy9ScGNDcmVhdG9yLmpzJztcbmltcG9ydCB7IEltYWdlUmVzb2x1dGlvbiB9IGZyb20gJy4uL3JwYy9zdHJ1Y3RzL0ltYWdlUmVzb2x1dGlvbi5qcyc7XG5pbXBvcnQgeyBWaWRlb1N0cmVhbWluZ0Zvcm1hdCB9IGZyb20gJy4uL3JwYy9zdHJ1Y3RzL1ZpZGVvU3RyZWFtaW5nRm9ybWF0LmpzJztcblxuLyoqXG4gKiBCYXNlIGltcGxlbWVudGF0aW9uIG9mIHNkbCBwcm90b2NvbC5cbiAqIFNob3VsZCBiZSBhYmxlIHRvIGhhbmRsZSBiYXNpYyBjb250cm9sIGZyYW1lcyBhbmQgYmUgYWJsZSB0b1xuICogc2VuZCBhbmQgcmVjZWl2ZSBwYWNrZXRzIGZyb20gdGhlIHRyYW5zcG9ydCBtYW5hZ2VyLlxuICogQWxzbyBzZW5kcyBrZXkgZXZlbnRzIHRvIHRoZSBzZGxQcm90b2NvbExpc3RlbmVyLlxuICovXG5jbGFzcyBTZGxQcm90b2NvbEJhc2Uge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHsgVHJhbnNwb3J0Q29uZmlnQmFzZSB9IGJhc2VUcmFuc3BvcnRDb25maWdcbiAgICAgKiBAcGFyYW0geyBTZGxQcm90b2NvbExpc3RlbmVyIH0gc2RsUHJvdG9jb2xMaXN0ZW5lclxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChiYXNlVHJhbnNwb3J0Q29uZmlnLCBzZGxQcm90b2NvbExpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMuX2Jhc2VUcmFuc3BvcnRDb25maWcgPSBiYXNlVHJhbnNwb3J0Q29uZmlnO1xuICAgICAgICB0aGlzLl90cmFuc3BvcnRDb25maWcgPSBiYXNlVHJhbnNwb3J0Q29uZmlnO1xuICAgICAgICB0aGlzLl9zZGxQcm90b2NvbExpc3RlbmVyID0gc2RsUHJvdG9jb2xMaXN0ZW5lcjtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0TWFuYWdlciA9IG51bGw7XG5cbiAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgICAgICB0aGlzLl9jcmVhdGVUcmFuc3BvcnRMaXN0ZW5lcigpO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogUmVzZXRzIHRoZSBzZGwgcHJvdG9jb2wgdG8gaXRzIGRlZmF1bHQgc3RhdGUuXG4gICAgICovXG4gICAgcmVzZXQgKCkge1xuICAgICAgICB0aGlzLl9wcm90b2NvbFZlcnNpb24gPSBuZXcgVmVyc2lvbigxLCAwLCAwKTtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q29uZmlnID0gdGhpcy5fYmFzZVRyYW5zcG9ydENvbmZpZztcbiAgICAgICAgdGhpcy5faGVhZGVyU2l6ZSA9IFNkbFByb3RvY29sQmFzZS5WMV9IRUFERVJfU0laRTtcbiAgICAgICAgdGhpcy5fc2VydmljZVN0YXR1cyA9IHt9O1xuICAgICAgICB0aGlzLl9zZXJ2aWNlU3RhdHVzW1NlcnZpY2VUeXBlLkNPTlRST0xdID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fbXR1cyA9IHt9O1xuICAgICAgICB0aGlzLl9tdHVzW1NlcnZpY2VUeXBlLlJQQ10gPSBTZGxQcm90b2NvbEJhc2UuVjFfVjJfTVRVX1NJWkUgLSB0aGlzLl9oZWFkZXJTaXplO1xuICAgICAgICB0aGlzLl9oYXNoSUQgPSAwO1xuICAgICAgICB0aGlzLl9tZXNzYWdlRnJhbWVBc3NlbWJsZXJzID0ge307XG4gICAgICAgIHRoaXMuX21lc3NhZ2VJRCA9IDE7XG4gICAgICAgIHRoaXMuX3Nlc3Npb25JRCA9IDA7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZXRzIGEgdHJhbnNwb3J0IG1hbmFnZXIuXG4gICAgICogQHBhcmFtIHsgVHJhbnNwb3J0TWFuYWdlckJhc2UgfSBtYW5hZ2VyXG4gICAgICovXG4gICAgc2V0VHJhbnNwb3J0TWFuYWdlciAobWFuYWdlcikge1xuICAgICAgICBpZiAoIXRoaXMuX3NlcnZpY2VTdGF0dXNbU2VydmljZVR5cGUuUlBDXSkge1xuICAgICAgICAgICAgLy8gUlBDIHNlcnZpY2UgaGFzbid0IGJlZW4gc3RhcnRlZCwgbGV0cyBzdGFydCBpdFxuICAgICAgICAgICAgdGhpcy5zdGFydFNlcnZpY2UoU2VydmljZVR5cGUuUlBDLCAwLCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0TWFuYWdlciA9IG1hbmFnZXI7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIHRoZSB0cmFuc3BvcnQgbGlzdGVuZXIuIFRoaXMgd2lsbCByZWNpZXZlIGluY29taW5nIHJlcXVlc3RzXG4gICAgICogZnJvbSB0aGUgdHJhbnNwb3J0IG1hbmFnZXIuXG4gICAgICovXG4gICAgX2NyZWF0ZVRyYW5zcG9ydExpc3RlbmVyICgpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICAgIHRoaXMuX3RyYW5zcG9ydExpc3RlbmVyID0gbmV3IFRyYW5zcG9ydExpc3RlbmVyKCk7XG4gICAgICAgIHRoaXMuX3RyYW5zcG9ydExpc3RlbmVyLnNldE9uVHJhbnNwb3J0Q29ubmVjdGVkKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNlbGYuX2hhbmRsZVRyYW5zcG9ydENvbm5lY3RlZCgpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0TGlzdGVuZXIuc2V0T25UcmFuc3BvcnREaXNjb25uZWN0ZWQoZnVuY3Rpb24gKCkge1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0TGlzdGVuZXIuc2V0T25QYWNrZXRSZWNlaXZlZChmdW5jdGlvbiAoc2RsUGFja2V0KSB7XG4gICAgICAgICAgICBzZWxmLl9oYW5kbGVQYWNrZXRSZWNlaXZlZChzZGxQYWNrZXQpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0TGlzdGVuZXIuc2V0T25FcnJvcihmdW5jdGlvbiAoKSB7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIF9oYW5kbGVUcmFuc3BvcnRDb25uZWN0ZWQgKCkge1xuICAgICAgICB0aGlzLl9zZGxQcm90b2NvbExpc3RlbmVyLm9uVHJhbnNwb3J0Q29ubmVjdGVkKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3RhcnRzIHVwIHRoZSBTREwgcHJvdG9jb2wgY2xhc3MuIEl0IHdpbGwga2ljayBvZmYgdGhlIHRyYW5zcG9ydCBtYW5hZ2VyIGFuZCB1bmRlcmx5aW5nIHRyYW5zcG9ydC5cbiAgICAgKi9cbiAgICBzdGFydCAoKSB7XG4gICAgICAgIGlmICghdGhpcy5fdHJhbnNwb3J0TWFuYWdlcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIHRyYW5zcG9ydCBtYW5hZ2VyIG11c3QgYmUgZGVmaW5lZCwgdW5hYmxlIHRvIHN0YXJ0IFNETCBQcm90b2NvbCcpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3RyYW5zcG9ydE1hbmFnZXIuc3RhcnQoKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBzZXJ2aWNlLiBUaGlzIGlzIHRoZSBmaXJzdCBzdGVwIGluIGNvbW11bmljYXRpbmcgd2l0aCBzZGwgY29yZS5cbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzZXNzaW9uSURcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGlzRW5jcnlwdGVkXG4gICAgICovXG4gICAgc3RhcnRTZXJ2aWNlIChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklELCBpc0VuY3J5cHRlZCkge1xuICAgICAgICBjb25zdCBwcm90b2NvbFZlcnNpb24gPSB0aGlzLmNvbnN0cnVjdG9yLk1BWF9QUk9UT0NPTF9WRVJTSU9OO1xuICAgICAgICBjb25zdCBtZXNzYWdlSUQgPSAwO1xuICAgICAgICBjb25zdCBoZWFkZXIgPSBuZXcgU2RsUGFja2V0KHByb3RvY29sVmVyc2lvbi5nZXRNYWpvcigpLCBpc0VuY3J5cHRlZCwgRnJhbWVUeXBlLkNPTlRST0wsXG4gICAgICAgICAgICBzZXJ2aWNlVHlwZSwgU2RsUGFja2V0LkZSQU1FX0lORk9fU1RBUlRfU0VSVklDRSwgc2Vzc2lvbklELFxuICAgICAgICAgICAgMCwgbWVzc2FnZUlELCBudWxsKTtcbiAgICAgICAgaWYgKHNlcnZpY2VUeXBlID09PSBTZXJ2aWNlVHlwZS5BVURJTykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2VuZFBhY2tldChoZWFkZXIpO1xuICAgICAgICB9IGVsc2UgaWYgKHNlcnZpY2VUeXBlID09PSBTZXJ2aWNlVHlwZS5SUEMpIHtcbiAgICAgICAgICAgIGhlYWRlci5wdXRUYWcoQ29udHJvbEZyYW1lVGFncy5SUEMuU3RhcnRTZXJ2aWNlLlBST1RPQ09MX1ZFUlNJT04sIHByb3RvY29sVmVyc2lvbi50b1N0cmluZygpKTtcbiAgICAgICAgfSBlbHNlIGlmIChzZXJ2aWNlVHlwZSA9PT0gU2VydmljZVR5cGUuVklERU8pIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9zZGxQcm90b2NvbExpc3RlbmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdmlkZW9TdHJlYW1pbmdQYXJhbWV0ZXJzID0gdGhpcy5fc2RsUHJvdG9jb2xMaXN0ZW5lci5nZXREZXNpcmVkVmlkZW9QYXJhbXMoKTtcbiAgICAgICAgICAgICAgICBpZiAodmlkZW9TdHJlYW1pbmdQYXJhbWV0ZXJzICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRlc2lyZWRSZXNvbHV0aW9uID0gdmlkZW9TdHJlYW1pbmdQYXJhbWV0ZXJzLmdldFJlc29sdXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVzaXJlZEZvcm1hdCA9IHZpZGVvU3RyZWFtaW5nUGFyYW1ldGVycy5nZXRGb3JtYXQoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlc2lyZWRSZXNvbHV0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBoZWFkZXIucHV0VGFnKENvbnRyb2xGcmFtZVRhZ3MuVmlkZW8uU3RhcnRTZXJ2aWNlLldJRFRILCBkZXNpcmVkUmVzb2x1dGlvbi5nZXRSZXNvbHV0aW9uV2lkdGgoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBoZWFkZXIucHV0VGFnKENvbnRyb2xGcmFtZVRhZ3MuVmlkZW8uU3RhcnRTZXJ2aWNlLkhFSUdIVCwgZGVzaXJlZFJlc29sdXRpb24uZ2V0UmVzb2x1dGlvbkhlaWdodCgpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGVzaXJlZEZvcm1hdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyLnB1dFRhZyhDb250cm9sRnJhbWVUYWdzLlZpZGVvLlN0YXJ0U2VydmljZS5WSURFT19DT0RFQywgZGVzaXJlZEZvcm1hdC5nZXRDb2RlYygpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlci5wdXRUYWcoQ29udHJvbEZyYW1lVGFncy5WaWRlby5TdGFydFNlcnZpY2UuVklERU9fUFJPVE9DT0wsIGRlc2lyZWRGb3JtYXQuZ2V0UHJvdG9jb2woKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zZW5kUGFja2V0KGhlYWRlcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NlcnZpY2UgdHlwZSBub3QgaW1wbGVtZW50ZWQnKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNlbmRQYWNrZXQoaGVhZGVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAgR2V0IHRoZSBtYXggdHJhbnNwb3J0IHVuaXQgb2YgYSBzcGVjaWZpYyBzZXJ2aWNlIHR5cGUuXG4gICAgICogQHBhcmFtIHsgU2VydmljZVR5cGUgfSBzZXJ2aWNlVHlwZVxuICAgICAqIEByZXR1cm4ge251bWJlcn0gbWF4IHRyYW5zcG9ydCB1bml0IGZvciB0aGUgZ2l2ZW4gc2VydmljZSB0eXBlXG4gICAgICovXG4gICAgZ2V0TXR1IChzZXJ2aWNlVHlwZSkge1xuICAgICAgICBjb25zdCByZXRWYWwgPSB0aGlzLl9tdHVzW3NlcnZpY2VUeXBlXTtcbiAgICAgICAgaWYgKHJldFZhbCkge1xuICAgICAgICAgICAgcmV0dXJuIHJldFZhbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gU2RsUHJvdG9jb2xCYXNlLlYxX1YyX01UVV9TSVpFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0cmFuc3BvcnQgbWFuYWdlciBpcyBjb25uZWN0ZWQuXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn0gaXNDb25uZWN0ZWRcbiAgICAgKi9cbiAgICBpc0Nvbm5lY3RlZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnRNYW5hZ2VyICYmIHRoaXMuX3RyYW5zcG9ydE1hbmFnZXIuaXNDb25uZWN0ZWQobnVsbCwgbnVsbCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjdXJyZW50IHByb3RvY29sIHZlcnNpb24gaW4gdXNlLlxuICAgICAqIEByZXR1cm5zIHtWZXJzaW9ufSBwcm90b2NvbCB2ZXJzaW9uXG4gICAgICovXG4gICAgZ2V0UHJvdG9jb2xWZXJzaW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Byb3RvY29sVmVyc2lvbjtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIHdpbGwgc2V0IHRoZSBtYWpvciBwcm90b2NvbCB2ZXJzaW9uIHRoYXQgd2Ugc2hvdWxkIHVzZS5cbiAgICAgKiBJdCB3aWxsIGFsc28gc2V0IHRoZSBkZWZhdWx0IE1UVSBiYXNlZCBvbiB2ZXJzaW9uLlxuICAgICAqIEBwYXJhbSB7IG51bWJlciB9IHZlcnNpb24gbWFqb3IgdmVyc2lvbiB0byB1c2VcbiAgICAgKi9cbiAgICBfc2V0VmVyc2lvbiAodmVyc2lvbikge1xuICAgICAgICBpZiAodmVyc2lvbiA+IDUpIHtcbiAgICAgICAgICAgIHRoaXMuX3Byb3RvY29sVmVyc2lvbiA9IG5ldyBWZXJzaW9uKCc1LjEuMCcpOyAvLyBwcm90ZWN0IGZvciBmdXR1cmUsIHByb3h5IG9ubHkgc3VwcG9ydHMgdjUgb3IgbG93ZXJcbiAgICAgICAgICAgIHRoaXMuaGVhZGVyU2l6ZSA9IHRoaXMuY29uc3RydWN0b3IuVjJfSEVBREVSX1NJWkU7XG4gICAgICAgICAgICB0aGlzLl9tdHVzW1NlcnZpY2VUeXBlLlJQQ10gPSB0aGlzLmNvbnN0cnVjdG9yLlYzX1Y0X01UVV9TSVpFO1xuICAgICAgICB9IGVsc2UgaWYgKHZlcnNpb24gPT09IDUpIHtcbiAgICAgICAgICAgIHRoaXMuX3Byb3RvY29sVmVyc2lvbiA9IG5ldyBWZXJzaW9uKCc1LjAuMCcpO1xuICAgICAgICAgICAgdGhpcy5oZWFkZXJTaXplID0gdGhpcy5jb25zdHJ1Y3Rvci5WMl9IRUFERVJfU0laRTtcbiAgICAgICAgICAgIHRoaXMuX210dXNbU2VydmljZVR5cGUuUlBDXSA9IHRoaXMuY29uc3RydWN0b3IuVjNfVjRfTVRVX1NJWkU7XG4gICAgICAgIH0gZWxzZSBpZiAodmVyc2lvbiA9PT0gNCkge1xuICAgICAgICAgICAgdGhpcy5fcHJvdG9jb2xWZXJzaW9uID0gbmV3IFZlcnNpb24oJzQuMC4wJyk7XG4gICAgICAgICAgICB0aGlzLmhlYWRlclNpemUgPSB0aGlzLmNvbnN0cnVjdG9yLlYyX0hFQURFUl9TSVpFO1xuICAgICAgICAgICAgdGhpcy5fbXR1c1tTZXJ2aWNlVHlwZS5SUENdID0gdGhpcy5jb25zdHJ1Y3Rvci5WM19WNF9NVFVfU0laRTsgLy8gdmVyc2lvbnMgNCBzdXBwb3J0cyAxMjhrIE1UVVxuICAgICAgICB9IGVsc2UgaWYgKHZlcnNpb24gPT09IDMpIHtcbiAgICAgICAgICAgIHRoaXMuX3Byb3RvY29sVmVyc2lvbiA9IG5ldyBWZXJzaW9uKCczLjAuMCcpO1xuICAgICAgICAgICAgdGhpcy5oZWFkZXJTaXplID0gdGhpcy5jb25zdHJ1Y3Rvci5WMl9IRUFERVJfU0laRTtcbiAgICAgICAgICAgIHRoaXMuX210dXNbU2VydmljZVR5cGUuUlBDXSA9IHRoaXMuY29uc3RydWN0b3IuVjNfVjRfTVRVX1NJWkU7IC8vIHZlcnNpb25zIDMgc3VwcG9ydHMgMTI4ayBNVFVcbiAgICAgICAgfSBlbHNlIGlmICh2ZXJzaW9uID09PSAyKSB7XG4gICAgICAgICAgICB0aGlzLl9wcm90b2NvbFZlcnNpb24gPSBuZXcgVmVyc2lvbignMi4wLjAnKTtcbiAgICAgICAgICAgIHRoaXMuaGVhZGVyU2l6ZSA9IHRoaXMuY29uc3RydWN0b3IuVjJfSEVBREVSX1NJWkU7XG4gICAgICAgICAgICB0aGlzLl9tdHVzW1NlcnZpY2VUeXBlLlJQQ10gPSB0aGlzLmNvbnN0cnVjdG9yLlYxX1YyX01UVV9TSVpFIC0gdGhpcy5oZWFkZXJTaXplO1xuICAgICAgICB9IGVsc2UgaWYgKHZlcnNpb24gPT09IDEpIHtcbiAgICAgICAgICAgIHRoaXMuX3Byb3RvY29sVmVyc2lvbiA9IG5ldyBWZXJzaW9uKCcxLjAuMCcpO1xuICAgICAgICAgICAgdGhpcy5oZWFkZXJTaXplID0gdGhpcy5jb25zdHJ1Y3Rvci5WMV9IRUFERVJfU0laRTtcbiAgICAgICAgICAgIHRoaXMuX210dXNbU2VydmljZVR5cGUuUlBDXSA9IHRoaXMuY29uc3RydWN0b3IuVjFfVjJfTVRVX1NJWkUgLSB0aGlzLmhlYWRlclNpemU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZW5kcyBhbiBzZGxQYWNrZXQuXG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldFxuICAgICAqL1xuICAgIHNlbmRQYWNrZXQgKHNkbFBhY2tldCkge1xuICAgICAgICBpZiAodGhpcy5fdHJhbnNwb3J0TWFuYWdlcikge1xuICAgICAgICAgICAgdGhpcy5fdHJhbnNwb3J0TWFuYWdlci5zZW5kUGFja2V0KHNkbFBhY2tldCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBzZXNzaW9uSWQgaW4gdXNlLlxuICAgICAqIEByZXR1cm5zIHtOdW1iZXJ9XG4gICAgICovXG4gICAgX2dldFNlc3Npb25JZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zZGxQcm90b2NvbExpc3RlbmVyLmdldFNlc3Npb25JZCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIG5leHQgYXZhaWxhYmxlIG1lc3NhZ2VJRCBmb3Igc2VuZGluZyByZXF1ZXN0cy5cbiAgICAgKiBAcmV0dXJucyB7TnVtYmVyfVxuICAgICAqL1xuICAgIF9nZXROZXh0TWVzc2FnZUlEICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21lc3NhZ2VJRCsrO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRha2VzIGFuIHJwYyBtZXNzYWdlIGFuZCBzZW5kcyBhIHNpbmdsZSBvciBtdWx0aSBmcmFtZSBwYWNrZXRzLlxuICAgICAqIEBwYXJhbSB7UnBjUmVxdWVzdH0gcnBjTWVzc2FnZVxuICAgICAqL1xuICAgIHNlbmRScGMgKHJwY1JlcXVlc3QpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICAgIGNvbnN0IHNlc3Npb25JZCA9IHRoaXMuX2dldFNlc3Npb25JZCgpO1xuICAgICAgICBjb25zdCBtZXNzYWdlSUQgPSB0aGlzLl9nZXROZXh0TWVzc2FnZUlEKCk7XG4gICAgICAgIGNvbnN0IG10dSA9IHNlbGYuX210dXNbU2VydmljZVR5cGUuUlBDXTtcbiAgICAgICAgY29uc3QgdmVyc2lvbiA9IHNlbGYuX3Byb3RvY29sVmVyc2lvbi5nZXRNYWpvcigpO1xuICAgICAgICBjb25zdCBpc0VuY3J5cHRlZCA9IHJwY1JlcXVlc3QuZ2V0SXNFbmNyeXB0ZWQoKTtcblxuICAgICAgICBNZXNzYWdlRnJhbWVEaXNhc3NlbWJsZXIuYnVpbGRSUEMocnBjUmVxdWVzdCwgc2Vzc2lvbklkLCBtZXNzYWdlSUQsIG10dSwgdmVyc2lvbiwgaXNFbmNyeXB0ZWQsIGZ1bmN0aW9uIChzZGxQYWNrZXQpIHtcbiAgICAgICAgICAgIHNlbGYuc2VuZFBhY2tldChzZGxQYWNrZXQpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGVzIGluY29taW5nIHBhY2tldHMuXG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldFxuICAgICAqL1xuICAgIF9oYW5kbGVQYWNrZXRSZWNlaXZlZCAoc2RsUGFja2V0KSB7XG4gICAgICAgIGlmICh0aGlzLl9wcm90b2NvbFZlcnNpb24gPT09IG51bGwgfHwgdGhpcy5fcHJvdG9jb2xWZXJzaW9uLmdldE1ham9yKCkgPT09IDEpIHtcbiAgICAgICAgICAgIHRoaXMuX3NldFZlcnNpb24oc2RsUGFja2V0LmdldFZlcnNpb24oKSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZnJhbWVUeXBlID0gc2RsUGFja2V0LmdldEZyYW1lVHlwZSgpO1xuICAgICAgICBpZiAoZnJhbWVUeXBlID09PSBGcmFtZVR5cGUuQ09OVFJPTCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2hhbmRsZUNvbnRyb2xQYWNrZXQoc2RsUGFja2V0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2VGcmFtZUFzc2VtYmxlciA9IHRoaXMuX2dldE1lc3NhZ2VGcmFtZUFzc2VtYmxlcihzZGxQYWNrZXQpO1xuICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2VGcmFtZUFzc2VtYmxlci5oYW5kbGVGcmFtZShzZGxQYWNrZXQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlcyBub24tY29udHJvbCBwYWNrZXRzIGFmdGVyIHRoZXkgaGF2ZSBiZWVuIGFzc2VtYmxlZC5cbiAgICAgKiBAcGFyYW0ge1NkbFBhY2tldH0gc2RsUGFja2V0XG4gICAgICovXG4gICAgX2hhbmRsZU9uTWVzc2FnZUFzc2VtYmxlZCAoc2RsUGFja2V0KSB7XG4gICAgICAgIGNvbnN0IHNlcnZpY2VUeXBlID0gc2RsUGFja2V0LmdldFNlcnZpY2VUeXBlKCk7XG5cbiAgICAgICAgaWYgKHNlcnZpY2VUeXBlID09PSBTZXJ2aWNlVHlwZS5SUEMgfHwgc2VydmljZVR5cGUgPT09IFNlcnZpY2VUeXBlLkhZQlJJRCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2hhbmRsZVJQQ1BhY2tldChzZGxQYWNrZXQpO1xuICAgICAgICB9IGVsc2UgaWYgKHNlcnZpY2VUeXBlID09PSBTZXJ2aWNlVHlwZS5IWUJSSUQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVSUENQYWNrZXQoc2RsUGFja2V0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignVW5oYW5kbGVkIHNlcnZpY2UgdHlwZSAnLCBzZGxQYWNrZXQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBtZXNzYWdlIGZyYW1lIGFzc2VtYmxlciBmb3IgdGhlIHBhY2tldC5cbiAgICAgKiBAcGFyYW0ge1NkbFBhY2tldH0gc2RsUGFja2V0XG4gICAgICovXG4gICAgX2dldE1lc3NhZ2VGcmFtZUFzc2VtYmxlciAoc2RsUGFja2V0KSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICBsZXQgbWVzc2FnZUZyYW1lQXNzZW1ibGVyID0gc2VsZi5fbWVzc2FnZUZyYW1lQXNzZW1ibGVyc1tzZGxQYWNrZXQuZ2V0TWVzc2FnZUlEKCldO1xuICAgICAgICBpZiAoIW1lc3NhZ2VGcmFtZUFzc2VtYmxlcikge1xuICAgICAgICAgICAgbWVzc2FnZUZyYW1lQXNzZW1ibGVyID0gbmV3IE1lc3NhZ2VGcmFtZUFzc2VtYmxlcihmdW5jdGlvbiAoZXJyLCBzZGxQYWNrZXQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzZWxmLl9tZXNzYWdlRnJhbWVBc3NlbWJsZXJzW3NkbFBhY2tldC5nZXRNZXNzYWdlSUQoKV0gPSBudWxsOyAvLyBSZW1vdmUgdGhlIG1hcHBpbmdcbiAgICAgICAgICAgICAgICBzZWxmLl9oYW5kbGVPbk1lc3NhZ2VBc3NlbWJsZWQoc2RsUGFja2V0KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc2VsZi5fbWVzc2FnZUZyYW1lQXNzZW1ibGVyc1tzZGxQYWNrZXQuZ2V0TWVzc2FnZUlEKCldID0gbWVzc2FnZUZyYW1lQXNzZW1ibGVyO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2VGcmFtZUFzc2VtYmxlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGVzIGluY29taW5nIGNvbnRyb2wgcGFja2V0cy5cbiAgICAgKiBAcGFyYW0geyBTZGxQYWNrZXQgfSBzZGxQYWNrZXRcbiAgICAgKi9cbiAgICBfaGFuZGxlQ29udHJvbFBhY2tldCAoc2RsUGFja2V0KSB7XG4gICAgICAgIGNvbnN0IGZyYW1lSW5mbyA9IHNkbFBhY2tldC5nZXRGcmFtZUluZm8oKTtcblxuICAgICAgICBpZiAoZnJhbWVJbmZvID09PSBTZGxQYWNrZXQuRlJBTUVfSU5GT19IRUFSVF9CRUFUKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faGFuZGxlUHJvdG9jb2xIZWFydGJlYXQoc2RsUGFja2V0KTtcbiAgICAgICAgfSBlbHNlIGlmIChmcmFtZUluZm8gPT09IFNkbFBhY2tldC5GUkFNRV9JTkZPX0hFQVJUX0JFQVRfQUNLKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faGFuZGxlUHJvdG9jb2xIZWFydGJlYXRBQ0soc2RsUGFja2V0KTtcbiAgICAgICAgfSBlbHNlIGlmIChmcmFtZUluZm8gPT09IFNkbFBhY2tldC5GUkFNRV9JTkZPX1NUQVJUX1NFUlZJQ0VfQUNLKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faGFuZGxlU3RhcnRTZXJ2aWNlQUNLKHNkbFBhY2tldCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZnJhbWVJbmZvID09PSBTZGxQYWNrZXQuRlJBTUVfSU5GT19TVEFSVF9TRVJWSUNFX05BSykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2hhbmRsZVN0YXJ0U2VydmljZU5BSyhzZGxQYWNrZXQpO1xuICAgICAgICB9IGVsc2UgaWYgKGZyYW1lSW5mbyA9PT0gU2RsUGFja2V0LkZSQU1FX0lORk9fRU5EX1NFUlZJQ0VfQUNLKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faGFuZGxlRW5kU2VydmljZUFDSyhzZGxQYWNrZXQpO1xuICAgICAgICB9IGVsc2UgaWYgKGZyYW1lSW5mbyA9PT0gU2RsUGFja2V0LkZSQU1FX0lORk9fRU5EX1NFUlZJQ0UpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVFbmRTZXJ2aWNlKHNkbFBhY2tldCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZnJhbWVJbmZvID09PSBTZGxQYWNrZXQuRlJBTUVfSU5GT19FTkRfU0VSVklDRV9OQUspIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVFbmRTZXJ2aWNlTkFLKHNkbFBhY2tldCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1VuaGFuZGxlZCBjb250cm9sIHBhY2tldCcsIHsgZnJhbWVJbmZvIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGUgaGVhcnRiZWF0IChPbmx5IGF2YWlsYWJsZSBpbiBwcm90b2NvbCB2ZXJzaW9uIDMpXG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldFxuICAgICAqL1xuICAgIF9oYW5kbGVQcm90b2NvbEhlYXJ0YmVhdCAoc2RsUGFja2V0KSB7XG4gICAgICAgIGNvbnN0IGhlYXJ0YmVhdCA9IFNkbFBhY2tldEZhY3RvcnkuY3JlYXRlSGVhcnRiZWF0QUNLKFxuICAgICAgICAgICAgU2VydmljZVR5cGUuQ09OVFJPTCxcbiAgICAgICAgICAgIHRoaXMuX2dldFNlc3Npb25JZCgpLFxuICAgICAgICAgICAgdGhpcy5fcHJvdG9jb2xWZXJzaW9uLmdldE1ham9yKCkpO1xuICAgICAgICB0aGlzLnNlbmRQYWNrZXQoaGVhcnRiZWF0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGVzIGhlYXJ0YmVhdCBBQ0suXG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldFxuICAgICAqL1xuICAgIF9oYW5kbGVQcm90b2NvbEhlYXJ0YmVhdEFDSyAoc2RsUGFja2V0KSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBSZWNlaXZlZCBIZWFydGJlYXRBQ0sgLSAke3NkbFBhY2tldC50b1N0cmluZygpfWApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhhbmRsZXMgc3RhcnQgc2VydmljZSBBQ0suIFNldHMgdGhlIGFwcHJvcHJpYXRlIHZlcnNpb24sIE1UVSwgYW5kIG90aGVyXG4gICAgICogc2VydmljZSByZWxhdGVkIGluZm8uXG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldFxuICAgICAqL1xuICAgIF9oYW5kbGVTdGFydFNlcnZpY2VBQ0sgKHNkbFBhY2tldCkge1xuICAgICAgICBjb25zdCB2ZXJzaW9uID0gc2RsUGFja2V0LmdldFZlcnNpb24oKTtcbiAgICAgICAgY29uc3Qgc2VydmljZVR5cGUgPSBzZGxQYWNrZXQuZ2V0U2VydmljZVR5cGUoKTtcbiAgICAgICAgaWYgKHZlcnNpb24gPj0gNSkge1xuICAgICAgICAgICAgbGV0IG10dVRhZyA9IG51bGw7XG4gICAgICAgICAgICBpZiAoc2VydmljZVR5cGUgPT09IFNlcnZpY2VUeXBlLlJQQykge1xuICAgICAgICAgICAgICAgIG10dVRhZyA9IENvbnRyb2xGcmFtZVRhZ3MuUlBDLlN0YXJ0U2VydmljZUFDSy5NVFU7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHNlcnZpY2VUeXBlID09PSAoU2VydmljZVR5cGUuUENNKSkge1xuICAgICAgICAgICAgICAgIG10dVRhZyA9IENvbnRyb2xGcmFtZVRhZ3MuQXVkaW8uU3RhcnRTZXJ2aWNlQUNLLk1UVTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoc2VydmljZVR5cGUgPT09IChTZXJ2aWNlVHlwZS5OQVYpKSB7XG4gICAgICAgICAgICAgICAgbXR1VGFnID0gQ29udHJvbEZyYW1lVGFncy5WaWRlby5TdGFydFNlcnZpY2VBQ0suTVRVO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbXR1ID0gc2RsUGFja2V0LmdldFRhZyhtdHVUYWcpO1xuXG4gICAgICAgICAgICBpZiAobXR1ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbXR1c1tzZXJ2aWNlVHlwZV0gPSBtdHU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc2VydmljZVR5cGUgPT09IFNlcnZpY2VUeXBlLlJQQykge1xuICAgICAgICAgICAgICAgIHRoaXMuX3Nlc3Npb25JRCA9IHNkbFBhY2tldC5nZXRTZXNzaW9uSUQoKTtcbiAgICAgICAgICAgICAgICAvLyBUT0RPIGhhbmRsZSBvbGRlciB2ZXJzaW9ucyBvZiB0aGUgcHJvdG9jb2wgd2hlcmUgdGhpcyB3YXMganVzdCB0aGVpciBwYXlsb2FkLCBubyBCU09OXG4gICAgICAgICAgICAgICAgdGhpcy5faGFzaElEID0gc2RsUGFja2V0LmdldFRhZyhDb250cm9sRnJhbWVUYWdzLlJQQy5TdGFydFNlcnZpY2VBQ0suSEFTSF9JRCk7XG4gICAgICAgICAgICAgICAgY29uc3QgdmVyc2lvbiA9IHNkbFBhY2tldC5nZXRUYWcoQ29udHJvbEZyYW1lVGFncy5SUEMuU3RhcnRTZXJ2aWNlQUNLLlBST1RPQ09MX1ZFUlNJT04pO1xuICAgICAgICAgICAgICAgIGlmICh2ZXJzaW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEF0IHRoaXMgcG9pbnQgd2UgaGF2ZSBjb25maXJtZWQgdGhlIG5lZ290aWF0ZWQgdmVyc2lvbiBiZXR3ZWVuIHRoZSBtb2R1bGUgYW5kIHRoZSBwcm94eVxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wcm90b2NvbFZlcnNpb24gPSAobmV3IFZlcnNpb24oKSkuZnJvbVN0cmluZyh2ZXJzaW9uKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wcm90b2NvbFZlcnNpb24gPSBuZXcgVmVyc2lvbig1LCAwLCAwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHNlcnZpY2VUeXBlID09PSBTZXJ2aWNlVHlwZS5WSURFTykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9zZGxQcm90b2NvbExpc3RlbmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFjY2VwdGVkUmVzb2x1dGlvbiA9IG5ldyBJbWFnZVJlc29sdXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWNjZXB0ZWRGb3JtYXQgPSBuZXcgVmlkZW9TdHJlYW1pbmdGb3JtYXQoKTtcbiAgICAgICAgICAgICAgICAgICAgYWNjZXB0ZWRSZXNvbHV0aW9uLnNldFJlc29sdXRpb25IZWlnaHQoTWF0aC5mbG9vcihzZGxQYWNrZXQuZ2V0VGFnKENvbnRyb2xGcmFtZVRhZ3MuVmlkZW8uU3RhcnRTZXJ2aWNlQUNLLkhFSUdIVCkpKTtcbiAgICAgICAgICAgICAgICAgICAgYWNjZXB0ZWRSZXNvbHV0aW9uLnNldFJlc29sdXRpb25XaWR0aChNYXRoLmZsb29yKHNkbFBhY2tldC5nZXRUYWcoQ29udHJvbEZyYW1lVGFncy5WaWRlby5TdGFydFNlcnZpY2VBQ0suV0lEVEgpKSk7XG5cbiAgICAgICAgICAgICAgICAgICAgYWNjZXB0ZWRGb3JtYXQuc2V0Q29kZWMoc2RsUGFja2V0LmdldFRhZyhDb250cm9sRnJhbWVUYWdzLlZpZGVvLlN0YXJ0U2VydmljZUFDSy5WSURFT19DT0RFQykpO1xuICAgICAgICAgICAgICAgICAgICBhY2NlcHRlZEZvcm1hdC5zZXRQcm90b2NvbChzZGxQYWNrZXQuZ2V0VGFnKENvbnRyb2xGcmFtZVRhZ3MuVmlkZW8uU3RhcnRTZXJ2aWNlQUNLLlZJREVPX1BST1RPQ09MKSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFncmVlZFZpZGVvUGFyYW1zID0gdGhpcy5fc2RsUHJvdG9jb2xMaXN0ZW5lci5nZXREZXNpcmVkVmlkZW9QYXJhbXMoKTtcbiAgICAgICAgICAgICAgICAgICAgYWdyZWVkVmlkZW9QYXJhbXMuc2V0UmVzb2x1dGlvbihhY2NlcHRlZFJlc29sdXRpb24pO1xuICAgICAgICAgICAgICAgICAgICBhZ3JlZWRWaWRlb1BhcmFtcy5zZXRGb3JtYXQoYWNjZXB0ZWRGb3JtYXQpO1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3NkbFByb3RvY29sTGlzdGVuZXIuc2V0QWNjZXB0ZWRWaWRlb1BhcmFtcyhhZ3JlZWRWaWRlb1BhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3Byb3RvY29sVmVyc2lvbi5nZXRNYWpvcigpID4gMSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBzZGxQYWNrZXQuZ2V0UGF5bG9hZCgpO1xuICAgICAgICAgICAgICAgIGlmIChwYXlsb2FkICE9PSBudWxsICYmIHBheWxvYWQubGVuZ3RoID09PSA0KSB7IC8vIGhhc2hpZCB3aWxsIGJlIDQgYnl0ZXMgaW4gbGVuZ3RoXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhc2hJRCA9IEJpdENvbnZlcnRlci5hcnJheUJ1ZmZlclRvSW50MzIocGF5bG9hZC5idWZmZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3NkbFByb3RvY29sTGlzdGVuZXIub25Qcm90b2NvbFNlc3Npb25TdGFydGVkKHNlcnZpY2VUeXBlLFxuICAgICAgICAgICAgc2RsUGFja2V0LmdldFNlc3Npb25JRCgpLCB0aGlzLl9wcm90b2NvbFZlcnNpb24uZ2V0TWFqb3IoKSwgJycsIHRoaXMuX2hhc2hJRCwgc2RsUGFja2V0LmdldEVuY3J5cHRpb24oKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlcyBzdGFydCBzZXJ2aWNlIHJlamVjdGlvbi5cbiAgICAgKiBAcGFyYW0ge1NkbFBhY2tldH0gc2RsUGFja2V0XG4gICAgICovXG4gICAgX2hhbmRsZVN0YXJ0U2VydmljZU5BSyAoc2RsUGFja2V0KSB7XG4gICAgICAgIGNvbnN0IGVycm9yID0gYEdvdCBTdGFydFNlc3Npb25OQUNLIGZvciBwcm90b2NvbCBzZXNzaW9uSUQgJHtzZGxQYWNrZXQuZ2V0U2Vzc2lvbklEKCl9YDtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEhhbmRsZXMgc2VydmljZSBlbmRlZCBieSBhcHAgcHJvY2Vzcy5cbiAgICAgKiBAcGFyYW0ge1NkbFBhY2tldH0gc2RsUGFja2V0XG4gICAgICovXG4gICAgX2hhbmRsZUVuZFNlcnZpY2VBQ0sgKHNkbFBhY2tldCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faGFuZGxlU2VydmljZUVuZGVkKHNkbFBhY2tldCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VydmljZSBlbmRlZCBieSBub24gYXBwIHByb2Nlc3Mgb3IgZm9yIHNvbWUgdW5leHBlY3RlZCByZWFzb24uXG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldFxuICAgICAqL1xuICAgIF9oYW5kbGVFbmRTZXJ2aWNlIChzZGxQYWNrZXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2hhbmRsZVNlcnZpY2VFbmRlZChzZGxQYWNrZXQpO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlcyBzZXJpdmNlIGVuZGluZy5cbiAgICAgKiBAcGFyYW0geyp9IHNkbFBhY2tldFxuICAgICAqL1xuICAgIF9oYW5kbGVTZXJ2aWNlRW5kZWQgKHNkbFBhY2tldCkge1xuICAgICAgICB0aGlzLl9zZGxQcm90b2NvbExpc3RlbmVyLm9uUHJvdG9jb2xTZXNzaW9uRW5kZWQoc2RsUGFja2V0LmdldFNlcnZpY2VUeXBlKCksIHNkbFBhY2tldC5nZXRTZXNzaW9uSUQoKSwgJycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhhbmRsZXMgc2VydmljZSBlbmQgcmVqZWN0aW9uLlxuICAgICAqIEBwYXJhbSB7U2RsUGFja2V0fSBzZGxQYWNrZXRcbiAgICAgKi9cbiAgICBfaGFuZGxlRW5kU2VydmljZU5BSyAoc2RsUGFja2V0KSB7XG4gICAgICAgIGNvbnN0IHNlcnZpY2VUeXBlID0gc2RsUGFja2V0LmdldFNlcnZpY2VUeXBlKCk7XG4gICAgICAgIGNvbnN0IHByb3RvY29sVmVyc2lvbiA9IHNkbFBhY2tldC5nZXRWZXJzaW9uKCk7XG4gICAgICAgIGlmIChwcm90b2NvbFZlcnNpb24gPj0gNSkge1xuICAgICAgICAgICAgbGV0IHJlamVjdGVkVGFnID0gbnVsbDtcbiAgICAgICAgICAgIGlmIChzZXJ2aWNlVHlwZSA9PT0gU2VydmljZVR5cGUuQVVESU8pIHtcbiAgICAgICAgICAgICAgICByZWplY3RlZFRhZyA9IENvbnRyb2xGcmFtZVRhZ3MuQXVkaW8uRW5kU2VydmljZU5BSy5SRUpFQ1RFRF9QQVJBTVM7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHNlcnZpY2VUeXBlID09PSBTZXJ2aWNlVHlwZS5WSURFTykge1xuICAgICAgICAgICAgICAgIHJlamVjdGVkVGFnID0gQ29udHJvbEZyYW1lVGFncy5WaWRlby5FbmRTZXJ2aWNlTkFLLlJFSkVDVEVEX1BBUkFNUztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHJlamVjdGVkUGFyYW1zID0gc2RsUGFja2V0LmdldFRhZyhyZWplY3RlZFRhZyk7XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShyZWplY3RlZFBhcmFtcykgJiYgcmVqZWN0ZWRQYXJhbXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0dvdCBFbmRTZXNzaW9uTkFLIHdpdGggcmVqZWN0ZWQgcGFyYW1zJywgcmVqZWN0ZWRQYXJhbXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3NkbFByb3RvY29sTGlzdGVuZXIub25Qcm90b2NvbFNlc3Npb25FbmRlZE5BQ0tlZChzZXJ2aWNlVHlwZSwgc2RsUGFja2V0LmdldFNlc3Npb25JRCgpLCAnJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlcyBpbmNvbWluZyBhc3NlbWJsZWQgcnBjIHBhY2tldC5cbiAgICAgKiBOb3RpZmllcyBzZGxQcm90b2NvbExpc3RlbmVyIG9mIHRoZSBldmVudCBhZnRlciBhc3NlbWJsZWluZyBhbiBScGNNZXNzYWdlXG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldFxuICAgICAqL1xuICAgIF9oYW5kbGVSUENQYWNrZXQgKHNkbFBhY2tldCkge1xuICAgICAgICBjb25zdCBycGNNZXNzYWdlID0gUnBjQ3JlYXRvci5jb25zdHJ1Y3Qoc2RsUGFja2V0KTtcbiAgICAgICAgaWYgKHJwY01lc3NhZ2UgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX3NkbFByb3RvY29sTGlzdGVuZXIub25ScGNNZXNzYWdlUmVjZWl2ZWQocnBjTWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFbmRzIHRoZSBkZWZhdWx0IHNlc3Npb24uXG4gICAgICovXG4gICAgZW5kU2Vzc2lvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNlc3Npb25JZCA9IHRoaXMuX2dldFNlc3Npb25JZCgpO1xuICAgICAgICBjb25zdCBoYXNoSUQgPSB0aGlzLl9oYXNoSUQ7XG4gICAgICAgIGNvbnN0IHNlcnZpY2VUeXBlID0gU2VydmljZVR5cGUuUlBDO1xuICAgICAgICBjb25zdCBtZXNzYWdlSUQgPSB0aGlzLl9nZXROZXh0TWVzc2FnZUlEKCk7XG4gICAgICAgIGNvbnN0IHZlcnNpb24gPSB0aGlzLl9wcm90b2NvbFZlcnNpb24uZ2V0TWFqb3IoKTtcbiAgICAgICAgY29uc3Qgc2RsUGFja2V0ID0gU2RsUGFja2V0RmFjdG9yeS5jcmVhdGVFbmRTZXNzaW9uKHNlcnZpY2VUeXBlLCBzZXNzaW9uSWQsIG1lc3NhZ2VJRCwgdmVyc2lvbiwgaGFzaElEKTtcbiAgICAgICAgdGhpcy5zZW5kUGFja2V0KHNkbFBhY2tldCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRW5kcyBhIHNwZWNpZmljIHNlcnZpY2VcbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZSAtIFNlcnZpY2UgdHlwZSBiZWluZyBlbmRlZC4gV2hlbiB0aGUgUlBDIHNlcnZpY2UgaXMgZW5kZWQgdGhlIGVudGlyZSBzZXNzaW9uIGVuZHMuXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlc3Npb25JZCAtIHJlcHJlc2VudHMgYSBieXRlXG4gICAgICovXG4gICAgZW5kU2VydmljZSAoc2VydmljZVR5cGUsIHNlc3Npb25JZCkge1xuICAgICAgICBpZiAoc2VydmljZVR5cGUgPT09IFNlcnZpY2VUeXBlLlJQQykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5kU2Vzc2lvbigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgaGFzaElEID0gdGhpcy5faGFzaElEO1xuICAgICAgICAgICAgY29uc3QgbWVzc2FnZUlEID0gdGhpcy5fZ2V0TmV4dE1lc3NhZ2VJRCgpO1xuICAgICAgICAgICAgY29uc3QgdmVyc2lvbiA9IHRoaXMuX3Byb3RvY29sVmVyc2lvbi5nZXRNYWpvcigpO1xuICAgICAgICAgICAgY29uc3Qgc2RsUGFja2V0ID0gU2RsUGFja2V0RmFjdG9yeS5jcmVhdGVFbmRTZXNzaW9uKHNlcnZpY2VUeXBlLCBzZXNzaW9uSWQsIG1lc3NhZ2VJRCwgdmVyc2lvbiwgaGFzaElEKTtcbiAgICAgICAgICAgIHRoaXMuc2VuZFBhY2tldChzZGxQYWNrZXQpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG4vKipcbiAqIE9yaWdpbmFsIGhlYWRlciBzaXplIGJhc2VkIG9uIHZlcnNpb24gMS4wLjAgb25seVxuICovXG5TZGxQcm90b2NvbEJhc2UuVjFfSEVBREVSX1NJWkUgPSA4O1xuLyoqXG4gKiBMYXJnZXIgaGVhZGVyIHNpemUgdGhhdCBpcyB1c2VkIGJ5IHZlcnNpb25zIDIuMC4wIGFuZCB1cFxuICovXG5TZGxQcm90b2NvbEJhc2UuVjJfSEVBREVSX1NJWkUgPSAxMjtcblxuU2RsUHJvdG9jb2xCYXNlLlYxX1YyX01UVV9TSVpFID0gMTUwMDtcblNkbFByb3RvY29sQmFzZS5WM19WNF9NVFVfU0laRSA9IDEzMTA3MjtcblxuLyoqXG4gKiBNYXggc3VwcG9ydGVkIHByb3RvY29sIHZlcnNpb24gaW4gdGhpcyByZWxlYXNlIG9mIHRoZSBsaWJyYXJ5XG4qL1xuU2RsUHJvdG9jb2xCYXNlLk1BWF9QUk9UT0NPTF9WRVJTSU9OID0gbmV3IFZlcnNpb24oNSwgMiwgMCk7XG5cbmV4cG9ydCB7IFNkbFByb3RvY29sQmFzZSB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBUcmFuc3BvcnRUeXBlXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBUcmFuc3BvcnRUeXBlIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBXRUJTT0NLRVRfQ0xJRU5UICgpIHtcbiAgICAgICAgcmV0dXJuIFRyYW5zcG9ydFR5cGUuX01BUC5XRUJTT0NLRVRfQ0xJRU5UO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IFdFQlNPQ0tFVF9TRVJWRVIgKCkge1xuICAgICAgICByZXR1cm4gVHJhbnNwb3J0VHlwZS5fTUFQLldFQlNPQ0tFVF9TRVJWRVI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N0cmluZ31cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ1VTVE9NICgpIHtcbiAgICAgICAgcmV0dXJuIFRyYW5zcG9ydFR5cGUuX01BUC5DVVNUT007XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFRyYW5zcG9ydFR5cGUuX3ZhbHVlRm9yS2V5KGtleSwgVHJhbnNwb3J0VHlwZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gVHJhbnNwb3J0VHlwZS5fa2V5Rm9yVmFsdWUodmFsdWUsIFRyYW5zcG9ydFR5cGUuX01BUCk7XG4gICAgfVxufVxuXG5UcmFuc3BvcnRUeXBlLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnV0VCU09DS0VUX0NMSUVOVCc6ICdXRUJTT0NLRVRfQ0xJRU5UJyxcbiAgICAnV0VCU09DS0VUX1NFUlZFUic6ICdXRUJTT0NLRVRfU0VSVkVSJyxcbiAgICAnQ1VTVE9NJzogJ0NVU1RPTScsXG59KTtcblxuZXhwb3J0IHsgVHJhbnNwb3J0VHlwZSB9OyIsIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4gKlxuICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4gKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4gKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuICogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4gKiBkaXN0cmlidXRpb24uXG4gKlxuICogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiAqIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuICogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4gKlxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiAqIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4gKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4gKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4gKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuICogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4gKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuICogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiAqIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4gKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqL1xuXG5pbXBvcnQgeyBGcmFtZVR5cGUgfSBmcm9tICcuLi9wcm90b2NvbC9lbnVtcy9GcmFtZVR5cGUuanMnO1xuaW1wb3J0IHsgU2RsUGFja2V0IH0gZnJvbSAnLi4vcHJvdG9jb2wvU2RsUGFja2V0LmpzJztcbmltcG9ydCB7IFNkbFByb3RvY29sQmFzZSB9IGZyb20gJy4uL3Byb3RvY29sL1NkbFByb3RvY29sQmFzZS5qcyc7XG5cbi8qKlxuICogUGFyc2VzIGluY29taW5nIGJ5dGVzIGFjY29yZGluZyB0byB0aGUgcHJvdG9jb2wgc3BlYy5cbiAqL1xuY2xhc3MgU2RsUHNtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHRoaXMucmVzZXQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGFuZ2VzIGFsbCBpbnRlcm5hbCBtZW1iZXJzIHRvIGRlZmF1bHRcbiAgICAgKi9cbiAgICByZXNldCAoKSB7XG4gICAgICAgIHRoaXMuX3N0YXRlID0gU2RsUHNtLlNUQVJUX1NUQVRFO1xuICAgICAgICB0aGlzLl92ZXJzaW9uID0gMDtcbiAgICAgICAgdGhpcy5fZW5jcnlwdGlvbiA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9mcmFtZVR5cGUgPSBGcmFtZVR5cGUuU0lOR0xFO1xuICAgICAgICB0aGlzLl9zZXJ2aWNlVHlwZSA9IDA7XG4gICAgICAgIHRoaXMuX2NvbnRyb2xGcmFtZUluZm8gPSBudWxsO1xuICAgICAgICB0aGlzLl9zZXNzaW9uSUQgPSBudWxsO1xuICAgICAgICB0aGlzLl9kdW1wU2l6ZSA9IG51bGw7XG4gICAgICAgIHRoaXMuX2RhdGFMZW5ndGggPSAwO1xuICAgICAgICB0aGlzLl9tZXNzYWdlSUQgPSAwO1xuICAgICAgICB0aGlzLl9wYXlsb2FkID0gbnVsbDtcbiAgICB9XG5cblxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfSAtIFN0YXRlIHJlcHJlc2VudGVkIGJ5IGEgTnVtYmVyXG4gICAgICovXG4gICAgZ2V0U3RhdGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U2RsUGFja2V0fSAtIFJldHVybnMgbnVsbCBpZiBub3QgY29tcGxldGVcbiAgICAgKi9cblxuICAgIGdldEZvcm1lZFBhY2tldCAoKSB7XG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gU2RsUHNtLkZJTklTSEVEX1NUQVRFKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFNkbFBhY2tldCh0aGlzLl92ZXJzaW9uLCB0aGlzLl9lbmNyeXB0aW9uLCB0aGlzLl9mcmFtZVR5cGUsIHRoaXMuX3NlcnZpY2VUeXBlLCB0aGlzLl9jb250cm9sRnJhbWVJbmZvLCB0aGlzLl9zZXNzaW9uSUQsIHRoaXMuX2RhdGFMZW5ndGgsIHRoaXMuX21lc3NhZ2VJRCwgdGhpcy5fcGF5bG9hZCwgMCwgdGhpcy5fZGF0YUxlbmd0aCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhhbmRsZXMgdGhlIG5leHQgYnl0ZSBpbiB0aGUgc3RyZWFtIG9mIGRhdGEuXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGRhdGEgLSBSZXByZXNlbnRzIGEgYnl0ZVxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59IC0gVHJ1ZSBpZiBzdWNjZXNzZnVsLCBmYWxzZSBvdGhlcndpc2VcbiAgICAgKi9cbiAgICBoYW5kbGVCeXRlIChkYXRhKSB7XG4gICAgICAgIHRoaXMuX3N0YXRlID0gdGhpcy5fdHJhbnNpdGlvbk9uSW5wdXQoZGF0YSwgdGhpcy5fc3RhdGUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFNkbFBzbS5FUlJPUl9TVEFURSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSByYXdCeXRlIC0gUmVwcmVzZW50cyBhIGJ5dGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc3RhdGVcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgX3RyYW5zaXRpb25PbklucHV0IChyYXdCeXRlLCBzdGF0ZSkge1xuICAgICAgICBpZiAoc3RhdGUgPT09IFNkbFBzbS5TVEFSVF9TVEFURSkgeyAvLyBieXRlIDFcbiAgICAgICAgICAgIHRoaXMuX3ZlcnNpb24gPSAocmF3Qnl0ZSAmIFNkbFBzbS5WRVJTSU9OX01BU0spID4+IDQ7XG4gICAgICAgICAgICBpZiAodGhpcy5fdmVyc2lvbiA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBTZGxQc20uRVJST1JfU1RBVEU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuX2VuY3J5cHRpb24gPSAoMSA9PT0gKChyYXdCeXRlICYgU2RsUHNtLkVOQ1JZUFRJT05fTUFTSykgPj4gMykpO1xuICAgICAgICAgICAgdGhpcy5fZnJhbWVUeXBlID0gcmF3Qnl0ZSAmIFNkbFBzbS5GUkFNRV9UWVBFX01BU0s7XG5cbiAgICAgICAgICAgIGlmICgodGhpcy5fdmVyc2lvbiA8IDEgfHwgdGhpcy5fdmVyc2lvbiA+IDUpICYmIHRoaXMuX2ZyYW1lVHlwZSAhPT0gRnJhbWVUeXBlLkNPTlRST0wpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gU2RsUHNtLkVSUk9SX1NUQVRFO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5fZnJhbWVUeXBlIDwgRnJhbWVUeXBlLkNPTlRST0wgfHwgdGhpcy5fZnJhbWVUeXBlID4gRnJhbWVUeXBlLkNPTlNFQ1VUSVZFKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFNkbFBzbS5FUlJPUl9TVEFURTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBTZGxQc20uU0VSVklDRV9UWVBFX1NUQVRFO1xuICAgICAgICB9IGVsc2UgaWYgKHN0YXRlID09PSBTZGxQc20uU0VSVklDRV9UWVBFX1NUQVRFKSB7IC8vIGJ5dGUgMlxuICAgICAgICAgICAgdGhpcy5fc2VydmljZVR5cGUgPSAocmF3Qnl0ZSAmIDB4RkYpO1xuXG4gICAgICAgICAgICByZXR1cm4gU2RsUHNtLkNPTlRST0xfRlJBTUVfSU5GT19TVEFURTtcbiAgICAgICAgfSBlbHNlIGlmIChzdGF0ZSA9PT0gU2RsUHNtLkNPTlRST0xfRlJBTUVfSU5GT19TVEFURSkgeyAvLyBieXRlIDNcbiAgICAgICAgICAgIHRoaXMuX2NvbnRyb2xGcmFtZUluZm8gPSByYXdCeXRlICYgMHhGRjtcblxuICAgICAgICAgICAgc3dpdGNoICh0aGlzLl9mcmFtZVR5cGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlIEZyYW1lVHlwZS5DT05UUk9MOlxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIEZyYW1lVHlwZS5TSU5HTEU6IC8vIEZhbGwgdGhyb3VnaCBzaW5jZSB0aGV5IGFyZSBib3RoIHRoZSBzYW1lXG4gICAgICAgICAgICAgICAgY2FzZSBGcmFtZVR5cGUuRklSU1Q6XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9jb250cm9sRnJhbWVJbmZvICE9PSAweDAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gU2RsUHNtLkVSUk9SX1NUQVRFO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgRnJhbWVUeXBlLkNPTlNFQ1VUSVZFOlxuICAgICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBTZGxQc20uRVJST1JfU1RBVEU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gU2RsUHNtLlNFU1NJT05fSURfU1RBVEU7XG4gICAgICAgIH0gZWxzZSBpZiAoc3RhdGUgPT09IFNkbFBzbS5TRVNTSU9OX0lEX1NUQVRFKSB7IC8vIGJ5dGUgNFxuICAgICAgICAgICAgdGhpcy5fc2Vzc2lvbklEID0gKHJhd0J5dGUgJiAweEZGKTtcbiAgICAgICAgICAgIHJldHVybiBTZGxQc20uREFUQV9TSVpFXzFfU1RBVEU7XG4gICAgICAgIH0gZWxzZSBpZiAoc3RhdGUgPT09IFNkbFBzbS5EQVRBX1NJWkVfMV9TVEFURSkgeyAvLyBieXRlIDVcbiAgICAgICAgICAgIHRoaXMuX2RhdGFMZW5ndGggKz0gKHJhd0J5dGUgJiAweEZGKSA8PCAyNDtcbiAgICAgICAgICAgIHJldHVybiBTZGxQc20uREFUQV9TSVpFXzJfU1RBVEU7XG4gICAgICAgIH0gZWxzZSBpZiAoc3RhdGUgPT09IFNkbFBzbS5EQVRBX1NJWkVfMl9TVEFURSkgeyAvLyBieXRlIDZcbiAgICAgICAgICAgIHRoaXMuX2RhdGFMZW5ndGggKz0gKHJhd0J5dGUgJiAweEZGKSA8PCAxNjsgLy8gIyAyIGJ5dGVzIHggOCBiaXRzXG4gICAgICAgICAgICByZXR1cm4gU2RsUHNtLkRBVEFfU0laRV8zX1NUQVRFO1xuICAgICAgICB9IGVsc2UgaWYgKHN0YXRlID09PSBTZGxQc20uREFUQV9TSVpFXzNfU1RBVEUpIHsgLy8gYnl0ZSA3XG4gICAgICAgICAgICB0aGlzLl9kYXRhTGVuZ3RoICs9IChyYXdCeXRlICYgMHhGRikgPDwgODsgLy8gIyAgMSBieXRlIHggOCBiaXRzXG4gICAgICAgICAgICByZXR1cm4gU2RsUHNtLkRBVEFfU0laRV80X1NUQVRFO1xuICAgICAgICB9IGVsc2UgaWYgKHN0YXRlID09PSBTZGxQc20uREFUQV9TSVpFXzRfU1RBVEUpIHsgLy8gYnl0ZSA4XG4gICAgICAgICAgICB0aGlzLl9kYXRhTGVuZ3RoICs9IChyYXdCeXRlICYgMHhGRik7IC8vICMgMiBieXRlcyB4IDggYml0c1xuXG4gICAgICAgICAgICBzd2l0Y2ggKHRoaXMuX2ZyYW1lVHlwZSkgeyAvLyBJZiBhbGwgaXMgY29ycmVjdCB3ZSBzaG91bGQgYnJlYWsgb3V0IG9mIHRoaXMgc3dpdGNoIHN0YXRlbWVudFxuICAgICAgICAgICAgICAgIGNhc2UgRnJhbWVUeXBlLlNJTkdMRTpcbiAgICAgICAgICAgICAgICBjYXNlIEZyYW1lVHlwZS5DT05TRUNVVElWRTpcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBGcmFtZVR5cGUuQ09OVFJPTDpcbiAgICAgICAgICAgICAgICAvLyBPaywgd2VsbCBoZXJlJ3Mgc29tZSBpbnRlcmVzdGluZyBiaXQgb2Yga25vd2xlZGdlLiBCZWNhdXNlIHRoZSBzdGFydCBzZXNzaW9uIHJlcXVlc3QgaXMgZnJvbSB0aGUgcGhvbmUgd2l0aCBubyBrbm93bGVkZ2Ugb2YgdmVyc2lvbiBpdCBzZW5kcyBvdXRcbiAgICAgICAgICAgICAgICAvLyBhIHYxIHBhY2tldC4gVEhFUkVGT1JFIHRoZXJlIGlzIG5vIG1lc3NhZ2UgaWQgZmllbGQuICoqKiogTm93IHlvdSBrbm93IGFuZCBrbm93aW5nIGlzIGhhbGYgdGhlIGJhdHRsZSAqKioqXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl92ZXJzaW9uID09PSAxICYmIHRoaXMuX2NvbnRyb2xGcmFtZUluZm8gPT09IFNkbFBhY2tldC5GUkFNRV9JTkZPX1NUQVJUX1NFUlZJQ0UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9kYXRhTGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNkbFBzbS5GSU5JU0hFRF9TVEFURTsgLy8gV2UgYXJlIGRvbmUgaWYgd2UgZG9uJ3QgaGF2ZSBhbnkgcGF5bG9hZFxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX2RhdGFMZW5ndGggPD0gU2RsUHJvdG9jb2xCYXNlLlYxX1YyX01UVV9TSVpFIC0gU2RsUHJvdG9jb2xCYXNlLlYxX0hFQURFUl9TSVpFKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGF5bG9hZCA9IG5ldyBVaW50OEFycmF5KHRoaXMuX2RhdGFMZW5ndGgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gU2RsUHNtLkVSUk9SX1NUQVRFO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZHVtcFNpemUgPSB0aGlzLl9kYXRhTGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNkbFBzbS5EQVRBX1BVTVBfU1RBVEU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICBjYXNlIEZyYW1lVHlwZS5GSVJTVDpcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX2RhdGFMZW5ndGggIT09IFNkbFBzbS5GSVJTVF9GUkFNRV9EQVRBX1NJWkUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBTZGxQc20uRVJST1JfU1RBVEU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNkbFBzbS5FUlJPUl9TVEFURTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuX3ZlcnNpb24gPT09IDEpIHsgLy8gVmVyc2lvbiAxIHBhY2tldHMgd2lsbCBub3QgaGF2ZSBtZXNzYWdlIGlkJ3NcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fZGF0YUxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gU2RsUHNtLkZJTklTSEVEX1NUQVRFOyAvLyBXZSBhcmUgZG9uZSBpZiB3ZSBkb24ndCBoYXZlIGFueSBwYXlsb2FkXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9kYXRhTGVuZ3RoIDw9IFNkbFByb3RvY29sQmFzZS5WMV9WMl9NVFVfU0laRSAtIFNkbFByb3RvY29sQmFzZS5WMV9IRUFERVJfU0laRSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wYXlsb2FkID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5fZGF0YUxlbmd0aCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNkbFBzbS5FUlJPUl9TVEFURTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5fZHVtcFNpemUgPSB0aGlzLl9kYXRhTGVuZ3RoO1xuICAgICAgICAgICAgICAgIHJldHVybiBTZGxQc20uREFUQV9QVU1QX1NUQVRFO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gU2RsUHNtLk1FU1NBR0VfMV9TVEFURTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChzdGF0ZSA9PT0gU2RsUHNtLk1FU1NBR0VfMV9TVEFURSkgeyAvLyBieXRlIDksIGJ5dGVzIDktMTIgYXZhaWxhYmxlIGluIHZlcnNpb24gMisuXG4gICAgICAgICAgICB0aGlzLl9tZXNzYWdlSUQgKz0gKHJhd0J5dGUgJiAweEZGKSA8PCAyNDtcbiAgICAgICAgICAgIHJldHVybiBTZGxQc20uTUVTU0FHRV8yX1NUQVRFO1xuICAgICAgICB9IGVsc2UgaWYgKHN0YXRlID09PSBTZGxQc20uTUVTU0FHRV8yX1NUQVRFKSB7IC8vIGJ5dGUgMTBcbiAgICAgICAgICAgIHRoaXMuX21lc3NhZ2VJRCArPSAocmF3Qnl0ZSAmIDB4RkYpIDw8IDE2O1xuICAgICAgICAgICAgcmV0dXJuIFNkbFBzbS5NRVNTQUdFXzNfU1RBVEU7XG4gICAgICAgIH0gZWxzZSBpZiAoc3RhdGUgPT09IFNkbFBzbS5NRVNTQUdFXzNfU1RBVEUpIHsgLy8gYnl0ZSAxMVxuICAgICAgICAgICAgdGhpcy5fbWVzc2FnZUlEICs9IChyYXdCeXRlICYgMHhGRikgPDwgODtcbiAgICAgICAgICAgIHJldHVybiBTZGxQc20uTUVTU0FHRV80X1NUQVRFO1xuICAgICAgICB9IGVsc2UgaWYgKHN0YXRlID09PSBTZGxQc20uTUVTU0FHRV80X1NUQVRFKSB7IC8vIGJ5dGUgMTJcbiAgICAgICAgICAgIHRoaXMuX21lc3NhZ2VJRCArPSAocmF3Qnl0ZSAmIDB4RkYpO1xuICAgICAgICAgICAgaWYgKHRoaXMuX2RhdGFMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gU2RsUHNtLkZJTklTSEVEX1NUQVRFO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fZHVtcFNpemUgPSB0aGlzLl9kYXRhTGVuZ3RoO1xuICAgICAgICAgICAgdGhpcy5fcGF5bG9hZCA9IG5ldyBVaW50OEFycmF5KHRoaXMuX2RhdGFMZW5ndGgpO1xuICAgICAgICAgICAgcmV0dXJuIFNkbFBzbS5EQVRBX1BVTVBfU1RBVEU7XG4gICAgICAgIH0gZWxzZSBpZiAoc3RhdGUgPT09IFNkbFBzbS5EQVRBX1BVTVBfU1RBVEUpIHsgLy8gYnl0ZSAxM1xuICAgICAgICAgICAgdGhpcy5fcGF5bG9hZFt0aGlzLl9kYXRhTGVuZ3RoIC0gdGhpcy5fZHVtcFNpemVdID0gcmF3Qnl0ZTtcbiAgICAgICAgICAgIHRoaXMuX2R1bXBTaXplIC09IDE7XG4gICAgICAgICAgICAvLyBEbyB3ZSBoYXZlIGFueSBtb3JlIGJ5dGVzIHRvIHJlYWQgaW4/XG4gICAgICAgICAgICBpZiAodGhpcy5fZHVtcFNpemUgPiAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFNkbFBzbS5EQVRBX1BVTVBfU1RBVEU7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX2R1bXBTaXplID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFNkbFBzbS5GSU5JU0hFRF9TVEFURTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFNkbFBzbS5FUlJPUl9TVEFURTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuU2RsUHNtLlNUQVJUX1NUQVRFICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDA7XG5TZGxQc20uU0VSVklDRV9UWVBFX1NUQVRFICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDI7XG5TZGxQc20uQ09OVFJPTF9GUkFNRV9JTkZPX1NUQVRFICAgICAgICAgICAgICAgICA9IDB4MDM7XG5TZGxQc20uU0VTU0lPTl9JRF9TVEFURSAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDQ7XG5TZGxQc20uREFUQV9TSVpFXzFfU1RBVEUgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDU7XG5TZGxQc20uREFUQV9TSVpFXzJfU1RBVEUgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDY7XG5TZGxQc20uREFUQV9TSVpFXzNfU1RBVEUgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDc7XG5TZGxQc20uREFUQV9TSVpFXzRfU1RBVEUgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDg7XG5TZGxQc20uTUVTU0FHRV8xX1NUQVRFICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDk7XG5TZGxQc20uTUVTU0FHRV8yX1NUQVRFICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEE7XG5TZGxQc20uTUVTU0FHRV8zX1NUQVRFICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEI7XG5TZGxQc20uTUVTU0FHRV80X1NUQVRFICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEM7XG5TZGxQc20uREFUQV9QVU1QX1NUQVRFICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEQ7XG5TZGxQc20uRklOSVNIRURfU1RBVEUgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4RkY7XG5TZGxQc20uRVJST1JfU1RBVEUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IC0xO1xuXG5TZGxQc20uRklSU1RfRlJBTUVfREFUQV9TSVpFICAgICAgICAgICAgICAgICAgICA9IDB4MDg7XG5TZGxQc20uVkVSU0lPTl9NQVNLICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4RjA7IC8vIDQgaGlnaGVzdCBiaXRzXG5TZGxQc20uRU5DUllQVElPTl9NQVNLICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDg7IC8vIDR0aCBsb3dlc3QgYml0XG5TZGxQc20uRlJBTUVfVFlQRV9NQVNLICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDc7IC8vIDMgbG93ZXN0IGJpdHNcblxuZXhwb3J0IHsgU2RsUHNtIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFNkbFBzbSB9IGZyb20gJy4vU2RsUHNtLmpzJztcblxuY2xhc3MgVHJhbnNwb3J0QmFzZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtCYXNlVHJhbnNwb3J0Q29uZmlnfSB0cmFuc3BvcnRDb25maWdcbiAgICAgKiBAcGFyYW0ge1RyYW5zcG9ydENhbGxiYWNrfSB0cmFuc3BvcnRDYWxsYmFja1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICh0cmFuc3BvcnRDb25maWcsIHRyYW5zcG9ydENhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX3NkbFBzbSA9IG5ldyBTZGxQc20oKTtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q29uZmlnID0gdHJhbnNwb3J0Q29uZmlnO1xuICAgICAgICB0aGlzLl90cmFuc3BvcnRDYWxsYmFjayA9IHRyYW5zcG9ydENhbGxiYWNrO1xuICAgIH1cblxuICAgIHN0YXJ0ICgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdzdGFydCBtZXRob2QgbXVzdCBiZSBvdmVycmlkZGVuJyk7XG4gICAgfVxuXG4gICAgc3RvcCAoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignc3RvcCBtZXRob2QgbXVzdCBiZSBvdmVycmlkZGVuJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldFxuICAgICAqL1xuICAgIHNlbmRQYWNrZXQgKHNkbFBhY2tldCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NlbmRQYWNrZXQgbWV0aG9kIG11c3QgYmUgb3ZlcnJpZGRlbicpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VHJhbnNwb3J0Q2FsbGJhY2t9IGNhbGxiYWNrXG4gICAgICovXG4gICAgc2V0VHJhbnNwb3J0Q2FsbGJhY2sgKGNhbGxiYWNrKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignc2V0VHJhbnNwb3J0Q2FsbGJhY2sgbWV0aG9kIG11c3QgYmUgb3ZlcnJpZGRlbicpO1xuICAgIH1cbn1cblxuZXhwb3J0IHsgVHJhbnNwb3J0QmFzZSB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFRyYW5zcG9ydEJhc2UgfSBmcm9tICcuL1RyYW5zcG9ydEJhc2UuanMnO1xuaW1wb3J0IHsgU2RsUHNtIH0gZnJvbSAnLi9TZGxQc20uanMnO1xuXG5jbGFzcyBXZWJTb2NrZXRDbGllbnQgZXh0ZW5kcyBUcmFuc3BvcnRCYXNlIHtcbiAgICBjb25zdHJ1Y3RvciAoY29uZmlnLCB0cmFuc3BvcnRDYWxsYmFjaykge1xuICAgICAgICBzdXBlcihjb25maWcsIHRyYW5zcG9ydENhbGxiYWNrKTtcbiAgICAgICAgdGhpcy5fcXVldWUgPSBbXTtcbiAgICAgICAgdGhpcy5faXNSdW5uaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3dzVXJsID0gYCR7Y29uZmlnLmdldEhvc3QoKX06JHtjb25maWcuZ2V0UG9ydCgpfWA7XG4gICAgICAgIHRoaXMuX3dzID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1RyYW5zcG9ydENhbGxiYWNrfSBjYWxsYmFja1xuICAgICAqL1xuICAgIHNldFRyYW5zcG9ydENhbGxiYWNrIChjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl90cmFuc3BvcnRDYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9wZW5zIHRoZSB0cmFuc3BvcnQgY29ubmVjdGlvblxuICAgICAqL1xuICAgIHN0YXJ0ICgpIHtcbiAgICAgICAgdGhpcy5faW5pdCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEluaXRpYXRlcyBhIHdlYnNvY2tldCBjb25uZWN0aW9uIHRvIHRoZSB1cmwgcGFzc2VkIGluIGFuZCBsaXN0ZW5zIGZvciBtZXNzYWdlc1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgX2luaXQgKCkge1xuICAgICAgICB0aGlzLl93cyAgPSBuZXcgV2ViU29ja2V0KHRoaXMuX3dzVXJsKTtcblxuICAgICAgICB0aGlzLl93cy5vbm9wZW4gPSAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLl90cmFuc3BvcnRDYWxsYmFjay5vbkNvbm5lY3Rpb25Fc3RhYmxpc2hlZCgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuX3dzLm9uZXJyb3IgPSAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBjb25uZWN0JywgZXJyb3IpO1xuICAgICAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2sub25FcnJvcigpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuX3dzLm9ubWVzc2FnZSA9IChtc2cpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2hhbmRsZUluY29taW5nKG1zZyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5fd3Mub25jbG9zZSA9ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX3RyYW5zcG9ydENhbGxiYWNrLm9uQ29ubmVjdGlvblRlcm1pbmF0ZWQoKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDbG9zZXMgdGhlIHRyYW5zcG9ydCBjb25uZWN0aW9uXG4gICAgICovXG4gICAgc3RvcCAoKSB7XG4gICAgICAgIHRoaXMuX3dzLmNsb3NlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGNvbnRlbnRzIGluIHRoZSBwYWNrZXQgc2hvdWxkIGJlIHNlbnQgb3V0IHRocm91Z2ggdGhlIHRyYW5zcG9ydFxuICAgICAqIEBwYXJhbSB7U2RsUGFja2V0fSBwYWNrZXRcbiAgICAgKi9cbiAgICBzZW5kUGFja2V0IChwYWNrZXQpIHtcbiAgICAgICAgY29uc3QgYnl0ZXMgPSBwYWNrZXQudG9QYWNrZXQoKTtcbiAgICAgICAgdGhpcy5fd3Muc2VuZChieXRlcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBpcyBjYWxsZWQgd2hlbmV2ZXIgYSBuZXcgbWVzc2FnZSBjb21lcyBpblxuICAgICAqIEBwYXJhbSB7TWVzc2FnZUV2ZW50fSBtc2dcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9oYW5kbGVJbmNvbWluZyAobXNnKSB7XG4gICAgICAgIHRoaXMuX3F1ZXVlLnB1c2gobXNnLmRhdGEpO1xuICAgICAgICB0aGlzLl9tdWx0aUJ5dGVIYW5kbGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJvY2Vzc2VzIHJlY2VpdmVkIGRhdGEgZnJvbSB0aGUgaW50ZXJuYWwgcXVldWVcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9tdWx0aUJ5dGVIYW5kbGVyICgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2lzUnVubmluZykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2lzUnVubmluZyA9IHRydWU7XG5cbiAgICAgICAgd2hpbGUgKHRoaXMuX3F1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IG1zZ0RhdGEgPSB0aGlzLl9xdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgbmV3IFJlc3BvbnNlKG1zZ0RhdGEpLmFycmF5QnVmZmVyKCkudGhlbigoYXJyYXlCdWZmZXIpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB1aW50OCA9IG5ldyBVaW50OEFycmF5KGFycmF5QnVmZmVyKTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGJ5dGUgb2YgdWludDgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlQnl0ZShieXRlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2lzUnVubmluZyA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZlZWRzIGEgYnl0ZSB0aHJvdWdoIHRoZSBpbnRlcm5hbCBQU01cbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYnl0ZSAtIHVuc2lnbmVkIDgtYml0IGludGVnZXJcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9oYW5kbGVCeXRlIChieXRlKSB7XG4gICAgICAgIGNvbnN0IHN1Y2Nlc3MgPSB0aGlzLl9zZGxQc20uaGFuZGxlQnl0ZShieXRlKTtcbiAgICAgICAgaWYgKCFzdWNjZXNzKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdmYWlsZWQnLCB0aGlzLl9zZGxQc20pO1xuICAgICAgICAgICAgdGhpcy5fc2RsUHNtLnJlc2V0KCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaXNGaW5pc2hlZCA9IHRoaXMuX3NkbFBzbS5nZXRTdGF0ZSgpID09PSBTZGxQc20uRklOSVNIRURfU1RBVEU7XG5cbiAgICAgICAgaWYgKGlzRmluaXNoZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhY2tldCA9IHRoaXMuX3NkbFBzbS5nZXRGb3JtZWRQYWNrZXQoKTtcbiAgICAgICAgICAgIHRoaXMuX3NkbFBzbS5yZXNldCgpO1xuICAgICAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2sub25QYWNrZXRSZWNlaXZlZChwYWNrZXQpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5cbmV4cG9ydCB7IFdlYlNvY2tldENsaWVudCB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5jbGFzcyBUcmFuc3BvcnRDYWxsYmFjayB7XG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICB0aGlzLl9vbkNvbm5lY3Rpb25Fc3RhYmxpc2hlZCA9IG51bGw7XG4gICAgICAgIHRoaXMuX29uRXJyb3IgPSBudWxsO1xuICAgICAgICB0aGlzLl9vbkNvbm5lY3Rpb25UZXJtaW5hdGVkID0gbnVsbDtcbiAgICAgICAgdGhpcy5fb25QYWNrZXRSZWNlaXZlZCA9IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBzZXRPbkNvbm5lY3Rpb25Fc3RhYmxpc2hlZCAobGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5fb25Db25uZWN0aW9uRXN0YWJsaXNoZWQgPSBsaXN0ZW5lcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBsaXN0ZW5lclxuICAgICAqL1xuICAgIHNldE9uRXJyb3IgKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMuX29uRXJyb3IgPSBsaXN0ZW5lcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBsaXN0ZW5lclxuICAgICAqL1xuICAgIHNldE9uQ29ubmVjdGlvblRlcm1pbmF0ZWQgKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMuX29uQ29ubmVjdGlvblRlcm1pbmF0ZWQgPSBsaXN0ZW5lcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBsaXN0ZW5lclxuICAgICAqL1xuICAgIHNldE9uUGFja2V0UmVjZWl2ZWQgKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMuX29uUGFja2V0UmVjZWl2ZWQgPSBsaXN0ZW5lcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGVyIGZvciB3aGVuIGEgY29ubmVjdGlvbiBpcyBzdWNjZXNzZnVsXG4gICAgICovXG4gICAgb25Db25uZWN0aW9uRXN0YWJsaXNoZWQgKCkge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX29uQ29ubmVjdGlvbkVzdGFibGlzaGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9vbkNvbm5lY3Rpb25Fc3RhYmxpc2hlZCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlciBmb3Igd2hlbiBhIGNvbm5lY3Rpb24gaXMgc3VjY2Vzc2Z1bFxuICAgICAqL1xuICAgIG9uRXJyb3IgKCkge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX29uRXJyb3IgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuX29uRXJyb3IoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhhbmRsZXIgZm9yIHdoZW4gYSBjb25uZWN0aW9uIGlzIGRyb3BwZWRcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gcmVhc29uXG4gICAgICovXG4gICAgb25Db25uZWN0aW9uVGVybWluYXRlZCAocmVhc29uKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fb25Db25uZWN0aW9uVGVybWluYXRlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5fb25Db25uZWN0aW9uVGVybWluYXRlZChyZWFzb24pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlciBmb3Igd2hlbiBhIHBhY2tldCBpcyByZWNlaXZlZFxuICAgICAqIEBwYXJhbSB7U2RsUGFja2V0fSBwYWNrZXRcbiAgICAgKi9cbiAgICBvblBhY2tldFJlY2VpdmVkIChwYWNrZXQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9vblBhY2tldFJlY2VpdmVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9vblBhY2tldFJlY2VpdmVkKHBhY2tldCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cblxuZXhwb3J0IHsgVHJhbnNwb3J0Q2FsbGJhY2sgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgVHJhbnNwb3J0VHlwZSB9IGZyb20gJy4vZW51bXMvVHJhbnNwb3J0VHlwZS5qcyc7XG5pbXBvcnQgeyBXZWJTb2NrZXRDbGllbnQgfSBmcm9tICcuL1dlYlNvY2tldENsaWVudC5qcyc7XG5pbXBvcnQgeyBUcmFuc3BvcnRDYWxsYmFjayB9IGZyb20gJy4vVHJhbnNwb3J0Q2FsbGJhY2suanMnO1xuXG5jbGFzcyBUcmFuc3BvcnRNYW5hZ2VyQmFzZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtCYXNlVHJhbnNwb3J0Q29uZmlnfSBiYXNlVHJhbnNwb3J0Q29uZmlnXG4gICAgICogQHBhcmFtIHtUcmFuc3BvcnRMaXN0ZW5lcn0gdHJhbnNwb3J0TGlzdGVuZXJcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoYmFzZVRyYW5zcG9ydENvbmZpZywgdHJhbnNwb3J0TGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q29uZmlnID0gYmFzZVRyYW5zcG9ydENvbmZpZztcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0TGlzdGVuZXIgPSB0cmFuc3BvcnRMaXN0ZW5lcjtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0ID0gbnVsbDtcbiAgICAgICAgdGhpcy5faXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2sgPSBuZXcgVHJhbnNwb3J0Q2FsbGJhY2soKTtcblxuICAgICAgICB0aGlzLl90cmFuc3BvcnRDYWxsYmFjay5zZXRPbkNvbm5lY3Rpb25Fc3RhYmxpc2hlZCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9pc0Nvbm5lY3RlZCA9IHRydWU7XG4gICAgICAgICAgICB0cmFuc3BvcnRMaXN0ZW5lci5vblRyYW5zcG9ydENvbm5lY3RlZCgpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2suc2V0T25Db25uZWN0aW9uVGVybWluYXRlZCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9pc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2suc2V0T25QYWNrZXRSZWNlaXZlZCh0aGlzLm9uUGFja2V0UmVjZWl2ZWQuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgaWYgKHRoaXMuX3RyYW5zcG9ydENvbmZpZy5nZXRUcmFuc3BvcnRUeXBlKCkgPT09IFRyYW5zcG9ydFR5cGUuV0VCU09DS0VUX0NMSUVOVCkge1xuICAgICAgICAgICAgdGhpcy5fdHJhbnNwb3J0ID0gbmV3IFdlYlNvY2tldENsaWVudCh0aGlzLl90cmFuc3BvcnRDb25maWcsIHRoaXMuX3RyYW5zcG9ydENhbGxiYWNrKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLl90cmFuc3BvcnRDb25maWcuZ2V0VHJhbnNwb3J0VHlwZSgpID09PSBUcmFuc3BvcnRUeXBlLkNVU1RPTSkge1xuICAgICAgICAgICAgdGhpcy5fdHJhbnNwb3J0ID0gdGhpcy5fdHJhbnNwb3J0Q29uZmlnLmdldFRyYW5zcG9ydCgpO1xuICAgICAgICAgICAgdGhpcy5fdHJhbnNwb3J0LnNldFRyYW5zcG9ydENhbGxiYWNrKHRoaXMuX3RyYW5zcG9ydENhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uVHJhbnNwb3J0Q29ubmVjdGVkICgpIHtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0TGlzdGVuZXIub25UcmFuc3BvcnRDb25uZWN0ZWQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jXG4gICAgICovXG4gICAgb25UcmFuc3BvcnREaXNjb25uZWN0ZWQgKGZ1bmMpIHtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0TGlzdGVuZXIub25UcmFuc3BvcnREaXNjb25uZWN0ZWQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jXG4gICAgICovXG4gICAgb25FcnJvciAoZnVuYykge1xuICAgICAgICB0aGlzLl90cmFuc3BvcnRMaXN0ZW5lci5vbkVycm9yKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldFxuICAgICAqL1xuICAgIG9uUGFja2V0UmVjZWl2ZWQgKHNkbFBhY2tldCkge1xuICAgICAgICB0aGlzLl90cmFuc3BvcnRMaXN0ZW5lci5vblBhY2tldFJlY2VpdmVkKHNkbFBhY2tldCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT3BlbnMgdGhlIHRyYW5zcG9ydCBjb25uZWN0aW9uXG4gICAgICovXG4gICAgc3RhcnQgKCkge1xuICAgICAgICBpZiAodGhpcy5fdHJhbnNwb3J0ICE9PSBudWxsICYmIHR5cGVvZiB0aGlzLl90cmFuc3BvcnQuc3RhcnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuX3RyYW5zcG9ydC5zdGFydCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2xvc2VzIHRoZSB0cmFuc3BvcnQgY29ubmVjdGlvblxuICAgICAqL1xuICAgIHN0b3AgKCkge1xuICAgICAgICBpZiAodGhpcy5fdHJhbnNwb3J0ICE9PSBudWxsICYmIHR5cGVvZiB0aGlzLl90cmFuc3BvcnQuc3RvcCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5fdHJhbnNwb3J0LnN0b3AoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBjb250ZW50cyBpbiB0aGUgcGFja2V0IHNob3VsZCBiZSBzZW50IG91dCB0aHJvdWdoIHRoZSB0cmFuc3BvcnRcbiAgICAgKiBAcGFyYW0ge1NkbFBhY2tldH0gcGFja2V0XG4gICAgICovXG4gICAgc2VuZFBhY2tldCAocGFja2V0KSB7XG4gICAgICAgIGlmICh0aGlzLl90cmFuc3BvcnQgIT09IG51bGwgJiYgdHlwZW9mIHRoaXMuX3RyYW5zcG9ydC5zZW5kUGFja2V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl90cmFuc3BvcnQuc2VuZFBhY2tldChwYWNrZXQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtUcmFuc3BvcnRUeXBlfSB0cmFuc3BvcnRUeXBlXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGFkZHJlc3NcbiAgICAgKi9cbiAgICBpc0Nvbm5lY3RlZCAodHJhbnNwb3J0VHlwZSwgYWRkcmVzcykge1xuICAgICAgICByZXR1cm4gdGhpcy5faXNDb25uZWN0ZWQ7XG4gICAgfVxufVxuXG5leHBvcnQgeyBUcmFuc3BvcnRNYW5hZ2VyQmFzZSB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5jbGFzcyBTc2xDb25maWcge1xuICAgIGNvbnN0cnVjdG9yIChwZW1DZXJ0aWZpY2F0ZSA9IG51bGwsIHByaXZhdGVLZXkgPSBudWxsLCBwYXNzd29yZCA9IG51bGwpIHtcbiAgICAgICAgdGhpcy5fcGVtQ2VydGlmaWNhdGUgPSBwZW1DZXJ0aWZpY2F0ZTtcbiAgICAgICAgdGhpcy5fcHJpdmF0ZUtleSA9IHByaXZhdGVLZXk7XG4gICAgICAgIHRoaXMuX3Bhc3N3b3JkID0gcGFzc3dvcmQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBSZXR1cm5zIHRoZSBQRU0gQ2VydGlmaWNhdGVcbiAgICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICAqL1xuICAgIGdldFBlbUNlcnRpZmljYXRlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BlbUNlcnRpZmljYXRlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogUmV0dXJucyB0aGUgUHJpdmF0ZSBLZXlcbiAgICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICAqL1xuICAgIGdldFByaXZhdGVLZXkgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcHJpdmF0ZUtleTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIFJldHVybnMgdGhlIHBhc3N3b3JkXG4gICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAgKi9cbiAgICBnZXRQYXNzd29yZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXNzd29yZDtcbiAgICB9XG59XG5cbmV4cG9ydCB7IFNzbENvbmZpZyB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmNvbnN0IHsgVHJhbnNwb3J0QmFzZSB9ID0gcmVxdWlyZSgnLi9UcmFuc3BvcnRCYXNlLmpzJyk7XG5jb25zdCB7IFNzbENvbmZpZyB9ID0gcmVxdWlyZSgnLi9Tc2xDb25maWcuanMnKTtcbmNvbnN0IHsgU2RsUHNtIH0gPSByZXF1aXJlKCcuL1NkbFBzbS5qcycpO1xuY29uc3QgV2ViU29ja2V0ID0gcmVxdWlyZSgnd3MnKTtcbmNvbnN0IGh0dHBzID0gcmVxdWlyZSgnaHR0cHMnKTtcblxuY2xhc3MgV2ViU29ja2V0U2VydmVyIGV4dGVuZHMgVHJhbnNwb3J0QmFzZSB7XG4gICAgY29uc3RydWN0b3IgKHRyYW5zcG9ydENvbmZpZywgdHJhbnNwb3J0Q2FsbGJhY2sgPSBudWxsKSB7XG4gICAgICAgIHN1cGVyKHRyYW5zcG9ydENvbmZpZywgdHJhbnNwb3J0Q2FsbGJhY2spO1xuICAgICAgICB0aGlzLl93cyA9IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtUcmFuc3BvcnRDYWxsYmFja30gY2FsbGJhY2tcbiAgICAgKi9cbiAgICBzZXRUcmFuc3BvcnRDYWxsYmFjayAoY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdGFydCBsaXN0ZW5pbmcgZm9yIGNvbm5lY3Rpb25zIHRvIHRoZSBXZWJTb2NrZXQgU2VydmVyXG4gICAgICogQHJldHVybiB7V2ViU29ja2V0U2VydmVyfVxuICAgICAqL1xuICAgIHN0YXJ0ICgpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q29uZmlnLmdldFNzbENvbmZpZygpIGluc3RhbmNlb2YgU3NsQ29uZmlnXG4gICAgICAgICAgICAmJiB0aGlzLl90cmFuc3BvcnRDb25maWcuZ2V0U3NsQ29uZmlnKCkuZ2V0UGVtQ2VydGlmaWNhdGUoKSAhPT0gbnVsbFxuICAgICAgICAgICAgJiYgdGhpcy5fdHJhbnNwb3J0Q29uZmlnLmdldFNzbENvbmZpZygpLmdldFByaXZhdGVLZXkoKSAhPT0gbnVsbFxuICAgICAgICApIHtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBhIFdlYlNvY2tldCBTZWN1cmUgU2VydmVyXG4gICAgICAgICAgICBjb25zdCBzZXJ2ZXIgPSBodHRwcy5jcmVhdGVTZXJ2ZXIoe1xuICAgICAgICAgICAgICAgIGNlcnQ6IHRoaXMuX3RyYW5zcG9ydENvbmZpZy5nZXRTc2xDb25maWcoKS5nZXRQZW1DZXJ0aWZpY2F0ZSgpLFxuICAgICAgICAgICAgICAgIGtleTogdGhpcy5fdHJhbnNwb3J0Q29uZmlnLmdldFNzbENvbmZpZygpLmdldFByaXZhdGVLZXkoKSxcbiAgICAgICAgICAgICAgICBwYXNzcGhyYXNlOiB0aGlzLl90cmFuc3BvcnRDb25maWcuZ2V0U3NsQ29uZmlnKCkuZ2V0UGFzc3dvcmQoKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fd3MgPSBuZXcgV2ViU29ja2V0LlNlcnZlcih7XG4gICAgICAgICAgICAgICAgc2VydmVyLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBzZXJ2ZXIubGlzdGVuKHRoaXMuX3RyYW5zcG9ydENvbmZpZy5nZXRQb3J0KCkpO1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFdTUyBzdGFydGVkIG9uIHBvcnQgJHt0aGlzLl90cmFuc3BvcnRDb25maWcuZ2V0UG9ydCgpfWApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gY3JlYXRlIGEgV2ViU29ja2V0IFNlcnZlclxuICAgICAgICAgICAgdGhpcy5fd3MgPSBuZXcgV2ViU29ja2V0LlNlcnZlcih7XG4gICAgICAgICAgICAgICAgcG9ydDogdGhpcy5fdHJhbnNwb3J0Q29uZmlnLmdldFBvcnQoKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFdTIHN0YXJ0ZWQgb24gcG9ydCAke3RoaXMuX3RyYW5zcG9ydENvbmZpZy5nZXRQb3J0KCl9YCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBFdmVudCBsaXN0ZW5lciBmb3IgaW5jb21pbmcgV2ViU29ja2V0IGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuX3dzLm9uKCdjb25uZWN0aW9uJywgKGNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdjb25uZWN0aW9uIGVzdGFibGlzaGVkJyk7XG5cbiAgICAgICAgICAgIC8vIEV2ZW50IGxpc3RlbmVyIGZvciBhbiBpbmNvbWluZyBtZXNzYWdlXG4gICAgICAgICAgICBjb25uZWN0aW9uLm9uKCdtZXNzYWdlJywgKG1lc3NhZ2UpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVNZXNzYWdlKG1lc3NhZ2UpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIEV2ZW50IGxpc3RlbmVyIGZvciBhIGNsb3NlZCBjb25uZWN0aW9uXG4gICAgICAgICAgICBjb25uZWN0aW9uLm9uKCdjbG9zZScsICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnc2VydmVyIHJlY2VpdmVkIGNsb3NlIGV2ZW50Jyk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX3RyYW5zcG9ydENhbGxiYWNrICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3RyYW5zcG9ydENhbGxiYWNrLm9uQ29ubmVjdGlvblRlcm1pbmF0ZWQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gRXZlbnQgbGlzdGVuZXIgZm9yIGVycm9yc1xuICAgICAgICAgICAgY29ubmVjdGlvbi5vbignZXJyb3InLCAoZXJyb3JFdmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdzZXJ2ZXIgcmVjZWl2ZWQgZXJyb3IgZXZlbnQnKTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2sgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2sub25FcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBQb25nIGhlYXJ0YmVhdCBsaXN0ZW5lclxuICAgICAgICAgICAgY29ubmVjdGlvbi5vbigncG9uZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnc2VydmVyIHJlY2VpdmVkIHBvbmcgZXZlbnQnKTtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uLmlzQWxpdmUgPSB0cnVlO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIFRyaWdnZXIgZXZlbnQgZm9yIGNvbm5lY3Rpb24gZXN0YWJsaXNoZWRcbiAgICAgICAgICAgIC8vIEZJWE1FOiBwYXNzIGEgY2xpZW50IGNvbnRleHQgdG8gdGhlIHRyYW5zcG9ydCBsaXN0ZW5lcj9cbiAgICAgICAgICAgIGlmICh0aGlzLl90cmFuc3BvcnRDYWxsYmFjayAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RyYW5zcG9ydENhbGxiYWNrLm9uQ29ubmVjdGlvbkVzdGFibGlzaGVkKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25uZWN0aW9uLmlzQWxpdmUgPSB0cnVlO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBEZXRlY3QgYnJva2VuIGNvbm5lY3Rpb25zXG4gICAgICAgIGlmICh0aGlzLl90cmFuc3BvcnRDb25maWcuZ2V0Q29ubmVjdGlvbkxvc3RUaW1lb3V0KCkgPiAwKSB7XG4gICAgICAgICAgICBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd3MuY2xpZW50cy5mb3JFYWNoKGZ1bmN0aW9uIGVhY2ggKGNsaWVudCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY2xpZW50LmlzQWxpdmUgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnc2VydmVyIGRlZW1lZCBjbGllbnQgZGVhZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNsaWVudC50ZXJtaW5hdGUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIEFzc3VtZSB0aGUgY2xpZW50IGlzIGRlYWQgYW5kIGFzayBpdCBpZiBpdCdzIGFsaXZlXG4gICAgICAgICAgICAgICAgICAgIGNsaWVudC5pc0FsaXZlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdzZXJ2ZXIgc2VuZGluZyBwaW5nIHRvIGNsaWVudCcpO1xuICAgICAgICAgICAgICAgICAgICBjbGllbnQucGluZyhmdW5jdGlvbiAoKSB7fSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9LCB0aGlzLl90cmFuc3BvcnRDb25maWcuZ2V0Q29ubmVjdGlvbkxvc3RUaW1lb3V0KCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3RvcHMgdGhlIFdlYlNvY2tldCBTZXJ2ZXIgZnJvbSBsaXN0ZW5pbmcgYW5kIGNsb3NlcyBleGlzdGluZyBjb25uZWN0aW9uc1xuICAgICAqIEByZXR1cm4ge1dlYlNvY2tldFNlcnZlcn1cbiAgICAgKi9cbiAgICBzdG9wICgpIHtcbiAgICAgICAgaWYgKHRoaXMuX3dzICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl93cy5jbG9zZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VuZHMgYSBwYWNrZXQgdG8gYWxsIGNvbm5lY3RlZCBXZWJTb2NrZXQgY2xpZW50c1xuICAgICAqIEZJWE1FOiBTZW5kaW5nIHBhY2tldHMgc2hvdWxkIGJlIGlzb2xhdGVkIHRvIGEgY2xpZW50IHJhdGhlciB0aGFuIHRhcmdldGluZyBhbGwgY2xpZW50c1xuICAgICAqIEByZXR1cm4ge1dlYlNvY2tldFNlcnZlcn1cbiAgICAgKi9cbiAgICBzZW5kUGFja2V0IChzZGxQYWNrZXQpIHtcbiAgICAgICAgaWYgKHRoaXMuX3dzICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl93cy5jbGllbnRzLmZvckVhY2goZnVuY3Rpb24gZWFjaCAoY2xpZW50KSB7XG4gICAgICAgICAgICAgICAgaWYgKGNsaWVudC5yZWFkeVN0YXRlID09PSBXZWJTb2NrZXQuT1BFTikge1xuICAgICAgICAgICAgICAgICAgICBjbGllbnQuc2VuZChzZGxQYWNrZXQudG9QYWNrZXQoKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGlzIGNhbGxlZCB3aGVuZXZlciBhIG5ldyBtZXNzYWdlIGNvbWVzIGluXG4gICAgICogQHBhcmFtIHtNZXNzYWdlRXZlbnR9IG1lc3NhZ2VcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9oYW5kbGVNZXNzYWdlIChtZXNzYWdlKSB7XG4gICAgICAgIC8vIFJlcXVpcmUgbWVzc2FnZXMgdG8gYmUgYmluYXJ5IG9iamVjdHNcbiAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSAnb2JqZWN0JyB8fCBtZXNzYWdlLmNvbnN0cnVjdG9yLm5hbWUgIT09ICdCdWZmZXInKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBQYXJzZSB0aGUgbWVzc2FnZVxuICAgICAgICBsZXQgc3RhdGVQcm9ncmVzcyA9IGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBtZXNzYWdlSW5kZXggPSAwOyBtZXNzYWdlSW5kZXggPCBtZXNzYWdlLmxlbmd0aDsgbWVzc2FnZUluZGV4KyspIHtcbiAgICAgICAgICAgIHN0YXRlUHJvZ3Jlc3MgPSB0aGlzLl9zZGxQc20uaGFuZGxlQnl0ZShtZXNzYWdlW21lc3NhZ2VJbmRleF0pO1xuXG4gICAgICAgICAgICBpZiAoIXN0YXRlUHJvZ3Jlc3MpIHsgLy8gV2UgYXJlIHRyeWluZyB0byB3ZWVkIHRocm91Z2ggdGhlIGJhZCBwYWNrZXQgaW5mbyB1bnRpbCB3ZSBnZXQgc29tZXRoaW5nXG4gICAgICAgICAgICAgICAgdGhpcy5fc2RsUHNtLnJlc2V0KCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX3NkbFBzbS5nZXRTdGF0ZSgpID09PSBTZGxQc20uRklOSVNIRURfU1RBVEUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYWNrZXQgPSB0aGlzLl9zZGxQc20uZ2V0Rm9ybWVkUGFja2V0KCk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX3RyYW5zcG9ydENhbGxiYWNrICE9PSBudWxsICYmIHBhY2tldCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl90cmFuc3BvcnRDYWxsYmFjay5vblBhY2tldFJlY2VpdmVkKHBhY2tldCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5fc2RsUHNtLnJlc2V0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAgIFdlYlNvY2tldFNlcnZlcixcbn07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmNvbnN0IHsgVHJhbnNwb3J0TWFuYWdlckJhc2UgfSA9IHJlcXVpcmUoJy4vVHJhbnNwb3J0TWFuYWdlckJhc2UuanMnKTtcbmNvbnN0IHsgVHJhbnNwb3J0VHlwZSB9ID0gcmVxdWlyZSgnLi9lbnVtcy9UcmFuc3BvcnRUeXBlLmpzJyk7XG5jb25zdCB7IFdlYlNvY2tldFNlcnZlciB9ID0gcmVxdWlyZSgnLi9XZWJTb2NrZXRTZXJ2ZXIuanMnKTtcblxuY2xhc3MgVHJhbnNwb3J0TWFuYWdlciBleHRlbmRzIFRyYW5zcG9ydE1hbmFnZXJCYXNlIHtcbiAgICBjb25zdHJ1Y3RvciAodHJhbnNwb3J0Q29uZmlnLCB0cmFuc3BvcnRMaXN0ZW5lcikge1xuICAgICAgICBzdXBlcih0cmFuc3BvcnRDb25maWcsIHRyYW5zcG9ydExpc3RlbmVyKTtcblxuICAgICAgICBpZiAodGhpcy5fdHJhbnNwb3J0Q29uZmlnLmdldFRyYW5zcG9ydFR5cGUoKSA9PT0gVHJhbnNwb3J0VHlwZS5XRUJTT0NLRVRfU0VSVkVSKSB7XG4gICAgICAgICAgICB0aGlzLl90cmFuc3BvcnQgPSBuZXcgV2ViU29ja2V0U2VydmVyKHRoaXMuX3RyYW5zcG9ydENvbmZpZywgdGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2spO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX3RyYW5zcG9ydCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCB0cmFuc3BvcnQgdHlwZScpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAgIFRyYW5zcG9ydE1hbmFnZXIsXG59OyIsIlxuaW1wb3J0IHsgU2RsUHJvdG9jb2xCYXNlIH0gZnJvbSAnLi9TZGxQcm90b2NvbEJhc2UuanMnO1xuaW1wb3J0IHsgVHJhbnNwb3J0TWFuYWdlciB9IGZyb20gJy4vLi4vdHJhbnNwb3J0L1RyYW5zcG9ydE1hbmFnZXIuanMnO1xuXG5cbmNsYXNzIFNkbFByb3RvY29sIGV4dGVuZHMgU2RsUHJvdG9jb2xCYXNlIHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1RyYW5zcG9ydENvbmZpZ0Jhc2V9IGJhc2VUcmFuc3BvcnRDb25maWdcbiAgICAgKiBAcGFyYW0ge1NkbFByb3RvY29sTGlzdGVuZXJ9IHNkbFByb3RvY29sTGlzdGVuZXJcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoYmFzZVRyYW5zcG9ydENvbmZpZywgc2RsUHJvdG9jb2xMaXN0ZW5lcikge1xuICAgICAgICBzdXBlcihiYXNlVHJhbnNwb3J0Q29uZmlnLCBzZGxQcm90b2NvbExpc3RlbmVyKTtcbiAgICAgICAgdGhpcy5zZXRUcmFuc3BvcnRNYW5hZ2VyKG5ldyBUcmFuc3BvcnRNYW5hZ2VyKHRoaXMuX3RyYW5zcG9ydENvbmZpZywgdGhpcy5fdHJhbnNwb3J0TGlzdGVuZXIpKTtcbiAgICB9XG59XG5cbmV4cG9ydCB7IFNkbFByb3RvY29sIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFNlcnZpY2VUeXBlIH0gZnJvbSAnLi4vcHJvdG9jb2wvZW51bXMvU2VydmljZVR5cGUuanMnO1xuXG5jbGFzcyBTZXJ2aWNlTGlzdGVuZXJNYXAge1xuICAgIC8qKlxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHRoaXMuX2xpc3RlbmVycyA9IHt9O1xuXG4gICAgICAgIC8vIGluaXRpYWxpemUgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIGZvciBlYWNoIHNlcnZpY2UgdHlwZVxuICAgICAgICB0aGlzLl9saXN0ZW5lcnNbU2VydmljZVR5cGUuQ09OVFJPTF0gPSBbXTtcbiAgICAgICAgdGhpcy5fbGlzdGVuZXJzW1NlcnZpY2VUeXBlLlJQQ10gPSBbXTtcbiAgICAgICAgdGhpcy5fbGlzdGVuZXJzW1NlcnZpY2VUeXBlLkFVRElPXSA9IFtdO1xuICAgICAgICB0aGlzLl9saXN0ZW5lcnNbU2VydmljZVR5cGUuVklERU9dID0gW107XG4gICAgICAgIHRoaXMuX2xpc3RlbmVyc1tTZXJ2aWNlVHlwZS5IWUJSSURdID0gW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTZXJ2aWNlVHlwZX0gc2VydmljZVR5cGVcbiAgICAgKiBAcGFyYW0ge1NkbFNlcnZpY2VMaXN0ZW5lcn0gc2VydmljZUxpc3RlbmVyXG4gICAgICovXG4gICAgYWRkTGlzdGVuZXIgKHNlcnZpY2VUeXBlLCBzZXJ2aWNlTGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKCFzZXJ2aWNlVHlwZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2xpc3RlbmVyc1tzZXJ2aWNlVHlwZV0ucHVzaChzZXJ2aWNlTGlzdGVuZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHBhcmFtIHtTZGxTZXJ2aWNlTGlzdGVuZXJ9IHNlcnZpY2VMaXN0ZW5lclxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59IC0gd2hldGhlciB0aGUgc2VydmljZSBnb3QgcmVtb3ZlZFxuICAgICAqL1xuICAgIHJlbW92ZUxpc3RlbmVyIChzZXJ2aWNlVHlwZSwgc2VydmljZUxpc3RlbmVyKSB7XG4gICAgICAgIGlmICghc2VydmljZVR5cGUpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBsaXN0ZW5lckFycmF5ID0gdGhpcy5fbGlzdGVuZXJzW3NlcnZpY2VUeXBlXTtcbiAgICAgICAgbGV0IHJlbW92ZWQgPSBmYWxzZTtcbiAgICAgICAgLy8gcmVtb3ZlIG1hdGNoaW5nIHJlZmVyZW5jZXMgdG8gdGhlIHBhc3NlZCBpbiBzZXJ2aWNlIGxpc3RlbmVyXG4gICAgICAgIHRoaXMuX2xpc3RlbmVyc1tzZXJ2aWNlVHlwZV0gPSBsaXN0ZW5lckFycmF5LmZpbHRlcihsaXN0ZW5lciA9PiB7XG4gICAgICAgICAgICByZW1vdmVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHJldHVybiBsaXN0ZW5lciAhPT0gc2VydmljZUxpc3RlbmVyO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJlbW92ZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VuZHMgdGhpcyBldmVudCB0byBhbGwgbGlzdGVuZXJzIGJlbG9uZ2luZyB0byBhIHNwZWNpZmljIHNlcnZpY2UgdHlwZVxuICAgICAqIEBwYXJhbSB7U2RsU2Vzc2lvbn0gc2Vzc2lvblxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBpc0VuY3J5cHRlZFxuICAgICAqL1xuICAgIHNlbmRFdmVudFNlcnZpY2VTdGFydGVkIChzZXNzaW9uLCBzZXJ2aWNlVHlwZSwgaXNFbmNyeXB0ZWQpIHtcbiAgICAgICAgY29uc3QgbGlzdGVuZXJBcnJheSA9IHRoaXMuX2xpc3RlbmVyc1tzZXJ2aWNlVHlwZV07XG4gICAgICAgIGZvciAoY29uc3QgaW5kZXggaW4gbGlzdGVuZXJBcnJheSkge1xuICAgICAgICAgICAgbGlzdGVuZXJBcnJheVtpbmRleF0ub25TZXJ2aWNlU3RhcnRlZChzZXNzaW9uLCBzZXJ2aWNlVHlwZSwgaXNFbmNyeXB0ZWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VuZHMgdGhpcyBldmVudCB0byBhbGwgbGlzdGVuZXJzIGJlbG9uZ2luZyB0byBhIHNwZWNpZmljIHNlcnZpY2UgdHlwZVxuICAgICAqIEBwYXJhbSB7U2RsU2Vzc2lvbn0gc2Vzc2lvblxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICovXG4gICAgc2VuZEV2ZW50U2VydmljZUVuZGVkIChzZXNzaW9uLCBzZXJ2aWNlVHlwZSkge1xuICAgICAgICBjb25zdCBsaXN0ZW5lckFycmF5ID0gdGhpcy5fbGlzdGVuZXJzW3NlcnZpY2VUeXBlXTtcbiAgICAgICAgZm9yIChjb25zdCBpbmRleCBpbiBsaXN0ZW5lckFycmF5KSB7XG4gICAgICAgICAgICBsaXN0ZW5lckFycmF5W2luZGV4XS5vblNlcnZpY2VFbmRlZChzZXNzaW9uLCBzZXJ2aWNlVHlwZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZW5kcyB0aGlzIGV2ZW50IHRvIGFsbCBsaXN0ZW5lcnMgYmVsb25naW5nIHRvIGEgc3BlY2lmaWMgc2VydmljZSB0eXBlXG4gICAgICogQHBhcmFtIHtTZGxTZXNzaW9ufSBzZXNzaW9uXG4gICAgICogQHBhcmFtIHtTZXJ2aWNlVHlwZX0gc2VydmljZVR5cGVcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gcmVhc29uXG4gICAgICovXG4gICAgc2VuZEV2ZW50U2VydmljZUVycm9yIChzZXNzaW9uLCBzZXJ2aWNlVHlwZSwgcmVhc29uKSB7XG4gICAgICAgIGNvbnN0IGxpc3RlbmVyQXJyYXkgPSB0aGlzLl9saXN0ZW5lcnNbc2VydmljZVR5cGVdO1xuICAgICAgICBmb3IgKGNvbnN0IGluZGV4IGluIGxpc3RlbmVyQXJyYXkpIHtcbiAgICAgICAgICAgIGxpc3RlbmVyQXJyYXlbaW5kZXhdLm9uU2VydmljZUVycm9yKHNlc3Npb24sIHNlcnZpY2VUeXBlLCByZWFzb24pO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgeyBTZXJ2aWNlTGlzdGVuZXJNYXAgfTtcbiIsImltcG9ydCB7IFZpZGVvU3RyZWFtaW5nRm9ybWF0IH0gZnJvbSAnLi4vLi4vcnBjL3N0cnVjdHMvVmlkZW9TdHJlYW1pbmdGb3JtYXQnO1xuaW1wb3J0IHsgVmlkZW9TdHJlYW1pbmdDb2RlYyB9IGZyb20gJy4uLy4uL3JwYy9lbnVtcy9WaWRlb1N0cmVhbWluZ0NvZGVjJztcbmltcG9ydCB7IFZpZGVvU3RyZWFtaW5nUHJvdG9jb2wgfSBmcm9tICcuLi8uLi9ycGMvZW51bXMvVmlkZW9TdHJlYW1pbmdQcm90b2NvbCc7XG5pbXBvcnQgeyBJbWFnZVJlc29sdXRpb24gfSBmcm9tICcuLi8uLi9ycGMvc3RydWN0cy9JbWFnZVJlc29sdXRpb24nO1xuXG4vKlxuICogQ29weXJpZ2h0IChjKSAyMDE5IExpdmlvLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4gKlxuICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4gKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4gKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuICogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4gKiBkaXN0cmlidXRpb24uXG4gKlxuICogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiAqIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuICogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4gKlxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiAqIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4gKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4gKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4gKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuICogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4gKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuICogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiAqIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4gKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqL1xuXG5jb25zdCBERUZBVUxUX1BST1RPQ09MID0gVmlkZW9TdHJlYW1pbmdQcm90b2NvbC5SQVc7XG5jb25zdCBERUZBVUxUX0NPREVDID0gVmlkZW9TdHJlYW1pbmdDb2RlYy5IMjY0O1xuY29uc3QgREVGQVVMVF9XSURUSCA9IDEwMjQ7XG5jb25zdCBERUZBVUxUX0hFSUdIVCA9IDU3NjtcbmNvbnN0IERFRkFVTFRfREVOU0lUWSA9IDI0MDtcbmNvbnN0IERFRkFVTFRfRlJBTUVSQVRFID0gMzA7XG5jb25zdCBERUZBVUxUX0JJVFJBVEUgPSA1MTIwMDA7XG5jb25zdCBERUZBVUxUX0lOVEVSVkFMID0gNTtcbmNvbnN0IERFRkFVTFRfU0NBTEUgPSAxLjA7XG5cbmNsYXNzIFZpZGVvU3RyZWFtaW5nUGFyYW1ldGVycyB7XG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZGlzcGxheURlbnNpdHlcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZnJhbWVSYXRlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdHJhdGVcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gaW50ZXJ2YWxcbiAgICAgKiBAcGFyYW0ge0ltYWdlUmVzb2x1dGlvbn0gcmVzb2x1dGlvblxuICAgICAqIEBwYXJhbSB7VmlkZW9TdHJlYW1pbmdGb3JtYXR9IGZvcm1hdFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChkaXNwbGF5RGVuc2l0eSA9IG51bGwsIGZyYW1lUmF0ZSA9IG51bGwsIGJpdHJhdGUgPSBudWxsLCBpbnRlcnZhbCA9IG51bGwsIHJlc29sdXRpb24gPSBudWxsLCBmb3JtYXQgPSBudWxsKSB7XG4gICAgICAgIHRoaXMuX2Rpc3BsYXlEZW5zaXR5ID0gZGlzcGxheURlbnNpdHkgfHwgREVGQVVMVF9ERU5TSVRZO1xuICAgICAgICB0aGlzLl9mcmFtZVJhdGUgPSBmcmFtZVJhdGUgfHwgREVGQVVMVF9GUkFNRVJBVEU7XG4gICAgICAgIHRoaXMuX2JpdHJhdGUgPSBiaXRyYXRlIHx8IERFRkFVTFRfQklUUkFURTtcbiAgICAgICAgdGhpcy5faW50ZXJ2YWwgPSBpbnRlcnZhbCB8fCBERUZBVUxUX0lOVEVSVkFMO1xuXG4gICAgICAgIGlmICghKHJlc29sdXRpb24gaW5zdGFuY2VvZiBJbWFnZVJlc29sdXRpb24pKSB7XG4gICAgICAgICAgICByZXNvbHV0aW9uID0gbmV3IEltYWdlUmVzb2x1dGlvbigpO1xuICAgICAgICAgICAgcmVzb2x1dGlvbi5zZXRSZXNvbHV0aW9uV2lkdGgoREVGQVVMVF9XSURUSCk7XG4gICAgICAgICAgICByZXNvbHV0aW9uLnNldFJlc29sdXRpb25IZWlnaHQoREVGQVVMVF9IRUlHSFQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3Jlc29sdXRpb24gPSByZXNvbHV0aW9uO1xuXG4gICAgICAgIGlmICghKGZvcm1hdCBpbnN0YW5jZW9mIFZpZGVvU3RyZWFtaW5nRm9ybWF0KSkge1xuICAgICAgICAgICAgZm9ybWF0ID0gbmV3IFZpZGVvU3RyZWFtaW5nRm9ybWF0KCk7XG4gICAgICAgICAgICBmb3JtYXQuc2V0UHJvdG9jb2woREVGQVVMVF9QUk9UT0NPTCk7XG4gICAgICAgICAgICBmb3JtYXQuc2V0Q29kZWMoREVGQVVMVF9DT0RFQyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9mb3JtYXQgPSBmb3JtYXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXBkYXRlIHRoZSB2YWx1ZXMgY29udGFpbmVkIGluIHRoZSBjYXBhYmlsaXR5IHRoYXQgc2hvdWxkIGhhdmUgYmVlbiByZXR1cm5lZCB0aHJvdWdoIHRoZSBTeXN0ZW1DYXBhYmlsaXR5TWFuYWdlci5cbiAgICAgKiBUaGlzIHVwZGF0ZSB3aWxsIHVzZSB0aGUgbW9zdCBwcmVmZXJyZWQgc3RyZWFtaW5nIGZvcm1hdCBmcm9tIHRoZSBtb2R1bGUuXG4gICAgICogQHBhcmFtIHtWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHl9IGNhcGFiaWxpdHkgdGhlIHZpZGVvIHN0cmVhbWluZyBjYXBhYmlsaXR5IHJldHVybmVkIGZyb20gdGhlIFN5c3RlbUNhcGFiaWxpdHlNYW5hZ2VyXG4gICAgICovXG4gICAgdXBkYXRlIChjYXBhYmlsaXR5KSB7XG4gICAgICAgIGlmIChjYXBhYmlsaXR5LmdldE1heEJpdHJhdGUoKSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fYml0cmF0ZSA9IGNhcGFiaWxpdHkuZ2V0TWF4Qml0cmF0ZSgpICogMTAwMDsgLy8gTk9URTogdGhlIHVuaXQgb2YgbWF4Qml0cmF0ZSBpbiBnZXRTeXN0ZW1DYXBhYmlsaXR5IGlzIGticHMuXG4gICAgICAgIH1cbiAgICAgICAgbGV0IHNjYWxlID0gREVGQVVMVF9TQ0FMRTtcbiAgICAgICAgaWYgKGNhcGFiaWxpdHkuZ2V0U2NhbGUoKSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgc2NhbGUgPSBjYXBhYmlsaXR5LmdldFNjYWxlKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzb2x1dGlvbiA9IGNhcGFiaWxpdHkuZ2V0UHJlZmVycmVkUmVzb2x1dGlvbigpO1xuICAgICAgICBpZiAocmVzb2x1dGlvbiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKHJlc29sdXRpb24uZ2V0UmVzb2x1dGlvbkhlaWdodCgpICE9PSBudWxsICYmIHJlc29sdXRpb24uZ2V0UmVzb2x1dGlvbkhlaWdodCgpID4gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3Jlc29sdXRpb24uc2V0UmVzb2x1dGlvbkhlaWdodChNYXRoLmZsb29yKChyZXNvbHV0aW9uLmdldFJlc29sdXRpb25IZWlnaHQoKSAvIHNjYWxlKSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHJlc29sdXRpb24uZ2V0UmVzb2x1dGlvbldpZHRoKCkgIT09IG51bGwgJiYgcmVzb2x1dGlvbi5nZXRSZXNvbHV0aW9uV2lkdGgoKSA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yZXNvbHV0aW9uLnNldFJlc29sdXRpb25XaWR0aChNYXRoLmZsb29yKChyZXNvbHV0aW9uLmdldFJlc29sdXRpb25XaWR0aCgpIC8gc2NhbGUpKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZm9ybWF0cyA9IGNhcGFiaWxpdHkuZ2V0U3VwcG9ydGVkRm9ybWF0cygpO1xuICAgICAgICBpZiAoZm9ybWF0cyAhPT0gbnVsbCAmJiBmb3JtYXRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuX2Zvcm1hdCA9IGZvcm1hdHNbMF07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBkaXNwbGF5RGVuc2l0eVxuICAgICAqIEByZXR1cm4ge1ZpZGVvU3RyZWFtaW5nUGFyYW1ldGVyc31cbiAgICAgKi9cbiAgICBzZXREaXNwbGF5RGVuc2l0eSAoZGlzcGxheURlbnNpdHkpIHtcbiAgICAgICAgdGhpcy5fZGlzcGxheURlbnNpdHkgPSBkaXNwbGF5RGVuc2l0eTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7bnVtYmVyfVxuICAgICAqL1xuICAgIGdldERpc3BsYXlEZW5zaXR5ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rpc3BsYXlEZW5zaXR5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBmcmFtZVJhdGVcbiAgICAgKiBAcmV0dXJuIHtWaWRlb1N0cmVhbWluZ1BhcmFtZXRlcnN9XG4gICAgICovXG4gICAgc2V0RnJhbWVSYXRlIChmcmFtZVJhdGUpIHtcbiAgICAgICAgdGhpcy5fZnJhbWVSYXRlID0gZnJhbWVSYXRlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge251bWJlcn1cbiAgICAgKi9cbiAgICBnZXRGcmFtZVJhdGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZnJhbWVSYXRlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRyYXRlXG4gICAgICogQHJldHVybiB7VmlkZW9TdHJlYW1pbmdQYXJhbWV0ZXJzfVxuICAgICAqL1xuICAgIHNldEJpdHJhdGUgKGJpdHJhdGUpIHtcbiAgICAgICAgdGhpcy5fYml0cmF0ZSA9IGJpdHJhdGU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtudW1iZXJ9XG4gICAgICovXG4gICAgZ2V0Qml0cmF0ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaXRyYXRlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpbnRlcnZhbFxuICAgICAqIEByZXR1cm4ge1ZpZGVvU3RyZWFtaW5nUGFyYW1ldGVyc31cbiAgICAgKi9cbiAgICBzZXRJbnRlcnZhbCAoaW50ZXJ2YWwpIHtcbiAgICAgICAgdGhpcy5faW50ZXJ2YWwgPSBpbnRlcnZhbDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7bnVtYmVyfVxuICAgICAqL1xuICAgIGdldEludGVydmFsICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ludGVydmFsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmlkZW9TdHJlYW1pbmdGb3JtYXR9IGZvcm1hdFxuICAgICAqIEByZXR1cm4ge1ZpZGVvU3RyZWFtaW5nUGFyYW1ldGVyc31cbiAgICAgKi9cbiAgICBzZXRGb3JtYXQgKGZvcm1hdCkge1xuICAgICAgICB0aGlzLl9mb3JtYXQgPSBmb3JtYXQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZpZGVvU3RyZWFtaW5nRm9ybWF0fVxuICAgICAqL1xuICAgIGdldEZvcm1hdCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mb3JtYXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb25cbiAgICAgKiBAcmV0dXJuIHtWaWRlb1N0cmVhbWluZ1BhcmFtZXRlcnN9XG4gICAgICovXG4gICAgc2V0UmVzb2x1dGlvbiAocmVzb2x1dGlvbikge1xuICAgICAgICB0aGlzLl9yZXNvbHV0aW9uID0gcmVzb2x1dGlvbjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7bnVtYmVyfVxuICAgICAqL1xuICAgIGdldFJlc29sdXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmVzb2x1dGlvbjtcbiAgICB9XG59XG5cbmV4cG9ydCB7IFZpZGVvU3RyZWFtaW5nUGFyYW1ldGVycyB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBTZGxQcm90b2NvbExpc3RlbmVyIH0gZnJvbSAnLi4vcHJvdG9jb2wvU2RsUHJvdG9jb2xMaXN0ZW5lci5qcyc7XG5pbXBvcnQgeyBTZGxQcm90b2NvbCB9IGZyb20gJy4uL3Byb3RvY29sL1NkbFByb3RvY29sLmpzJztcbmltcG9ydCB7IFNlcnZpY2VUeXBlIH0gZnJvbSAnLi4vcHJvdG9jb2wvZW51bXMvU2VydmljZVR5cGUuanMnO1xuaW1wb3J0IHsgU2VydmljZUxpc3RlbmVyTWFwIH0gZnJvbSAnLi9TZXJ2aWNlTGlzdGVuZXJNYXAuanMnO1xuaW1wb3J0IHsgVmlkZW9TdHJlYW1pbmdQYXJhbWV0ZXJzIH0gZnJvbSAnLi4vc3RyZWFtaW5nL3ZpZGVvL1ZpZGVvU3RyZWFtaW5nUGFyYW1ldGVycy5qcyc7XG5cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBTZGxTZXNzaW9uXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBzdGFydFxuICogQHByb3BlcnR5IHtGdW5jdGlvbn0gZ2V0U2Vzc2lvbklkXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBvblByb3RvY29sU2Vzc2lvblN0YXJ0ZWRcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IG9uUHJvdG9jb2xTZXNzaW9uRW5kZWRcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IG9uUHJvdG9jb2xTZXNzaW9uRW5kZWROQUNLZWRcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IG9uUnBjTWVzc2FnZVJlY2VpdmVkXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBlbmRTZXNzaW9uXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBzZW5kUnBjXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBnZXRNdHVcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGNsb3NlXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBzdGFydFNlcnZpY2VcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGVuZFNlcnZpY2VcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGdldEN1cnJlbnRUcmFuc3BvcnRUeXBlXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBnZXRJc0Nvbm5lY3RlZFxuICogQHByb3BlcnR5IHtGdW5jdGlvbn0gZ2V0UHJvdG9jb2xWZXJzaW9uXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBnZXRUcmFuc3BvcnRDb25maWdcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGdldFNlc3Npb25IYXNoSWRcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGFkZFNlcnZpY2VMaXN0ZW5lclxuICogQHByb3BlcnR5IHtGdW5jdGlvbn0gcmVtb3ZlU2VydmljZUxpc3RlbmVyXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBnZXRTZXJ2aWNlTGlzdGVuZXJzXG4gKi9cbmNsYXNzIFNkbFNlc3Npb24ge1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VHJhbnNwb3J0Q29uZmlnQmFzZX0gYmFzZVRyYW5zcG9ydENvbmZpZ1xuICAgICAqIEBwYXJhbSB7U2RsU2Vzc2lvbkxpc3RlbmVyfSBzZGxTZXNzaW9uTGlzdGVuZXJcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoYmFzZVRyYW5zcG9ydENvbmZpZywgc2RsU2Vzc2lvbkxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMuX2Jhc2VUcmFuc3BvcnRDb25maWcgPSBiYXNlVHJhbnNwb3J0Q29uZmlnO1xuICAgICAgICB0aGlzLl9zZXNzaW9uSWQgPSBudWxsO1xuICAgICAgICB0aGlzLl9zZXNzaW9uSGFzaElkID0gbnVsbDtcbiAgICAgICAgdGhpcy5fc2RsU2Vzc2lvbkxpc3RlbmVyID0gc2RsU2Vzc2lvbkxpc3RlbmVyO1xuICAgICAgICB0aGlzLl9iYXNlVHJhbnNwb3J0Q29uZmlnID0gYmFzZVRyYW5zcG9ydENvbmZpZztcblxuICAgICAgICAvLyBhIGhhc2ggd2hlcmUgZWFjaCBrZXkgaXMgYSBzZXJ2aWNlIHR5cGUsIGFuZCBoYXMgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIGF0dGFjaGVkXG4gICAgICAgIHRoaXMuX3NlcnZpY2VMaXN0ZW5lcnMgPSBuZXcgU2VydmljZUxpc3RlbmVyTWFwKCk7XG5cbiAgICAgICAgdGhpcy5fc2RsUHJvdG9jb2xMaXN0ZW5lciA9IHRoaXMuX3NldHVwU2RsUHJvdG9jb2xMaXN0ZW5lcigpO1xuXG4gICAgICAgIHRoaXMuX3NkbFByb3RvY29sID0gbmV3IFNkbFByb3RvY29sKGJhc2VUcmFuc3BvcnRDb25maWcsIHRoaXMuX3NkbFByb3RvY29sTGlzdGVuZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1NkbFByb3RvY29sTGlzdGVuZXJ9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBfc2V0dXBTZGxQcm90b2NvbExpc3RlbmVyICgpIHtcbiAgICAgICAgY29uc3Qgc2RsUHJvdG9jb2xMaXN0ZW5lciA9IG5ldyBTZGxQcm90b2NvbExpc3RlbmVyKCk7XG4gICAgICAgIHNkbFByb3RvY29sTGlzdGVuZXIuc2V0R2V0U2Vzc2lvbklkKHRoaXMuZ2V0U2Vzc2lvbklkLmJpbmQodGhpcykpO1xuICAgICAgICBzZGxQcm90b2NvbExpc3RlbmVyLnNldE9uUHJvdG9jb2xTZXNzaW9uU3RhcnRlZCh0aGlzLm9uUHJvdG9jb2xTZXNzaW9uU3RhcnRlZC5iaW5kKHRoaXMpKTtcbiAgICAgICAgc2RsUHJvdG9jb2xMaXN0ZW5lci5zZXRPblByb3RvY29sU2Vzc2lvbkVuZGVkKHRoaXMub25Qcm90b2NvbFNlc3Npb25FbmRlZC5iaW5kKHRoaXMpKTtcbiAgICAgICAgc2RsUHJvdG9jb2xMaXN0ZW5lci5zZXRPblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkKHRoaXMub25Qcm90b2NvbFNlc3Npb25FbmRlZE5BQ0tlZC5iaW5kKHRoaXMpKTtcbiAgICAgICAgc2RsUHJvdG9jb2xMaXN0ZW5lci5zZXRPblJwY01lc3NhZ2VSZWNlaXZlZCh0aGlzLm9uUnBjTWVzc2FnZVJlY2VpdmVkLmJpbmQodGhpcykpO1xuICAgICAgICBzZGxQcm90b2NvbExpc3RlbmVyLnNldE9uVHJhbnNwb3J0Q29ubmVjdGVkKHRoaXMub25UcmFuc3BvcnRDb25uZWN0ZWQuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgc2RsUHJvdG9jb2xMaXN0ZW5lci5zZXRHZXREZXNpcmVkVmlkZW9QYXJhbXModGhpcy5nZXREZXNpcmVkVmlkZW9QYXJhbXMuYmluZCh0aGlzKSk7XG4gICAgICAgIHNkbFByb3RvY29sTGlzdGVuZXIuc2V0U2V0QWNjZXB0ZWRWaWRlb1BhcmFtcyh0aGlzLnNldEFjY2VwdGVkVmlkZW9QYXJhbXMuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgcmV0dXJuIHNkbFByb3RvY29sTGlzdGVuZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3RhcnRzIHVwIHRoZSBTREwgcHJvdG9jb2wgY2xhc3MuIEl0IHdpbGwga2ljayBvZmYgdGhlIHRyYW5zcG9ydCBtYW5hZ2VyIGFuZCB1bmRlcmx5aW5nIHRyYW5zcG9ydC5cbiAgICAgKi9cbiAgICBzdGFydCAoKSB7XG4gICAgICAgIHRoaXMuX3NkbFByb3RvY29sLnN0YXJ0KCk7XG4gICAgfVxuXG4gICAgLyoqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCRUdJTjogICAgU2RsUHJvdG9jb2xMaXN0ZW5lciBpbXBsZW1lbnRlZCBtZXRob2RzXG4gICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn0gIC0gcmVwcmVzZW50cyBhIGJ5dGVcbiAgICAgKi9cbiAgICBnZXRTZXNzaW9uSWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2Vzc2lvbklkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV2ZW50IGZpcmVkIHdoZW4gdHJhbnNwb3J0IChlZyB0Y3AsIHdzLCBibHVldG9vdGgpIGhhcyBjb25uZWN0ZWQuXG4gICAgICovXG4gICAgb25UcmFuc3BvcnRDb25uZWN0ZWQgKCkge1xuICAgICAgICB0aGlzLl9zZGxTZXNzaW9uTGlzdGVuZXIub25UcmFuc3BvcnRDb25uZWN0ZWQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzZXNzaW9uSWQgLSByZXByZXNlbnRzIGEgYnl0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB2ZXJzaW9uIC0gcmVwcmVzZW50cyBhIGJ5dGVcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gY29ycmVsYXRpb25JZFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBoYXNoSWRcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGlzRW5jcnlwdGVkXG4gICAgICovXG4gICAgb25Qcm90b2NvbFNlc3Npb25TdGFydGVkIChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklkLCB2ZXJzaW9uLCBjb3JyZWxhdGlvbklkLCBoYXNoSWQsIGlzRW5jcnlwdGVkKSB7XG4gICAgICAgIHRoaXMuX3Nlc3Npb25JZCA9IHNlc3Npb25JZDtcblxuICAgICAgICBpZiAoc2VydmljZVR5cGUgPT09IFNlcnZpY2VUeXBlLlJQQykge1xuICAgICAgICAgICAgdGhpcy5fc2Vzc2lvbkhhc2hJZCA9IGhhc2hJZDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3NkbFNlc3Npb25MaXN0ZW5lci5vblByb3RvY29sU2Vzc2lvblN0YXJ0ZWQoc2VydmljZVR5cGUsIHNlc3Npb25JZCwgdmVyc2lvbiwgY29ycmVsYXRpb25JZCwgaGFzaElkLCBpc0VuY3J5cHRlZCk7XG4gICAgICAgIHRoaXMuX3NlcnZpY2VMaXN0ZW5lcnMuc2VuZEV2ZW50U2VydmljZVN0YXJ0ZWQodGhpcywgc2VydmljZVR5cGUsIGlzRW5jcnlwdGVkKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzZXNzaW9uSWQgLSByZXByZXNlbnRzIGEgYnl0ZVxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBjb3JyZWxhdGlvbklkXG4gICAgICovXG4gICAgb25Qcm90b2NvbFNlc3Npb25FbmRlZCAoc2VydmljZVR5cGUsIHNlc3Npb25JZCwgY29ycmVsYXRpb25JZCkge1xuICAgICAgICB0aGlzLl9zZGxTZXNzaW9uTGlzdGVuZXIub25Qcm90b2NvbFNlc3Npb25FbmRlZChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklkLCBjb3JyZWxhdGlvbklkKTtcbiAgICAgICAgdGhpcy5fc2VydmljZUxpc3RlbmVycy5zZW5kRXZlbnRTZXJ2aWNlRW5kZWQodGhpcywgc2VydmljZVR5cGUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlc3Npb25JZCAtIHJlcHJlc2VudHMgYSBieXRlXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGNvcnJlbGF0aW9uSWRcbiAgICAgKi9cbiAgICBvblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkIChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklkLCBjb3JyZWxhdGlvbklkKSB7XG4gICAgICAgIHRoaXMuX3NkbFNlc3Npb25MaXN0ZW5lci5vblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkKHNlcnZpY2VUeXBlLCBzZXNzaW9uSWQsIGNvcnJlbGF0aW9uSWQpO1xuICAgICAgICB0aGlzLl9zZXJ2aWNlTGlzdGVuZXJzLnNlbmRFdmVudFNlcnZpY2VFcnJvcih0aGlzLCBzZXJ2aWNlVHlwZSwgYEVuZCAke3NlcnZpY2VUeXBlLnRvU3RyaW5nKCl9IFNlcnZpY2UgTkFDSydlZGApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7UnBjTWVzc2FnZX0gcnBjTWVzc2FnZVxuICAgICAqL1xuICAgIG9uUnBjTWVzc2FnZVJlY2VpdmVkIChycGNNZXNzYWdlKSB7XG4gICAgICAgIHRoaXMuX3NkbFNlc3Npb25MaXN0ZW5lci5vblJwY01lc3NhZ2VSZWNlaXZlZChycGNNZXNzYWdlKTtcbiAgICB9XG5cblxuICAgIC8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRU5EOiAgICBTZGxQcm90b2NvbExpc3RlbmVyIGltcGxlbWVudGVkIG1ldGhvZHNcbiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4gICAgZW5kU2Vzc2lvbiAoKSB7XG4gICAgICAgIHRoaXMuX3NkbFByb3RvY29sLmVuZFNlc3Npb24oKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1JwY01lc3NhZ2V9IHJwY01lc3NhZ2VcbiAgICAgKi9cbiAgICBzZW5kUnBjIChycGNNZXNzYWdlKSB7XG4gICAgICAgIHRoaXMuX3NkbFByb3RvY29sLnNlbmRScGMocnBjTWVzc2FnZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VuZHMgYW4gc2RsUGFja2V0LlxuICAgICAqIEBwYXJhbSB7U2RsUGFja2V0fSBzZGxQYWNrZXRcbiAgICAgKi9cbiAgICBzZW5kUGFja2V0IChzZGxQYWNrZXQpIHtcbiAgICAgICAgdGhpcy5fc2RsUHJvdG9jb2wuc2VuZFBhY2tldChzZGxQYWNrZXQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHJldHVybiB7TnVtYmVyfSBtYXggdHJhbnNwb3J0IHVuaXQgZm9yIHRoZSBnaXZlbiBzZXJ2aWNlIHR5cGVcbiAgICAgKi9cbiAgICBnZXRNdHUgKHNlcnZpY2VUeXBlKSB7XG4gICAgICAgIHRoaXMuX3NkbFByb3RvY29sLmdldE10dShzZXJ2aWNlVHlwZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRW5kcyB0aGUgY3VycmVudCBzZXNzaW9uXG4gICAgICovXG4gICAgY2xvc2UgKCkge1xuICAgICAgICB0aGlzLl9zZGxQcm90b2NvbC5lbmRTZXNzaW9uKHRoaXMuX3Nlc3Npb25JZCwgdGhpcy5fc2Vzc2lvbkhhc2hJZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTZXJ2aWNlVHlwZX0gc2VydmljZVR5cGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc2Vzc2lvbklkIC0gcmVwcmVzZW50cyBhIGJ5dGVcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGlzRW5jcnlwdGVkXG4gICAgICovXG4gICAgc3RhcnRTZXJ2aWNlIChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklkLCBpc0VuY3J5cHRlZCkge1xuICAgICAgICB0aGlzLl9zZGxQcm90b2NvbC5zdGFydFNlcnZpY2Uoc2VydmljZVR5cGUsIHNlc3Npb25JZCwgaXNFbmNyeXB0ZWQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlc3Npb25JZCAtIHJlcHJlc2VudHMgYSBieXRlXG4gICAgICovXG4gICAgZW5kU2VydmljZSAoc2VydmljZVR5cGUsIHNlc3Npb25JZCkge1xuICAgICAgICB0aGlzLl9zZGxQcm90b2NvbC5lbmRTZXJ2aWNlKHNlcnZpY2VUeXBlLCBzZXNzaW9uSWQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1RyYW5zcG9ydFR5cGV9XG4gICAgICovXG4gICAgZ2V0Q3VycmVudFRyYW5zcG9ydFR5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmFzZVRyYW5zcG9ydENvbmZpZy5nZXRUcmFuc3BvcnRUeXBlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn0gaXNDb25uZWN0ZWRcbiAgICAgKi9cbiAgICBnZXRJc0Nvbm5lY3RlZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zZGxQcm90b2NvbC5pc0Nvbm5lY3RlZCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlcnNpb259XG4gICAgICovXG4gICAgZ2V0UHJvdG9jb2xWZXJzaW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NkbFByb3RvY29sLmdldFByb3RvY29sVmVyc2lvbigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1RyYW5zcG9ydENvbmZpZ0Jhc2V9XG4gICAgICovXG4gICAgZ2V0VHJhbnNwb3J0Q29uZmlnICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Jhc2VUcmFuc3BvcnRDb25maWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFNlc3Npb25IYXNoSWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2Vzc2lvbkhhc2hJZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZVxuICAgICAqIEBwYXJhbSB7U2RsU2VydmljZUxpc3RlbmVyfSBzZGxTZXJ2aWNlTGlzdGVuZXJcbiAgICAgKi9cbiAgICBhZGRTZXJ2aWNlTGlzdGVuZXIgKHNlcnZpY2VUeXBlLCBzZGxTZXJ2aWNlTGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5fc2VydmljZUxpc3RlbmVycy5hZGRMaXN0ZW5lcihzZXJ2aWNlVHlwZSwgc2RsU2VydmljZUxpc3RlbmVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZVxuICAgICAqIEBwYXJhbSB7U2RsU2VydmljZUxpc3RlbmVyfSBzZGxTZXJ2aWNlTGlzdGVuZXJcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufSAtIHdoZXRoZXIgdGhlIHJlbW92YWwgd2FzIHN1Y2Nlc3NmdWxcbiAgICAgKi9cbiAgICByZW1vdmVTZXJ2aWNlTGlzdGVuZXIgKHNlcnZpY2VUeXBlLCBzZGxTZXJ2aWNlTGlzdGVuZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NlcnZpY2VMaXN0ZW5lcnMucmVtb3ZlTGlzdGVuZXIoc2VydmljZVR5cGUsIHNkbFNlcnZpY2VMaXN0ZW5lcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U2VydmljZUxpc3RlbmVyTWFwfVxuICAgICAqL1xuICAgIGdldFNlcnZpY2VMaXN0ZW5lcnMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2VydmljZUxpc3RlbmVycztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7VmlkZW9TdHJlYW1pbmdQYXJhbWV0ZXJzfSBwYXJhbXNcbiAgICAgKi9cbiAgICBzZXREZXNpcmVkVmlkZW9QYXJhbXMgKHBhcmFtcykge1xuICAgICAgICB0aGlzLl9kZXNpcmVkVmlkZW9QYXJhbXMgPSBwYXJhbXM7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnRseSBzZXQgZGVzaXJlZCB2aWRlbyBzdHJlYW1pbmcgcGFyYW1ldGVycy4gSWYgdGhlcmUgaGF2ZW4ndCBiZWVuIGFueSBzZXQsXG4gICAgICogdGhlIGRlZmF1bHQgb3B0aW9ucyB3aWxsIGJlIHJldHVybmVkIGFuZCBzZXQgZm9yIHRoaXMgaW5zdGFuY2UuXG4gICAgICogQHJldHVybiB7VmlkZW9TdHJlYW1pbmdQYXJhbWV0ZXJzfSB0aGUgZGVzaXJlZCB2aWRlbyBzdHJlYW1pbmcgcGFyYW1ldGVyc1xuICAgICAqL1xuICAgIGdldERlc2lyZWRWaWRlb1BhcmFtcyAoKSB7XG4gICAgICAgIGlmICghKHRoaXMuX2Rlc2lyZWRWaWRlb1BhcmFtcyBpbnN0YW5jZW9mIFZpZGVvU3RyZWFtaW5nUGFyYW1ldGVycykpIHtcbiAgICAgICAgICAgIHRoaXMuX2Rlc2lyZWRWaWRlb1BhcmFtcyA9IG5ldyBWaWRlb1N0cmVhbWluZ1BhcmFtZXRlcnMoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fZGVzaXJlZFZpZGVvUGFyYW1zO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmlkZW9TdHJlYW1pbmdQYXJhbWV0ZXJzfSBwYXJhbXNcbiAgICAgKi9cbiAgICBzZXRBY2NlcHRlZFZpZGVvUGFyYW1zIChwYXJhbXMpIHtcbiAgICAgICAgdGhpcy5fZGVzaXJlZFZpZGVvUGFyYW1zID0gcGFyYW1zO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5cbmV4cG9ydCB7IFNkbFNlc3Npb24gfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBTZGxTZXNzaW9uTGlzdGVuZXJcbiAqL1xuY2xhc3MgU2RsU2Vzc2lvbkxpc3RlbmVyIHtcbiAgICAvKipcblx0ICogQGNvbnN0cnVjdG9yXG5cdCAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgdGhpcy5fb25Qcm90b2NvbFNlc3Npb25TdGFydGVkID0gbnVsbDtcbiAgICAgICAgdGhpcy5fb25Qcm90b2NvbFNlc3Npb25FbmRlZCA9IG51bGw7XG4gICAgICAgIHRoaXMuX29uUHJvdG9jb2xTZXNzaW9uRW5kZWROQUNLZWQgPSBudWxsO1xuICAgICAgICB0aGlzLl9vblJwY01lc3NhZ2VSZWNlaXZlZCA9IG51bGw7XG4gICAgICAgIHRoaXMuX29uVHJhbnNwb3J0Q29ubmVjdGVkID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBsaXN0ZW5lclxuICAgICAqL1xuICAgIHNldE9uUHJvdG9jb2xTZXNzaW9uU3RhcnRlZCAobGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5fb25Qcm90b2NvbFNlc3Npb25TdGFydGVkID0gbGlzdGVuZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBzZXRPblByb3RvY29sU2Vzc2lvbkVuZGVkIChsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLl9vblByb3RvY29sU2Vzc2lvbkVuZGVkID0gbGlzdGVuZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBzZXRPblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkIChsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLl9vblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkID0gbGlzdGVuZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBzZXRPblJwY01lc3NhZ2VSZWNlaXZlZCAobGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5fb25ScGNNZXNzYWdlUmVjZWl2ZWQgPSBsaXN0ZW5lcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBsaXN0ZW5lclxuICAgICAqL1xuICAgIHNldE9uVHJhbnNwb3J0Q29ubmVjdGVkIChsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLl9vblRyYW5zcG9ydENvbm5lY3RlZCA9IGxpc3RlbmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlc3Npb25JRCAtIHJlcHJlc2VudHMgYSBieXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHZlcnNpb24gLSByZXByZXNlbnRzIGEgYnl0ZVxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBjb3JyZWxhdGlvbklEXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGhhc2hJRFxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNFbmNyeXB0ZWRcbiAgICAgKi9cbiAgICBvblByb3RvY29sU2Vzc2lvblN0YXJ0ZWQgKHNlcnZpY2VUeXBlLCBzZXNzaW9uSUQsIHZlcnNpb24sIGNvcnJlbGF0aW9uSUQsIGhhc2hJRCwgaXNFbmNyeXB0ZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9vblByb3RvY29sU2Vzc2lvblN0YXJ0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuX29uUHJvdG9jb2xTZXNzaW9uU3RhcnRlZChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklELCB2ZXJzaW9uLCBjb3JyZWxhdGlvbklELCBoYXNoSUQsIGlzRW5jcnlwdGVkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlc3Npb25JRCAtIHJlcHJlc2VudHMgYSBieXRlXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGNvcnJlbGF0aW9uSURcbiAgICAgKi9cbiAgICBvblByb3RvY29sU2Vzc2lvbkVuZGVkIChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklELCBjb3JyZWxhdGlvbklEKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fb25Qcm90b2NvbFNlc3Npb25FbmRlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5fb25Qcm90b2NvbFNlc3Npb25FbmRlZChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklELCBjb3JyZWxhdGlvbklEKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlc3Npb25JRCAtIHJlcHJlc2VudHMgYSBieXRlXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGNvcnJlbGF0aW9uSURcbiAgICAgKi9cbiAgICBvblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkIChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklELCBjb3JyZWxhdGlvbkkpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9vblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9vblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkKHNlcnZpY2VUeXBlLCBzZXNzaW9uSUQsIGNvcnJlbGF0aW9uSSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1JwY01lc3NhZ2V9IHJwY01lc3NhZ2VcbiAgICAgKi9cbiAgICBvblJwY01lc3NhZ2VSZWNlaXZlZCAocnBjTWVzc2FnZSkge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX29uUnBjTWVzc2FnZVJlY2VpdmVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9vblJwY01lc3NhZ2VSZWNlaXZlZChycGNNZXNzYWdlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEludm9rZWQgd2hlbiB0aGUgYXBwIGFuZCBjb3JlIGNvbm5lY3RcbiAgICAgKi9cbiAgICBvblRyYW5zcG9ydENvbm5lY3RlZCAoKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fb25UcmFuc3BvcnRDb25uZWN0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuX29uVHJhbnNwb3J0Q29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCB7IFNkbFNlc3Npb25MaXN0ZW5lciB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEFycmF5VG9vbHNcbiAqL1xuY2xhc3MgQXJyYXlUb29scyB7XG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyB0aGUgaXRlbSBmcm9tIHRoZSBhcnJheS5cbiAgICAgKiBUaGlzIGRvZXMgbm90IG11dGF0ZSB0aGUgcGFzc2VkIGluIGFycmF5LlxuICAgICAqIE9ubHkgdGhlIHJldHVybmVkIGFycmF5IGhhcyB0aGUgdmFsdWUgcmVtb3ZlZC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheVxuICAgICAqIEBwYXJhbSB7YW55fSB2YWx1ZVxuICAgICAqIEByZXR1cm4ge0FycmF5fVxuICAgICAqL1xuICAgIHN0YXRpYyBhcnJheVJlbW92ZSAoYXJyYXksIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBhcnJheS5maWx0ZXIoZnVuY3Rpb24gKGVsZSkge1xuICAgICAgICAgICAgcmV0dXJuIGVsZSAhPT0gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbmV4cG9ydCB7IEFycmF5VG9vbHMgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUmVnaXN0ZXJBcHBJbnRlcmZhY2UgfSBmcm9tICcuLi8uLi9ycGMvbWVzc2FnZXMvUmVnaXN0ZXJBcHBJbnRlcmZhY2UuanMnO1xuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uLy4uL3JwYy9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vLi4vcnBjL1JwY1Jlc3BvbnNlLmpzJztcbmltcG9ydCB7IFJwY0xpc3RlbmVyIH0gZnJvbSAnLi4vLi4vcnBjL1JwY0xpc3RlbmVyLmpzJztcbmltcG9ydCB7IFNkbFNlc3Npb24gfSBmcm9tICcuLi8uLi9zZXNzaW9uL1NkbFNlc3Npb24uanMnO1xuaW1wb3J0IHsgU2RsU2Vzc2lvbkxpc3RlbmVyIH0gZnJvbSAnLi4vLi4vc2Vzc2lvbi9TZGxTZXNzaW9uTGlzdGVuZXIuanMnO1xuaW1wb3J0IHsgVmVyc2lvbiB9IGZyb20gJy4uLy4uL3V0aWwvVmVyc2lvbi5qcyc7XG5pbXBvcnQgeyBBcnJheVRvb2xzIH0gZnJvbSAnLi4vLi4vdXRpbC9BcnJheVRvb2xzLmpzJztcbmltcG9ydCB7IFNkbE1zZ1ZlcnNpb24gfSBmcm9tICcuLi8uLi9ycGMvc3RydWN0cy9TZGxNc2dWZXJzaW9uLmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi8uLi9ycGMvZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBTZXJ2aWNlVHlwZSB9IGZyb20gJy4uLy4uL3Byb3RvY29sL2VudW1zL1NlcnZpY2VUeXBlLmpzJztcblxuLyoqXG4gKiBOT1RFOiBUaGlzIGNvdWxkIGFsbCBjaGFuZ2UgYW5kIHNob3VsZCBvbmx5IGJlIHVzZWQgZm9yIHRlc3RpbmcuXG4gKiBUaGlzIGNsYXNzIHNob3VsZCBhbHNvIGJlIG1hcmtlZCBwcml2YXRlIGFuZCBiZWhpbmQgdGhlIFNkbE1hbmFnZXIgQVBJXG4gKlxuICogdXNhZ2Ugc2hvdWxkIGJlOlxuICogdmFyIGxjbSA9IG5ldyBMaWZlY3ljbGVNYW5hZ2VyKGFwcENvbmZpZywgbGlmZWN5Y2xlTGlzdGVuZXIpO1xuICogbGNtLnNldFJwY0xpc3RlbmVyKCAuLi4gKTtcbiAqIGxjbS5zdGFydCgpO1xuICogLi4uLlxuICpcbiAqIGxpZmVjeWNsZUxpc3RlbmVyLk9uUHJveHlDb25uZWN0ZWQoKXtcbiAqICAvL1Bvc3NpYmxlIHRvIHN0YXJ0IHNlbmRpbmcgUlBDcywgSE1JIGxldmVsIHNob3VsZCBiZSBOT05FIHRvIHN0YXJ0XG4gKlxuICogfVxuICpcbiAqL1xuY2xhc3MgTGlmZWN5Y2xlTWFuYWdlciB7XG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0FwcENvbmZpZ30gc2RsQ29uZmlnXG4gICAgKiBAcGFyYW0ge0xpZmVjeWNsZUxpc3RlbmVyfSBsaWZlY3ljbGVMaXN0ZW5lclxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoYXBwQ29uZmlnLCBsaWZlY3ljbGVMaXN0ZW5lcikge1xuICAgICAgICBpZiAoYXBwQ29uZmlnID09PSBudWxsIHx8IGxpZmVjeWNsZUxpc3RlbmVyID09PSBudWxsXG4gICAgICAgICAgICB8fCBhcHBDb25maWcgPT09IHVuZGVmaW5lZCB8fCBsaWZlY3ljbGVMaXN0ZW5lciA9PT0gdW5kZWZpbmVkXG4gICAgICAgICkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQYXJhbXMgbXVzdCBub3QgYmUgbnVsbCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fYXBwQ29uZmlnID0gYXBwQ29uZmlnO1xuICAgICAgICB0aGlzLl9saWZlY3ljbGVMaXN0ZW5lciA9IGxpZmVjeWNsZUxpc3RlbmVyO1xuICAgICAgICB0aGlzLl9zZGxTZXNzaW9uID0gbmV3IFNkbFNlc3Npb24odGhpcy5fYXBwQ29uZmlnLmdldFRyYW5zcG9ydENvbmZpZygpLCB0aGlzLl9jcmVhdGVTZXNzaW9uTGlzdGVuZXIoKSk7XG5cbiAgICAgICAgLy8gVGhpcyBpcyBieSBkZWZhdWx0IHVudGlsIHdlIHJlY2VpdmUgdGhlIFJBSSBSZXNwb25zZVxuICAgICAgICB0aGlzLl9ycGNTcGVjVmVyc2lvbiA9IG5ldyBWZXJzaW9uKDEsIDAsIDApO1xuXG4gICAgICAgIHRoaXMuX2N1cnJlbnRITUlTdGF0dXMgPSBudWxsO1xuICAgICAgICB0aGlzLl9maXJzdFRpbWVGdWxsID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fcmVzcG9uc2VMaXN0ZW5lcnMgPSBuZXcgTWFwKCk7XG4gICAgICAgIHRoaXMuX21heENvcnJlbGF0aW9uSWQgPSAwOyAvLyBUT0RPIHJlbW92ZSB3aGVuIGNvcnJlbGF0aW9uIGdlbiBpcyBpbXBsZW1lbnRlZFxuICAgICAgICB0aGlzLl9ycGNMaXN0ZW5lcnMgPSBuZXcgTWFwKCk7IC8vIDxOdW1iZXIsIEFycmF5PFJwY0xpc3RlbmVyPj5cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTZGxTZXNzaW9uTGlzdGVuZXJ9XG4gICAgICovXG4gICAgX2NyZWF0ZVNlc3Npb25MaXN0ZW5lciAoKSB7XG4gICAgICAgIGNvbnN0IHNlc3Npb25MaXN0ZW5lciA9IG5ldyBTZGxTZXNzaW9uTGlzdGVuZXIoKTtcbiAgICAgICAgc2Vzc2lvbkxpc3RlbmVyLnNldE9uUHJvdG9jb2xTZXNzaW9uU3RhcnRlZCgoc2VydmljZVR5cGUsIHNlc3Npb25JRCwgdmVyc2lvbiwgY29ycmVsYXRpb25JRCwgaGFzaElELCBpc0VuY3J5cHRlZCkgPT4ge1xuICAgICAgICAgICAgLy8gU2Vzc2lvbiBoYXMgYmVlbiBzdGFydGVkXG4gICAgICAgICAgICAvLyBUT0RPIGNoZWNrIG1pbiBwcm90b2NvbCBzcGVjIHZlcnNpb25cbiAgICAgICAgICAgIGlmIChzZXJ2aWNlVHlwZSA9PT0gU2VydmljZVR5cGUuUlBDKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2FwcENvbmZpZyAhPT0gbnVsbCAmJiB0aGlzLl9hcHBDb25maWcgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBUT0RPIGNhbGwgcHJlcGFyZSBvbiBjb25maWcgdG8gbWFrZSBzdXJlIGl0IGlzIHNhdGlzZmFjdG9yeVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbmRScGNNZXNzYWdlKHRoaXMuX2NyZWF0ZVJlZ2lzdGVyQXBwSW50ZXJmYWNlKCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHNlc3Npb25MaXN0ZW5lci5zZXRPblByb3RvY29sU2Vzc2lvbkVuZGVkKChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklELCBjb3JyZWxhdGlvbklEKSA9PiB7XG4gICAgICAgICAgICAvLyBTZXNzaW9uIGhhcyBiZWVuIGVuZGVkXG4gICAgICAgIH0pO1xuICAgICAgICBzZXNzaW9uTGlzdGVuZXIuc2V0T25Qcm90b2NvbFNlc3Npb25FbmRlZE5BQ0tlZCgoc2VydmljZVR5cGUsIHNlc3Npb25JRCwgY29ycmVsYXRpb25JRCkgPT4ge1xuICAgICAgICAgICAgLy8gVE9ETyBpbSBub3Qgc3VyZSB3aHkgd2UgaGF2ZSB0aGlzXG4gICAgICAgIH0pO1xuICAgICAgICBzZXNzaW9uTGlzdGVuZXIuc2V0T25ScGNNZXNzYWdlUmVjZWl2ZWQoKHJwY01lc3NhZ2UpID0+IHtcbiAgICAgICAgICAgIC8vIE1lc3NhZ2UgaGFzIGJlZW4gcmVjZWl2ZWRcbiAgICAgICAgICAgIHRoaXMuX2hhbmRsZVJwYyhycGNNZXNzYWdlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHNlc3Npb25MaXN0ZW5lci5zZXRPblRyYW5zcG9ydENvbm5lY3RlZCgoKSA9PiB7XG4gICAgICAgICAgICAvLyB0cmFuc3BvcnQgaGFzIGJlZW4gY29ubmVjdGVkXG4gICAgICAgICAgICB0aGlzLl9zZGxTZXNzaW9uLnN0YXJ0U2VydmljZShTZXJ2aWNlVHlwZS5SUEMsIDAsIGZhbHNlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHNlc3Npb25MaXN0ZW5lcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0geyBScGNNZXNzYWdlIH0gcnBjTWVzc2FnZVxuICAgICAqL1xuICAgIF9oYW5kbGVScGMgKHJwY01lc3NhZ2UpIHtcbiAgICAgICAgaWYgKHJwY01lc3NhZ2UgPT09IG51bGwgfHwgcnBjTWVzc2FnZSA9PT0gdW5kZWZpbmVkIHx8IHJwY01lc3NhZ2UuZ2V0RnVuY3Rpb25OYW1lKCkgPT09IG51bGwgfHwgcnBjTWVzc2FnZS5nZXRGdW5jdGlvbk5hbWUoKSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmdW5jdGlvbklEID0gRnVuY3Rpb25JRC52YWx1ZUZvcktleShycGNNZXNzYWdlLmdldEZ1bmN0aW9uTmFtZSgpKTsgLy8gdGhpcyBpcyB0aGUgbnVtYmVyIHZhbHVlXG4gICAgICAgIGNvbnN0IGxpc3RlbmVyQXJyYXkgPSB0aGlzLl9ycGNMaXN0ZW5lcnMuZ2V0KGZ1bmN0aW9uSUQpO1xuICAgICAgICBpZiAobGlzdGVuZXJBcnJheSAhPT0gbnVsbCAmJiBsaXN0ZW5lckFycmF5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGxpc3RlbmVyQXJyYXkuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgICAgIGl0ZW0ub25ScGNNZXNzYWdlKHJwY01lc3NhZ2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBIYW5kbGUgaW5kaXZpZHVhbCBSUEMgbGlzdGVuZXJzIGZvciByZXF1ZXN0L3Jlc3BvbnNlIHBhaXJzXG4gICAgICAgIGlmIChycGNNZXNzYWdlIGluc3RhbmNlb2YgUnBjUmVzcG9uc2UpIHtcbiAgICAgICAgICAgIC8vIG51bGwgY2hlY2sgbm90IG5lZWRlZC4gaXRzIGFsd2F5cyBkZWZpbmVkIGluIHRoZSBjb25zdHJ1Y3RvclxuICAgICAgICAgICAgaWYgKHRoaXMuX3Jlc3BvbnNlTGlzdGVuZXJzLmhhcyhycGNNZXNzYWdlLmdldENvcnJlbGF0aW9uSWQoKSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yZXNwb25zZUxpc3RlbmVycy5nZXQocnBjTWVzc2FnZS5nZXRDb3JyZWxhdGlvbklkKCkpLnJlc29sdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TGlmZWN5Y2xlTWFuYWdlcn1cbiAgICAqL1xuICAgIHN0YXJ0ICgpIHtcbiAgICAgICAgdGhpcy5fc2V0dXBJbnRlcm5hbFJwY0xpc3RlbmVycygpO1xuICAgICAgICB0aGlzLl9zZGxTZXNzaW9uLnN0YXJ0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHN0b3AgKCkge1xuICAgICAgICB0aGlzLl9zZGxTZXNzaW9uLmNsb3NlKCk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25JRH0gZnVuY3Rpb25JRFxuICAgICAqIEBwYXJhbSB7UnBjTGlzdGVuZXJ9IHJwY0xpc3RlbmVyXG4gICAgICovXG4gICAgYWRkUnBjTGlzdGVuZXIgKGZ1bmN0aW9uSUQsIHJwY0xpc3RlbmVyKSB7XG4gICAgICAgIGxldCBsaXN0ZW5lckFycmF5ID0gdGhpcy5fcnBjTGlzdGVuZXJzLmdldChmdW5jdGlvbklEKTtcbiAgICAgICAgLy8gSWYgbm8gYXJyYXkgZXhpc3RzIHlldCBmb3IgdGhpcyBmdW5jdGlvbiBpZCwgY3JlYXRlIG9uZVxuICAgICAgICBpZiAobGlzdGVuZXJBcnJheSA9PT0gbnVsbCB8fCBsaXN0ZW5lckFycmF5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3JwY0xpc3RlbmVycy5zZXQoZnVuY3Rpb25JRCwgW10pO1xuICAgICAgICAgICAgbGlzdGVuZXJBcnJheSA9IHRoaXMuX3JwY0xpc3RlbmVycy5nZXQoZnVuY3Rpb25JRCk7XG4gICAgICAgIH1cbiAgICAgICAgbGlzdGVuZXJBcnJheS5wdXNoKHJwY0xpc3RlbmVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25JRH0gZnVuY3Rpb25JRFxuICAgICAqIEBwYXJhbSB7UnBjTGlzdGVuZXJ9IHJwY0xpc3RlbmVyXG4gICAgICovXG4gICAgcmVtb3ZlUnBjTGlzdGVuZXIgKGZ1bmN0aW9uSUQsIHJwY0xpc3RlbmVyKSB7XG4gICAgICAgIGlmIChycGNMaXN0ZW5lciAhPT0gbnVsbCAmJiBycGNMaXN0ZW5lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjb25zdCBsaXN0ZW5lckFycmF5ID0gdGhpcy5fcnBjTGlzdGVuZXJzLmdldChmdW5jdGlvbklEKTtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lckFycmF5ICE9PSBudWxsICYmIGxpc3RlbmVyQXJyYXkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3JwY0xpc3RlbmVycy5zZXQoZnVuY3Rpb25JRCwgQXJyYXlUb29scy5hcnJheVJlbW92ZShsaXN0ZW5lckFycmF5LCBycGNMaXN0ZW5lcikpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1JwY01lc3NhZ2V9IHJwY01lc3NhZ2VcbiAgICAgKi9cbiAgICBzZW5kUnBjTWVzc2FnZSAocnBjTWVzc2FnZSkge1xuICAgICAgICBpZiAocnBjTWVzc2FnZSAhPT0gbnVsbCAmJiBycGNNZXNzYWdlICE9PSB1bmRlZmluZWQgJiYgdGhpcy5fc2RsU2Vzc2lvbi5nZXRJc0Nvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAvLyBUT0RPIHdlIHN0aWxsIG5lZWQgdG8gbWFrZSBwcm9wZXIgY2hhbmdlcyB0byBoYW5kbGUgc3BlY2lmaWMgY2FzZXMgZm9yIFJQQ3MgaWUgUExBWV9QQVVTRSAvIE9LXG5cbiAgICAgICAgICAgIC8vIFRPRE8gY3JlYXRlIGEgY29ycmVsYXRpb24gaWQgZ2VuZXJhdG9yIGFuZCBoYW5kbGUgdGhpcyBpbiB0aGUgUlBDIGNsYXNzZXNcbiAgICAgICAgICAgIGlmIChycGNNZXNzYWdlIGluc3RhbmNlb2YgUnBjUmVxdWVzdCkge1xuICAgICAgICAgICAgICAgIGlmIChycGNNZXNzYWdlLmdldEZ1bmN0aW9uTmFtZSAhPT0gRnVuY3Rpb25JRC5SZWdpc3RlckFwcEludGVyZmFjZSkgeyAvLyBSQUkgaGFzIGEgYSBwcm90ZWN0ZWQgaWRcbiAgICAgICAgICAgICAgICAgICAgcnBjTWVzc2FnZS5zZXRDb3JyZWxhdGlvbklkKCsrdGhpcy5fbWF4Q29ycmVsYXRpb25JZCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gVE9ETzogY2FuJ3QgdXRpbGl6ZSB0aGUgYWJpbGl0eSBvZiBwcm9taXNlcyBsaWtlIHRoaXNcbiAgICAgICAgICAgICAgICBpZiAocnBjTWVzc2FnZS5nZXRPblJQQ1Jlc3BvbnNlUHJvbWlzZSgpICE9PSBudWxsICYmIHJwY01lc3NhZ2UuZ2V0T25SUENSZXNwb25zZVByb21pc2UoKSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFNldCB0aGUgaW5kaXZpZHVhbCByZXNwb25zZSBsaXN0ZW5lciBmb3IgdGhpcyBSUEMgbWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZXNwb25zZUxpc3RlbmVycy5zZXQocnBjTWVzc2FnZS5nZXRDb3JyZWxhdGlvbklkKCksIHJwY01lc3NhZ2UuZ2V0T25SUENSZXNwb25zZVByb21pc2UoKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fc2RsU2Vzc2lvbi5zZW5kUnBjKHJwY01lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgfVxuXG5cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2V9XG4gICAgICovXG4gICAgZ2V0UmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlO1xuICAgIH1cblxuXG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlfVxuICAgICovXG4gICAgX2NyZWF0ZVJlZ2lzdGVyQXBwSW50ZXJmYWNlICgpIHtcbiAgICAgICAgY29uc3QgcmVnaXN0ZXJBcHBJbnRlcmZhY2UgPSBuZXcgUmVnaXN0ZXJBcHBJbnRlcmZhY2UoKTtcbiAgICAgICAgcmVnaXN0ZXJBcHBJbnRlcmZhY2Uuc2V0U2RsTXNnVmVyc2lvbihuZXcgU2RsTXNnVmVyc2lvbigpLnNldE1ham9yVmVyc2lvbihMaWZlY3ljbGVNYW5hZ2VyLk1BWF9SUENfVkVSU0lPTi5nZXRNYWpvcigpKS5zZXRNaW5vclZlcnNpb24oTGlmZWN5Y2xlTWFuYWdlci5NQVhfUlBDX1ZFUlNJT04uZ2V0TWlub3IoKSkuc2V0UGF0Y2hWZXJzaW9uKExpZmVjeWNsZU1hbmFnZXIuTUFYX1JQQ19WRVJTSU9OLmdldFBhdGNoKCkpKVxuICAgICAgICAgICAgLnNldEFwcE5hbWUodGhpcy5fYXBwQ29uZmlnLmdldEFwcE5hbWUoKSlcbiAgICAgICAgICAgIC5zZXRGdWxsQXBwSWQodGhpcy5fYXBwQ29uZmlnLmdldEFwcElkKCkpXG4gICAgICAgICAgICAuc2V0TmduTWVkaWFTY3JlZW5BcHBOYW1lKHRoaXMuX2FwcENvbmZpZy5nZXRTaG9ydEFwcE5hbWUoKSlcbiAgICAgICAgICAgIC5zZXRBcHBIbWlUeXBlKHRoaXMuX2FwcENvbmZpZy5nZXRBcHBUeXBlcygpKVxuICAgICAgICAgICAgLnNldExhbmd1YWdlRGVzaXJlZCh0aGlzLl9hcHBDb25maWcuZ2V0TGFuZ3VhZ2VEZXNpcmVkKCkpXG4gICAgICAgICAgICAuc2V0SG1pRGlzcGxheUxhbmd1YWdlRGVzaXJlZCh0aGlzLl9hcHBDb25maWcuZ2V0SG1pRGlzcGxheUxhbmd1YWdlRGVzaXJlZCgpKVxuICAgICAgICAgICAgLnNldElzTWVkaWFBcHBsaWNhdGlvbih0aGlzLl9hcHBDb25maWcuaXNNZWRpYUFwcCgpKVxuICAgICAgICAgICAgLnNldERheUNvbG9yU2NoZW1lKHRoaXMuX2FwcENvbmZpZy5nZXREYXlDb2xvclNjaGVtZSgpKVxuICAgICAgICAgICAgLnNldE5pZ2h0Q29sb3JTY2hlbWUodGhpcy5fYXBwQ29uZmlnLmdldE5pZ2h0Q29sb3JTY2hlbWUoKSlcbiAgICAgICAgICAgIC5zZXRDb3JyZWxhdGlvbklkKExpZmVjeWNsZU1hbmFnZXIuUkVHSVNURVJfQVBQX0lOVEVSRkFDRV9DT1JSRUxBVElPTl9JRCk7XG5cbiAgICAgICAgLy8gVE9ETyBBZGQgYWxsIHBvc3NpYmxlIGl0ZW1zXG5cbiAgICAgICAgcmV0dXJuIHJlZ2lzdGVyQXBwSW50ZXJmYWNlO1xuICAgIH1cblxuXG4gICAgLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqIElOVEVSTkFMIC0gUlBDIExJU1RFTkVSUyAhISBTVEFSVCAhISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4gICAgX3NldHVwSW50ZXJuYWxScGNMaXN0ZW5lcnMgKCkge1xuICAgICAgICB0aGlzLl9ycGNMaXN0ZW5lciA9IG5ldyBScGNMaXN0ZW5lcigpLnNldE9uUnBjTWVzc2FnZShycGNNZXNzYWdlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGZ1bmN0aW9uSUQgPSBGdW5jdGlvbklELnZhbHVlRm9yS2V5KHJwY01lc3NhZ2UuZ2V0RnVuY3Rpb25OYW1lKCkpOyAvLyB0aGlzIGlzIHRoZSBudW1iZXIgdmFsdWVcblxuXG4gICAgICAgICAgICBzd2l0Y2ggKGZ1bmN0aW9uSUQpIHtcbiAgICAgICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuUmVnaXN0ZXJBcHBJbnRlcmZhY2U6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3NSYWlSZXNwb25zZShycGNNZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELk9uSE1JU3RhdHVzOiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHNlbmQgYSBzaW5nbGUgb25Qcm94eUNvbm5lY3RlZCwgd2hlbiB3ZSBnbyBmcm9tIGEgbnVsbCBITUkgbGV2ZWwgdG8gYSBkZWZpbmVkIEhNSSBsZXZlbFxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaG91bGRJbml0ID0gcnBjTWVzc2FnZS5nZXRITUlMZXZlbCgpICE9PSBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgICAmJiBycGNNZXNzYWdlLmdldEhNSUxldmVsKCkgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICAgICAgJiYgdGhpcy5fY3VycmVudEhNSVN0YXR1cyA9PT0gbnVsbDtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jdXJyZW50SE1JU3RhdHVzID0gcnBjTWVzc2FnZS5nZXRITUlMZXZlbCgpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9saWZlY3ljbGVMaXN0ZW5lciAhPT0gbnVsbCAmJiB0aGlzLl9saWZlY3ljbGVMaXN0ZW5lciAhPT0gdW5kZWZpbmVkICYmIHNob3VsZEluaXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2xpZmVjeWNsZUxpc3RlbmVyLm9uUHJveHlDb25uZWN0ZWQodGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgLy8gUlBDIG5vdCBoYW5kbGVkIHlldCBpbiBMQ01cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5hZGRScGNMaXN0ZW5lcihGdW5jdGlvbklELlJlZ2lzdGVyQXBwSW50ZXJmYWNlLCB0aGlzLl9ycGNMaXN0ZW5lcik7XG4gICAgICAgIHRoaXMuYWRkUnBjTGlzdGVuZXIoRnVuY3Rpb25JRC5PbkhNSVN0YXR1cywgdGhpcy5fcnBjTGlzdGVuZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlfSByZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlXG4gICAgICovXG4gICAgX3Byb2Nlc3NSYWlSZXNwb25zZSAocmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZSkge1xuICAgICAgICAvLyBDYWNoZSB0aGlzIFJBSSBSZXNwb25zZSBhcyBpdCBjYW4gYmUgdXNlZCBsYXRlclxuICAgICAgICB0aGlzLl9yZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlID0gcmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZTtcblxuICAgICAgICAvLyAgVE9ETyBLRVlfU0RMX01TR19WRVJTSU9OIHZzIEtFWV9TWU5DX01TR19WRVJTSU9OIHNkbFZlcnNpb246ICd7R0lUX0NPTU1JVH0nLCBJIHRoaW5rIHRoZSBrZXkgbmFtZSBjaGFuZ2VcbiAgICAgICAgLy8gaXMgbWVhbnQgdG8gbWFrZSB0aGluZ3MgY2xlYXJlciBhYm91dCB0aGlzIGJlaW5nIGFuIHNkbCB2ZXJzaW9uIHdoaWNoIGlzIG5vdCBzcGVjaWZpYyB0byBmb3JkJ3Mgc3luYy5cbiAgICAgICAgLy8gVGhlcmUgaXMgYSBrZXkgY2FsbGVkIHNkbFZlcnNpb24gdGhhdCBpcyByZXNwb25kaW5nIHdpdGgge0dJVF9DT01NSVR9IHRoYXQgSSdtIHVuc3VyZSB3aGF0IGl0IGlzIHN1cHBvc2VkIHRvIGRvLlxuICAgICAgICBjb25zdCBtc2dWZXJzaW9uID0gcmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5nZXRTZGxNc2dWZXJzaW9uKCk7XG5cbiAgICAgICAgaWYgKG1zZ1ZlcnNpb24gIT09IG51bGwgJiYgbXNnVmVyc2lvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLl9ycGNTcGVjVmVyc2lvbiA9IG5ldyBWZXJzaW9uKG1zZ1ZlcnNpb24uZ2V0TWFqb3JWZXJzaW9uKCksIG1zZ1ZlcnNpb24uZ2V0TWFqb3JWZXJzaW9uKCksIG1zZ1ZlcnNpb24uZ2V0UGF0Y2hWZXJzaW9uKCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fcnBjU3BlY1ZlcnNpb24gPSBMaWZlY3ljbGVNYW5hZ2VyLk1BWF9SUENfVkVSU0lPTjtcbiAgICAgICAgfVxuXG5cbiAgICAgICAgLy8gVE9ETyBjaGVjayBhZ2FpbnN0IG1pbiBSUEMgc3BlYyB2ZXJzaW9uIGNvbmZpZ1xuXG4gICAgICAgIC8vIFRPRE8gcGFyc2UgUkFJIGZvciBzeXN0ZW0gY2FwYWJpbGl0aWVzXG4gICAgfVxufVxuXG5MaWZlY3ljbGVNYW5hZ2VyLk1BWF9SUENfVkVSU0lPTiA9IG5ldyBWZXJzaW9uKDYsIDAsIDApO1xuTGlmZWN5Y2xlTWFuYWdlci5SRUdJU1RFUl9BUFBfSU5URVJGQUNFX0NPUlJFTEFUSU9OX0lEID0gNjU1Mjk7XG5MaWZlY3ljbGVNYW5hZ2VyLlVOUkVHSVNURVJfQVBQX0lOVEVSRkFDRV9DT1JSRUxBVElPTl9JRCA9IDY1NTMwO1xuXG5cbmV4cG9ydCB7IExpZmVjeWNsZU1hbmFnZXIgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IFZpZGVvU3RyZWFtaW5nRm9ybWF0IH0gZnJvbSAnLi9WaWRlb1N0cmVhbWluZ0Zvcm1hdC5qcyc7XG5pbXBvcnQgeyBJbWFnZVJlc29sdXRpb24gfSBmcm9tICcuL0ltYWdlUmVzb2x1dGlvbi5qcyc7XG5cbmNsYXNzIFZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eSBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7SW1hZ2VSZXNvbHV0aW9ufSB2YWxcbiAgICAqIEByZXR1cm4ge1ZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eX1cbiAgICAqL1xuICAgIHNldFByZWZlcnJlZFJlc29sdXRpb24gKHZhbCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShJbWFnZVJlc29sdXRpb24sIHZhbCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eS5LRVlfUFJFRkVSUkVEX1JFU09MVVRJT04sIHZhbCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7SW1hZ2VSZXNvbHV0aW9ufVxuICAgICovXG4gICAgZ2V0UHJlZmVycmVkUmVzb2x1dGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChJbWFnZVJlc29sdXRpb24sIFZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eS5LRVlfUFJFRkVSUkVEX1JFU09MVVRJT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbFxuICAgICogQHJldHVybiB7VmlkZW9TdHJlYW1pbmdDYXBhYmlsaXR5fVxuICAgICovXG4gICAgc2V0TWF4Qml0cmF0ZSAodmFsKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eS5LRVlfTUFYX0JJVFJBVEUsIHZhbCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7bnVtYmVyfVxuICAgICovXG4gICAgZ2V0TWF4Qml0cmF0ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHkuS0VZX01BWF9CSVRSQVRFKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtWaWRlb1N0cmVhbWluZ0Zvcm1hdFtdfSB2YWxcbiAgICAqIEByZXR1cm4ge1ZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eX1cbiAgICAqL1xuICAgIHNldFN1cHBvcnRlZEZvcm1hdHMgKHZhbCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWaWRlb1N0cmVhbWluZ0Zvcm1hdCwgdmFsLCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVmlkZW9TdHJlYW1pbmdDYXBhYmlsaXR5LktFWV9TVVBQT1JURURfRk9STUFUUywgdmFsKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1ZpZGVvU3RyZWFtaW5nRm9ybWF0W119XG4gICAgKi9cbiAgICBnZXRTdXBwb3J0ZWRGb3JtYXRzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZpZGVvU3RyZWFtaW5nRm9ybWF0LCBWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHkuS0VZX1NVUFBPUlRFRF9GT1JNQVRTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gdmFsXG4gICAgKiBAcmV0dXJuIHtWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHl9XG4gICAgKi9cbiAgICBzZXRIYXB0aWNTcGF0aWFsRGF0YVN1cHBvcnRlZCAodmFsKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eS5LRVlfSEFQVElDX1NQQVRJQUxfREFUQV9TVVBQT1JURUQsIHZhbCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAqL1xuICAgIGdldEhhcHRpY1NwYXRpYWxEYXRhU3VwcG9ydGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eS5LRVlfSEFQVElDX1NQQVRJQUxfREFUQV9TVVBQT1JURUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbFxuICAgICogQHJldHVybiB7VmlkZW9TdHJlYW1pbmdDYXBhYmlsaXR5fVxuICAgICovXG4gICAgc2V0RGlhZ29uYWxTY3JlZW5TaXplICh2YWwpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVmlkZW9TdHJlYW1pbmdDYXBhYmlsaXR5LktFWV9ESUFHT05BTF9TQ1JFRU5fU0laRSwgdmFsKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtudW1iZXJ9XG4gICAgKi9cbiAgICBnZXREaWFnb25hbFNjcmVlblNpemUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoVmlkZW9TdHJlYW1pbmdDYXBhYmlsaXR5LktFWV9ESUFHT05BTF9TQ1JFRU5fU0laRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge251bWJlcn0gdmFsXG4gICAgKiBAcmV0dXJuIHtWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHl9XG4gICAgKi9cbiAgICBzZXRQaXhlbFBlckluY2ggKHZhbCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHkuS0VZX1BJWEVMX1BFUl9JTkNILCB2YWwpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge251bWJlcn1cbiAgICAqL1xuICAgIGdldFBpeGVsUGVySW5jaCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHkuS0VZX1BJWEVMX1BFUl9JTkNIKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWxcbiAgICAqIEByZXR1cm4ge1ZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eX1cbiAgICAqL1xuICAgIHNldFNjYWxlICh2YWwpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVmlkZW9TdHJlYW1pbmdDYXBhYmlsaXR5LktFWV9TQ0FMRSwgdmFsKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtudW1iZXJ9XG4gICAgKi9cbiAgICBnZXRTY2FsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHkuS0VZX1NDQUxFKTtcbiAgICB9XG59XG5cblZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eS5LRVlfUFJFRkVSUkVEX1JFU09MVVRJT04gPSAncHJlZmVycmVkUmVzb2x1dGlvbic7XG5WaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHkuS0VZX01BWF9CSVRSQVRFID0gJ21heEJpdHJhdGUnO1xuVmlkZW9TdHJlYW1pbmdDYXBhYmlsaXR5LktFWV9TVVBQT1JURURfRk9STUFUUyA9ICdzdXBwb3J0ZWRGb3JtYXRzJztcblZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eS5LRVlfSEFQVElDX1NQQVRJQUxfREFUQV9TVVBQT1JURUQgPSAnaGFwdGljU3BhdGlhbERhdGFTdXBwb3J0ZWQnO1xuVmlkZW9TdHJlYW1pbmdDYXBhYmlsaXR5LktFWV9ESUFHT05BTF9TQ1JFRU5fU0laRSA9ICdkaWFnb25hbFNjcmVlblNpemUnO1xuVmlkZW9TdHJlYW1pbmdDYXBhYmlsaXR5LktFWV9QSVhFTF9QRVJfSU5DSCA9ICdwaXhlbFBlckluY2gnO1xuVmlkZW9TdHJlYW1pbmdDYXBhYmlsaXR5LktFWV9TQ0FMRSA9ICdzY2FsZSc7XG5cbmV4cG9ydCB7IFZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eSB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gU2RsU2VydmljZUxpc3RlbmVyXG4gKi9cbmNsYXNzIFNkbFNlcnZpY2VMaXN0ZW5lciB7XG4gICAgLyoqXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHRoaXMuX29uU2VydmljZVN0YXJ0ZWQgPSBudWxsO1xuICAgICAgICB0aGlzLl9vblNlcnZpY2VFbmRlZCA9IG51bGw7XG4gICAgICAgIHRoaXMuX29uU2VydmljZUVycm9yID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBsaXN0ZW5lclxuICAgICAqL1xuICAgIHNldE9uU2VydmljZVN0YXJ0ZWQgKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMuX29uU2VydmljZVN0YXJ0ZWQgPSBsaXN0ZW5lcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBsaXN0ZW5lclxuICAgICAqL1xuICAgIHNldE9uU2VydmljZUVuZGVkIChsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLl9vblNlcnZpY2VFbmRlZCA9IGxpc3RlbmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyXG4gICAgICovXG4gICAgc2V0T25TZXJ2aWNlRXJyb3IgKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMuX29uU2VydmljZUVycm9yID0gbGlzdGVuZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTZGxTZXNzaW9ufSBzZXNzaW9uXG4gICAgICogQHBhcmFtIHtTZXJ2aWNlVHlwZX0gc2VydmljZVR5cGVcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGlzRW5jcnlwdGVkXG4gICAgICovXG4gICAgb25TZXJ2aWNlU3RhcnRlZCAoc2Vzc2lvbiwgc2VydmljZVR5cGUsIGlzRW5jcnlwdGVkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fb25TZXJ2aWNlU3RhcnRlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5fb25TZXJ2aWNlU3RhcnRlZChzZXNzaW9uLCBzZXJ2aWNlVHlwZSwgaXNFbmNyeXB0ZWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTZGxTZXNzaW9ufSBzZXNzaW9uXG4gICAgICogQHBhcmFtIHtTZXJ2aWNlVHlwZX0gc2VydmljZVR5cGVcbiAgICAgKi9cbiAgICBvblNlcnZpY2VFbmRlZCAoc2Vzc2lvbiwgc2VydmljZVR5cGUpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9vblNlcnZpY2VFbmRlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5fb25TZXJ2aWNlRW5kZWQoc2Vzc2lvbiwgc2VydmljZVR5cGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTZGxTZXNzaW9ufSBzZXNzaW9uXG4gICAgICogQHBhcmFtIHtTZXJ2aWNlVHlwZX0gc2VydmljZVR5cGVcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gcmVhc29uXG4gICAgICovXG4gICAgb25TZXJ2aWNlRXJyb3IgKHNlc3Npb24sIHNlcnZpY2VUeXBlLCByZWFzb24pIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9vblNlcnZpY2VFcnJvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5fb25TZXJ2aWNlRXJyb3Ioc2Vzc2lvbiwgc2VydmljZVR5cGUsIHJlYXNvbik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCB7IFNkbFNlcnZpY2VMaXN0ZW5lciB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBUcmFuc3BvcnRCYXNlIH0gZnJvbSAnLi9UcmFuc3BvcnRCYXNlLmpzJztcbmltcG9ydCB7IFNkbFBzbSB9IGZyb20gJy4vU2RsUHNtLmpzJztcblxuY2xhc3MgQ3VzdG9tVHJhbnNwb3J0IGV4dGVuZHMgVHJhbnNwb3J0QmFzZSB7XG4gICAgY29uc3RydWN0b3IgKHRyYW5zcG9ydENvbmZpZywgdHJhbnNwb3J0Q2FsbGJhY2sgPSBudWxsKSB7XG4gICAgICAgIHN1cGVyKHRyYW5zcG9ydENvbmZpZywgdHJhbnNwb3J0Q2FsbGJhY2spO1xuICAgICAgICB0aGlzLl9xdWV1ZSA9IFtdO1xuICAgICAgICB0aGlzLl9pc1J1bm5pbmcgPSBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1RyYW5zcG9ydENhbGxiYWNrfSBjYWxsYmFja1xuICAgICAqL1xuICAgIHNldFRyYW5zcG9ydENhbGxiYWNrIChjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl90cmFuc3BvcnRDYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VycyB0aGUgdHJhbnNwb3J0IGNhbGxiYWNrIGZvciBjb25uZWN0aW9uIGVzdGFibGlzaGVkXG4gICAgICovXG4gICAgc3RhcnQgKCkge1xuICAgICAgICBpZiAodGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2sgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX3RyYW5zcG9ydENhbGxiYWNrLm9uQ29ubmVjdGlvbkVzdGFibGlzaGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VycyB0aGUgdHJhbnNwb3J0IGNhbGxiYWNrIGZvciBjb25uZWN0aW9uIHRlcm1pbmF0ZWRcbiAgICAgKi9cbiAgICBzdG9wICgpIHtcbiAgICAgICAgaWYgKHRoaXMuX3RyYW5zcG9ydENhbGxiYWNrICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl90cmFuc3BvcnRDYWxsYmFjay5vbkNvbm5lY3Rpb25UZXJtaW5hdGVkKCdUcmFuc3BvcnQgdG9sZCB0byBzdG9wJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VycyB0aGUgdHJhbnNwb3J0IGNhbGxiYWNrIGZvciBhbiBlcnJvclxuICAgICAqL1xuICAgIG9uRXJyb3IgKCkge1xuICAgICAgICBpZiAodGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2sgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX3RyYW5zcG9ydENhbGxiYWNrLm9uRXJyb3IoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBjb250ZW50cyBpbiB0aGUgcGFja2V0IHNob3VsZCBiZSBzZW50IG91dCB0aHJvdWdoIHRoZSB0cmFuc3BvcnRcbiAgICAgKiBAcGFyYW0ge1NkbFBhY2tldH0gcGFja2V0XG4gICAgICovXG4gICAgc2VuZFBhY2tldCAocGFja2V0KSB7XG4gICAgICAgIGNvbnN0IGJ5dGVzID0gcGFja2V0LnRvUGFja2V0KCk7XG4gICAgICAgIHRoaXMub25TZW5kUGFja2V0KGJ5dGVzLCAwLCBieXRlcy5sZW5ndGgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBhcHAgaW5zdGFudGlhdGluZyB0aGlzIGNsYXNzIG5lZWRzIHRvIGltcGxlbWVudCB0aGlzIG1ldGhvZCEgc2VuZFBhY2tldCBjYWxscyB0aGlzIG1ldGhvZFxuICAgICAqIEBwYXJhbSB7VUludDhBcnJheX0gYnl0ZXNcbiAgICAgKi9cbiAgICBvblNlbmRQYWNrZXQgKGJ5dGVzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignb25TZW5kUGFja2V0IG1ldGhvZCBtdXN0IGJlIG92ZXJyaWRkZW4nKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIGJ5dGUgYnVmZmVyIHdhcyBwYXNzZWQgaGVyZSBmb3IgcHJvY2Vzc2luZ1xuICAgICAqIEBwYXJhbSB7VWludDhBcnJheX0gbWVzc2FnZVxuICAgICAqL1xuICAgIG9uQnl0ZUJ1ZmZlclJlY2VpdmVkIChtZXNzYWdlKSB7XG4gICAgICAgIHRoaXMuX3F1ZXVlLnB1c2gobWVzc2FnZSk7XG4gICAgICAgIHRoaXMuX211bHRpQnl0ZUhhbmRsZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcm9jZXNzZXMgcmVjZWl2ZWQgZGF0YSBmcm9tIHRoZSBpbnRlcm5hbCBxdWV1ZVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgX211bHRpQnl0ZUhhbmRsZXIgKCkge1xuICAgICAgICBpZiAodGhpcy5faXNSdW5uaW5nKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5faXNSdW5uaW5nID0gdHJ1ZTtcblxuICAgICAgICB3aGlsZSAodGhpcy5fcXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgdWludDggPSB0aGlzLl9xdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgZm9yIChjb25zdCBieXRlIG9mIHVpbnQ4KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlQnl0ZShieXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2lzUnVubmluZyA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZlZWRzIGEgYnl0ZSB0aHJvdWdoIHRoZSBpbnRlcm5hbCBQU01cbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYnl0ZSAtIHVuc2lnbmVkIDgtYml0IGludGVnZXJcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9oYW5kbGVCeXRlIChieXRlKSB7XG4gICAgICAgIGNvbnN0IHNkbFBzbSA9IHRoaXMuX3NkbFBzbTtcblxuICAgICAgICBjb25zdCBzdWNjZXNzID0gc2RsUHNtLmhhbmRsZUJ5dGUoYnl0ZSk7XG4gICAgICAgIGlmICghc3VjY2Vzcykge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignZmFpbGVkJywgc2RsUHNtKTtcbiAgICAgICAgICAgIHNkbFBzbS5yZXNldCgpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGlzRmluaXNoZWQgPSBzZGxQc20uZ2V0U3RhdGUoKSA9PT0gU2RsUHNtLkZJTklTSEVEX1NUQVRFO1xuXG4gICAgICAgIGlmIChpc0ZpbmlzaGVkKSB7XG4gICAgICAgICAgICBjb25zdCBwYWNrZXQgPSBzZGxQc20uZ2V0Rm9ybWVkUGFja2V0KCk7XG4gICAgICAgICAgICBzZGxQc20ucmVzZXQoKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl90cmFuc3BvcnRDYWxsYmFjayAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RyYW5zcG9ydENhbGxiYWNrLm9uUGFja2V0UmVjZWl2ZWQocGFja2V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuXG5leHBvcnQgeyBDdXN0b21UcmFuc3BvcnQgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBUcmFuc3BvcnRDb25maWdCYXNlXG4gKiBAcHJvcGVydHkge1RyYW5zcG9ydFR5cGV9IF90cmFuc3BvcnRUeXBlXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBnZXRUcmFuc3BvcnRUeXBlXG4gKi9cbmNsYXNzIFRyYW5zcG9ydENvbmZpZ0Jhc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7VHJhbnNwb3J0VHlwZX0gdHJhbnNwb3J0VHlwZSAtIGVudW1cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAodHJhbnNwb3J0VHlwZSkge1xuICAgICAgICB0aGlzLl90cmFuc3BvcnRUeXBlID0gdHJhbnNwb3J0VHlwZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtUcmFuc3BvcnRUeXBlfVxuICAgICAqL1xuICAgIGdldFRyYW5zcG9ydFR5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0VHlwZTtcbiAgICB9XG59XG5cbmV4cG9ydCB7IFRyYW5zcG9ydENvbmZpZ0Jhc2UgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgVHJhbnNwb3J0Q29uZmlnQmFzZSB9IGZyb20gJy4vVHJhbnNwb3J0Q29uZmlnQmFzZS5qcyc7XG5pbXBvcnQgeyBUcmFuc3BvcnRUeXBlIH0gZnJvbSAnLi9lbnVtcy9UcmFuc3BvcnRUeXBlLmpzJztcblxuY2xhc3MgQ3VzdG9tVHJhbnNwb3J0Q29uZmlnIGV4dGVuZHMgVHJhbnNwb3J0Q29uZmlnQmFzZSB7XG4gICAgLyoqXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAqIEBwYXJhbSB7Q3VzdG9tVHJhbnNwb3J0fSBjdXN0b21UcmFuc3BvcnQgLSBBbiBpbnN0YW5jZSBvZiBhIGN1c3RvbSB0cmFuc3BvcnRcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChjdXN0b21UcmFuc3BvcnQpIHtcbiAgICAgICAgc3VwZXIoVHJhbnNwb3J0VHlwZS5DVVNUT00pO1xuICAgICAgICB0aGlzLl9jdXN0b21UcmFuc3BvcnQgPSBjdXN0b21UcmFuc3BvcnQ7XG4gICAgfVxuXG4gICAgZ2V0VHJhbnNwb3J0VHlwZSAoKSB7XG4gICAgICAgIHJldHVybiBUcmFuc3BvcnRUeXBlLkNVU1RPTTtcbiAgICB9XG5cbiAgICBnZXRUcmFuc3BvcnQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY3VzdG9tVHJhbnNwb3J0O1xuICAgIH1cbn1cblxuZXhwb3J0IHsgQ3VzdG9tVHJhbnNwb3J0Q29uZmlnIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFRyYW5zcG9ydFR5cGUgfSBmcm9tICcuL2VudW1zL1RyYW5zcG9ydFR5cGUuanMnO1xuaW1wb3J0IHsgVHJhbnNwb3J0Q29uZmlnQmFzZSB9IGZyb20gJy4vVHJhbnNwb3J0Q29uZmlnQmFzZS5qcyc7XG5cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBUcmFuc3BvcnRDb25maWdCYXNlXG4gKiBAcHJvcGVydHkge1RyYW5zcG9ydFR5cGV9IF90cmFuc3BvcnRUeXBlXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBnZXRUcmFuc3BvcnRUeXBlXG4gKi9cbmNsYXNzIFdlYlNvY2tldENsaWVudENvbmZpZyBleHRlbmRzIFRyYW5zcG9ydENvbmZpZ0Jhc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7VHJhbnNwb3J0VHlwZX0gdHJhbnNwb3J0VHlwZSAtIGVudW1cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoaG9zdCwgcG9ydCkge1xuICAgICAgICBzdXBlcihUcmFuc3BvcnRUeXBlLldFQlNPQ0tFVF9DTElFTlQpO1xuXG4gICAgICAgIHRoaXMuX2hvc3QgPSBob3N0O1xuICAgICAgICB0aGlzLl9wb3J0ID0gcG9ydDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIFN0cmluZ1xuICAgICAqL1xuICAgIGdldEhvc3QgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faG9zdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIE51bWJlclxuICAgICAqL1xuICAgIGdldFBvcnQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcG9ydDtcbiAgICB9XG59XG5cbmV4cG9ydCB7IFdlYlNvY2tldENsaWVudENvbmZpZyB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5jbGFzcyBUcmFuc3BvcnRSZWNvcmQge1xuICAgIC8qKlxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKiBAcGFyYW0ge1RyYW5zcG9ydFR5cGV9IHRyYW5zcG9ydFR5cGUgLSBUaGUgdHlwZSBvZiB0aGUgdHJhbnNwb3J0XG4gICAgKiBAcGFyYW0ge1N0cmluZ30gYWRkcmVzc1xuICAgICovXG4gICAgY29uc3RydWN0b3IgKHRyYW5zcG9ydFR5cGUsIGFkZHJlc3MpIHtcbiAgICAgICAgdGhpcy5fdHlwZSA9IHRyYW5zcG9ydFR5cGU7XG4gICAgICAgIHRoaXMuX2FkZHJlc3MgPSBhZGRyZXNzO1xuICAgIH1cblxuICAgIGdldFR5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHlwZTtcbiAgICB9XG5cbiAgICBnZXRBZGRyZXNzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZHJlc3M7XG4gICAgfVxuXG4gICAgZXF1YWxzIChvYmopIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIG9iaiBpbnN0YW5jZW9mIFRyYW5zcG9ydFJlY29yZFxuICAgICAgICAgICAgJiYgb2JqLmdldFR5cGUgIT09IG51bGxcbiAgICAgICAgICAgICYmIG9iai5nZXRUeXBlKCkgPT09IHRoaXMuZ2V0VHlwZSgpXG4gICAgICAgICAgICAmJiBvYmouZ2V0QWRkcmVzcygpID09PSB0aGlzLmdldEFkZHJlc3MoKVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHRvU3RyaW5nICgpIHtcbiAgICAgICAgcmV0dXJuIGBUcmFuc3BvcnQgVHlwZTogJHt0aGlzLl90eXBlLm5hbWUoKX0gXFxuIEFkZHJlc3M6ICR7dGhpcy5fYWRkcmVzc31gO1xuICAgIH1cbn1cblxuZXhwb3J0IHsgVHJhbnNwb3J0UmVjb3JkIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmNvbnN0IHsgVHJhbnNwb3J0Q29uZmlnQmFzZSB9ID0gcmVxdWlyZSgnLi9UcmFuc3BvcnRDb25maWdCYXNlLmpzJyk7XG5jb25zdCB7IFRyYW5zcG9ydFR5cGUgfSA9IHJlcXVpcmUoJy4vZW51bXMvVHJhbnNwb3J0VHlwZS5qcycpO1xuXG5jbGFzcyBXZWJTb2NrZXRTZXJ2ZXJDb25maWcgZXh0ZW5kcyBUcmFuc3BvcnRDb25maWdCYXNlIHtcbiAgICAvKipcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICogQHBhcmFtIHtOdW1iZXJ9IHBvcnQgLSBUaGUgcG9ydCB0byBsaXN0ZW4gZm9yIFdlYlNvY2tldCBjb25uZWN0aW9ucyBvbi5cbiAgICAqIEBwYXJhbSB7TnVtYmVyfSBjb25uZWN0aW9uTG9zdFRpbWVvdXQgLSBUaGUgdGltZW91dCBmb3IgYSBjb25uZWN0aW9uIGxvc3QsIHJlcHJlc2VudGVkIGluIG1pbGxpc2Vjb25kcy4gRGVmYXVsdCA2MDAwMC4gSWYgYSB2YWx1ZSBsZXNzIHRoYW4gMCBpcyB1c2VkLCB0aGVuIHRoZSB3ZWJzb2NrZXQgd2lsbCB3YWl0IGluZGVmaW5pdGVseS5cbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwb3J0ID0gMzAwMCwgY29ubmVjdGlvbkxvc3RUaW1lb3V0ID0gNjAwMDAsIHNzbENvbmZpZyA9IG51bGwpIHtcbiAgICAgICAgc3VwZXIoVHJhbnNwb3J0VHlwZS5XRUJTT0NLRVRfU0VSVkVSKTtcbiAgICAgICAgdGhpcy5fcG9ydCA9IHBvcnQ7XG4gICAgICAgIHRoaXMuX2Nvbm5lY3Rpb25Mb3N0VGltZW91dCA9IGNvbm5lY3Rpb25Mb3N0VGltZW91dDtcbiAgICAgICAgdGhpcy5fc3NsQ29uZmlnID0gc3NsQ29uZmlnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogUmV0dXJucyB0aGUgd2Vic29ja2V0IGxpc3RlbmVyIHBvcnRcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIGdldFBvcnQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcG9ydDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIFJldHVybnMgdGhlIHdlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QgdGltZW91dCB2YWx1ZSBpbiBtaWxsaXNlY29uZHNcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIGdldENvbm5lY3Rpb25Mb3N0VGltZW91dCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb25uZWN0aW9uTG9zdFRpbWVvdXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBSZXR1cm5zIHRoZSBTU0wgY29uZmlndXJhdGlvblxuICAgICogQHJldHVybiB7U3NsQ29uZmlnfVxuICAgICovXG4gICAgZ2V0U3NsQ29uZmlnICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NzbENvbmZpZztcbiAgICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAgIFdlYlNvY2tldFNlcnZlckNvbmZpZyxcbn07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEFwcENvbmZpZyB9IGZyb20gJy4vdG1wL21hbmFnZXIvQXBwQ29uZmlnLmpzJztcbmltcG9ydCB7IExpZmVjeWNsZUxpc3RlbmVyIH0gZnJvbSAnLi90bXAvbWFuYWdlci9saWZlY3ljbGUvTGlmZWN5Y2xlTGlzdGVuZXIuanMnO1xuaW1wb3J0IHsgTGlmZWN5Y2xlTWFuYWdlciB9IGZyb20gJy4vdG1wL21hbmFnZXIvbGlmZWN5Y2xlL0xpZmVjeWNsZU1hbmFnZXIuanMnO1xuaW1wb3J0IHsgQmluYXJ5RnJhbWVIZWFkZXIgfSBmcm9tICcuL3RtcC9wcm90b2NvbC9CaW5hcnlGcmFtZUhlYWRlci5qcyc7XG5pbXBvcnQgeyBNZXNzYWdlRnJhbWVBc3NlbWJsZXIgfSBmcm9tICcuL3RtcC9wcm90b2NvbC9NZXNzYWdlRnJhbWVBc3NlbWJsZXIuanMnO1xuaW1wb3J0IHsgTWVzc2FnZUZyYW1lRGlzYXNzZW1ibGVyIH0gZnJvbSAnLi90bXAvcHJvdG9jb2wvTWVzc2FnZUZyYW1lRGlzYXNzZW1ibGVyLmpzJztcbmltcG9ydCB7IFNkbFBhY2tldCB9IGZyb20gJy4vdG1wL3Byb3RvY29sL1NkbFBhY2tldC5qcyc7XG5pbXBvcnQgeyBTZGxQYWNrZXRGYWN0b3J5IH0gZnJvbSAnLi90bXAvcHJvdG9jb2wvU2RsUGFja2V0RmFjdG9yeS5qcyc7XG5pbXBvcnQgeyBTZGxQcm90b2NvbCB9IGZyb20gJy4vdG1wL3Byb3RvY29sL1NkbFByb3RvY29sLmpzJztcbmltcG9ydCB7IFNkbFByb3RvY29sQmFzZSB9IGZyb20gJy4vdG1wL3Byb3RvY29sL1NkbFByb3RvY29sQmFzZS5qcyc7XG5pbXBvcnQgeyBTZGxQcm90b2NvbExpc3RlbmVyIH0gZnJvbSAnLi90bXAvcHJvdG9jb2wvU2RsUHJvdG9jb2xMaXN0ZW5lci5qcyc7XG5pbXBvcnQgeyBDb250cm9sRnJhbWVUYWdzIH0gZnJvbSAnLi90bXAvcHJvdG9jb2wvZW51bXMvQ29udHJvbEZyYW1lVGFncy5qcyc7XG5pbXBvcnQgeyBGcmFtZVR5cGUgfSBmcm9tICcuL3RtcC9wcm90b2NvbC9lbnVtcy9GcmFtZVR5cGUuanMnO1xuaW1wb3J0IHsgU2VydmljZVR5cGUgfSBmcm9tICcuL3RtcC9wcm90b2NvbC9lbnVtcy9TZXJ2aWNlVHlwZS5qcyc7XG5pbXBvcnQgeyBScGNDcmVhdG9yIH0gZnJvbSAnLi90bXAvcnBjL1JwY0NyZWF0b3IuanMnO1xuaW1wb3J0IHsgUnBjTGlzdGVuZXIgfSBmcm9tICcuL3RtcC9ycGMvUnBjTGlzdGVuZXIuanMnO1xuaW1wb3J0IHsgUnBjTWVzc2FnZSB9IGZyb20gJy4vdG1wL3JwYy9ScGNNZXNzYWdlLmpzJztcbmltcG9ydCB7IFJwY05vdGlmaWNhdGlvbiB9IGZyb20gJy4vdG1wL3JwYy9ScGNOb3RpZmljYXRpb24uanMnO1xuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4vdG1wL3JwYy9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL1JwY1Jlc3BvbnNlLmpzJztcbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4vdG1wL3JwYy9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgQXBwSE1JVHlwZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9BcHBITUlUeXBlLmpzJztcbmltcG9ydCB7IEF1ZGlvU3RyZWFtaW5nU3RhdGUgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvQXVkaW9TdHJlYW1pbmdTdGF0ZS5qcyc7XG5pbXBvcnQgeyBBdWRpb1R5cGUgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvQXVkaW9UeXBlLmpzJztcbmltcG9ydCB7IEJpdHNQZXJTYW1wbGUgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvQml0c1BlclNhbXBsZS5qcyc7XG5pbXBvcnQgeyBCdXR0b25OYW1lIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL0J1dHRvbk5hbWUuanMnO1xuaW1wb3J0IHsgQ2hhcmFjdGVyU2V0IH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL0NoYXJhY3RlclNldC5qcyc7XG5pbXBvcnQgeyBEaXNwbGF5VHlwZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9EaXNwbGF5VHlwZS5qcyc7XG5pbXBvcnQgeyBGaWxlVHlwZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9GaWxlVHlwZS5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgSE1JTGV2ZWwgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvSE1JTGV2ZWwuanMnO1xuaW1wb3J0IHsgSG1pWm9uZUNhcGFiaWxpdGllcyB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9IbWlab25lQ2FwYWJpbGl0aWVzLmpzJztcbmltcG9ydCB7IEltYWdlRmllbGROYW1lIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL0ltYWdlRmllbGROYW1lLmpzJztcbmltcG9ydCB7IEltYWdlVHlwZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9JbWFnZVR5cGUuanMnO1xuaW1wb3J0IHsgTGFuZ3VhZ2UgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvTGFuZ3VhZ2UuanMnO1xuaW1wb3J0IHsgTWVkaWFDbG9ja0Zvcm1hdCB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9NZWRpYUNsb2NrRm9ybWF0LmpzJztcbmltcG9ydCB7IE1ldGFkYXRhVHlwZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9NZXRhZGF0YVR5cGUuanMnO1xuaW1wb3J0IHsgUHJlcmVjb3JkZWRTcGVlY2ggfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvUHJlcmVjb3JkZWRTcGVlY2guanMnO1xuaW1wb3J0IHsgUmVzdWx0IH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL1Jlc3VsdC5qcyc7XG5pbXBvcnQgeyBScGNUeXBlIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL1JwY1R5cGUuanMnO1xuaW1wb3J0IHsgU2FtcGxpbmdSYXRlIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL1NhbXBsaW5nUmF0ZS5qcyc7XG5pbXBvcnQgeyBTb2Z0QnV0dG9uVHlwZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9Tb2Z0QnV0dG9uVHlwZS5qcyc7XG5pbXBvcnQgeyBTcGVlY2hDYXBhYmlsaXRpZXMgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvU3BlZWNoQ2FwYWJpbGl0aWVzLmpzJztcbmltcG9ydCB7IFN5c3RlbUFjdGlvbiB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9TeXN0ZW1BY3Rpb24uanMnO1xuaW1wb3J0IHsgU3lzdGVtQ29udGV4dCB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9TeXN0ZW1Db250ZXh0LmpzJztcbmltcG9ydCB7IFRleHRBbGlnbm1lbnQgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvVGV4dEFsaWdubWVudC5qcyc7XG5pbXBvcnQgeyBUZXh0RmllbGROYW1lIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL1RleHRGaWVsZE5hbWUuanMnO1xuaW1wb3J0IHsgVmlkZW9TdHJlYW1pbmdDb2RlYyB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9WaWRlb1N0cmVhbWluZ0NvZGVjLmpzJztcbmltcG9ydCB7IFZpZGVvU3RyZWFtaW5nUHJvdG9jb2wgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvVmlkZW9TdHJlYW1pbmdQcm90b2NvbC5qcyc7XG5pbXBvcnQgeyBWaWRlb1N0cmVhbWluZ1N0YXRlIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL1ZpZGVvU3RyZWFtaW5nU3RhdGUuanMnO1xuaW1wb3J0IHsgVnJDYXBhYmlsaXRpZXMgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvVnJDYXBhYmlsaXRpZXMuanMnO1xuaW1wb3J0IHsgQWRkQ29tbWFuZCB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9BZGRDb21tYW5kLmpzJztcbmltcG9ydCB7IEFkZENvbW1hbmRSZXNwb25zZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9BZGRDb21tYW5kUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgT25IbWlTdGF0dXMgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvT25IbWlTdGF0dXMuanMnO1xuaW1wb3J0IHsgT25MYW5ndWFnZUNoYW5nZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9Pbkxhbmd1YWdlQ2hhbmdlLmpzJztcbmltcG9ydCB7IFB1dEZpbGUgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvUHV0RmlsZS5qcyc7XG5pbXBvcnQgeyBQdXRGaWxlUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvUHV0RmlsZVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFJlZ2lzdGVyQXBwSW50ZXJmYWNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1JlZ2lzdGVyQXBwSW50ZXJmYWNlLmpzJztcbmltcG9ydCB7IFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBTZXRBcHBJY29uIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1NldEFwcEljb24uanMnO1xuaW1wb3J0IHsgU2V0QXBwSWNvblJlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1NldEFwcEljb25SZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBTaG93IH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1Nob3cuanMnO1xuaW1wb3J0IHsgU2hvd1Jlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1Nob3dSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBVbnJlZ2lzdGVyQXBwSW50ZXJmYWNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1VucmVnaXN0ZXJBcHBJbnRlcmZhY2UuanMnO1xuaW1wb3J0IHsgVW5yZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1VucmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBBcHBJbmZvIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvQXBwSW5mby5qcyc7XG5pbXBvcnQgeyBBdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvQXVkaW9QYXNzVGhydUNhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBCdXR0b25DYXBhYmlsaXRpZXMgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9CdXR0b25DYXBhYmlsaXRpZXMuanMnO1xuaW1wb3J0IHsgRGV2aWNlSW5mbyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0RldmljZUluZm8uanMnO1xuaW1wb3J0IHsgRGlzcGxheUNhcGFiaWxpdGllcyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0Rpc3BsYXlDYXBhYmlsaXRpZXMuanMnO1xuaW1wb3J0IHsgR3JpZCB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0dyaWQuanMnO1xuaW1wb3J0IHsgSE1JQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvSE1JQ2FwYWJpbGl0aWVzLmpzJztcbmltcG9ydCB7IEltYWdlIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvSW1hZ2UuanMnO1xuaW1wb3J0IHsgSW1hZ2VGaWVsZCB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0ltYWdlRmllbGQuanMnO1xuaW1wb3J0IHsgSW1hZ2VSZXNvbHV0aW9uIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvSW1hZ2VSZXNvbHV0aW9uLmpzJztcbmltcG9ydCB7IE1lbnVQYXJhbXMgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9NZW51UGFyYW1zLmpzJztcbmltcG9ydCB7IE1ldGFkYXRhVGFncyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL01ldGFkYXRhVGFncy5qcyc7XG5pbXBvcnQgeyBNb2R1bGVJbmZvIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvTW9kdWxlSW5mby5qcyc7XG5pbXBvcnQgeyBQcmVzZXRCYW5rQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvUHJlc2V0QmFua0NhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBSR0JDb2xvciB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1JHQkNvbG9yLmpzJztcbmltcG9ydCB7IFNjcmVlblBhcmFtcyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1NjcmVlblBhcmFtcy5qcyc7XG5pbXBvcnQgeyBTZGxNc2dWZXJzaW9uIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvU2RsTXNnVmVyc2lvbi5qcyc7XG5pbXBvcnQgeyBTb2Z0QnV0dG9uIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvU29mdEJ1dHRvbi5qcyc7XG5pbXBvcnQgeyBTb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvU29mdEJ1dHRvbkNhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBUVFNDaHVuayB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1RUU0NodW5rLmpzJztcbmltcG9ydCB7IFRlbXBsYXRlQ29sb3JTY2hlbWUgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9UZW1wbGF0ZUNvbG9yU2NoZW1lLmpzJztcbmltcG9ydCB7IFRleHRGaWVsZCB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1RleHRGaWVsZC5qcyc7XG5pbXBvcnQgeyBUb3VjaEV2ZW50Q2FwYWJpbGl0aWVzIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvVG91Y2hFdmVudENhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBWZWhpY2xlVHlwZSB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1ZlaGljbGVUeXBlLmpzJztcbmltcG9ydCB7IFZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eSB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1ZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eS5qcyc7XG5pbXBvcnQgeyBWaWRlb1N0cmVhbWluZ0Zvcm1hdCB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1ZpZGVvU3RyZWFtaW5nRm9ybWF0LmpzJztcbmltcG9ydCB7IFNkbFNlcnZpY2VMaXN0ZW5lciB9IGZyb20gJy4vdG1wL3Nlc3Npb24vU2RsU2VydmljZUxpc3RlbmVyLmpzJztcbmltcG9ydCB7IFNkbFNlc3Npb24gfSBmcm9tICcuL3RtcC9zZXNzaW9uL1NkbFNlc3Npb24uanMnO1xuaW1wb3J0IHsgU2RsU2Vzc2lvbkxpc3RlbmVyIH0gZnJvbSAnLi90bXAvc2Vzc2lvbi9TZGxTZXNzaW9uTGlzdGVuZXIuanMnO1xuaW1wb3J0IHsgU2VydmljZUxpc3RlbmVyTWFwIH0gZnJvbSAnLi90bXAvc2Vzc2lvbi9TZXJ2aWNlTGlzdGVuZXJNYXAuanMnO1xuaW1wb3J0IHsgVmlkZW9TdHJlYW1pbmdQYXJhbWV0ZXJzIH0gZnJvbSAnLi90bXAvc3RyZWFtaW5nL3ZpZGVvL1ZpZGVvU3RyZWFtaW5nUGFyYW1ldGVycy5qcyc7XG5pbXBvcnQgeyBDdXN0b21UcmFuc3BvcnQgfSBmcm9tICcuL3RtcC90cmFuc3BvcnQvQ3VzdG9tVHJhbnNwb3J0LmpzJztcbmltcG9ydCB7IEN1c3RvbVRyYW5zcG9ydENvbmZpZyB9IGZyb20gJy4vdG1wL3RyYW5zcG9ydC9DdXN0b21UcmFuc3BvcnRDb25maWcuanMnO1xuaW1wb3J0IHsgU2RsUHNtIH0gZnJvbSAnLi90bXAvdHJhbnNwb3J0L1NkbFBzbS5qcyc7XG5pbXBvcnQgeyBTc2xDb25maWcgfSBmcm9tICcuL3RtcC90cmFuc3BvcnQvU3NsQ29uZmlnLmpzJztcbmltcG9ydCB7IFRyYW5zcG9ydEJhc2UgfSBmcm9tICcuL3RtcC90cmFuc3BvcnQvVHJhbnNwb3J0QmFzZS5qcyc7XG5pbXBvcnQgeyBUcmFuc3BvcnRDYWxsYmFjayB9IGZyb20gJy4vdG1wL3RyYW5zcG9ydC9UcmFuc3BvcnRDYWxsYmFjay5qcyc7XG5pbXBvcnQgeyBUcmFuc3BvcnRDb25maWdCYXNlIH0gZnJvbSAnLi90bXAvdHJhbnNwb3J0L1RyYW5zcG9ydENvbmZpZ0Jhc2UuanMnO1xuaW1wb3J0IHsgVHJhbnNwb3J0TGlzdGVuZXIgfSBmcm9tICcuL3RtcC90cmFuc3BvcnQvVHJhbnNwb3J0TGlzdGVuZXIuanMnO1xuaW1wb3J0IHsgVHJhbnNwb3J0TWFuYWdlciB9IGZyb20gJy4vdG1wL3RyYW5zcG9ydC9UcmFuc3BvcnRNYW5hZ2VyLmpzJztcbmltcG9ydCB7IFRyYW5zcG9ydE1hbmFnZXJCYXNlIH0gZnJvbSAnLi90bXAvdHJhbnNwb3J0L1RyYW5zcG9ydE1hbmFnZXJCYXNlLmpzJztcbmltcG9ydCB7IFdlYlNvY2tldENsaWVudCB9IGZyb20gJy4vdG1wL3RyYW5zcG9ydC9XZWJTb2NrZXRDbGllbnQuanMnO1xuaW1wb3J0IHsgV2ViU29ja2V0Q2xpZW50Q29uZmlnIH0gZnJvbSAnLi90bXAvdHJhbnNwb3J0L1dlYlNvY2tldENsaWVudENvbmZpZy5qcyc7XG5pbXBvcnQgeyBUcmFuc3BvcnRUeXBlIH0gZnJvbSAnLi90bXAvdHJhbnNwb3J0L2VudW1zL1RyYW5zcG9ydFR5cGUuanMnO1xuaW1wb3J0IHsgVHJhbnNwb3J0UmVjb3JkIH0gZnJvbSAnLi90bXAvdHJhbnNwb3J0L3V0aWwvVHJhbnNwb3J0UmVjb3JkLmpzJztcbmltcG9ydCB7IEFycmF5VG9vbHMgfSBmcm9tICcuL3RtcC91dGlsL0FycmF5VG9vbHMuanMnO1xuaW1wb3J0IHsgQml0Q29udmVydGVyIH0gZnJvbSAnLi90bXAvdXRpbC9CaXRDb252ZXJ0ZXIuanMnO1xuaW1wb3J0IHsgQnNvbiB9IGZyb20gJy4vdG1wL3V0aWwvQnNvbi5qcyc7XG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi90bXAvdXRpbC9FbnVtLmpzJztcbmltcG9ydCB7IEpzb25ScGNNYXJzaGFsbGVyIH0gZnJvbSAnLi90bXAvdXRpbC9Kc29uUnBjTWFyc2hhbGxlci5qcyc7XG5pbXBvcnQgeyBUZXh0RW5jb2RlciB9IGZyb20gJy4vdG1wL3V0aWwvVGV4dEVuY29kZXIuanMnO1xuaW1wb3J0IHsgVmVyc2lvbiB9IGZyb20gJy4vdG1wL3V0aWwvVmVyc2lvbi5qcyc7XG5pbXBvcnQgeyBXZWJTb2NrZXRTZXJ2ZXIgfSBmcm9tICcuL3RtcC90cmFuc3BvcnQvV2ViU29ja2V0U2VydmVyLmpzJztcbmltcG9ydCB7IFdlYlNvY2tldFNlcnZlckNvbmZpZyB9IGZyb20gJy4vdG1wL3RyYW5zcG9ydC9XZWJTb2NrZXRTZXJ2ZXJDb25maWcuanMnO1xuXG5jb25zdCBTREwgPSB7XG4gICAgbWFuYWdlcjoge1xuICAgICAgICBBcHBDb25maWcsXG4gICAgICAgIGxpZmVjeWNsZToge1xuICAgICAgICAgICAgTGlmZWN5Y2xlTGlzdGVuZXIsXG4gICAgICAgICAgICBMaWZlY3ljbGVNYW5hZ2VyLFxuICAgICAgICB9LFxuICAgIH0sXG4gICAgcHJvdG9jb2w6IHtcbiAgICAgICAgQmluYXJ5RnJhbWVIZWFkZXIsXG4gICAgICAgIE1lc3NhZ2VGcmFtZUFzc2VtYmxlcixcbiAgICAgICAgTWVzc2FnZUZyYW1lRGlzYXNzZW1ibGVyLFxuICAgICAgICBTZGxQYWNrZXQsXG4gICAgICAgIFNkbFBhY2tldEZhY3RvcnksXG4gICAgICAgIFNkbFByb3RvY29sLFxuICAgICAgICBTZGxQcm90b2NvbEJhc2UsXG4gICAgICAgIFNkbFByb3RvY29sTGlzdGVuZXIsXG4gICAgICAgIGVudW1zOiB7XG4gICAgICAgICAgICBDb250cm9sRnJhbWVUYWdzLFxuICAgICAgICAgICAgRnJhbWVUeXBlLFxuICAgICAgICAgICAgU2VydmljZVR5cGUsXG4gICAgICAgIH0sXG4gICAgfSxcbiAgICBycGM6IHtcbiAgICAgICAgUnBjQ3JlYXRvcixcbiAgICAgICAgUnBjTGlzdGVuZXIsXG4gICAgICAgIFJwY01lc3NhZ2UsXG4gICAgICAgIFJwY05vdGlmaWNhdGlvbixcbiAgICAgICAgUnBjUmVxdWVzdCxcbiAgICAgICAgUnBjUmVzcG9uc2UsXG4gICAgICAgIFJwY1N0cnVjdCxcbiAgICAgICAgZW51bXM6IHtcbiAgICAgICAgICAgIEFwcEhNSVR5cGUsXG4gICAgICAgICAgICBBdWRpb1N0cmVhbWluZ1N0YXRlLFxuICAgICAgICAgICAgQXVkaW9UeXBlLFxuICAgICAgICAgICAgQml0c1BlclNhbXBsZSxcbiAgICAgICAgICAgIEJ1dHRvbk5hbWUsXG4gICAgICAgICAgICBDaGFyYWN0ZXJTZXQsXG4gICAgICAgICAgICBEaXNwbGF5VHlwZSxcbiAgICAgICAgICAgIEZpbGVUeXBlLFxuICAgICAgICAgICAgRnVuY3Rpb25JRCxcbiAgICAgICAgICAgIEhNSUxldmVsLFxuICAgICAgICAgICAgSG1pWm9uZUNhcGFiaWxpdGllcyxcbiAgICAgICAgICAgIEltYWdlRmllbGROYW1lLFxuICAgICAgICAgICAgSW1hZ2VUeXBlLFxuICAgICAgICAgICAgTGFuZ3VhZ2UsXG4gICAgICAgICAgICBNZWRpYUNsb2NrRm9ybWF0LFxuICAgICAgICAgICAgTWV0YWRhdGFUeXBlLFxuICAgICAgICAgICAgUHJlcmVjb3JkZWRTcGVlY2gsXG4gICAgICAgICAgICBSZXN1bHQsXG4gICAgICAgICAgICBScGNUeXBlLFxuICAgICAgICAgICAgU2FtcGxpbmdSYXRlLFxuICAgICAgICAgICAgU29mdEJ1dHRvblR5cGUsXG4gICAgICAgICAgICBTcGVlY2hDYXBhYmlsaXRpZXMsXG4gICAgICAgICAgICBTeXN0ZW1BY3Rpb24sXG4gICAgICAgICAgICBTeXN0ZW1Db250ZXh0LFxuICAgICAgICAgICAgVGV4dEFsaWdubWVudCxcbiAgICAgICAgICAgIFRleHRGaWVsZE5hbWUsXG4gICAgICAgICAgICBWaWRlb1N0cmVhbWluZ0NvZGVjLFxuICAgICAgICAgICAgVmlkZW9TdHJlYW1pbmdQcm90b2NvbCxcbiAgICAgICAgICAgIFZpZGVvU3RyZWFtaW5nU3RhdGUsXG4gICAgICAgICAgICBWckNhcGFiaWxpdGllcyxcbiAgICAgICAgfSxcbiAgICAgICAgbWVzc2FnZXM6IHtcbiAgICAgICAgICAgIEFkZENvbW1hbmQsXG4gICAgICAgICAgICBBZGRDb21tYW5kUmVzcG9uc2UsXG4gICAgICAgICAgICBPbkhtaVN0YXR1cyxcbiAgICAgICAgICAgIE9uTGFuZ3VhZ2VDaGFuZ2UsXG4gICAgICAgICAgICBQdXRGaWxlLFxuICAgICAgICAgICAgUHV0RmlsZVJlc3BvbnNlLFxuICAgICAgICAgICAgUmVnaXN0ZXJBcHBJbnRlcmZhY2UsXG4gICAgICAgICAgICBSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLFxuICAgICAgICAgICAgU2V0QXBwSWNvbixcbiAgICAgICAgICAgIFNldEFwcEljb25SZXNwb25zZSxcbiAgICAgICAgICAgIFNob3csXG4gICAgICAgICAgICBTaG93UmVzcG9uc2UsXG4gICAgICAgICAgICBVbnJlZ2lzdGVyQXBwSW50ZXJmYWNlLFxuICAgICAgICAgICAgVW5yZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLFxuICAgICAgICB9LFxuICAgICAgICBzdHJ1Y3RzOiB7XG4gICAgICAgICAgICBBcHBJbmZvLFxuICAgICAgICAgICAgQXVkaW9QYXNzVGhydUNhcGFiaWxpdGllcyxcbiAgICAgICAgICAgIEJ1dHRvbkNhcGFiaWxpdGllcyxcbiAgICAgICAgICAgIERldmljZUluZm8sXG4gICAgICAgICAgICBEaXNwbGF5Q2FwYWJpbGl0aWVzLFxuICAgICAgICAgICAgR3JpZCxcbiAgICAgICAgICAgIEhNSUNhcGFiaWxpdGllcyxcbiAgICAgICAgICAgIEltYWdlLFxuICAgICAgICAgICAgSW1hZ2VGaWVsZCxcbiAgICAgICAgICAgIEltYWdlUmVzb2x1dGlvbixcbiAgICAgICAgICAgIE1lbnVQYXJhbXMsXG4gICAgICAgICAgICBNZXRhZGF0YVRhZ3MsXG4gICAgICAgICAgICBNb2R1bGVJbmZvLFxuICAgICAgICAgICAgUHJlc2V0QmFua0NhcGFiaWxpdGllcyxcbiAgICAgICAgICAgIFJHQkNvbG9yLFxuICAgICAgICAgICAgU2NyZWVuUGFyYW1zLFxuICAgICAgICAgICAgU2RsTXNnVmVyc2lvbixcbiAgICAgICAgICAgIFNvZnRCdXR0b24sXG4gICAgICAgICAgICBTb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzLFxuICAgICAgICAgICAgVFRTQ2h1bmssXG4gICAgICAgICAgICBUZW1wbGF0ZUNvbG9yU2NoZW1lLFxuICAgICAgICAgICAgVGV4dEZpZWxkLFxuICAgICAgICAgICAgVG91Y2hFdmVudENhcGFiaWxpdGllcyxcbiAgICAgICAgICAgIFZlaGljbGVUeXBlLFxuICAgICAgICAgICAgVmlkZW9TdHJlYW1pbmdDYXBhYmlsaXR5LFxuICAgICAgICAgICAgVmlkZW9TdHJlYW1pbmdGb3JtYXQsXG4gICAgICAgIH0sXG4gICAgfSxcbiAgICBzZXNzaW9uOiB7XG4gICAgICAgIFNkbFNlcnZpY2VMaXN0ZW5lcixcbiAgICAgICAgU2RsU2Vzc2lvbixcbiAgICAgICAgU2RsU2Vzc2lvbkxpc3RlbmVyLFxuICAgICAgICBTZXJ2aWNlTGlzdGVuZXJNYXAsXG4gICAgfSxcbiAgICBzdHJlYW1pbmc6IHtcbiAgICAgICAgdmlkZW86IHtcbiAgICAgICAgICAgIFZpZGVvU3RyZWFtaW5nUGFyYW1ldGVycyxcbiAgICAgICAgfSxcbiAgICB9LFxuICAgIHRyYW5zcG9ydDoge1xuICAgICAgICBDdXN0b21UcmFuc3BvcnQsXG4gICAgICAgIEN1c3RvbVRyYW5zcG9ydENvbmZpZyxcbiAgICAgICAgU2RsUHNtLFxuICAgICAgICBTc2xDb25maWcsXG4gICAgICAgIFRyYW5zcG9ydEJhc2UsXG4gICAgICAgIFRyYW5zcG9ydENhbGxiYWNrLFxuICAgICAgICBUcmFuc3BvcnRDb25maWdCYXNlLFxuICAgICAgICBUcmFuc3BvcnRMaXN0ZW5lcixcbiAgICAgICAgVHJhbnNwb3J0TWFuYWdlcixcbiAgICAgICAgVHJhbnNwb3J0TWFuYWdlckJhc2UsXG4gICAgICAgIFdlYlNvY2tldENsaWVudCxcbiAgICAgICAgV2ViU29ja2V0Q2xpZW50Q29uZmlnLFxuICAgICAgICBlbnVtczoge1xuICAgICAgICAgICAgVHJhbnNwb3J0VHlwZSxcbiAgICAgICAgfSxcbiAgICAgICAgdXRpbDoge1xuICAgICAgICAgICAgVHJhbnNwb3J0UmVjb3JkLFxuICAgICAgICB9LFxuICAgICAgICBXZWJTb2NrZXRTZXJ2ZXIsXG4gICAgICAgIFdlYlNvY2tldFNlcnZlckNvbmZpZyxcbiAgICB9LFxuICAgIHV0aWw6IHtcbiAgICAgICAgQXJyYXlUb29scyxcbiAgICAgICAgQml0Q29udmVydGVyLFxuICAgICAgICBCc29uLFxuICAgICAgICBFbnVtLFxuICAgICAgICBKc29uUnBjTWFyc2hhbGxlcixcbiAgICAgICAgVGV4dEVuY29kZXIsXG4gICAgICAgIFZlcnNpb24sXG4gICAgfSxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFNETDsiXSwibmFtZXMiOlsiQXBwQ29uZmlnIiwiY29uc3RydWN0b3IiLCJfdHJhbnNwb3J0Q29uZmlnIiwiX2FwcElkIiwiX2FwcE5hbWUiLCJfaWNvbk5hbWUiLCJfaWNvbkZpbGUiLCJfc2hvcnRBcHBOYW1lIiwiX3R0c05hbWUiLCJfdnJTeW5vbnltcyIsIl9pc01lZGlhQXBwIiwiX2xhbmd1YWdlRGVzaXJlZCIsIl9obWlEaXNwbGF5TGFuZ3VhZ2VEZXNpcmVkIiwiX2FwcFR5cGVzIiwiX2RheUNvbG9yU2NoZW1lIiwiX25pZ2h0Q29sb3JTY2hlbWUiLCJfbWluaW11bVJQQ1ZlcnNpb24iLCJfbWluaW11bVByb3RvY29sVmVyc2lvbiIsInNldFRyYW5zcG9ydENvbmZpZyIsInRyYW5zcG9ydENvbmZpZyIsImdldFRyYW5zcG9ydENvbmZpZyIsInNldEFwcElkIiwiYXBwSWQiLCJnZXRBcHBJZCIsInNldEFwcE5hbWUiLCJhcHBOYW1lIiwiZ2V0QXBwTmFtZSIsInNldEFwcEljb24iLCJpY29uTmFtZSIsImZpbGVEYXRhIiwiZ2V0QXBwSWNvbk5hbWUiLCJnZXRBcHBJY29uRmlsZURhdGEiLCJzZXRTaG9ydEFwcE5hbWUiLCJzaG9ydEFwcE5hbWUiLCJnZXRTaG9ydEFwcE5hbWUiLCJzZXRUdHNOYW1lIiwidHRzTmFtZSIsImdldFR0c05hbWUiLCJzZXRWclN5bm9ueW1zIiwidnJTeW5vbnltcyIsImdldFZyU3lub255bXMiLCJzZXRJc01lZGlhQXBwIiwiaXNNZWRpYUFwcCIsInNldExhbmd1YWdlRGVzaXJlZCIsImxhbmd1YWdlRGVzaXJlZCIsImdldExhbmd1YWdlRGVzaXJlZCIsInNldEhtaURpc3BsYXlMYW5ndWFnZURlc2lyZWQiLCJobWlEaXNwbGF5TGFuZ3VhZ2VEZXNpcmVkIiwiZ2V0SG1pRGlzcGxheUxhbmd1YWdlRGVzaXJlZCIsInNldEFwcFR5cGVzIiwiYXBwVHlwZXMiLCJnZXRBcHBUeXBlcyIsInNldERheUNvbG9yU2NoZW1lIiwiZGF5Q29sb3JTY2hlbWUiLCJnZXREYXlDb2xvclNjaGVtZSIsInNldE5pZ2h0Q29sb3JTY2hlbWUiLCJuaWdodENvbG9yU2NoZW1lIiwiZ2V0TmlnaHRDb2xvclNjaGVtZSIsInNldE1pbmltdW1SUENWZXJzaW9uIiwibWluaW11bVJQQ1ZlcnNpb24iLCJnZXRNaW5pbXVtUlBDVmVyc2lvbiIsInNldE1pbmltdW1Qcm90b2NvbFZlcnNpb24iLCJtaW5pbXVtUHJvdG9jb2xWZXJzaW9uIiwiZ2V0TWluaW11bVByb3RvY29sVmVyc2lvbiIsIkxpZmVjeWNsZUxpc3RlbmVyIiwiX29uUHJveHlDb25uZWN0ZWQiLCJfb25Qcm94eUNsb3NlZCIsIl9vblNlcnZpY2VTdGFydGVkIiwiX29uU2VydmljZUVuZGVkIiwiX29uRXJyb3IiLCJzZXRPblByb3h5Q29ubmVjdGVkIiwibGlzdGVuZXIiLCJzZXRPblByb3h5Q2xvc2VkIiwic2V0T25TZXJ2aWNlU3RhcnRlZCIsInNldE9uU2VydmljZUVuZGVkIiwic2V0T25FcnJvciIsIm9uUHJveHlDb25uZWN0ZWQiLCJsaWZlY3ljbGVNYW5hZ2VyIiwib25Qcm94eUNsb3NlZCIsImluZm8iLCJyZWFzb24iLCJvblNlcnZpY2VTdGFydGVkIiwic2VydmljZVR5cGUiLCJzZXNzaW9uSUQiLCJjb3JyZWxhdGlvbklEIiwiX29uUHJvdG9jb2xTZXNzaW9uRW5kZWROQUNLZWQiLCJvblNlcnZpY2VFbmRlZCIsIm9uRXJyb3IiLCJFbnVtIiwiX2tleUZvclZhbHVlIiwidmFsdWUiLCJtYXAiLCJrZXkiLCJrZXlGb3JWYWx1ZSIsIkVycm9yIiwiX3ZhbHVlRm9yS2V5IiwidmFsdWVGb3JLZXkiLCJScGNTdHJ1Y3QiLCJwYXJhbWV0ZXJzIiwiX2lzRm9ybWF0UmVxdWVzdGVkIiwiX3JwY1NwZWNWZXJzaW9uIiwiX3BhcmFtZXRlcnMiLCJnZXRQYXJhbWV0ZXJzIiwiZ2V0UGFyYW1ldGVyIiwic2V0UGFyYW1ldGVyIiwiZ2V0T2JqZWN0IiwidENsYXNzIiwiZm9ybWF0T2JqZWN0Iiwib2JqIiwidW5kZWZpbmVkIiwiU3RyaW5nIiwiT2JqZWN0IiwicHJvdG90eXBlIiwiQXJyYXkiLCJsZW5ndGgiLCJvdXRBcnJheSIsIml0ZW0iLCJwdXNoIiwidmFsaWRhdGVUeXBlIiwiaXNBcnJheSIsIm5hbWUiLCJGdW5jdGlvbklEIiwiUmVnaXN0ZXJBcHBJbnRlcmZhY2UiLCJfTUFQIiwiVW5yZWdpc3RlckFwcEludGVyZmFjZSIsIlNldEdsb2JhbFByb3BlcnRpZXMiLCJSZXNldEdsb2JhbFByb3BlcnRpZXMiLCJBZGRDb21tYW5kIiwiRGVsZXRlQ29tbWFuZCIsIkFkZFN1Yk1lbnUiLCJEZWxldGVTdWJNZW51IiwiQ3JlYXRlSW50ZXJhY3Rpb25DaG9pY2VTZXQiLCJQZXJmb3JtSW50ZXJhY3Rpb24iLCJEZWxldGVJbnRlcmFjdGlvbkNob2ljZVNldCIsIkFsZXJ0IiwiU2hvdyIsIlNwZWFrIiwiU2V0TWVkaWFDbG9ja1RpbWVyIiwiUGVyZm9ybUF1ZGlvUGFzc1RocnUiLCJFbmRBdWRpb1Bhc3NUaHJ1IiwiU3Vic2NyaWJlQnV0dG9uIiwiVW5zdWJzY3JpYmVCdXR0b24iLCJTdWJzY3JpYmVWZWhpY2xlRGF0YSIsIlVuc3Vic2NyaWJlVmVoaWNsZURhdGEiLCJHZXRWZWhpY2xlRGF0YSIsIlJlYWRESUQiLCJHZXREVENzIiwiU2Nyb2xsYWJsZU1lc3NhZ2UiLCJTbGlkZXIiLCJTaG93Q29uc3RhbnRUQlQiLCJBbGVydE1hbmV1dmVyIiwiVXBkYXRlVHVybkxpc3QiLCJDaGFuZ2VSZWdpc3RyYXRpb24iLCJHZW5lcmljUmVzcG9uc2UiLCJQdXRGaWxlIiwiRGVsZXRlRmlsZSIsIkxpc3RGaWxlcyIsIlNldEFwcEljb24iLCJTZXREaXNwbGF5TGF5b3V0IiwiRGlhZ25vc3RpY01lc3NhZ2UiLCJTeXN0ZW1SZXF1ZXN0IiwiU2VuZExvY2F0aW9uIiwiRGlhbE51bWJlciIsIkJ1dHRvblByZXNzIiwiR2V0SW50ZXJpb3JWZWhpY2xlRGF0YSIsIlNldEludGVyaW9yVmVoaWNsZURhdGEiLCJHZXRXYXlQb2ludHMiLCJTdWJzY3JpYmVXYXlQb2ludHMiLCJVbnN1YnNjcmliZVdheVBvaW50cyIsIkdldFN5c3RlbUNhcGFiaWxpdHkiLCJTZW5kSGFwdGljRGF0YSIsIlNldENsb3VkQXBwUHJvcGVydGllcyIsIkdldENsb3VkQXBwUHJvcGVydGllcyIsIlB1Ymxpc2hBcHBTZXJ2aWNlIiwiR2V0QXBwU2VydmljZURhdGEiLCJHZXRGaWxlIiwiUGVyZm9ybUFwcFNlcnZpY2VJbnRlcmFjdGlvbiIsIlVucHVibGlzaEFwcFNlcnZpY2UiLCJDYW5jZWxJbnRlcmFjdGlvbiIsIkNsb3NlQXBwbGljYXRpb24iLCJTaG93QXBwTWVudSIsIkNyZWF0ZVdpbmRvdyIsIkRlbGV0ZVdpbmRvdyIsIkdldEludGVyaW9yVmVoaWNsZURhdGFDb25zZW50IiwiUmVsZWFzZUludGVyaW9yVmVoaWNsZURhdGFNb2R1bGUiLCJPbkhNSVN0YXR1cyIsIk9uQXBwSW50ZXJmYWNlVW5yZWdpc3RlcmVkIiwiT25CdXR0b25FdmVudCIsIk9uQnV0dG9uUHJlc3MiLCJPblZlaGljbGVEYXRhIiwiT25Db21tYW5kIiwiT25UQlRDbGllbnRTdGF0ZSIsIk9uRHJpdmVyRGlzdHJhY3Rpb24iLCJPblBlcm1pc3Npb25zQ2hhbmdlIiwiT25BdWRpb1Bhc3NUaHJ1IiwiT25MYW5ndWFnZUNoYW5nZSIsIk9uS2V5Ym9hcmRJbnB1dCIsIk9uVG91Y2hFdmVudCIsIk9uU3lzdGVtUmVxdWVzdCIsIk9uSGFzaENoYW5nZSIsIk9uSW50ZXJpb3JWZWhpY2xlRGF0YSIsIk9uV2F5UG9pbnRDaGFuZ2UiLCJPblJDU3RhdHVzIiwiT25BcHBTZXJ2aWNlRGF0YSIsIk9uU3lzdGVtQ2FwYWJpbGl0eVVwZGF0ZWQiLCJmcmVlemUiLCJScGNNZXNzYWdlIiwic3RvcmUiLCJfaXNFbmNyeXB0ZWQiLCJfcnBjVHlwZSIsInJwY1R5cGUiLCJfZnVuY3Rpb25OYW1lIiwiZnVuY3Rpb25OYW1lIiwiX2NvcnJlbGF0aW9uSUQiLCJzZXRCdWxrRGF0YSIsImJ1bGtEYXRhIiwiZ2V0UlBDVHlwZSIsInNldFJQQ1R5cGUiLCJ0eXBlIiwiZ2V0RnVuY3Rpb25OYW1lIiwic2V0RnVuY3Rpb25OYW1lIiwiZ2V0Q29ycmVsYXRpb25JZCIsInNldENvcnJlbGF0aW9uSWQiLCJpZCIsImdldEJ1bGtEYXRhIiwiX2J1bGtEYXRhIiwiZGF0YSIsInNsaWNlIiwiZ2V0SXNFbmNyeXB0ZWQiLCJzZXRJc0VuY3J5cHRlZCIsImJvb2wiLCJScGNUeXBlIiwiTk9USUZJQ0FUSU9OIiwiUkVTUE9OU0UiLCJSRVFVRVNUIiwiUnBjUmVxdWVzdCIsIl9wcm9taXNlIiwiZ2V0T25SUENSZXNwb25zZVByb21pc2UiLCJzZXRPblJQQ1Jlc3BvbnNlUHJvbWlzZSIsInByb21pc2UiLCJQcm9taXNlIiwiU2RsTXNnVmVyc2lvbiIsInNldE1ham9yVmVyc2lvbiIsIktFWV9NQUpPUl9WRVJTSU9OIiwiZ2V0TWFqb3JWZXJzaW9uIiwic2V0TWlub3JWZXJzaW9uIiwiS0VZX01JTk9SX1ZFUlNJT04iLCJnZXRNaW5vclZlcnNpb24iLCJzZXRQYXRjaFZlcnNpb24iLCJLRVlfUEFUQ0hfVkVSU0lPTiIsImdldFBhdGNoVmVyc2lvbiIsIlNwZWVjaENhcGFiaWxpdGllcyIsIlNDX1RFWFQiLCJTQVBJX1BIT05FTUVTIiwiTEhQTFVTX1BIT05FTUVTIiwiUFJFX1JFQ09SREVEIiwiU0lMRU5DRSIsIkZJTEUiLCJUVFNDaHVuayIsInNldFRleHQiLCJ0ZXh0IiwiS0VZX1RFWFQiLCJnZXRUZXh0Iiwic2V0VHlwZSIsIktFWV9UWVBFIiwiZ2V0VHlwZSIsIkRldmljZUluZm8iLCJzZXRIYXJkd2FyZSIsImhhcmR3YXJlIiwiS0VZX0hBUkRXQVJFIiwiZ2V0SGFyZHdhcmUiLCJzZXRGaXJtd2FyZVJldiIsImZpcm13YXJlUmV2IiwiS0VZX0ZJUk1XQVJFX1JFViIsImdldEZpcm13YXJlUmV2Iiwic2V0T3MiLCJvcyIsIktFWV9PUyIsImdldE9zIiwic2V0T3NWZXJzaW9uIiwib3NWZXJzaW9uIiwiS0VZX09TX1ZFUlNJT04iLCJnZXRPc1ZlcnNpb24iLCJzZXRDYXJyaWVyIiwiY2FycmllciIsIktFWV9DQVJSSUVSIiwiZ2V0Q2FycmllciIsInNldE1heE51bWJlclJGQ09NTVBvcnRzIiwibWF4TnVtYmVyUkZDT01NUG9ydHMiLCJOdW1iZXIiLCJLRVlfTUFYX05VTUJFUl9SRkNPTU1fUE9SVFMiLCJnZXRNYXhOdW1iZXJSRkNPTU1Qb3J0cyIsIkFwcEluZm8iLCJzZXRBcHBEaXNwbGF5TmFtZSIsImFwcERpc3BsYXlOYW1lIiwiS0VZX0FQUF9ESVNQTEFZX05BTUUiLCJnZXRBcHBEaXNwbGF5TmFtZSIsInNldEFwcEJ1bmRsZUlEIiwiYXBwQnVuZGxlSUQiLCJLRVlfQVBQX0JVTkRMRV9JRCIsImdldEFwcEJ1bmRsZUlEIiwic2V0QXBwVmVyc2lvbiIsImFwcFZlcnNpb24iLCJLRVlfQVBQX1ZFUlNJT04iLCJnZXRBcHBWZXJzaW9uIiwiYXBwSWNvbiIsIktFWV9BUFBfSUNPTiIsImdldEFwcEljb24iLCJSR0JDb2xvciIsInNldFJlZFZhbHVlIiwicmVkVmFsdWUiLCJLRVlfUkVEIiwiZ2V0UmVkVmFsdWUiLCJzZXRHcmVlblZhbHVlIiwiZ3JlZW5WYWx1ZSIsIktFWV9HUkVFTiIsImdldEdyZWVuVmFsdWUiLCJzZXRCbHVlVmFsdWUiLCJibHVlVmFsdWUiLCJLRVlfQkxVRSIsImdldEJsdWVWYWx1ZSIsIlRlbXBsYXRlQ29sb3JTY2hlbWUiLCJzZXRQcmltYXJ5Q29sb3IiLCJwcmltYXJ5Q29sb3IiLCJLRVlfUFJJTUFSWV9DT0xPUiIsImdldFByaW1hcnlDb2xvciIsInNldFNlY29uZGFyeUNvbG9yIiwic2Vjb25kYXJ5Q29sb3IiLCJLRVlfU0VDT05EQVJZX0NPTE9SIiwiZ2V0U2Vjb25kYXJ5Q29sb3IiLCJzZXRCYWNrZ3JvdW5kQ29sb3IiLCJiYWNrZ3JvdW5kQ29sb3IiLCJLRVlfQkFDS0dST1VORF9DT0xPUiIsImdldEJhY2tncm91bmRDb2xvciIsIkxhbmd1YWdlIiwiRU5fU0EiLCJIRV9JTCIsIlJPX1JPIiwiVUtfVUEiLCJJRF9JRCIsIlZJX1ZOIiwiTVNfTVkiLCJISV9JTiIsIk5MX0JFIiwiRUxfR1IiLCJIVV9IVSIsIkZJX0ZJIiwiU0tfU0siLCJFTl9VUyIsIkVTX01YIiwiRlJfQ0EiLCJERV9ERSIsIkVTX0VTIiwiRU5fR0IiLCJSVV9SVSIsIlRSX1RSIiwiUExfUEwiLCJGUl9GUiIsIklUX0lUIiwiU1ZfU0UiLCJQVF9QVCIsIk5MX05MIiwiRU5fQVUiLCJaSF9DTiIsIlpIX1RXIiwiSkFfSlAiLCJBUl9TQSIsIktPX0tSIiwiUFRfQlIiLCJDU19DWiIsIkRBX0RLIiwiTk9fTk8iLCJFTl9JTiIsIlRIX1RIIiwiQXBwSE1JVHlwZSIsIkRFRkFVTFQiLCJDT01NVU5JQ0FUSU9OIiwiTUVESUEiLCJNRVNTQUdJTkciLCJOQVZJR0FUSU9OIiwiSU5GT1JNQVRJT04iLCJTT0NJQUwiLCJCQUNLR1JPVU5EX1BST0NFU1MiLCJURVNUSU5HIiwiU1lTVEVNIiwiUFJPSkVDVElPTiIsIlJFTU9URV9DT05UUk9MIiwic2V0U2RsTXNnVmVyc2lvbiIsInNkbE1zZ1ZlcnNpb24iLCJLRVlfU0RMX01TR19WRVJTSU9OIiwiZ2V0U2RsTXNnVmVyc2lvbiIsIktFWV9BUFBfTkFNRSIsInR0c05hbWVzIiwiS0VZX1RUU19OQU1FIiwic2V0TmduTWVkaWFTY3JlZW5BcHBOYW1lIiwibmducHBOYW1lIiwiS0VZX05HTl9NRURJQV9TQ1JFRU5fQVBQX05BTUUiLCJnZXROZ25NZWRpYVNjcmVlbkFwcE5hbWUiLCJLRVlfVlJfU1lOT05ZTVMiLCJzZXRJc01lZGlhQXBwbGljYXRpb24iLCJpc01lZGlhQXBwbGljYXRpb24iLCJLRVlfSVNfTUVESUFfQVBQTElDQVRJT04iLCJnZXRJc01lZGlhQXBwbGljYXRpb24iLCJLRVlfTEFOR1VBR0VfREVTSVJFRCIsIktFWV9ITUlfRElTUExBWV9MQU5HVUFHRV9ERVNJUkVEIiwic2V0QXBwSG1pVHlwZSIsImFwcEhNSVR5cGUiLCJLRVlfQVBQX0hNSV9UWVBFIiwiZ2V0QXBwSG1pVHlwZSIsInNldEhhc2hJRCIsImhhc2hJRCIsIktFWV9IQVNIX0lEIiwiZ2V0SGFzaElEIiwic2V0RGV2aWNlSW5mbyIsImRldmljZUluZm8iLCJLRVlfREVWSUNFX0lORk8iLCJnZXREZXZpY2VJbmZvIiwiX3NldEFwcElkIiwiS0VZX0FQUF9JRCIsInNldEZ1bGxBcHBJZCIsImZ1bGxBcHBJZCIsInRvTG93ZXJDYXNlIiwiS0VZX0ZVTExfQVBQX0lEIiwiQVBQX0lEX01BWF9MRU5HVEgiLCJyZXBsYWNlIiwic3Vic3RyaW5nIiwiZ2V0RnVsbEFwcElkIiwic2V0QXBwSW5mbyIsImFwcEluZm8iLCJLRVlfQVBQX0lORk8iLCJnZXRBcHBJbmZvIiwiS0VZX0RBWV9DT0xPUl9TQ0hFTUUiLCJLRVlfTklHSFRfQ09MT1JfU0NIRU1FIiwiS0VZX1NZTkNfTVNHX1ZFUlNJT04iLCJSZXN1bHQiLCJTVUNDRVNTIiwiVU5TVVBQT1JURURfUkVRVUVTVCIsIlVOU1VQUE9SVEVEX1JFU09VUkNFIiwiRElTQUxMT1dFRCIsIlJFSkVDVEVEIiwiQUJPUlRFRCIsIklHTk9SRUQiLCJSRVRSWSIsIklOX1VTRSIsIlZFSElDTEVfREFUQV9OT1RfQVZBSUxBQkxFIiwiVElNRURfT1VUIiwiSU5WQUxJRF9EQVRBIiwiQ0hBUl9MSU1JVF9FWENFRURFRCIsIklOVkFMSURfSUQiLCJEVVBMSUNBVEVfTkFNRSIsIkFQUExJQ0FUSU9OX05PVF9SRUdJU1RFUkVEIiwiV1JPTkdfTEFOR1VBR0UiLCJPVVRfT0ZfTUVNT1JZIiwiVE9PX01BTllfUEVORElOR19SRVFVRVNUUyIsIlRPT19NQU5ZX0FQUExJQ0FUSU9OUyIsIkFQUExJQ0FUSU9OX1JFR0lTVEVSRURfQUxSRUFEWSIsIldBUk5JTkdTIiwiR0VORVJJQ19FUlJPUiIsIlVTRVJfRElTQUxMT1dFRCIsIlRSVU5DQVRFRF9EQVRBIiwiVU5TVVBQT1JURURfVkVSU0lPTiIsIlZFSElDTEVfREFUQV9OT1RfQUxMT1dFRCIsIkZJTEVfTk9UX0ZPVU5EIiwiQ0FOQ0VMX1JPVVRFIiwiU0FWRUQiLCJJTlZBTElEX0NFUlQiLCJFWFBJUkVEX0NFUlQiLCJSRVNVTUVfRkFJTEVEIiwiREFUQV9OT1RfQVZBSUxBQkxFIiwiUkVBRF9PTkxZIiwiQ09SUlVQVEVEX0RBVEEiLCJScGNSZXNwb25zZSIsImdldFN1Y2Nlc3MiLCJLRVlfU1VDQ0VTUyIsInNldFN1Y2Nlc3MiLCJzdWNjZXNzIiwiZ2V0SW5mbyIsIktFWV9JTkZPIiwic2V0SW5mbyIsImdldFJlc3VsdENvZGUiLCJLRVlfUkVTVUxUX0NPREUiLCJzZXRSZXN1bHRDb2RlIiwicmVzdWx0Q29kZSIsIlJwY0xpc3RlbmVyIiwiX29uUnBjTWVzc2FnZSIsInNldE9uUnBjTWVzc2FnZSIsImZ1bmMiLCJvblJwY01lc3NhZ2UiLCJycGNNZXNzYWdlIiwiU2RsUHJvdG9jb2xMaXN0ZW5lciIsIl9vblJwY01lc3NhZ2VSZWNlaXZlZCIsIl9vblByb3RvY29sU2Vzc2lvblN0YXJ0ZWQiLCJfb25Qcm90b2NvbFNlc3Npb25FbmRlZCIsIl9nZXRTZXNzaW9uSWQiLCJfb25UcmFuc3BvcnRDb25uZWN0ZWQiLCJzZXRPblRyYW5zcG9ydENvbm5lY3RlZCIsInNldE9uUnBjTWVzc2FnZVJlY2VpdmVkIiwib25ScGNNZXNzYWdlUmVjZWl2ZWQiLCJzZXRPblByb3RvY29sU2Vzc2lvblN0YXJ0ZWQiLCJvblRyYW5zcG9ydENvbm5lY3RlZCIsIm9uUHJvdG9jb2xTZXNzaW9uU3RhcnRlZCIsInNlc3Npb25JZCIsInZlcnNpb24iLCJjb3JyZWxhdGlvbklkIiwiaGFzaElkIiwiaXNFbmNyeXB0ZWQiLCJzZXRPblByb3RvY29sU2Vzc2lvbkVuZGVkIiwib25Qcm90b2NvbFNlc3Npb25FbmRlZCIsInNldE9uUHJvdG9jb2xTZXNzaW9uRW5kZWROQUNLZWQiLCJvblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkIiwic2V0R2V0U2Vzc2lvbklkIiwiZ2V0dGVyIiwiZ2V0U2Vzc2lvbklkIiwic2V0R2V0RGVzaXJlZFZpZGVvUGFyYW1zIiwiX2dldERlc2lyZWRWaWRlb1BhcmFtcyIsImdldERlc2lyZWRWaWRlb1BhcmFtcyIsInNldFNldEFjY2VwdGVkVmlkZW9QYXJhbXMiLCJzZXR0ZXIiLCJfc2V0QWNjZXB0ZWRWaWRlb1BhcmFtcyIsInNldEFjY2VwdGVkVmlkZW9QYXJhbXMiLCJwYXJhbXMiLCJGcmFtZVR5cGUiLCJDT05UUk9MIiwiRklSU1QiLCJDT05TRUNVVElWRSIsIlNJTkdMRSIsImV4cG9ydHMiLCJtb2R1bGVzIiwiaW5zdGFsbGVkTW9kdWxlcyIsIl9fd2VicGFja19yZXF1aXJlX18iLCJtb2R1bGVJZCIsIm1vZHVsZSIsImkiLCJsIiwiY2FsbCIsIm0iLCJjIiwiZCIsIm8iLCJkZWZpbmVQcm9wZXJ0eSIsImNvbmZpZ3VyYWJsZSIsImVudW1lcmFibGUiLCJnZXQiLCJuIiwiX19lc01vZHVsZSIsImdldERlZmF1bHQiLCJnZXRNb2R1bGVFeHBvcnRzIiwib2JqZWN0IiwicHJvcGVydHkiLCJoYXNPd25Qcm9wZXJ0eSIsInAiLCJzIiwiZyIsIkZ1bmN0aW9uIiwiZXZhbCIsImUiLCJ3aW5kb3ciLCJnbG9iYWwiLCJiYXNlNjQiLCJpZWVlNzU0IiwiQnVmZmVyIiwiU2xvd0J1ZmZlciIsIklOU1BFQ1RfTUFYX0JZVEVTIiwiVFlQRURfQVJSQVlfU1VQUE9SVCIsInR5cGVkQXJyYXlTdXBwb3J0Iiwia01heExlbmd0aCIsImFyciIsIlVpbnQ4QXJyYXkiLCJfX3Byb3RvX18iLCJmb28iLCJzdWJhcnJheSIsImJ5dGVMZW5ndGgiLCJjcmVhdGVCdWZmZXIiLCJ0aGF0IiwiUmFuZ2VFcnJvciIsImFyZyIsImVuY29kaW5nT3JPZmZzZXQiLCJhbGxvY1Vuc2FmZSIsImZyb20iLCJwb29sU2l6ZSIsIl9hdWdtZW50IiwiVHlwZUVycm9yIiwiQXJyYXlCdWZmZXIiLCJmcm9tQXJyYXlCdWZmZXIiLCJmcm9tU3RyaW5nIiwiZnJvbU9iamVjdCIsIlN5bWJvbCIsInNwZWNpZXMiLCJhc3NlcnRTaXplIiwic2l6ZSIsImFsbG9jIiwiZmlsbCIsImVuY29kaW5nIiwiY2hlY2tlZCIsImFsbG9jVW5zYWZlU2xvdyIsInN0cmluZyIsImlzRW5jb2RpbmciLCJhY3R1YWwiLCJ3cml0ZSIsImZyb21BcnJheUxpa2UiLCJhcnJheSIsImJ5dGVPZmZzZXQiLCJpc0J1ZmZlciIsImxlbiIsImNvcHkiLCJidWZmZXIiLCJpc25hbiIsInRvU3RyaW5nIiwiYiIsIl9pc0J1ZmZlciIsImNvbXBhcmUiLCJhIiwieCIsInkiLCJNYXRoIiwibWluIiwiY29uY2F0IiwibGlzdCIsInBvcyIsImJ1ZiIsImlzVmlldyIsImxvd2VyZWRDYXNlIiwidXRmOFRvQnl0ZXMiLCJiYXNlNjRUb0J5dGVzIiwic2xvd1RvU3RyaW5nIiwic3RhcnQiLCJlbmQiLCJoZXhTbGljZSIsInV0ZjhTbGljZSIsImFzY2lpU2xpY2UiLCJsYXRpbjFTbGljZSIsImJhc2U2NFNsaWNlIiwidXRmMTZsZVNsaWNlIiwic3dhcCIsInN3YXAxNiIsInN3YXAzMiIsInN3YXA2NCIsImFyZ3VtZW50cyIsImFwcGx5IiwiZXF1YWxzIiwiaW5zcGVjdCIsInN0ciIsIm1heCIsIm1hdGNoIiwiam9pbiIsInRhcmdldCIsInRoaXNTdGFydCIsInRoaXNFbmQiLCJ0aGlzQ29weSIsInRhcmdldENvcHkiLCJiaWRpcmVjdGlvbmFsSW5kZXhPZiIsInZhbCIsImRpciIsImlzTmFOIiwiYXJyYXlJbmRleE9mIiwiaW5kZXhPZiIsImxhc3RJbmRleE9mIiwiaW5kZXhTaXplIiwiYXJyTGVuZ3RoIiwidmFsTGVuZ3RoIiwicmVhZCIsInJlYWRVSW50MTZCRSIsImZvdW5kSW5kZXgiLCJmb3VuZCIsImoiLCJpbmNsdWRlcyIsImhleFdyaXRlIiwib2Zmc2V0IiwicmVtYWluaW5nIiwic3RyTGVuIiwicGFyc2VkIiwicGFyc2VJbnQiLCJzdWJzdHIiLCJ1dGY4V3JpdGUiLCJibGl0QnVmZmVyIiwiYXNjaWlXcml0ZSIsImFzY2lpVG9CeXRlcyIsImxhdGluMVdyaXRlIiwiYmFzZTY0V3JpdGUiLCJ1Y3MyV3JpdGUiLCJ1dGYxNmxlVG9CeXRlcyIsImlzRmluaXRlIiwidG9KU09OIiwiX2FyciIsImZyb21CeXRlQXJyYXkiLCJyZXMiLCJmaXJzdEJ5dGUiLCJjb2RlUG9pbnQiLCJieXRlc1BlclNlcXVlbmNlIiwic2Vjb25kQnl0ZSIsInRoaXJkQnl0ZSIsImZvdXJ0aEJ5dGUiLCJ0ZW1wQ29kZVBvaW50IiwiZGVjb2RlQ29kZVBvaW50c0FycmF5IiwiTUFYX0FSR1VNRU5UU19MRU5HVEgiLCJjb2RlUG9pbnRzIiwiZnJvbUNoYXJDb2RlIiwicmV0Iiwib3V0IiwidG9IZXgiLCJieXRlcyIsIm5ld0J1ZiIsInNsaWNlTGVuIiwiY2hlY2tPZmZzZXQiLCJleHQiLCJyZWFkVUludExFIiwibm9Bc3NlcnQiLCJtdWwiLCJyZWFkVUludEJFIiwicmVhZFVJbnQ4IiwicmVhZFVJbnQxNkxFIiwicmVhZFVJbnQzMkxFIiwicmVhZFVJbnQzMkJFIiwicmVhZEludExFIiwicG93IiwicmVhZEludEJFIiwicmVhZEludDgiLCJyZWFkSW50MTZMRSIsInJlYWRJbnQxNkJFIiwicmVhZEludDMyTEUiLCJyZWFkSW50MzJCRSIsInJlYWRGbG9hdExFIiwicmVhZEZsb2F0QkUiLCJyZWFkRG91YmxlTEUiLCJyZWFkRG91YmxlQkUiLCJjaGVja0ludCIsIndyaXRlVUludExFIiwibWF4Qnl0ZXMiLCJ3cml0ZVVJbnRCRSIsIndyaXRlVUludDgiLCJmbG9vciIsIm9iamVjdFdyaXRlVUludDE2IiwibGl0dGxlRW5kaWFuIiwid3JpdGVVSW50MTZMRSIsIndyaXRlVUludDE2QkUiLCJvYmplY3RXcml0ZVVJbnQzMiIsIndyaXRlVUludDMyTEUiLCJ3cml0ZVVJbnQzMkJFIiwid3JpdGVJbnRMRSIsImxpbWl0Iiwic3ViIiwid3JpdGVJbnRCRSIsIndyaXRlSW50OCIsIndyaXRlSW50MTZMRSIsIndyaXRlSW50MTZCRSIsIndyaXRlSW50MzJMRSIsIndyaXRlSW50MzJCRSIsImNoZWNrSUVFRTc1NCIsIndyaXRlRmxvYXQiLCJ3cml0ZUZsb2F0TEUiLCJ3cml0ZUZsb2F0QkUiLCJ3cml0ZURvdWJsZSIsIndyaXRlRG91YmxlTEUiLCJ3cml0ZURvdWJsZUJFIiwidGFyZ2V0U3RhcnQiLCJzZXQiLCJjb2RlIiwiY2hhckNvZGVBdCIsIklOVkFMSURfQkFTRTY0X1JFIiwiYmFzZTY0Y2xlYW4iLCJzdHJpbmd0cmltIiwidHJpbSIsInVuaXRzIiwiSW5maW5pdHkiLCJsZWFkU3Vycm9nYXRlIiwiYnl0ZUFycmF5IiwiaGkiLCJsbyIsInRvQnl0ZUFycmF5Iiwic3JjIiwiZHN0IiwiZmFjdG9yeSIsImxvbmciLCJjb21tb25qc0dsb2JhbCIsInNlbGYiLCJjcmVhdGVDb21tb25qc01vZHVsZSIsImZuIiwiZ2V0Q2pzRXhwb3J0RnJvbU5hbWVzcGFjZSIsIk1hcCIsIl9rZXlzIiwiX3ZhbHVlcyIsImVudHJ5IiwidiIsImNsZWFyIiwic3BsaWNlIiwiZW50cmllcyIsImluZGV4IiwibmV4dCIsImRvbmUiLCJmb3JFYWNoIiwiY2FsbGJhY2siLCJoYXMiLCJrZXlzIiwidmFsdWVzIiwibWFwXzEiLCJ0b0V4dGVuZGVkSlNPTiIsIm9wdGlvbnMiLCJyZWxheGVkIiwidG9OdW1iZXIiLCIkbnVtYmVyTG9uZyIsImZyb21FeHRlbmRlZEpTT04iLCJkb2MiLCJyZXN1bHQiLCJsb25nXzEiLCJfY2xhc3NDYWxsQ2hlY2siLCJpbnN0YW5jZSIsIkNvbnN0cnVjdG9yIiwiX2RlZmluZVByb3BlcnRpZXMiLCJwcm9wcyIsImRlc2NyaXB0b3IiLCJ3cml0YWJsZSIsIl9jcmVhdGVDbGFzcyIsInByb3RvUHJvcHMiLCJzdGF0aWNQcm9wcyIsIkRvdWJsZSIsInZhbHVlT2YiLCIkbnVtYmVyRG91YmxlIiwicGFyc2VGbG9hdCIsImRvdWJsZV8xIiwiX3R5cGVvZiIsIl90eXBlb2YyIiwiaXRlcmF0b3IiLCJfY2xhc3NDYWxsQ2hlY2skMSIsIl9kZWZpbmVQcm9wZXJ0aWVzJDEiLCJfY3JlYXRlQ2xhc3MkMSIsIl9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuIiwiX2Fzc2VydFRoaXNJbml0aWFsaXplZCIsIlJlZmVyZW5jZUVycm9yIiwiX2dldFByb3RvdHlwZU9mIiwic2V0UHJvdG90eXBlT2YiLCJnZXRQcm90b3R5cGVPZiIsIl9pbmhlcml0cyIsInN1YkNsYXNzIiwic3VwZXJDbGFzcyIsImNyZWF0ZSIsIl9zZXRQcm90b3R5cGVPZiIsIlRpbWVzdGFtcCIsIl9Mb25nIiwibG93IiwiaGlnaCIsIl90aGlzIiwiaXNMb25nIiwiJHRpbWVzdGFtcCIsInQiLCJmcm9tSW50IiwiZnJvbU51bWJlciIsImZyb21CaXRzIiwibG93Qml0cyIsImhpZ2hCaXRzIiwib3B0X3JhZGl4IiwidGltZXN0YW1wIiwiZW1wdHkiLCJlbXB0eSQxIiwicmVxdWlyZSQkMCIsIm5vcm1hbGl6ZWRGdW5jdGlvblN0cmluZyIsImluc2VjdXJlUmFuZG9tQnl0ZXMiLCJyYW5kb20iLCJyYW5kb21CeXRlcyIsImNyeXB0byIsImdldFJhbmRvbVZhbHVlcyIsInV0aWxzIiwic2V0VGltZW91dCIsImNsZWFyVGltZW91dCIsInBlcmZvcm1hbmNlIiwicGVyZm9ybWFuY2VOb3ciLCJub3ciLCJtb3pOb3ciLCJtc05vdyIsIm9Ob3ciLCJ3ZWJraXROb3ciLCJEYXRlIiwiZ2V0VGltZSIsImluaGVyaXRzIiwiY3RvciIsInN1cGVyQ3RvciIsInN1cGVyXyIsIlRlbXBDdG9yIiwiaW5oZXJpdHMkMSIsIl90eXBlb2YkMSIsImZvcm1hdFJlZ0V4cCIsImZvcm1hdCIsImYiLCJpc1N0cmluZyIsIm9iamVjdHMiLCJhcmdzIiwiSlNPTiIsInN0cmluZ2lmeSIsIl8iLCJpc051bGwiLCJpc09iamVjdCIsImRlcHJlY2F0ZSIsIm1zZyIsImlzVW5kZWZpbmVkIiwicHJvY2VzcyIsIndhcm5lZCIsImRlcHJlY2F0ZWQiLCJjb25zb2xlIiwiZXJyb3IiLCJkZWJ1Z3MiLCJkZWJ1Z0Vudmlyb24iLCJkZWJ1Z2xvZyIsInRvVXBwZXJDYXNlIiwiUmVnRXhwIiwidGVzdCIsInBpZCIsIm9wdHMiLCJjdHgiLCJzZWVuIiwic3R5bGl6ZSIsInN0eWxpemVOb0NvbG9yIiwiZGVwdGgiLCJjb2xvcnMiLCJpc0Jvb2xlYW4iLCJzaG93SGlkZGVuIiwiX2V4dGVuZCIsImN1c3RvbUluc3BlY3QiLCJzdHlsaXplV2l0aENvbG9yIiwiZm9ybWF0VmFsdWUiLCJzdHlsZXMiLCJzdHlsZVR5cGUiLCJzdHlsZSIsImFycmF5VG9IYXNoIiwiaGFzaCIsImlkeCIsInJlY3Vyc2VUaW1lcyIsImlzRnVuY3Rpb24iLCJwcmltaXRpdmUiLCJmb3JtYXRQcmltaXRpdmUiLCJ2aXNpYmxlS2V5cyIsImdldE93blByb3BlcnR5TmFtZXMiLCJpc0Vycm9yIiwiZm9ybWF0RXJyb3IiLCJpc1JlZ0V4cCIsImlzRGF0ZSIsImJhc2UiLCJicmFjZXMiLCJ0b1VUQ1N0cmluZyIsIm91dHB1dCIsImZvcm1hdEFycmF5IiwiZm9ybWF0UHJvcGVydHkiLCJwb3AiLCJyZWR1Y2VUb1NpbmdsZVN0cmluZyIsInNpbXBsZSIsImlzTnVtYmVyIiwiZGVzYyIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsInNwbGl0IiwibGluZSIsInJlZHVjZSIsInByZXYiLCJjdXIiLCJhciIsImlzTnVsbE9yVW5kZWZpbmVkIiwiaXNTeW1ib2wiLCJyZSIsIm9iamVjdFRvU3RyaW5nIiwiaXNQcmltaXRpdmUiLCJtYXliZUJ1ZiIsInBhZCIsIm1vbnRocyIsInRpbWVzdGFtcCQxIiwidGltZSIsImdldEhvdXJzIiwiZ2V0TWludXRlcyIsImdldFNlY29uZHMiLCJnZXREYXRlIiwiZ2V0TW9udGgiLCJsb2ciLCJvcmlnaW4iLCJhZGQiLCJwcm9wIiwidXRpbCIsInV0aWwkMSIsInV0aWwkMiIsIl9jbGFzc0NhbGxDaGVjayQyIiwiX2RlZmluZVByb3BlcnRpZXMkMiIsIl9jcmVhdGVDbGFzcyQyIiwiQnVmZmVyJDEiLCJyYW5kb21CeXRlcyQxIiwiZGVwcmVjYXRlJDEiLCJQUk9DRVNTX1VOSVFVRSIsImNoZWNrRm9ySGV4UmVnRXhwIiwiaGFzQnVmZmVyVHlwZSIsImVyciIsImhleFRhYmxlIiwiX2kiLCJkZWNvZGVMb29rdXAiLCJfQnVmZmVyIiwiY29udmVydFRvSGV4IiwibWFrZU9iamVjdElkRXJyb3IiLCJpbnZhbGlkU3RyaW5nIiwiaW52YWxpZENoYXJhY3RlciIsIk9iamVjdElkIiwiZ2VuZXJhdGUiLCJjYWNoZUhleFN0cmluZyIsIl9faWQiLCJ2YWxpZCIsImlzVmFsaWQiLCJjcmVhdGVGcm9tSGV4U3RyaW5nIiwidG9IZXhTdHJpbmciLCJoZXhTdHJpbmciLCJfaTIiLCJoZXhDaGFyIiwib3RoZXJJZCIsImdldFRpbWVzdGFtcCIsInNldFRpbWUiLCIkb2lkIiwiZ2V0SW5jIiwiaW5jIiwiYnVmZmVyJCQxIiwiY3JlYXRlUGsiLCJjcmVhdGVGcm9tVGltZSIsImdldF9pbmMiLCJjdXN0b20iLCJvYmplY3RpZCIsIl9jbGFzc0NhbGxDaGVjayQzIiwiX2RlZmluZVByb3BlcnRpZXMkMyIsIl9jcmVhdGVDbGFzcyQzIiwiYWxwaGFiZXRpemUiLCJzb3J0IiwiQlNPTlJlZ0V4cCIsInBhdHRlcm4iLCIkcmVndWxhckV4cHJlc3Npb24iLCJyZWdleHAiLCJfY2xhc3NDYWxsQ2hlY2skNCIsIl9kZWZpbmVQcm9wZXJ0aWVzJDQiLCJfY3JlYXRlQ2xhc3MkNCIsIkJTT05TeW1ib2wiLCIkc3ltYm9sIiwic3ltYm9sIiwiX2NsYXNzQ2FsbENoZWNrJDUiLCJfZGVmaW5lUHJvcGVydGllcyQ1IiwiX2NyZWF0ZUNsYXNzJDUiLCJJbnQzMiIsIiRudW1iZXJJbnQiLCJpbnRfMzIiLCJfY2xhc3NDYWxsQ2hlY2skNiIsIl9kZWZpbmVQcm9wZXJ0aWVzJDYiLCJfY3JlYXRlQ2xhc3MkNiIsIkNvZGUiLCJzY29wZSIsIiRjb2RlIiwiJHNjb3BlIiwiQnVmZmVyJDIiLCJQQVJTRV9TVFJJTkdfUkVHRVhQIiwiUEFSU0VfSU5GX1JFR0VYUCIsIlBBUlNFX05BTl9SRUdFWFAiLCJFWFBPTkVOVF9NQVgiLCJFWFBPTkVOVF9NSU4iLCJFWFBPTkVOVF9CSUFTIiwiTUFYX0RJR0lUUyIsIk5BTl9CVUZGRVIiLCJyZXZlcnNlIiwiSU5GX05FR0FUSVZFX0JVRkZFUiIsIklORl9QT1NJVElWRV9CVUZGRVIiLCJFWFBPTkVOVF9SRUdFWCIsImlzRGlnaXQiLCJkaXZpZGV1MTI4IiwiRElWSVNPUiIsIl9yZW0iLCJwYXJ0cyIsInF1b3RpZW50IiwicmVtIiwic2hpZnRMZWZ0IiwiZGl2IiwibW9kdWxvIiwibXVsdGlwbHk2NHgyIiwibGVmdCIsInJpZ2h0IiwibGVmdEhpZ2giLCJzaGlmdFJpZ2h0VW5zaWduZWQiLCJsZWZ0TG93IiwiZ2V0TG93Qml0cyIsInJpZ2h0SGlnaCIsInJpZ2h0TG93IiwicHJvZHVjdEhpZ2giLCJtdWx0aXBseSIsInByb2R1Y3RNaWQiLCJwcm9kdWN0TWlkMiIsInByb2R1Y3RMb3ciLCJsZXNzVGhhbiIsInVobGVmdCIsInVocmlnaHQiLCJ1bGxlZnQiLCJ1bHJpZ2h0IiwiaW52YWxpZEVyciIsIm1lc3NhZ2UiLCJEZWNpbWFsMTI4IiwiaXNOZWdhdGl2ZSIsInNhd1JhZGl4IiwiZm91bmROb25aZXJvIiwic2lnbmlmaWNhbnREaWdpdHMiLCJuRGlnaXRzUmVhZCIsIm5EaWdpdHMiLCJyYWRpeFBvc2l0aW9uIiwiZmlyc3ROb25aZXJvIiwiZGlnaXRzIiwibkRpZ2l0c1N0b3JlZCIsImRpZ2l0c0luc2VydCIsImZpcnN0RGlnaXQiLCJsYXN0RGlnaXQiLCJleHBvbmVudCIsInNpZ25pZmljYW5kSGlnaCIsInNpZ25pZmljYW5kTG93IiwiYmlhc2VkRXhwb25lbnQiLCJzdHJpbmdNYXRjaCIsImluZk1hdGNoIiwibmFuTWF0Y2giLCJ1bnNpZ25lZE51bWJlciIsImV4cFNpZ24iLCJleHBOdW1iZXIiLCJkaWdpdHNTdHJpbmciLCJfZGlnaXRzU3RyaW5nIiwiZW5kT2ZTdHJpbmciLCJyb3VuZERpZ2l0Iiwicm91bmRCaXQiLCJkSWR4IiwiX2RJZHgiLCJfZElkeDIiLCJzaWduaWZpY2FuZCIsImRlYyIsImFuZCIsIm9yIiwiQ09NQklOQVRJT05fTUFTSyIsIkVYUE9ORU5UX01BU0siLCJDT01CSU5BVElPTl9JTkZJTklUWSIsIkNPTUJJTkFUSU9OX05BTiIsIm1pZGgiLCJtaWRsIiwiY29tYmluYXRpb24iLCJiaWFzZWRfZXhwb25lbnQiLCJzaWduaWZpY2FuZF9kaWdpdHMiLCJzY2llbnRpZmljX2V4cG9uZW50IiwiaXNfemVybyIsInNpZ25pZmljYW5kX21zYiIsInNpZ25pZmljYW5kMTI4IiwiayIsIlpFUk8iLCJsZWFzdF9kaWdpdHMiLCJyYWRpeF9wb3NpdGlvbiIsIl9pMyIsIl9pNCIsIiRudW1iZXJEZWNpbWFsIiwiZGVjaW1hbDEyOCIsIl9jbGFzc0NhbGxDaGVjayQ3IiwiX2RlZmluZVByb3BlcnRpZXMkNyIsIl9jcmVhdGVDbGFzcyQ3IiwiTWluS2V5IiwiJG1pbktleSIsIm1pbl9rZXkiLCJfY2xhc3NDYWxsQ2hlY2skOCIsIl9kZWZpbmVQcm9wZXJ0aWVzJDgiLCJfY3JlYXRlQ2xhc3MkOCIsIk1heEtleSIsIiRtYXhLZXkiLCJtYXhfa2V5IiwiX2NsYXNzQ2FsbENoZWNrJDkiLCJfZGVmaW5lUHJvcGVydGllcyQ5IiwiX2NyZWF0ZUNsYXNzJDkiLCJEQlJlZiIsImNvbGxlY3Rpb24iLCJvaWQiLCJkYiIsImZpZWxkcyIsInNoaWZ0IiwiYXNzaWduIiwiJHJlZiIsIiRpZCIsIiRkYiIsImRiX3JlZiIsIl9jbGFzc0NhbGxDaGVjayRhIiwiX2RlZmluZVByb3BlcnRpZXMkYSIsIl9jcmVhdGVDbGFzcyRhIiwiQnVmZmVyJDMiLCJCaW5hcnkiLCJzdWJUeXBlIiwic3ViX3R5cGUiLCJCU09OX0JJTkFSWV9TVUJUWVBFX0RFRkFVTFQiLCJwb3NpdGlvbiIsIndyaXRlU3RyaW5nVG9BcnJheSIsIkJVRkZFUl9TSVpFIiwicHV0IiwiYnl0ZV92YWx1ZSIsImRlY29kZWRfYnl0ZSIsIl9idWZmZXIiLCJpc1VpbnQ4QXJyYXkiLCJhc1JhdyIsIm5ld0J1ZmZlciIsImNvbnZlcnRBcnJheXRvVXRmOEJpbmFyeVN0cmluZyIsImJhc2U2NFN0cmluZyIsIiRiaW5hcnkiLCJzdGFydEluZGV4IiwiZW5kSW5kZXgiLCJTVUJUWVBFX0RFRkFVTFQiLCJTVUJUWVBFX0ZVTkNUSU9OIiwiU1VCVFlQRV9CWVRFX0FSUkFZIiwiU1VCVFlQRV9VVUlEX09MRCIsIlNVQlRZUEVfVVVJRCIsIlNVQlRZUEVfTUQ1IiwiU1VCVFlQRV9VU0VSX0RFRklORUQiLCJiaW5hcnkiLCJjb25zdGFudHMiLCJCU09OX0lOVDMyX01BWCIsIkJTT05fSU5UMzJfTUlOIiwiQlNPTl9JTlQ2NF9NQVgiLCJCU09OX0lOVDY0X01JTiIsIkpTX0lOVF9NQVgiLCJKU19JTlRfTUlOIiwiQlNPTl9EQVRBX05VTUJFUiIsIkJTT05fREFUQV9TVFJJTkciLCJCU09OX0RBVEFfT0JKRUNUIiwiQlNPTl9EQVRBX0FSUkFZIiwiQlNPTl9EQVRBX0JJTkFSWSIsIkJTT05fREFUQV9VTkRFRklORUQiLCJCU09OX0RBVEFfT0lEIiwiQlNPTl9EQVRBX0JPT0xFQU4iLCJCU09OX0RBVEFfREFURSIsIkJTT05fREFUQV9OVUxMIiwiQlNPTl9EQVRBX1JFR0VYUCIsIkJTT05fREFUQV9EQlBPSU5URVIiLCJCU09OX0RBVEFfQ09ERSIsIkJTT05fREFUQV9TWU1CT0wiLCJCU09OX0RBVEFfQ09ERV9XX1NDT1BFIiwiQlNPTl9EQVRBX0lOVCIsIkJTT05fREFUQV9USU1FU1RBTVAiLCJCU09OX0RBVEFfTE9ORyIsIkJTT05fREFUQV9ERUNJTUFMMTI4IiwiQlNPTl9EQVRBX01JTl9LRVkiLCJCU09OX0RBVEFfTUFYX0tFWSIsIkJTT05fQklOQVJZX1NVQlRZUEVfRlVOQ1RJT04iLCJCU09OX0JJTkFSWV9TVUJUWVBFX0JZVEVfQVJSQVkiLCJCU09OX0JJTkFSWV9TVUJUWVBFX1VVSUQiLCJCU09OX0JJTkFSWV9TVUJUWVBFX01ENSIsIkJTT05fQklOQVJZX1NVQlRZUEVfVVNFUl9ERUZJTkVEIiwiX3R5cGVvZiQyIiwia2V5c1RvQ29kZWNzIiwiZGVzZXJpYWxpemVWYWx1ZSIsIiR1bmRlZmluZWQiLCJmaWx0ZXIiLCJzdGFydHNXaXRoIiwiJGRhdGUiLCJkYXRlIiwicGFyc2UiLCIkZGJQb2ludGVyIiwiZG9sbGFyS2V5cyIsInN0cmljdCIsInJlcGxhY2VyIiwic3BhY2UiLCJzZXJpYWxpemVBcnJheSIsInNlcmlhbGl6ZURvY3VtZW50Iiwic2VyaWFsaXplIiwiYnNvbiIsImRlc2VyaWFsaXplIiwiZWpzb24iLCJzZXJpYWxpemVWYWx1ZSIsImdldElTT1N0cmluZyIsImlzb1N0ciIsInRvSVNPU3RyaW5nIiwiZ2V0VVRDTWlsbGlzZWNvbmRzIiwiZGF0ZU51bSIsImluUmFuZ2UiLCJpbnQzMlJhbmdlIiwiaW50NjRSYW5nZSIsImZsYWdzIiwicngiLCJzb3VyY2UiLCJCU09OX1RZUEVfTUFQUElOR1MiLCJzdWJ0eXBlIiwibmFtZXNwYWNlIiwiTG9uZyIsImxvd18iLCJoaWdoXyIsInVuc2lnbmVkIiwidW5zaWduZWRfIiwiT2JqZWN0SUQiLCJic29udHlwZSIsIl9ic29udHlwZSIsIl9kb2MiLCJfZG9jMiIsIm1hcHBlciIsImV4dGVuZGVkX2pzb24iLCJGSVJTVF9CSVQiLCJGSVJTVF9UV09fQklUUyIsIkZJUlNUX1RIUkVFX0JJVFMiLCJGSVJTVF9GT1VSX0JJVFMiLCJGSVJTVF9GSVZFX0JJVFMiLCJUV09fQklUX0NIQVIiLCJUSFJFRV9CSVRfQ0hBUiIsIkZPVVJfQklUX0NIQVIiLCJDT05USU5VSU5HX0NIQVIiLCJ2YWxpZGF0ZVV0ZjgiLCJjb250aW51YXRpb24iLCJieXRlIiwidmFsaWRhdGVVdGY4XzEiLCJ2YWxpZGF0ZV91dGY4IiwiQnVmZmVyJDQiLCJ2YWxpZGF0ZVV0ZjgkMSIsIkpTX0lOVF9NQVhfTE9ORyIsIkpTX0lOVF9NSU5fTE9ORyIsImZ1bmN0aW9uQ2FjaGUiLCJkZXNlcmlhbGl6ZSQxIiwiYWxsb3dPYmplY3RTbWFsbGVyVGhhbkJ1ZmZlclNpemUiLCJkZXNlcmlhbGl6ZU9iamVjdCIsImV2YWxGdW5jdGlvbnMiLCJjYWNoZUZ1bmN0aW9ucyIsImNhY2hlRnVuY3Rpb25zQ3JjMzIiLCJjcmMzMiIsImZpZWxkc0FzUmF3IiwicmF3IiwiYnNvblJlZ0V4cCIsInByb21vdGVCdWZmZXJzIiwicHJvbW90ZUxvbmdzIiwicHJvbW90ZVZhbHVlcyIsImFycmF5SW5kZXgiLCJlbGVtZW50VHlwZSIsInN0cmluZ1NpemUiLCJfaW5kZXgiLCJvYmplY3RTaXplIiwiX2luZGV4MiIsIl9vYmplY3RTaXplIiwiYXJyYXlPcHRpb25zIiwic3RvcEluZGV4IiwiX2xvd0JpdHMiLCJfaGlnaEJpdHMiLCJsb25nJCQxIiwibGVzc1RoYW5PckVxdWFsIiwiZ3JlYXRlclRoYW5PckVxdWFsIiwiZGVjaW1hbDEyOCQkMSIsInRvT2JqZWN0IiwiYmluYXJ5U2l6ZSIsInRvdGFsQmluYXJ5U2l6ZSIsInJlZ0V4cE9wdGlvbnMiLCJvcHRpb25zQXJyYXkiLCJfc291cmNlIiwiX3JlZ0V4cE9wdGlvbnMiLCJfc3RyaW5nU2l6ZSIsIl9sb3dCaXRzMiIsIl9oaWdoQml0czIiLCJfc3RyaW5nU2l6ZTIiLCJmdW5jdGlvblN0cmluZyIsImlzb2xhdGVFdmFsV2l0aEhhc2giLCJpc29sYXRlRXZhbCIsInRvdGFsU2l6ZSIsIl9zdHJpbmdTaXplMyIsIl9mdW5jdGlvblN0cmluZyIsIl9pbmRleDMiLCJfb2JqZWN0U2l6ZTIiLCJzY29wZU9iamVjdCIsIl9oYXNoIiwiX3N0cmluZ1NpemU0Iiwib2lkQnVmZmVyIiwiX29pZCIsImJpbmQiLCJkZXNlcmlhbGl6ZXIiLCJyZWFkSUVFRTc1NCIsImVuZGlhbiIsIm1MZW4iLCJuQnl0ZXMiLCJiQkUiLCJlTGVuIiwiZU1heCIsImVCaWFzIiwibkJpdHMiLCJOYU4iLCJ3cml0ZUlFRUU3NTQiLCJydCIsImFicyIsIkxOMiIsImZsb2F0X3BhcnNlciIsIl90eXBlb2YkMyIsIkJ1ZmZlciQ1Iiwid3JpdGVJRUVFNzU0JDEiLCJub3JtYWxpemVkRnVuY3Rpb25TdHJpbmckMSIsInJlZ2V4cCQxIiwiaWdub3JlS2V5cyIsIlNldCIsImlzRGF0ZSQxIiwiaXNSZWdFeHAkMSIsInNlcmlhbGl6ZVN0cmluZyIsIm51bWJlck9mV3JpdHRlbkJ5dGVzIiwic2VyaWFsaXplTnVtYmVyIiwiX251bWJlck9mV3JpdHRlbkJ5dGVzIiwiX251bWJlck9mV3JpdHRlbkJ5dGVzMiIsImxvbmdWYWwiLCJnZXRIaWdoQml0cyIsIl9udW1iZXJPZldyaXR0ZW5CeXRlczMiLCJzZXJpYWxpemVOdWxsIiwic2VyaWFsaXplQm9vbGVhbiIsInNlcmlhbGl6ZURhdGUiLCJkYXRlSW5NaWxpcyIsInNlcmlhbGl6ZVJlZ0V4cCIsImlnbm9yZUNhc2UiLCJtdWx0aWxpbmUiLCJzZXJpYWxpemVCU09OUmVnRXhwIiwic2VyaWFsaXplTWluTWF4Iiwic2VyaWFsaXplT2JqZWN0SWQiLCJzZXJpYWxpemVCdWZmZXIiLCJzZXJpYWxpemVPYmplY3QiLCJjaGVja0tleXMiLCJzZXJpYWxpemVGdW5jdGlvbnMiLCJpZ25vcmVVbmRlZmluZWQiLCJwYXRoIiwic2VyaWFsaXplSW50byIsInNlcmlhbGl6ZURlY2ltYWwxMjgiLCJzZXJpYWxpemVMb25nIiwic2VyaWFsaXplSW50MzIiLCJzZXJpYWxpemVEb3VibGUiLCJzZXJpYWxpemVGdW5jdGlvbiIsInNlcmlhbGl6ZUNvZGUiLCJjb2RlU2l6ZSIsIl9udW1iZXJPZldyaXR0ZW5CeXRlczQiLCJzZXJpYWxpemVCaW5hcnkiLCJzZXJpYWxpemVTeW1ib2wiLCJzZXJpYWxpemVEQlJlZiIsInN0YXJ0aW5nSW5kZXgiLCJ0b0JTT04iLCJfa2V5IiwiX3ZhbHVlIiwiX3R5cGUiLCJfa2V5MiIsIl92YWx1ZTIiLCJfdHlwZTIiLCJzZXJpYWxpemVyIiwiX3R5cGVvZiQ0IiwiQnVmZmVyJDYiLCJub3JtYWxpemVkRnVuY3Rpb25TdHJpbmckMiIsImlzRGF0ZSQyIiwiY2FsY3VsYXRlT2JqZWN0U2l6ZSIsInRvdGFsTGVuZ3RoIiwiY2FsY3VsYXRlRWxlbWVudCIsIm9yZGVyZWRfdmFsdWVzIiwiY2FsY3VsYXRlX3NpemUiLCJCdWZmZXIkNyIsImVuc3VyZV9idWZmZXIiLCJlbnN1cmVCdWZmZXIiLCJwb3RlbnRpYWxCdWZmZXIiLCJCdWZmZXIkOCIsIk1BWFNJWkUiLCJidWZmZXIkMSIsInNldEludGVybmFsQnVmZmVyU2l6ZSIsInNlcmlhbGl6ZSQxIiwibWluSW50ZXJuYWxCdWZmZXJTaXplIiwic2VyaWFsaXphdGlvbkluZGV4IiwiZmluaXNoZWRCdWZmZXIiLCJzZXJpYWxpemVXaXRoQnVmZmVyQW5kSW5kZXgiLCJmaW5hbEJ1ZmZlciIsImRlc2VyaWFsaXplJDIiLCJjYWxjdWxhdGVPYmplY3RTaXplJDEiLCJkZXNlcmlhbGl6ZVN0cmVhbSIsIm51bWJlck9mRG9jdW1lbnRzIiwiZG9jdW1lbnRzIiwiZG9jU3RhcnRJbmRleCIsIkVKU09OIiwiYnNvbl8xIiwiYnNvbl8yIiwiYnNvbl8zIiwiYnNvbl80IiwiYnNvbl81IiwiYnNvbl82IiwiYnNvbl83IiwiYnNvbl84IiwiYnNvbl85IiwiYnNvbl8xMCIsImJzb25fMTEiLCJic29uXzEyIiwiYnNvbl8xMyIsImJzb25fMTQiLCJic29uXzE1IiwiYnNvbl8xNiIsImJzb25fMTciLCJic29uXzE4IiwiYnNvbl8xOSIsImJzb25fMjAiLCJic29uXzIxIiwiYnNvbl8yMiIsImJzb25fMjMiLCJic29uXzI0IiwiYnNvbl8yNSIsImJzb25fMjYiLCJic29uXzI3IiwiYnNvbl8yOCIsImJzb25fMjkiLCJic29uXzMwIiwiYnNvbl8zMSIsImJzb25fMzIiLCJic29uXzMzIiwiYnNvbl8zNCIsImJzb25fMzUiLCJic29uXzM2IiwiYnNvbl8zNyIsImJzb25fMzgiLCJic29uXzM5IiwiYnNvbl80MCIsImJzb25fNDEiLCJic29uXzQyIiwiYnNvbl80MyIsImJzb25fNDQiLCJic29uXzQ1IiwiYnNvbl80NiIsImJzb25fNDciLCJic29uXzQ4IiwiYnNvbl80OSIsImJzb25fNTAiLCJic29uXzUxIiwiYnNvbl81MiIsImJzb25fNTMiLCJic29uXzU0IiwibG9va3VwIiwicmV2TG9va3VwIiwiQXJyIiwiZ2V0TGVucyIsImI2NCIsInZhbGlkTGVuIiwicGxhY2VIb2xkZXJzTGVuIiwibGVucyIsIl9ieXRlTGVuZ3RoIiwidG1wIiwiY3VyQnl0ZSIsInRyaXBsZXRUb0Jhc2U2NCIsIm51bSIsImVuY29kZUNodW5rIiwidWludDgiLCJleHRyYUJ5dGVzIiwibWF4Q2h1bmtMZW5ndGgiLCJsZW4yIiwiaXNMRSIsIndhc20iLCJXZWJBc3NlbWJseSIsIkluc3RhbmNlIiwiTW9kdWxlIiwiX19pc0xvbmdfXyIsIklOVF9DQUNIRSIsIlVJTlRfQ0FDSEUiLCJjYWNoZWRPYmoiLCJjYWNoZSIsIlVaRVJPIiwiVFdPX1BXUl82NF9EQkwiLCJNQVhfVU5TSUdORURfVkFMVUUiLCJUV09fUFdSXzYzX0RCTCIsIk1JTl9WQUxVRSIsIk1BWF9WQUxVRSIsIm5lZyIsIlRXT19QV1JfMzJfREJMIiwicG93X2RibCIsInJhZGl4IiwicmFkaXhUb1Bvd2VyIiwicG93ZXIiLCJmcm9tVmFsdWUiLCJUV09fUFdSXzE2X0RCTCIsIlRXT19QV1JfMjRfREJMIiwiVFdPX1BXUl8yNCIsIk9ORSIsIlVPTkUiLCJORUdfT05FIiwiTG9uZ1Byb3RvdHlwZSIsInRvSW50IiwiaXNaZXJvIiwiZXEiLCJyYWRpeExvbmciLCJyZW0xIiwicmVtRGl2IiwiaW50dmFsIiwiZ2V0SGlnaEJpdHNVbnNpZ25lZCIsImdldExvd0JpdHNVbnNpZ25lZCIsImdldE51bUJpdHNBYnMiLCJiaXQiLCJlcXoiLCJpc1Bvc2l0aXZlIiwiaXNPZGQiLCJpc0V2ZW4iLCJvdGhlciIsIm5vdEVxdWFscyIsIm5lcSIsIm5lIiwiY29tcCIsImx0IiwibHRlIiwibGUiLCJncmVhdGVyVGhhbiIsImd0IiwiZ3RlIiwiZ2UiLCJ0aGlzTmVnIiwib3RoZXJOZWciLCJuZWdhdGUiLCJub3QiLCJhZGRlbmQiLCJhNDgiLCJhMzIiLCJhMTYiLCJhMDAiLCJiNDgiLCJiMzIiLCJiMTYiLCJiMDAiLCJjNDgiLCJjMzIiLCJjMTYiLCJjMDAiLCJzdWJ0cmFjdCIsInN1YnRyYWhlbmQiLCJtdWx0aXBsaWVyIiwiZ2V0X2hpZ2giLCJkaXZpZGUiLCJkaXZpc29yIiwiZGl2X3UiLCJkaXZfcyIsImFwcHJveCIsImhhbGZUaGlzIiwic2hyIiwic2hsIiwidG9VbnNpZ25lZCIsInNocnUiLCJsb2cyIiwiY2VpbCIsImRlbHRhIiwiYXBwcm94UmVzIiwiYXBwcm94UmVtIiwicmVtX3UiLCJyZW1fcyIsIm1vZCIsInhvciIsIm51bUJpdHMiLCJzaGlmdFJpZ2h0Iiwic2hyX3UiLCJ0b1NpZ25lZCIsInRvQnl0ZXMiLCJ0b0J5dGVzTEUiLCJ0b0J5dGVzQkUiLCJmcm9tQnl0ZXMiLCJmcm9tQnl0ZXNMRSIsImZyb21CeXRlc0JFIiwiQlNPTiIsIkJzb24iLCJTZGxQYWNrZXQiLCJlbmNyeXB0aW9uIiwiZnJhbWVUeXBlIiwiZnJhbWVJbmZvIiwiZGF0YVNpemUiLCJtZXNzYWdlSUQiLCJwYXlsb2FkIiwiYnl0ZXNUb1dyaXRlIiwiX3ZlcnNpb24iLCJfZW5jcnlwdGlvbiIsIl9mcmFtZVR5cGUiLCJfc2VydmljZVR5cGUiLCJfZnJhbWVJbmZvIiwiX3Nlc3Npb25JRCIsIl9kYXRhU2l6ZSIsIl9tZXNzYWdlSUQiLCJfcGF5bG9hZCIsIl9vZmZzZXQiLCJfYnl0ZXNUb1dyaXRlIiwiX2Jzb25QYXlsb2FkIiwiZ2V0VmVyc2lvbiIsImdldEVuY3J5cHRpb24iLCJnZXRTZXJ2aWNlVHlwZSIsImdldEZyYW1lSW5mbyIsImdldFNlc3Npb25JRCIsImdldE1lc3NhZ2VJRCIsImdldERhdGFTaXplIiwic2V0UGF5bG9hZCIsImdldFBheWxvYWQiLCJnZXRFbmNyeXB0aW9uQml0IiwiRU5DUllQVElPTl9NQVNLIiwiZ2V0RnJhbWVUeXBlIiwiY29uc3RydWN0UGFja2V0IiwiY29udHJvbEZyYW1lSW5mbyIsImRhdGFWaWV3IiwiZGF0YVZpZXdJbmRleCIsIkhFQURFUl9TSVpFIiwiSEVBREVSX1NJWkVfVjEiLCJ0b1BhY2tldCIsInB1dFRhZyIsInRhZyIsImdldFRhZyIsIkVYVFJBX1BBUkNFTF9EQVRBX0xFTkdUSCIsIlNFUlZJQ0VfVFlQRV9DT05UUk9MIiwiU0VSVklDRV9UWVBFX1JQQyIsIlNFUlZJQ0VfVFlQRV9QQ00iLCJTRVJWSUNFX1RZUEVfVklERU8iLCJTRVJWSUNFX1RZUEVfQlVMS19EQVRBIiwiRlJBTUVfSU5GT19IRUFSVF9CRUFUIiwiRlJBTUVfSU5GT19TVEFSVF9TRVJWSUNFIiwiRlJBTUVfSU5GT19TVEFSVF9TRVJWSUNFX0FDSyIsIkZSQU1FX0lORk9fU1RBUlRfU0VSVklDRV9OQUsiLCJGUkFNRV9JTkZPX0VORF9TRVJWSUNFIiwiRlJBTUVfSU5GT19FTkRfU0VSVklDRV9BQ0siLCJGUkFNRV9JTkZPX0VORF9TRVJWSUNFX05BSyIsIkZSQU1FX0lORk9fUkVHSVNURVJfU0VDT05EQVJZX1RSQU5TUE9SVCIsIkZSQU1FX0lORk9fUkVHSVNURVJfU0VDT05EQVJZX1RSQU5TUE9SVF9BQ0siLCJGUkFNRV9JTkZPX1JFR0lTVEVSX1NFQ09OREFSWV9UUkFOU1BPUlRfTkFLIiwiRlJBTUVfSU5GT19UUkFOU1BPUlRfRVZFTlRfVVBEQVRFIiwiRlJBTUVfSU5GT19TRVJWSUNFX0RBVEFfQUNLIiwiRlJBTUVfSU5GT19IRUFSVF9CRUFUX0FDSyIsIkZSQU1FX0lORk9fRklOQUxfQ09OTkVTQ1VUSVZFX0ZSQU1FIiwiRlJBTUVfSU5GT19SRVNFUlZFRCIsImJhc2U2NC5mcm9tQnl0ZUFycmF5IiwiaWVlZTc1NC5yZWFkIiwiaWVlZTc1NC53cml0ZSIsImJhc2U2NC50b0J5dGVBcnJheSIsIlRleHRFbmNvZGVyIiwiZW5jb2RlIiwiTGVuIiwicmVzUG9zIiwicmVzQXJyIiwicG9pbnQiLCJuZXh0Y29kZSIsIkpzb25ScGNNYXJzaGFsbGVyIiwibWFyc2hhbGwiLCJycGNTdHJ1Y3QiLCJqc29uQnl0ZXMiLCJwYXJhbWlmeSIsImpzb25PYmplY3QiLCJzdHJpbmdWZXJzaW9uIiwiX2VuY29kZSIsInVubWFyc2hhbGwiLCJqc29uU3RyaW5nIiwiX2RlY29kZSIsIkJpbmFyeUZyYW1lSGVhZGVyIiwiZnVuY3Rpb25JZCIsImpzb25TaXplIiwiX2Z1bmN0aW9uSWQiLCJfY29ycmVsYXRpb25JZCIsIl9qc29uU2l6ZSIsIl9qc29uRGF0YSIsImZyb21CaW5hcnlIZWFkZXIiLCJiaW5hcnlGcmFtZUhlYWRlckRhdGEiLCJiaW5hcnlGcmFtZUhlYWRlciIsImpzb25EYXRhU3RhcnQiLCJqc29uRGF0YUVuZCIsInNldEpzb25EYXRhIiwiYXNzZW1ibGVIZWFkZXJCeXRlcyIsInNldFJwY1R5cGUiLCJnZXRScGNUeXBlIiwic2V0RnVuY3Rpb25JZCIsImdldEZ1bmN0aW9uSWQiLCJzZXRKc29uU2l6ZSIsImdldEpzb25TaXplIiwiZ2V0SnNvbkRhdGEiLCJNZXNzYWdlRnJhbWVEaXNhc3NlbWJsZXIiLCJycGNSZXF1ZXN0IiwibWVzc2FnZUlkIiwibXR1IiwicGFja2V0Q2FsbGJhY2siLCJfcnBjUmVxdWVzdCIsIl9zZXNzaW9uSWQiLCJfbWVzc2FnZUlkIiwiX210dSIsIl9wYWNrZXRDYWxsYmFjayIsImJ1aWxkUlBDIiwiY2IiLCJkb1JlcXVlc3QiLCJfYnVpbGRSUENNYWluQnVmZmVyIiwicnBjQnVsa0RhdGEiLCJqc29uQnVmZmVyIiwiYmZoIiwiaGVhZGVyU2l6ZSIsImJ1bGtEYXRhU2l6ZSIsInRvdGFsTWVzc2FnZVNpemUiLCJtYWluQnVmZmVyIiwiZnJhbWVDb3VudCIsImZ1bGxQYWNrZXQiLCJfY29uc3RydWN0UGFja2V0IiwidmlldyIsIkRhdGFWaWV3Iiwic2V0VWludDMyIiwiZmlyc3RIZWFkZXIiLCJfYnVpbGRDb25zZWN1dGl2ZUZyYW1lcyIsInNkbFBhY2tldCIsImZyYW1lU2VxdWVuY2VOdW1iZXIiLCJjb3VudCIsImhlYWRlciIsIlRyYW5zcG9ydExpc3RlbmVyIiwiX29uVHJhbnNwb3J0RGlzY29ubmVjdGVkIiwiX29uUGFja2V0UmVjZWl2ZWQiLCJzZXRPblRyYW5zcG9ydERpc2Nvbm5lY3RlZCIsInNldE9uUGFja2V0UmVjZWl2ZWQiLCJvblRyYW5zcG9ydERpc2Nvbm5lY3RlZCIsIm9uUGFja2V0UmVjZWl2ZWQiLCJWZXJzaW9uIiwibWFqb3IiLCJtaW5vciIsInBhdGNoIiwic2V0TWFqb3IiLCJzZXRNaW5vciIsInNldFBhdGNoIiwiX21ham9yIiwiZ2V0TWFqb3IiLCJfbWlub3IiLCJnZXRNaW5vciIsIl9wYXRjaCIsImdldFBhdGNoIiwidmVyc2lvbnMiLCJpc05ld2VyVGhhbiIsIlNlcnZpY2VUeXBlIiwiUlBDIiwiQVVESU8iLCJWSURFTyIsIkhZQlJJRCIsIk1lc3NhZ2VGcmFtZUFzc2VtYmxlciIsIl9jYWxsYmFjayIsIl9hY2N1bXVsYXRvciIsIl90b3RhbENvbnNlY3V0aXZlRnJhbWVzIiwiX2NvbnNlY3V0aXZlRnJhbWVzSGFuZGxlZENvdW50IiwiX2NvbnNlY3V0aXZlRnJhbWVzRGF0YUxlbmd0aCIsImhhbmRsZUZyYW1lIiwiX2hhbmRsZU11bHRpRnJhbWVNZXNzYWdlIiwiX2hhbmRsZUZpcnN0RGF0YUZyYW1lIiwiZGF0YUxlbmd0aCIsIl9oYW5kbGVDb25zZWN1dGl2ZUZyYW1lIiwiZnJhbWVTZXF1ZW5jZSIsIndhcm4iLCJmaW5pc2hlZFNkbFBhY2tldCIsIkNvbnRyb2xGcmFtZVRhZ3MiLCJTdGFydFNlcnZpY2VBQ0tCYXNlIiwiTVRVIiwiTkFLQmFzZSIsIlJFSkVDVEVEX1BBUkFNUyIsIlN0YXJ0U2VydmljZVByb3RvY29sVmVyc2lvbiIsIlBST1RPQ09MX1ZFUlNJT04iLCJTdGFydFNlcnZpY2VIYXNoSWQiLCJIQVNIX0lEIiwiU3RhcnRTZXJ2aWNlRGltZW5zaW9ucyIsIkhFSUdIVCIsIldJRFRIIiwiU3RhcnRTZXJ2aWNlIiwiU3RhcnRTZXJ2aWNlQUNLIiwiU0VDT05EQVJZX1RSQU5TUE9SVFMiLCJBVURJT19TRVJWSUNFX1RSQU5TUE9SVFMiLCJWSURFT19TRVJWSUNFX1RSQU5TUE9SVFMiLCJBVVRIX1RPS0VOIiwiU3RhcnRTZXJ2aWNlTkFLIiwiRW5kU2VydmljZSIsIkVuZFNlcnZpY2VBQ0siLCJFbmRTZXJ2aWNlTkFLIiwiVHJhbnNwb3J0RXZlbnRVcGRhdGUiLCJUQ1BfSVBfQUREUkVTUyIsIlRDUF9QT1JUIiwiUmVnaXN0ZXJTZWNvbmRhcnlUcmFuc3BvcnQiLCJSZWdpc3RlclNlY29uZGFyeVRyYW5zcG9ydEFDSyIsIlJlZ2lzdGVyU2Vjb25kYXJ5VHJhbnNwb3J0TkFLIiwiUkVBU09OIiwiQXVkaW8iLCJWaWRlbyIsIlZJREVPX1BST1RPQ09MIiwiVklERU9fQ09ERUMiLCJCaXRDb252ZXJ0ZXIiLCJhcnJheUJ1ZmZlclRvSW50MzIiLCJnZXRVaW50MzIiLCJpbnQzMlRvQXJyYXlCdWZmZXIiLCJTZGxQYWNrZXRGYWN0b3J5IiwiY3JlYXRlSGVhcnRiZWF0QUNLIiwiY3JlYXRlRW5kU2Vzc2lvbiIsImVuZFNlc3Npb24iLCJJbWFnZVR5cGUiLCJTVEFUSUMiLCJEWU5BTUlDIiwiSW1hZ2UiLCJzZXRWYWx1ZSIsIktFWV9WQUxVRSIsImdldFZhbHVlIiwic2V0SW1hZ2VUeXBlIiwiS0VZX0lNQUdFX1RZUEUiLCJnZXRJbWFnZVR5cGUiLCJzZXRJc1RlbXBsYXRlIiwiaXNUZW1wbGF0ZSIsIktFWV9JU19URU1QTEFURSIsImdldElzVGVtcGxhdGUiLCJNZW51UGFyYW1zIiwic2V0UGFyZW50SUQiLCJLRVlfUEFSRU5UX0lEIiwiZ2V0UGFyZW50SUQiLCJzZXRQb3NpdGlvbiIsIktFWV9QT1NJVElPTiIsImdldFBvc2l0aW9uIiwic2V0TWVudU5hbWUiLCJtZW51TmFtZSIsIktFWV9NRU5VX05BTUUiLCJnZXRNZW51TmFtZSIsInNldENtZElEIiwiS0VZX0NNRF9JRCIsImdldENtZElEIiwic2V0TWVudVBhcmFtcyIsIm1lbnVQYXJhbXMiLCJLRVlfTUVOVV9QQVJBTVMiLCJnZXRNZW51UGFyYW1zIiwic2V0VnJDb21tYW5kcyIsInZyQ29tbWFuZHMiLCJLRVlfVlJfQ09NTUFORFMiLCJnZXRWckNvbW1hbmRzIiwic2V0Q21kSWNvbiIsImljb24iLCJLRVlfQ01EX0lDT04iLCJnZXRDbWRJY29uIiwiQWRkQ29tbWFuZFJlc3BvbnNlIiwiUnBjTm90aWZpY2F0aW9uIiwiSE1JTGV2ZWwiLCJITUlfRlVMTCIsIkhNSV9MSU1JVEVEIiwiSE1JX0JBQ0tHUk9VTkQiLCJITUlfTk9ORSIsIkF1ZGlvU3RyZWFtaW5nU3RhdGUiLCJBVURJQkxFIiwiQVRURU5VQVRFRCIsIk5PVF9BVURJQkxFIiwiVmlkZW9TdHJlYW1pbmdTdGF0ZSIsIlNUUkVBTUFCTEUiLCJOT1RfU1RSRUFNQUJMRSIsIlN5c3RlbUNvbnRleHQiLCJTWVNDVFhUX01BSU4iLCJTWVNDVFhUX1ZSU0VTU0lPTiIsIlNZU0NUWFRfTUVOVSIsIlNZU0NUWFRfSE1JX09CU0NVUkVEIiwiU1lTQ1RYVF9BTEVSVCIsIk9uSG1pU3RhdHVzIiwic2V0SE1JTGV2ZWwiLCJobWlMZXZlbCIsIktFWV9ITUlfTEVWRUwiLCJnZXRITUlMZXZlbCIsInNldEF1ZGlvU3RyZWFtaW5nU3RhdGUiLCJhdWRpb1N0cmVhbWluZ1N0YXRlIiwiS0VZX0FVRElPX1NUUkVBTUlOR19TVEFURSIsImdldEF1ZGlvU3RyZWFtaW5nU3RhdGUiLCJzZXRTeXN0ZW1Db250ZXh0Iiwic3lzdGVtQ29udGV4dCIsIktFWV9TWVNURU1fQ09OVEVYVCIsImdldFN5c3RlbUNvbnRleHQiLCJzZXRWaWRlb1N0cmVhbWluZ1N0YXRlIiwidmlkZW9TdHJlYW1pbmdTdGF0ZSIsIktFWV9WSURFT19TVFJFQU1JTkdfU1RBVEUiLCJnZXRWaWRlb1N0cmVhbWluZ1N0YXRlIiwic2V0V2luZG93SUQiLCJ3aW5kb3dJRCIsIktFWV9XSU5ET1dfSUQiLCJnZXRXaW5kb3dJRCIsInNldExhbmd1YWdlIiwibGFuZ3VhZ2UiLCJLRVlfTEFOR1VBR0UiLCJnZXRMYW5ndWFnZSIsInNldEhNSURpc3BsYXlMYW5ndWFnZSIsIktFWV9ITUlfRElTUExBWV9MQU5HVUFHRSIsImdldEhNSURpc3BsYXlMYW5ndWFnZSIsIkZpbGVUeXBlIiwiR1JBUEhJQ19CTVAiLCJHUkFQSElDX0pQRUciLCJHUkFQSElDX1BORyIsIkFVRElPX1dBVkUiLCJBVURJT19BQUMiLCJCSU5BUlkiLCJzZXRGaWxlRGF0YSIsImdldEZpbGVEYXRhIiwic2V0RmlsZU5hbWUiLCJmaWxlTmFtZSIsIktFWV9GSUxFX05BTUUiLCJnZXRGaWxlTmFtZSIsInNldEZpbGVUeXBlIiwiZmlsZVR5cGUiLCJLRVlfRklMRV9UWVBFIiwiZ2V0RmlsZVR5cGUiLCJzZXRQZXJzaXN0ZW50RmlsZSIsInBlcnNpc3RlbnRGaWxlIiwiS0VZX1BFUlNJU1RFTlRfRklMRSIsImdldFBlcnNpc3RlbnRGaWxlIiwic2V0U3lzdGVtRmlsZSIsInN5c3RlbUZpbGUiLCJLRVlfU1lTVEVNX0ZJTEUiLCJnZXRTeXN0ZW1GaWxlIiwic2V0T2Zmc2V0IiwiS0VZX09GRlNFVCIsImdldE9mZnNldCIsInNldExlbmd0aCIsIktFWV9MRU5HVEgiLCJnZXRMZW5ndGgiLCJzZXRDUkMiLCJjcmMiLCJLRVlfQ1JDIiwiZ2V0Q1JDIiwiUHV0RmlsZVJlc3BvbnNlIiwic2V0U3BhY2VBdmFpbGFibGUiLCJzcGFjZUF2YWlsYWJsZSIsIktFWV9TUEFDRV9BVkFJTEFCTEUiLCJnZXRTcGFjZUF2YWlsYWJsZSIsIlRleHRGaWVsZE5hbWUiLCJtYWluRmllbGQxIiwibWFpbkZpZWxkMiIsIm1haW5GaWVsZDMiLCJtYWluRmllbGQ0Iiwic3RhdHVzQmFyIiwibWVkaWFDbG9jayIsIm1lZGlhVHJhY2siLCJ0ZW1wbGF0ZVRpdGxlIiwiYWxlcnRUZXh0MSIsImFsZXJ0VGV4dDIiLCJhbGVydFRleHQzIiwic2Nyb2xsYWJsZU1lc3NhZ2VCb2R5IiwiaW5pdGlhbEludGVyYWN0aW9uVGV4dCIsIm5hdmlnYXRpb25UZXh0MSIsIm5hdmlnYXRpb25UZXh0MiIsIkVUQSIsInRvdGFsRGlzdGFuY2UiLCJhdWRpb1Bhc3NUaHJ1RGlzcGxheVRleHQxIiwiYXVkaW9QYXNzVGhydURpc3BsYXlUZXh0MiIsInNsaWRlckhlYWRlciIsInNsaWRlckZvb3RlciIsInNlY29uZGFyeVRleHQiLCJ0ZXJ0aWFyeVRleHQiLCJtZW51VGl0bGUiLCJsb2NhdGlvbk5hbWUiLCJsb2NhdGlvbkRlc2NyaXB0aW9uIiwiYWRkcmVzc0xpbmVzIiwicGhvbmVOdW1iZXIiLCJDaGFyYWN0ZXJTZXQiLCJUWVBFMlNFVCIsIlRZUEU1U0VUIiwiQ0lEMVNFVCIsIkNJRDJTRVQiLCJUZXh0RmllbGQiLCJzZXRUZXh0RmllbGROYW1lIiwidGV4dEZpZWxkTmFtZSIsIktFWV9OQU1FIiwiZ2V0VGV4dEZpZWxkTmFtZSIsInNldENoYXJhY3RlclNldCIsImNoYXJhY3RlclNldCIsIktFWV9DSEFSQUNURVJfU0VUIiwiZ2V0Q2hhcmFjdGVyU2V0Iiwic2V0V2lkdGgiLCJ3aWR0aCIsIktFWV9XSURUSCIsImdldFdpZHRoIiwic2V0Um93cyIsInJvd3MiLCJLRVlfUk9XUyIsImdldFJvd3MiLCJJbWFnZVJlc29sdXRpb24iLCJzZXRSZXNvbHV0aW9uV2lkdGgiLCJyZXNvbHV0aW9uV2lkdGgiLCJLRVlfUkVTT0xVVElPTl9XSURUSCIsImdldFJlc29sdXRpb25XaWR0aCIsInNldFJlc29sdXRpb25IZWlnaHQiLCJyZXNvbHV0aW9uSGVpZ2h0IiwiS0VZX1JFU09MVVRJT05fSEVJR0hUIiwiZ2V0UmVzb2x1dGlvbkhlaWdodCIsIkltYWdlRmllbGROYW1lIiwic29mdEJ1dHRvbkltYWdlIiwiY2hvaWNlSW1hZ2UiLCJjaG9pY2VTZWNvbmRhcnlJbWFnZSIsInZySGVscEl0ZW0iLCJ0dXJuSWNvbiIsIm1lbnVJY29uIiwiY21kSWNvbiIsImdyYXBoaWMiLCJzZWNvbmRhcnlHcmFwaGljIiwic2hvd0NvbnN0YW50VEJUSWNvbiIsInNob3dDb25zdGFudFRCVE5leHRUdXJuSWNvbiIsImxvY2F0aW9uSW1hZ2UiLCJhbGVydEljb24iLCJJbWFnZUZpZWxkIiwic2V0SW1hZ2VGaWVsZE5hbWUiLCJpbWFnZUZpZWxkTmFtZSIsImdldEltYWdlRmllbGROYW1lIiwic2V0SW1hZ2VUeXBlU3VwcG9ydGVkIiwiaW1hZ2VUeXBlU3VwcG9ydGVkIiwiS0VZX0lNQUdFX1RZUEVfU1VQUE9SVEVEIiwiZ2V0SW1hZ2VUeXBlU3VwcG9ydGVkIiwic2V0SW1hZ2VSZXNvbHV0aW9uIiwiaW1hZ2VSZXNvbHV0aW9uIiwiS0VZX0lNQUdFX1JFU09MVVRJT04iLCJnZXRJbWFnZVJlc29sdXRpb24iLCJUb3VjaEV2ZW50Q2FwYWJpbGl0aWVzIiwic2V0UHJlc3NBdmFpbGFibGUiLCJwcmVzc0F2YWlsYWJsZSIsIktFWV9QUkVTU19BVkFJTEFCTEUiLCJnZXRQcmVzc0F2YWlsYWJsZSIsInNldE11bHRpVG91Y2hBdmFpbGFibGUiLCJtdWx0aVRvdWNoQXZhaWxhYmxlIiwiS0VZX01VTFRJX1RPVUNIX0FWQUlMQUJMRSIsImdldE11bHRpVG91Y2hBdmFpbGFibGUiLCJzZXREb3VibGVQcmVzc0F2YWlsYWJsZSIsImRvdWJsZVByZXNzQXZhaWxhYmxlIiwiS0VZX0RPVUJMRV9QUkVTU19BVkFJTEFCTEUiLCJnZXREb3VibGVQcmVzc0F2YWlsYWJsZSIsIlNjcmVlblBhcmFtcyIsInNldFJlc29sdXRpb24iLCJyZXNvbHV0aW9uIiwiS0VZX1JFU09MVVRJT04iLCJnZXRSZXNvbHV0aW9uIiwic2V0VG91Y2hFdmVudEF2YWlsYWJsZSIsInRvdWNoRXZlbnRDYXBhYmlsaXRpZXMiLCJLRVlfVE9VQ0hfRVZFTlRfQVZBSUxBQkxFIiwiZ2V0VG91Y2hFdmVudEF2YWlsYWJsZSIsIkRpc3BsYXlUeXBlIiwiQ0lEIiwiVFlQRTIiLCJUWVBFNSIsIk5HTiIsIkdFTjJfOF9ETUEiLCJHRU4yXzZfRE1BIiwiTUZEMyIsIk1GRDQiLCJNRkQ1IiwiR0VOM184X0lOQ0giLCJTRExfR0VORVJJQyIsIk1lZGlhQ2xvY2tGb3JtYXQiLCJDTE9DSzEiLCJDTE9DSzIiLCJDTE9DSzMiLCJDTE9DS1RFWFQxIiwiQ0xPQ0tURVhUMiIsIkNMT0NLVEVYVDMiLCJDTE9DS1RFWFQ0IiwiRGlzcGxheUNhcGFiaWxpdGllcyIsInNldERpc3BsYXlUeXBlIiwiZGlzcGxheVR5cGUiLCJLRVlfRElTUExBWV9UWVBFIiwiZ2V0RGlzcGxheVR5cGUiLCJzZXREaXNwbGF5TmFtZSIsImRpc3BsYXlOYW1lIiwiS0VZX0RJU1BMQVlfTkFNRSIsImdldERpc3BsYXlOYW1lIiwic2V0VGV4dEZpZWxkcyIsInRleHRGaWVsZHMiLCJLRVlfVEVYVF9GSUVMRFMiLCJnZXRUZXh0RmllbGRzIiwic2V0SW1hZ2VGaWVsZHMiLCJpbWFnZUZpZWxkcyIsIktFWV9JTUFHRV9GSUVMRFMiLCJnZXRJbWFnZUZpZWxkcyIsInNldE1lZGlhQ2xvY2tGb3JtYXRzIiwibWVkaWFDbG9ja0Zvcm1hdHMiLCJLRVlfTUVESUFfQ0xPQ0tfRk9STUFUUyIsImdldE1lZGlhQ2xvY2tGb3JtYXRzIiwic2V0R3JhcGhpY3NTdXBwb3J0ZWQiLCJncmFwaGljU3VwcG9ydGVkIiwiS0VZX0dSQVBISUNTX1NVUFBPUlRFRCIsImdldEdyYXBoaWNzU3VwcG9ydGVkIiwic2V0VGVtcGxhdGVzQXZhaWxhYmxlIiwidGVtcGxhdGVzQXZhaWxhYmxlIiwiS0VZX1RFTVBMQVRFU19BVkFJTEFCTEUiLCJnZXRUZW1wbGF0ZXNBdmFpbGFibGUiLCJzZXRTY3JlZW5QYXJhbXMiLCJzY3JlZW5QYXJhbXMiLCJLRVlfU0NSRUVOX1BBUkFNUyIsImdldFNjcmVlblBhcmFtcyIsInNldE51bUN1c3RvbVByZXNldHNBdmFpbGFibGUiLCJudW1DdXN0b21QcmVzZXRzQXZhaWxhYmxlIiwiS0VZX05VTV9DVVNUT01fUFJFU0VUU19BVkFJTEFCTEUiLCJnZXROdW1DdXN0b21QcmVzZXRzQXZhaWxhYmxlIiwiR3JpZCIsInNldENvbHVtbiIsImNvbHVtbiIsIktFWV9DT0xVTU4iLCJnZXRDb2x1bW4iLCJzZXRSb3ciLCJyb3ciLCJLRVlfUk9XIiwiZ2V0Um93Iiwic2V0TGV2ZWwiLCJsZXZlbCIsIktFWV9MRVZFTCIsImdldExldmVsIiwic2V0Q29sdW1uU3BhbiIsImNvbHVtblNwYW4iLCJLRVlfQ09MVU1OX1NQQU4iLCJnZXRDb2x1bW5TcGFuIiwic2V0Um93U3BhbiIsInJvd1NwYW4iLCJLRVlfUk9XX1NQQU4iLCJnZXRSb3dTcGFuIiwic2V0TGV2ZWxTcGFuIiwibGV2ZWxTcGFuIiwiS0VZX0xFVkVMX1NQQU4iLCJnZXRMZXZlbFNwYW4iLCJNb2R1bGVJbmZvIiwic2V0TW9kdWxlSWQiLCJLRVlfTU9EVUxFX0lEIiwiZ2V0TW9kdWxlSWQiLCJzZXRMb2NhdGlvbiIsImxvY2F0aW9uIiwiS0VZX0xPQ0FUSU9OIiwiZ2V0TG9jYXRpb24iLCJzZXRTZXJ2aWNlQXJlYSIsInNlcnZpY2VBcmVhIiwiS0VZX1NFUlZJQ0VfQVJFQSIsImdldFNlcnZpY2VBcmVhIiwic2V0QWxsb3dNdWx0aXBsZUFjY2VzcyIsImFsbG93TXVsdGlwbGVBY2Nlc3MiLCJLRVlfQUxMT1dfTVVMVElQTEVfQUNDRVNTIiwiZ2V0QWxsb3dNdWx0aXBsZUFjY2VzcyIsIkJ1dHRvbk5hbWUiLCJPSyIsIlBMQVlfUEFVU0UiLCJTRUVLTEVGVCIsIlNFRUtSSUdIVCIsIlRVTkVVUCIsIlRVTkVET1dOIiwiUFJFU0VUXzAiLCJQUkVTRVRfMSIsIlBSRVNFVF8yIiwiUFJFU0VUXzMiLCJQUkVTRVRfNCIsIlBSRVNFVF81IiwiUFJFU0VUXzYiLCJQUkVTRVRfNyIsIlBSRVNFVF84IiwiUFJFU0VUXzkiLCJDVVNUT01fQlVUVE9OIiwiU0VBUkNIIiwiQUNfTUFYIiwiQUMiLCJSRUNJUkNVTEFURSIsIkZBTl9VUCIsIkZBTl9ET1dOIiwiVEVNUF9VUCIsIlRFTVBfRE9XTiIsIkRFRlJPU1RfTUFYIiwiREVGUk9TVCIsIkRFRlJPU1RfUkVBUiIsIlVQUEVSX1ZFTlQiLCJMT1dFUl9WRU5UIiwiVk9MVU1FX1VQIiwiVk9MVU1FX0RPV04iLCJFSkVDVCIsIlNPVVJDRSIsIlNIVUZGTEUiLCJSRVBFQVQiLCJOQVZfQ0VOVEVSX0xPQ0FUSU9OIiwiTkFWX1pPT01fSU4iLCJOQVZfWk9PTV9PVVQiLCJOQVZfUEFOX1VQIiwiTkFWX1BBTl9VUF9SSUdIVCIsIk5BVl9QQU5fUklHSFQiLCJOQVZfUEFOX0RPV05fUklHSFQiLCJOQVZfUEFOX0RPV04iLCJOQVZfUEFOX0RPV05fTEVGVCIsIk5BVl9QQU5fTEVGVCIsIk5BVl9QQU5fVVBfTEVGVCIsIk5BVl9USUxUX1RPR0dMRSIsIk5BVl9ST1RBVEVfQ0xPQ0tXSVNFIiwiTkFWX1JPVEFURV9DT1VOVEVSQ0xPQ0tXSVNFIiwiTkFWX0hFQURJTkdfVE9HR0xFIiwiQnV0dG9uQ2FwYWJpbGl0aWVzIiwic2V0TmFtZSIsImdldE5hbWUiLCJzZXRNb2R1bGVJbmZvIiwibW9kdWxlSW5mbyIsIktFWV9NT0RVTEVfSU5GTyIsImdldE1vZHVsZUluZm8iLCJzZXRTaG9ydFByZXNzQXZhaWxhYmxlIiwic2hvcnRQcmVzc0F2YWlsYWJsZSIsIktFWV9TSE9SVF9QUkVTU19BVkFJTEFCTEUiLCJnZXRTaG9ydFByZXNzQXZhaWxhYmxlIiwic2V0TG9uZ1ByZXNzQXZhaWxhYmxlIiwibG9uZ1ByZXNzQXZhaWxhYmxlIiwiS0VZX0xPTkdfUFJFU1NfQVZBSUxBQkxFIiwiZ2V0TG9uZ1ByZXNzQXZhaWxhYmxlIiwic2V0VXBEb3duQXZhaWxhYmxlIiwidXBEb3duQXZhaWxhYmxlIiwiS0VZX1VQX0RPV05fQVZBSUxBQkxFIiwiZ2V0VXBEb3duQXZhaWxhYmxlIiwiU29mdEJ1dHRvbkNhcGFiaWxpdGllcyIsInNldEltYWdlU3VwcG9ydGVkIiwiaW1hZ2VTdXBwb3J0ZWQiLCJLRVlfSU1BR0VfU1VQUE9SVEVEIiwiZ2V0SW1hZ2VTdXBwb3J0ZWQiLCJzZXRUZXh0U3VwcG9ydGVkIiwidGV4dFN1cHBvcnRlZCIsIktFWV9URVhUX1NVUFBPUlRFRCIsImdldFRleHRTdXBwb3J0ZWQiLCJQcmVzZXRCYW5rQ2FwYWJpbGl0aWVzIiwic2V0T25TY3JlZW5QcmVzZXRzQXZhaWxhYmxlIiwib25TY3JlZW5QcmVzZXRzQXZhaWxhYmxlIiwiS0VZX09OX1NDUkVFTl9QUkVTRVRTX0FWQUlMQUJMRSIsImdldE9uU2NyZWVuUHJlc2V0c0F2YWlsYWJsZSIsIlZlaGljbGVUeXBlIiwic2V0TWFrZSIsIm1ha2UiLCJLRVlfTUFLRSIsImdldE1ha2UiLCJzZXRNb2RlbCIsIm1vZGVsIiwiS0VZX01PREVMIiwiZ2V0TW9kZWwiLCJzZXRNb2RlbFllYXIiLCJtb2RlbFllYXIiLCJLRVlfTU9ERUxfWUVBUiIsImdldE1vZGVsWWVhciIsInNldFRyaW0iLCJLRVlfVFJJTSIsImdldFRyaW0iLCJIbWlab25lQ2FwYWJpbGl0aWVzIiwiRlJPTlQiLCJCQUNLIiwiUHJlcmVjb3JkZWRTcGVlY2giLCJIRUxQX0pJTkdMRSIsIklOSVRJQUxfSklOR0xFIiwiTElTVEVOX0pJTkdMRSIsIlBPU0lUSVZFX0pJTkdMRSIsIk5FR0FUSVZFX0pJTkdMRSIsIlNhbXBsaW5nUmF0ZSIsIlNhbXBsaW5nUmF0ZV84S0haIiwiU2FtcGxpbmdSYXRlXzE2S0haIiwiU2FtcGxpbmdSYXRlXzIyS0haIiwiU2FtcGxpbmdSYXRlXzQ0S0haIiwiQml0c1BlclNhbXBsZSIsIkJpdHNQZXJTYW1wbGVfOF9CSVQiLCJCaXRzUGVyU2FtcGxlXzE2X0JJVCIsIkF1ZGlvVHlwZSIsIlBDTSIsIkF1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXMiLCJzZXRTYW1wbGluZ1JhdGUiLCJzYW1wbGluZ1JhdGUiLCJLRVlfU0FNUExJTkdfUkFURSIsImdldFNhbXBsaW5nUmF0ZSIsInNldEJpdHNQZXJTYW1wbGUiLCJiaXRzUGVyU2FtcGxlIiwiS0VZX0JJVFNfUEVSX1NBTVBMRSIsImdldEJpdHNQZXJTYW1wbGUiLCJzZXRBdWRpb1R5cGUiLCJhdWRpb1R5cGUiLCJLRVlfQVVESU9fVFlQRSIsImdldEF1ZGlvVHlwZSIsIlZyQ2FwYWJpbGl0aWVzIiwiVlJfVEVYVCIsIkhNSUNhcGFiaWxpdGllcyIsInNldE5hdmlnYXRpb24iLCJuYXZpZ2F0aW9uIiwiS0VZX05BVklHQVRJT04iLCJnZXROYXZpZ2F0aW9uIiwic2V0UGhvbmVDYWxsIiwicGhvbmVDYWxsIiwiS0VZX1BIT05FX0NBTEwiLCJnZXRQaG9uZUNhbGwiLCJzZXRWaWRlb1N0cmVhbWluZyIsInZpZGVvU3RyZWFtaW5nIiwiS0VZX1ZJREVPX1NUUkVBTUlORyIsImdldFZpZGVvU3RyZWFtaW5nIiwic2V0UmVtb3RlQ29udHJvbCIsInJlbW90ZUNvbnRyb2wiLCJLRVlfUkVNT1RFX0NPTlRST0wiLCJnZXRSZW1vdGVDb250cm9sIiwic2V0QXBwU2VydmljZSIsImFwcFNlcnZpY2VzIiwiS0VZX0FQUF9TRVJWSUNFUyIsImdldEFwcFNlcnZpY2UiLCJzZXREaXNwbGF5cyIsImRpc3BsYXlzIiwiS0VZX0RJU1BMQVlTIiwiZ2V0RGlzcGxheXMiLCJzZXRTZWF0TG9jYXRpb24iLCJzZWF0TG9jYXRpb24iLCJLRVlfU0VBVF9MT0NBVElPTiIsImdldFNlYXRMb2NhdGlvbiIsIlJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UiLCJzZXRIbWlEaXNwbGF5TGFuZ3VhZ2UiLCJobWlEaXNwbGF5TGFuZ3VhZ2UiLCJnZXRIbWlEaXNwbGF5TGFuZ3VhZ2UiLCJzZXREaXNwbGF5Q2FwYWJpbGl0aWVzIiwiZGlzcGxheUNhcGFiaWxpdGllcyIsIktFWV9ESVNQTEFZX0NBUEFCSUxJVElFUyIsImdldERpc3BsYXlDYXBhYmlsaXRpZXMiLCJzZXRCdXR0b25DYXBhYmlsaXRpZXMiLCJidXR0b25DYXBhYmlsaXRpZXMiLCJLRVlfQlVUVE9OX0NBUEFCSUxJVElFUyIsImdldEJ1dHRvbkNhcGFiaWxpdGllcyIsInNldFNvZnRCdXR0b25DYXBhYmlsaXRpZXMiLCJzb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzIiwiS0VZX1NPRlRfQlVUVE9OX0NBUEFCSUxJVElFUyIsImdldFNvZnRCdXR0b25DYXBhYmlsaXRpZXMiLCJzZXRQcmVzZXRCYW5rQ2FwYWJpbGl0aWVzIiwicHJlc2V0QmFua0NhcGFiaWxpdGllcyIsIktFWV9QUkVTRVRfQkFOS19DQVBBQklMSVRJRVMiLCJnZXRQcmVzZXRCYW5rQ2FwYWJpbGl0aWVzIiwic2V0SG1pWm9uZUNhcGFiaWxpdGllcyIsImhtaVpvbmVDYXBhYmlsaXRpZXMiLCJLRVlfSE1JX1pPTkVfQ0FQQUJJTElUSUVTIiwiZ2V0SG1pWm9uZUNhcGFiaWxpdGllcyIsInNldFNwZWVjaENhcGFiaWxpdGllcyIsInNwZWVjaENhcGFiaWxpdGllcyIsIktFWV9TUEVFQ0hfQ0FQQUJJTElUSUVTIiwiZ2V0U3BlZWNoQ2FwYWJpbGl0aWVzIiwic2V0UHJlcmVjb3JkZWRTcGVlY2giLCJLRVlfUFJFUkVDT1JERURfU1BFRUNIIiwiZ2V0UHJlcmVjb3JkZWRTcGVlY2giLCJzZXRWckNhcGFiaWxpdGllcyIsInZyQ2FwYWJpbGl0aWVzIiwiS0VZX1ZSX0NBUEFCSUxJVElFUyIsImdldFZyQ2FwYWJpbGl0aWVzIiwic2V0QXVkaW9QYXNzVGhydUNhcGFiaWxpdGllcyIsImF1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXMiLCJLRVlfQVVESU9fUEFTU19USFJVX0NBUEFCSUxJVElFUyIsImdldEF1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXMiLCJzZXRQY21TdHJlYW1DYXBhYmlsaXRpZXMiLCJwY21TdHJlYW1DYXBhYmlsaXRpZXMiLCJLRVlfUENNX1NUUkVBTV9DQVBBQklMSVRJRVMiLCJnZXRQY21TdHJlYW1DYXBhYmlsaXRpZXMiLCJzZXRWZWhpY2xlVHlwZSIsInZlaGljbGVUeXBlIiwiS0VZX1ZFSElDTEVfVFlQRSIsImdldFZlaGljbGVUeXBlIiwic2V0U3VwcG9ydGVkRGlhZ01vZGVzIiwic3VwcG9ydGVkRGlhZ01vZGVzIiwiS0VZX1NVUFBPUlRFRF9ESUFHX01PREUiLCJnZXRTdXBwb3J0ZWREaWFnTW9kZXMiLCJzZXRITUlDYXBhYmlsaXRpZXMiLCJobWlDYXBhYmlsaXRpZXMiLCJLRVlfSE1JX0NBUEFCSUxJVElFUyIsImdldEhNSUNhcGFiaWxpdGllcyIsInNldFNkbFZlcnNpb24iLCJzZGxWZXJzaW9uIiwiS0VZX1NETF9WRVJTSU9OIiwiZ2V0U2RsVmVyc2lvbiIsInNldFN5c3RlbVNvZnR3YXJlVmVyc2lvbiIsInN5c3RlbVNvZnR3YXJlVmVyc2lvbiIsIktFWV9TWVNURU1fU09GVFdBUkVfVkVSU0lPTiIsImdldFN5c3RlbVNvZnR3YXJlVmVyc2lvbiIsInNldEljb25SZXN1bWVkIiwiaWNvblJlc3VtZWQiLCJLRVlfSUNPTl9SRVNVTUVEIiwiZ2V0SWNvblJlc3VtZWQiLCJTZXRBcHBJY29uUmVzcG9uc2UiLCJTb2Z0QnV0dG9uVHlwZSIsIlNCVF9URVhUIiwiU0JUX0lNQUdFIiwiU0JUX0JPVEgiLCJTeXN0ZW1BY3Rpb24iLCJERUZBVUxUX0FDVElPTiIsIlNURUFMX0ZPQ1VTIiwiS0VFUF9DT05URVhUIiwiU29mdEJ1dHRvbiIsInNldEltYWdlIiwiaW1hZ2UiLCJLRVlfSU1BR0UiLCJnZXRJbWFnZSIsInNldElzSGlnaGxpZ2h0ZWQiLCJpc0hpZ2hsaWdodGVkIiwiS0VZX0lTX0hJR0hMSUdIVEVEIiwiZ2V0SXNIaWdobGlnaHRlZCIsInNldFNvZnRCdXR0b25JRCIsInNvZnRCdXR0b25JRCIsIktFWV9TT0ZUX0JVVFRPTl9JRCIsImdldFNvZnRCdXR0b25JRCIsInNldFN5c3RlbUFjdGlvbiIsInN5c3RlbUFjdGlvbiIsIktFWV9TWVNURU1fQUNUSU9OIiwiZ2V0U3lzdGVtQWN0aW9uIiwiTWV0YWRhdGFUeXBlIiwibWVkaWFUaXRsZSIsIm1lZGlhQXJ0aXN0IiwibWVkaWFBbGJ1bSIsIm1lZGlhWWVhciIsIm1lZGlhR2VucmUiLCJtZWRpYVN0YXRpb24iLCJyYXRpbmciLCJjdXJyZW50VGVtcGVyYXR1cmUiLCJtYXhpbXVtVGVtcGVyYXR1cmUiLCJtaW5pbXVtVGVtcGVyYXR1cmUiLCJ3ZWF0aGVyVGVybSIsImh1bWlkaXR5IiwiTWV0YWRhdGFUYWdzIiwic2V0TWFpbkZpZWxkMSIsIktFWV9NQUlOX0ZJRUxEXzEiLCJnZXRNYWluRmllbGQxIiwic2V0TWFpbkZpZWxkMiIsIktFWV9NQUlOX0ZJRUxEXzIiLCJnZXRNYWluRmllbGQyIiwic2V0TWFpbkZpZWxkMyIsIktFWV9NQUlOX0ZJRUxEXzMiLCJnZXRNYWluRmllbGQzIiwic2V0TWFpbkZpZWxkNCIsIktFWV9NQUlOX0ZJRUxEXzQiLCJnZXRNYWluRmllbGQ0IiwiVGV4dEFsaWdubWVudCIsIkxFRlRfQUxJR05FRCIsIlJJR0hUX0FMSUdORUQiLCJDRU5URVJFRCIsInNldEFsaWdubWVudCIsImFsaWdubWVudCIsIktFWV9BTElHTk1FTlQiLCJnZXRBbGlnbm1lbnQiLCJzZXRTdGF0dXNCYXIiLCJLRVlfU1RBVFVTX0JBUiIsImdldFN0YXR1c0JhciIsInNldE1lZGlhQ2xvY2siLCJLRVlfTUVESUFfQ0xPQ0siLCJnZXRNZWRpYUNsb2NrIiwic2V0TWVkaWFUcmFjayIsIktFWV9NRURJQV9UUkFDSyIsImdldE1lZGlhVHJhY2siLCJzZXRHcmFwaGljIiwiS0VZX0dSQVBISUMiLCJnZXRHcmFwaGljIiwic2V0U2Vjb25kYXJ5R3JhcGhpYyIsIktFWV9TRUNPTkRBUllfR1JBUEhJQyIsImdldFNlY29uZGFyeUdyYXBoaWMiLCJzZXRTb2Z0QnV0dG9ucyIsInNvZnRCdXR0b25zIiwiS0VZX1NPRlRfQlVUVE9OUyIsImdldFNvZnRCdXR0b25zIiwic2V0Q3VzdG9tUHJlc2V0cyIsImN1c3RvbVByZXNldHMiLCJLRVlfQ1VTVE9NX1BSRVNFVFMiLCJnZXRDdXN0b21QcmVzZXRzIiwic2V0TWV0YWRhdGFUYWdzIiwibWV0YWRhdGFUYWdzIiwiS0VZX01FVEFEQVRBX1RBR1MiLCJnZXRNZXRhZGF0YVRhZ3MiLCJzZXRUZW1wbGF0ZVRpdGxlIiwiS0VZX1RFTVBMQVRFX1RJVExFIiwiZ2V0VGVtcGxhdGVUaXRsZSIsIlNob3dSZXNwb25zZSIsIlVucmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZSIsIlJwY0NyZWF0b3IiLCJjb25zdHJ1Y3QiLCJycGNOYW1lIiwianNvbkRhdGEiLCJWaWRlb1N0cmVhbWluZ1Byb3RvY29sIiwiUkFXIiwiUlRQIiwiUlRTUCIsIlJUTVAiLCJXRUJNIiwiVmlkZW9TdHJlYW1pbmdDb2RlYyIsIkgyNjQiLCJIMjY1IiwiVGhlb3JhIiwiVlA4IiwiVlA5IiwiVmlkZW9TdHJlYW1pbmdGb3JtYXQiLCJzZXRQcm90b2NvbCIsIktFWV9QUk9UT0NPTCIsImdldFByb3RvY29sIiwic2V0Q29kZWMiLCJLRVlfQ09ERUMiLCJnZXRDb2RlYyIsIlNkbFByb3RvY29sQmFzZSIsImJhc2VUcmFuc3BvcnRDb25maWciLCJzZGxQcm90b2NvbExpc3RlbmVyIiwiX2Jhc2VUcmFuc3BvcnRDb25maWciLCJfc2RsUHJvdG9jb2xMaXN0ZW5lciIsIl90cmFuc3BvcnRNYW5hZ2VyIiwicmVzZXQiLCJfY3JlYXRlVHJhbnNwb3J0TGlzdGVuZXIiLCJfcHJvdG9jb2xWZXJzaW9uIiwiX2hlYWRlclNpemUiLCJWMV9IRUFERVJfU0laRSIsIl9zZXJ2aWNlU3RhdHVzIiwiX210dXMiLCJWMV9WMl9NVFVfU0laRSIsIl9oYXNoSUQiLCJfbWVzc2FnZUZyYW1lQXNzZW1ibGVycyIsInNldFRyYW5zcG9ydE1hbmFnZXIiLCJtYW5hZ2VyIiwic3RhcnRTZXJ2aWNlIiwiX3RyYW5zcG9ydExpc3RlbmVyIiwiX2hhbmRsZVRyYW5zcG9ydENvbm5lY3RlZCIsIl9oYW5kbGVQYWNrZXRSZWNlaXZlZCIsInByb3RvY29sVmVyc2lvbiIsIk1BWF9QUk9UT0NPTF9WRVJTSU9OIiwic2VuZFBhY2tldCIsInZpZGVvU3RyZWFtaW5nUGFyYW1ldGVycyIsImRlc2lyZWRSZXNvbHV0aW9uIiwiZGVzaXJlZEZvcm1hdCIsImdldEZvcm1hdCIsImdldE10dSIsInJldFZhbCIsImlzQ29ubmVjdGVkIiwiZ2V0UHJvdG9jb2xWZXJzaW9uIiwiX3NldFZlcnNpb24iLCJWMl9IRUFERVJfU0laRSIsIlYzX1Y0X01UVV9TSVpFIiwiX2dldE5leHRNZXNzYWdlSUQiLCJzZW5kUnBjIiwiX2hhbmRsZUNvbnRyb2xQYWNrZXQiLCJtZXNzYWdlRnJhbWVBc3NlbWJsZXIiLCJfZ2V0TWVzc2FnZUZyYW1lQXNzZW1ibGVyIiwiX2hhbmRsZU9uTWVzc2FnZUFzc2VtYmxlZCIsIl9oYW5kbGVSUENQYWNrZXQiLCJfaGFuZGxlUHJvdG9jb2xIZWFydGJlYXQiLCJfaGFuZGxlUHJvdG9jb2xIZWFydGJlYXRBQ0siLCJfaGFuZGxlU3RhcnRTZXJ2aWNlQUNLIiwiX2hhbmRsZVN0YXJ0U2VydmljZU5BSyIsIl9oYW5kbGVFbmRTZXJ2aWNlQUNLIiwiX2hhbmRsZUVuZFNlcnZpY2UiLCJfaGFuZGxlRW5kU2VydmljZU5BSyIsImhlYXJ0YmVhdCIsIm10dVRhZyIsIk5BViIsImFjY2VwdGVkUmVzb2x1dGlvbiIsImFjY2VwdGVkRm9ybWF0IiwiYWdyZWVkVmlkZW9QYXJhbXMiLCJzZXRGb3JtYXQiLCJfaGFuZGxlU2VydmljZUVuZGVkIiwicmVqZWN0ZWRUYWciLCJyZWplY3RlZFBhcmFtcyIsImVuZFNlcnZpY2UiLCJUcmFuc3BvcnRUeXBlIiwiV0VCU09DS0VUX0NMSUVOVCIsIldFQlNPQ0tFVF9TRVJWRVIiLCJDVVNUT00iLCJTZGxQc20iLCJfc3RhdGUiLCJTVEFSVF9TVEFURSIsIl9jb250cm9sRnJhbWVJbmZvIiwiX2R1bXBTaXplIiwiX2RhdGFMZW5ndGgiLCJnZXRTdGF0ZSIsImdldEZvcm1lZFBhY2tldCIsIkZJTklTSEVEX1NUQVRFIiwiaGFuZGxlQnl0ZSIsIl90cmFuc2l0aW9uT25JbnB1dCIsIkVSUk9SX1NUQVRFIiwicmF3Qnl0ZSIsInN0YXRlIiwiVkVSU0lPTl9NQVNLIiwiRlJBTUVfVFlQRV9NQVNLIiwiU0VSVklDRV9UWVBFX1NUQVRFIiwiQ09OVFJPTF9GUkFNRV9JTkZPX1NUQVRFIiwiU0VTU0lPTl9JRF9TVEFURSIsIkRBVEFfU0laRV8xX1NUQVRFIiwiREFUQV9TSVpFXzJfU1RBVEUiLCJEQVRBX1NJWkVfM19TVEFURSIsIkRBVEFfU0laRV80X1NUQVRFIiwiREFUQV9QVU1QX1NUQVRFIiwiRklSU1RfRlJBTUVfREFUQV9TSVpFIiwiTUVTU0FHRV8xX1NUQVRFIiwiTUVTU0FHRV8yX1NUQVRFIiwiTUVTU0FHRV8zX1NUQVRFIiwiTUVTU0FHRV80X1NUQVRFIiwiVHJhbnNwb3J0QmFzZSIsInRyYW5zcG9ydENhbGxiYWNrIiwiX3NkbFBzbSIsIl90cmFuc3BvcnRDYWxsYmFjayIsInN0b3AiLCJzZXRUcmFuc3BvcnRDYWxsYmFjayIsIldlYlNvY2tldENsaWVudCIsImNvbmZpZyIsIl9xdWV1ZSIsIl9pc1J1bm5pbmciLCJfd3NVcmwiLCJnZXRIb3N0IiwiZ2V0UG9ydCIsIl93cyIsIl9pbml0IiwiV2ViU29ja2V0Iiwib25vcGVuIiwib25Db25uZWN0aW9uRXN0YWJsaXNoZWQiLCJvbmVycm9yIiwib25tZXNzYWdlIiwiX2hhbmRsZUluY29taW5nIiwib25jbG9zZSIsIm9uQ29ubmVjdGlvblRlcm1pbmF0ZWQiLCJjbG9zZSIsInBhY2tldCIsInNlbmQiLCJfbXVsdGlCeXRlSGFuZGxlciIsIm1zZ0RhdGEiLCJSZXNwb25zZSIsImFycmF5QnVmZmVyIiwidGhlbiIsIl9oYW5kbGVCeXRlIiwiaXNGaW5pc2hlZCIsIlRyYW5zcG9ydENhbGxiYWNrIiwiX29uQ29ubmVjdGlvbkVzdGFibGlzaGVkIiwiX29uQ29ubmVjdGlvblRlcm1pbmF0ZWQiLCJzZXRPbkNvbm5lY3Rpb25Fc3RhYmxpc2hlZCIsInNldE9uQ29ubmVjdGlvblRlcm1pbmF0ZWQiLCJUcmFuc3BvcnRNYW5hZ2VyQmFzZSIsInRyYW5zcG9ydExpc3RlbmVyIiwiX3RyYW5zcG9ydCIsIl9pc0Nvbm5lY3RlZCIsImdldFRyYW5zcG9ydFR5cGUiLCJnZXRUcmFuc3BvcnQiLCJ0cmFuc3BvcnRUeXBlIiwiYWRkcmVzcyIsIlNzbENvbmZpZyIsInBlbUNlcnRpZmljYXRlIiwicHJpdmF0ZUtleSIsInBhc3N3b3JkIiwiX3BlbUNlcnRpZmljYXRlIiwiX3ByaXZhdGVLZXkiLCJfcGFzc3dvcmQiLCJnZXRQZW1DZXJ0aWZpY2F0ZSIsImdldFByaXZhdGVLZXkiLCJnZXRQYXNzd29yZCIsInJlcXVpcmUkJDEiLCJyZXF1aXJlJCQyIiwiV2ViU29ja2V0U2VydmVyIiwiZ2V0U3NsQ29uZmlnIiwic2VydmVyIiwiaHR0cHMiLCJjcmVhdGVTZXJ2ZXIiLCJjZXJ0IiwicGFzc3BocmFzZSIsIlNlcnZlciIsImxpc3RlbiIsInBvcnQiLCJvbiIsImNvbm5lY3Rpb24iLCJfaGFuZGxlTWVzc2FnZSIsImVycm9yRXZlbnQiLCJpc0FsaXZlIiwiZ2V0Q29ubmVjdGlvbkxvc3RUaW1lb3V0Iiwic2V0SW50ZXJ2YWwiLCJjbGllbnRzIiwiZWFjaCIsImNsaWVudCIsInRlcm1pbmF0ZSIsInBpbmciLCJyZWFkeVN0YXRlIiwiT1BFTiIsInN0YXRlUHJvZ3Jlc3MiLCJtZXNzYWdlSW5kZXgiLCJUcmFuc3BvcnRNYW5hZ2VyIiwiU2RsUHJvdG9jb2wiLCJTZXJ2aWNlTGlzdGVuZXJNYXAiLCJfbGlzdGVuZXJzIiwiYWRkTGlzdGVuZXIiLCJzZXJ2aWNlTGlzdGVuZXIiLCJyZW1vdmVMaXN0ZW5lciIsImxpc3RlbmVyQXJyYXkiLCJyZW1vdmVkIiwic2VuZEV2ZW50U2VydmljZVN0YXJ0ZWQiLCJzZXNzaW9uIiwic2VuZEV2ZW50U2VydmljZUVuZGVkIiwic2VuZEV2ZW50U2VydmljZUVycm9yIiwib25TZXJ2aWNlRXJyb3IiLCJERUZBVUxUX1BST1RPQ09MIiwiREVGQVVMVF9DT0RFQyIsIkRFRkFVTFRfV0lEVEgiLCJERUZBVUxUX0hFSUdIVCIsIkRFRkFVTFRfREVOU0lUWSIsIkRFRkFVTFRfRlJBTUVSQVRFIiwiREVGQVVMVF9CSVRSQVRFIiwiREVGQVVMVF9JTlRFUlZBTCIsIkRFRkFVTFRfU0NBTEUiLCJWaWRlb1N0cmVhbWluZ1BhcmFtZXRlcnMiLCJkaXNwbGF5RGVuc2l0eSIsImZyYW1lUmF0ZSIsImJpdHJhdGUiLCJpbnRlcnZhbCIsIl9kaXNwbGF5RGVuc2l0eSIsIl9mcmFtZVJhdGUiLCJfYml0cmF0ZSIsIl9pbnRlcnZhbCIsIl9yZXNvbHV0aW9uIiwiX2Zvcm1hdCIsInVwZGF0ZSIsImNhcGFiaWxpdHkiLCJnZXRNYXhCaXRyYXRlIiwic2NhbGUiLCJnZXRTY2FsZSIsImdldFByZWZlcnJlZFJlc29sdXRpb24iLCJmb3JtYXRzIiwiZ2V0U3VwcG9ydGVkRm9ybWF0cyIsInNldERpc3BsYXlEZW5zaXR5IiwiZ2V0RGlzcGxheURlbnNpdHkiLCJzZXRGcmFtZVJhdGUiLCJnZXRGcmFtZVJhdGUiLCJzZXRCaXRyYXRlIiwiZ2V0Qml0cmF0ZSIsImdldEludGVydmFsIiwiU2RsU2Vzc2lvbiIsInNkbFNlc3Npb25MaXN0ZW5lciIsIl9zZXNzaW9uSGFzaElkIiwiX3NkbFNlc3Npb25MaXN0ZW5lciIsIl9zZXJ2aWNlTGlzdGVuZXJzIiwiX3NldHVwU2RsUHJvdG9jb2xMaXN0ZW5lciIsIl9zZGxQcm90b2NvbCIsImdldEN1cnJlbnRUcmFuc3BvcnRUeXBlIiwiZ2V0SXNDb25uZWN0ZWQiLCJnZXRTZXNzaW9uSGFzaElkIiwiYWRkU2VydmljZUxpc3RlbmVyIiwic2RsU2VydmljZUxpc3RlbmVyIiwicmVtb3ZlU2VydmljZUxpc3RlbmVyIiwiZ2V0U2VydmljZUxpc3RlbmVycyIsInNldERlc2lyZWRWaWRlb1BhcmFtcyIsIl9kZXNpcmVkVmlkZW9QYXJhbXMiLCJTZGxTZXNzaW9uTGlzdGVuZXIiLCJjb3JyZWxhdGlvbkkiLCJBcnJheVRvb2xzIiwiYXJyYXlSZW1vdmUiLCJlbGUiLCJMaWZlY3ljbGVNYW5hZ2VyIiwiYXBwQ29uZmlnIiwibGlmZWN5Y2xlTGlzdGVuZXIiLCJfYXBwQ29uZmlnIiwiX2xpZmVjeWNsZUxpc3RlbmVyIiwiX3NkbFNlc3Npb24iLCJfY3JlYXRlU2Vzc2lvbkxpc3RlbmVyIiwiX2N1cnJlbnRITUlTdGF0dXMiLCJfZmlyc3RUaW1lRnVsbCIsIl9yZXNwb25zZUxpc3RlbmVycyIsIl9tYXhDb3JyZWxhdGlvbklkIiwiX3JwY0xpc3RlbmVycyIsInNlc3Npb25MaXN0ZW5lciIsInNlbmRScGNNZXNzYWdlIiwiX2NyZWF0ZVJlZ2lzdGVyQXBwSW50ZXJmYWNlIiwiX2hhbmRsZVJwYyIsImZ1bmN0aW9uSUQiLCJyZXNvbHZlIiwiX3NldHVwSW50ZXJuYWxScGNMaXN0ZW5lcnMiLCJhZGRScGNMaXN0ZW5lciIsInJwY0xpc3RlbmVyIiwicmVtb3ZlUnBjTGlzdGVuZXIiLCJnZXRSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlIiwiX3JlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UiLCJyZWdpc3RlckFwcEludGVyZmFjZSIsIk1BWF9SUENfVkVSU0lPTiIsIlJFR0lTVEVSX0FQUF9JTlRFUkZBQ0VfQ09SUkVMQVRJT05fSUQiLCJfcnBjTGlzdGVuZXIiLCJfcHJvY2Vzc1JhaVJlc3BvbnNlIiwic2hvdWxkSW5pdCIsInJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UiLCJtc2dWZXJzaW9uIiwiVU5SRUdJU1RFUl9BUFBfSU5URVJGQUNFX0NPUlJFTEFUSU9OX0lEIiwiVmlkZW9TdHJlYW1pbmdDYXBhYmlsaXR5Iiwic2V0UHJlZmVycmVkUmVzb2x1dGlvbiIsIktFWV9QUkVGRVJSRURfUkVTT0xVVElPTiIsInNldE1heEJpdHJhdGUiLCJLRVlfTUFYX0JJVFJBVEUiLCJzZXRTdXBwb3J0ZWRGb3JtYXRzIiwiS0VZX1NVUFBPUlRFRF9GT1JNQVRTIiwic2V0SGFwdGljU3BhdGlhbERhdGFTdXBwb3J0ZWQiLCJLRVlfSEFQVElDX1NQQVRJQUxfREFUQV9TVVBQT1JURUQiLCJnZXRIYXB0aWNTcGF0aWFsRGF0YVN1cHBvcnRlZCIsInNldERpYWdvbmFsU2NyZWVuU2l6ZSIsIktFWV9ESUFHT05BTF9TQ1JFRU5fU0laRSIsImdldERpYWdvbmFsU2NyZWVuU2l6ZSIsInNldFBpeGVsUGVySW5jaCIsIktFWV9QSVhFTF9QRVJfSU5DSCIsImdldFBpeGVsUGVySW5jaCIsInNldFNjYWxlIiwiS0VZX1NDQUxFIiwiU2RsU2VydmljZUxpc3RlbmVyIiwiX29uU2VydmljZUVycm9yIiwic2V0T25TZXJ2aWNlRXJyb3IiLCJDdXN0b21UcmFuc3BvcnQiLCJvblNlbmRQYWNrZXQiLCJvbkJ5dGVCdWZmZXJSZWNlaXZlZCIsInNkbFBzbSIsIlRyYW5zcG9ydENvbmZpZ0Jhc2UiLCJfdHJhbnNwb3J0VHlwZSIsIkN1c3RvbVRyYW5zcG9ydENvbmZpZyIsImN1c3RvbVRyYW5zcG9ydCIsIl9jdXN0b21UcmFuc3BvcnQiLCJXZWJTb2NrZXRDbGllbnRDb25maWciLCJob3N0IiwiX2hvc3QiLCJfcG9ydCIsIlRyYW5zcG9ydFJlY29yZCIsIl9hZGRyZXNzIiwiZ2V0QWRkcmVzcyIsIldlYlNvY2tldFNlcnZlckNvbmZpZyIsImNvbm5lY3Rpb25Mb3N0VGltZW91dCIsInNzbENvbmZpZyIsIl9jb25uZWN0aW9uTG9zdFRpbWVvdXQiLCJfc3NsQ29uZmlnIiwiU0RMIiwibGlmZWN5Y2xlIiwicHJvdG9jb2wiLCJlbnVtcyIsInJwYyIsIm1lc3NhZ2VzIiwic3RydWN0cyIsInN0cmVhbWluZyIsInZpZGVvIiwidHJhbnNwb3J0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7SUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQWdDQTtJQUNBO0lBRUEsTUFBTUEsU0FBTixDQUFnQjtJQUNaOzs7SUFHQUMsRUFBQUEsV0FBVyxHQUFJO0lBQ1gsU0FBS0MsZ0JBQUwsR0FBd0IsSUFBeEI7SUFDQSxTQUFLQyxNQUFMLEdBQWMsSUFBZDtJQUNBLFNBQUtDLFFBQUwsR0FBZ0IsSUFBaEI7SUFDQSxTQUFLQyxTQUFMLEdBQWlCLElBQWpCO0lBQ0EsU0FBS0MsU0FBTCxHQUFpQixJQUFqQjtJQUNBLFNBQUtDLGFBQUwsR0FBcUIsSUFBckI7SUFDQSxTQUFLQyxRQUFMLEdBQWdCLElBQWhCO0lBQ0EsU0FBS0MsV0FBTCxHQUFtQixJQUFuQjtJQUNBLFNBQUtDLFdBQUwsR0FBbUIsSUFBbkI7SUFDQSxTQUFLQyxnQkFBTCxHQUF3QixJQUF4QjtJQUNBLFNBQUtDLDBCQUFMLEdBQWtDLElBQWxDO0lBQ0EsU0FBS0MsU0FBTCxHQUFpQixJQUFqQjtJQUNBLFNBQUtDLGVBQUwsR0FBdUIsSUFBdkI7SUFDQSxTQUFLQyxpQkFBTCxHQUF5QixJQUF6QjtJQUNBLFNBQUtDLGtCQUFMLEdBQTBCLElBQTFCO0lBQ0EsU0FBS0MsdUJBQUwsR0FBK0IsSUFBL0I7SUFDSDtJQUVEOzs7Ozs7SUFJQUMsRUFBQUEsa0JBQWtCLENBQUVDLGVBQUYsRUFBbUI7SUFDakMsU0FBS2pCLGdCQUFMLEdBQXdCaUIsZUFBeEI7SUFDQSxXQUFPLElBQVA7SUFDSDtJQUVEOzs7OztJQUdBQyxFQUFBQSxrQkFBa0IsR0FBSTtJQUNsQixXQUFPLEtBQUtsQixnQkFBWjtJQUNIO0lBRUQ7Ozs7OztJQUlBbUIsRUFBQUEsUUFBUSxDQUFFQyxLQUFGLEVBQVM7SUFDYixTQUFL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QUc7SUFDckMsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLENBQUMsT0FBTTs7SUFFdEIsRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFO0lBQ25CLElBQUksTUFBTSxJQUFJLEtBQUssQ0FBQyxnREFBZ0QsQ0FBQztJQUNyRSxHQUFHOztJQUVIO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQSxFQUFFLFlBQVksR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEVBQUM7O0lBRXhFO0lBQ0EsRUFBRSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsWUFBWSxFQUFDOztJQUUzQztJQUNBLEVBQUUsQ0FBQyxHQUFHLFlBQVksR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxJQUFHOztJQUV0QyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUM7O0lBRVgsRUFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRTtJQUM1QyxJQUFJLEdBQUcsR0FBRyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLFNBQVMsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLFNBQVMsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBQztJ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dkMsSUFBSSxNQUFNLElBQUksSUFBRztJQUNqQixHQUFHOztJQUVILEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUM7O0lBRXBCLEVBQUUsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztJQUN2QixDQUFDOztJQzVHTSxTQUFTLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFO0lBQzFELEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBQztJQUNWLEVBQUUsSUFBSSxJQUFJLEdBQUcsTUFBTSxHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsRUFBQztJQUNsQyxFQUFFLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQyxJQUFJLElBQUksSUFBSSxFQUFDO0lBQzVCLEVBQUUsSUFBSSxLQUFLLEdBQUcsSUFBSSxJQUFJLEVBQUM7SUFDdkIsRUFBRSxJQUFJLEtBQUssR0FBRyxDQUFDLEVBQUM7SUFDaEIsRUFBRSxJQUFJLENBQUMsR0FBRyxJQUFJLElBQUksTUFBTSxHQUFHLENBQUMsSUFBSSxFQUFDO0lBQ2pDLEVBQUUsSUFBSSxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUM7SUFDdkIsRUFBRSxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBQzs7SUFFNUIsRUFBRSxDQUFDLElBQUksRUFBQzs7SUFFUixFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUM7SUFDL0IsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUM7SUFDaEIsRUFBRSxLQUFLLElBQUksS0FBSTtJQUNmLEVBQUUsT0FBTyxLQUFLLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLElBQUksQ0FBQyxFQUFFLEVBQUU7O0lBRTVFLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBQztJQUMvQixFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBQztJQUNoQixFQUFFLEtBQUssSUFBSSxLQUFJO0lBQ2YsRUFBRSxPQUFPLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssSUFBSSxDQUFDLEVBQUUsRUFBRTs7SUFFNUUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUU7SUFDZixJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsTUFBSztJQUNqQixHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssSUFBSSxFQUFFO0lBQ3pCLElBQUksT0FBTyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxRQUFRLENBQUM7SUFDOUMsR0FBRyxNQUFNO0lBQ1QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBQztJQUM3QixJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsTUFBSztJQUNqQixHQUFHO0lBQ0gsRUFBRSxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQztJQUNqRCxDQUFDOztBQUVELElBQU8sU0FBUyxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUU7SUFDbEUsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBQztJQUNiLEVBQUUsSUFBSSxJQUFJLEdBQUcsTUFBTSxHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsRUFBQztJQUNsQyxFQUFFLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQyxJQUFJLElBQUksSUFBSSxFQUFDO0lBQzVCLEVBQUUsSUFBSSxLQUFLLEdBQUcsSUFBSSxJQUFJLEVBQUM7SUFDdkIsRUFBRSxJQUFJLEVBQUUsSUFBSSxJQUFJLEtBQUssRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUM7SUFDbEUsRUFBRSxJQUFJLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLE1BQU0sR0FBRyxDQUFDLEVBQUM7SUFDakMsRUFBRSxJQUFJLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBQztJQUN2QixFQUFFLElBQUksQ0FBQyxHQUFHLEtBQUssR0FBRyxDQUFDLEtBQUssS0FBSyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFDOztJQUU3RCxFQUFFLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBQzs7SUFFekIsRUFBRSxJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLEtBQUssUUFBUSxFQUFFO0lBQzFDLElBQUksQ0FBQyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBQztJQUM1QixJQUFJLENBQUMsR0FBRyxLQUFJO0lBQ1osR0FBRyxNQUFNO0lBQ1QsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUM7SUFDOUMsSUFBSSxJQUFJLEtBQUssSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxD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QU0sQ0FBQztNQUNwQjs7SUFFRCxNQUFNLENBQUMsU0FBUyxDQUFDLFlBQVksR0FBRyxTQUFTLFlBQVksRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFO01BQ3ZFLElBQUksQ0FBQyxRQUFRLEVBQUUsV0FBVyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBQztNQUNsRCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztNQUM5Qzs7SUFFRCxNQUFNLENBQUMsU0FBUyxDQUFDLFlBQVksR0FBRyxTQUFTLFlBQVksRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFO01BQ3ZFLElBQUksQ0FBQyxRQUFRLEVBQUUsV0FBVyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBQztNQUNsRCxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztNQUM5Qzs7SUFFRCxNQUFNLENBQUMsU0FBUyxDQUFDLFlBQVksR0FBRyxTQUFTLFlBQVksRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFO01BQ3ZFLElBQUksQ0FBQyxRQUFRLEVBQUUsV0FBVyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBQzs7TUFFbEQsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztXQUNoQixJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztXQUN0QixJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztXQUN2QixJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQztNQUNuQzs7SUFFRCxNQUFNLENBQUMsU0FBUyxDQUFDLFlBQVksR0FBRyxTQUFTLFlBQVksRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFF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TSxDQUFDLFNBQVMsQ0FBQyxXQUFXLEdBQUcsU0FBUyxXQUFXLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRTtNQUNyRSxJQUFJLENBQUMsUUFBUSxFQUFFLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUM7O01BRWxELE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRTtTQUN2QixJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztTQUN2QixJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUN0QixJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO01BQ3JCOztJQUVELE1BQU0sQ0FBQyxTQUFTLENBQUMsV0FBVyxHQUFHLFNBQVMsV0FBVyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUU7TUFDckUsSUFBSSxDQUFDLFFBQVEsRUFBRSxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFDO01BQ2xELE9BQU9DLElBQVksQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO01BQy9DOztJQUVELE1BQU0sQ0FBQyxTQUFTLENBQUMsV0FBVyxHQUFHLFNBQVMsV0FBVyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUU7TUFDckUsSUFBSSxDQUFDLFFBQVEsRUFBRSxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFDO01BQ2xELE9BQU9BLElBQVksQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO01BQ2hEOztJQUVELE1BQU0sQ0FBQyxTQUFTLENBQUMsWUFBWSxHQUFHLFNBQVMsWUFBWSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUU7TUFDdkUsSUFBSSxDQUFDLFFBQVEsRUFBRSxXQUFXLENBQUMsTUFBTSxFQUFF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 +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzIjpbIi4uL3RtcC9tYW5hZ2VyL0FwcENvbmZpZy5qcyIsIi4uL3RtcC9tYW5hZ2VyL2xpZmVjeWNsZS9MaWZlY3ljbGVMaXN0ZW5lci5qcyIsIi4uL3RtcC91dGlsL0VudW0uanMiLCIuLi90bXAvcnBjL1JwY1N0cnVjdC5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9BcHBJbmZvLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1JHQkNvbG9yLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1RlbXBsYXRlQ29sb3JTY2hlbWUuanMiLCIuLi90bXAvcnBjL2VudW1zL0Z1bmN0aW9uSUQuanMiLCIuLi90bXAvcnBjL2VudW1zL1NwZWVjaENhcGFiaWxpdGllcy5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9UVFNDaHVuay5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9TZGxNc2dWZXJzaW9uLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9BcHBITUlUeXBlLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9MYW5ndWFnZS5qcyIsIi4uL3RtcC9ycGMvUnBjTWVzc2FnZS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvUnBjVHlwZS5qcyIsIi4uL3RtcC9ycGMvUnBjUmVxdWVzdC5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9EZXZpY2VJbmZvLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9SZWdpc3RlckFwcEludGVyZmFjZS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvUmVzdWx0LmpzIiwiLi4vdG1wL3JwYy9ScGNSZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvUnBjTGlzdGVuZXIuanMiLCIuLi90bXAvcHJvdG9jb2wvU2RsUHJvdG9jb2xMaXN0ZW5lci5qcyIsIi4uL3RtcC9wcm90b2NvbC9lbnVtcy9GcmFtZVR5cGUuanMiLCIuLi8uLi8uLi90aGlyZF9wYXJ0eS9ic29uLmNvbW1vbi5qcyIsIi4uL3RtcC91dGlsL0Jzb24uanMiLCIuLi90bXAvcHJvdG9jb2wvU2RsUGFja2V0LmpzIiwiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3JvbGx1cC1wbHVnaW4tbm9kZS1nbG9iYWxzL3NyYy9nbG9iYWwuanMiLCIuLi8uLi8uLi9ub2RlX21vZHVsZXMvYnVmZmVyLWVzNi9iYXNlNjQuanMiLCIuLi8uLi8uLi9ub2RlX21vZHVsZXMvYnVmZmVyLWVzNi9pZWVlNzU0LmpzIiwiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2J1ZmZlci1lczYvaXNBcnJheS5qcyIsIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9idWZmZXItZXM2L2luZGV4LmpzIiwiLi4vdG1wL3V0aWwvVGV4dEVuY29kZXIuanMiLCIuLi90bXAvdXRpbC9Kc29uUnBjTWFyc2hhbGxlci5qcyIsIi4uL3RtcC9wcm90b2NvbC9CaW5hcnlGcmFtZUhlYWRlci5qcyIsIi4uL3RtcC9wcm90b2NvbC9NZXNzYWdlRnJhbWVEaXNhc3NlbWJsZXIuanMiLCIuLi90bXAvdHJhbnNwb3J0L1RyYW5zcG9ydExpc3RlbmVyLmpzIiwiLi4vdG1wL3V0aWwvVmVyc2lvbi5qcyIsIi4uL3RtcC9wcm90b2NvbC9lbnVtcy9TZXJ2aWNlVHlwZS5qcyIsIi4uL3RtcC9wcm90b2NvbC9NZXNzYWdlRnJhbWVBc3NlbWJsZXIuanMiLCIuLi90bXAvcHJvdG9jb2wvZW51bXMvQ29udHJvbEZyYW1lVGFncy5qcyIsIi4uL3RtcC91dGlsL0JpdENvbnZlcnRlci5qcyIsIi4uL3RtcC9wcm90b2NvbC9TZGxQYWNrZXRGYWN0b3J5LmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1NvZnRCdXR0b25DYXBhYmlsaXRpZXMuanMiLCIuLi90bXAvcnBjL2VudW1zL1ByZXJlY29yZGVkU3BlZWNoLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1ByZXNldEJhbmtDYXBhYmlsaXRpZXMuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvVmVoaWNsZVR5cGUuanMiLCIuLi90bXAvcnBjL2VudW1zL0htaVpvbmVDYXBhYmlsaXRpZXMuanMiLCIuLi90bXAvcnBjL2VudW1zL01lZGlhQ2xvY2tGb3JtYXQuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvSW1hZ2VSZXNvbHV0aW9uLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1RvdWNoRXZlbnRDYXBhYmlsaXRpZXMuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvU2NyZWVuUGFyYW1zLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9JbWFnZUZpZWxkTmFtZS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvRmlsZVR5cGUuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvSW1hZ2VGaWVsZC5qcyIsIi4uL3RtcC9ycGMvZW51bXMvRGlzcGxheVR5cGUuanMiLCIuLi90bXAvcnBjL2VudW1zL1RleHRGaWVsZE5hbWUuanMiLCIuLi90bXAvcnBjL2VudW1zL0NoYXJhY3RlclNldC5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9UZXh0RmllbGQuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvRGlzcGxheUNhcGFiaWxpdGllcy5qcyIsIi4uL3RtcC9ycGMvZW51bXMvU2FtcGxpbmdSYXRlLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9CaXRzUGVyU2FtcGxlLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9BdWRpb1R5cGUuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvQXVkaW9QYXNzVGhydUNhcGFiaWxpdGllcy5qcyIsIi4uL3RtcC9ycGMvZW51bXMvVnJDYXBhYmlsaXRpZXMuanMiLCIuLi90bXAvcnBjL2VudW1zL0J1dHRvbk5hbWUuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvR3JpZC5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9Nb2R1bGVJbmZvLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL0J1dHRvbkNhcGFiaWxpdGllcy5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9ITUlDYXBhYmlsaXRpZXMuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1JlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1VucmVnaXN0ZXJBcHBJbnRlcmZhY2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1VucmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvV2luZG93VHlwZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvQ3JlYXRlV2luZG93LmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9DcmVhdGVXaW5kb3dSZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvRGVsZXRlV2luZG93LmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9EZWxldGVXaW5kb3dSZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvSW1hZ2VUeXBlLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL0ltYWdlLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1ZySGVscEl0ZW0uanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvU2VhdExvY2F0aW9uLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9NZW51TGF5b3V0LmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9LZXlib2FyZExheW91dC5qcyIsIi4uL3RtcC9ycGMvZW51bXMvS2V5cHJlc3NNb2RlLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL0tleWJvYXJkUHJvcGVydGllcy5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvU2V0R2xvYmFsUHJvcGVydGllcy5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvU2V0R2xvYmFsUHJvcGVydGllc1Jlc3BvbnNlLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9HbG9iYWxQcm9wZXJ0eS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvUmVzZXRHbG9iYWxQcm9wZXJ0aWVzLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9SZXNldEdsb2JhbFByb3BlcnRpZXNSZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9NZW51UGFyYW1zLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9BZGRDb21tYW5kLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9BZGRDb21tYW5kUmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL0RlbGV0ZUNvbW1hbmQuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL0RlbGV0ZUNvbW1hbmRSZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvQWRkU3ViTWVudS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvQWRkU3ViTWVudVJlc3BvbnNlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9EZWxldGVTdWJNZW51LmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9EZWxldGVTdWJNZW51UmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1Nob3dBcHBNZW51LmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9TaG93QXBwTWVudVJlc3BvbnNlLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL0Nob2ljZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvQ3JlYXRlSW50ZXJhY3Rpb25DaG9pY2VTZXQuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL0NyZWF0ZUludGVyYWN0aW9uQ2hvaWNlU2V0UmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL2VudW1zL0xheW91dE1vZGUuanMiLCIuLi90bXAvcnBjL2VudW1zL0ludGVyYWN0aW9uTW9kZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvUGVyZm9ybUludGVyYWN0aW9uLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9UcmlnZ2VyU291cmNlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9QZXJmb3JtSW50ZXJhY3Rpb25SZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvRGVsZXRlSW50ZXJhY3Rpb25DaG9pY2VTZXQuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL0RlbGV0ZUludGVyYWN0aW9uQ2hvaWNlU2V0UmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL2VudW1zL1NvZnRCdXR0b25UeXBlLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9TeXN0ZW1BY3Rpb24uanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvU29mdEJ1dHRvbi5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvQWxlcnQuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL0FsZXJ0UmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL2VudW1zL1RleHRBbGlnbm1lbnQuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvVGVtcGxhdGVDb25maWd1cmF0aW9uLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9NZXRhZGF0YVR5cGUuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvTWV0YWRhdGFUYWdzLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9TaG93LmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9TaG93UmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1NwZWFrLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9TcGVha1Jlc3BvbnNlLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1N0YXJ0VGltZS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvVXBkYXRlTW9kZS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvQXVkaW9TdHJlYW1pbmdJbmRpY2F0b3IuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1NldE1lZGlhQ2xvY2tUaW1lci5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvU2V0TWVkaWFDbG9ja1RpbWVyUmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1BlcmZvcm1BdWRpb1Bhc3NUaHJ1LmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9QZXJmb3JtQXVkaW9QYXNzVGhydVJlc3BvbnNlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9FbmRBdWRpb1Bhc3NUaHJ1LmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9FbmRBdWRpb1Bhc3NUaHJ1UmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1N1YnNjcmliZUJ1dHRvbi5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvU3Vic2NyaWJlQnV0dG9uUmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1Vuc3Vic2NyaWJlQnV0dG9uLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9VbnN1YnNjcmliZUJ1dHRvblJlc3BvbnNlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9TdWJzY3JpYmVWZWhpY2xlRGF0YS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvVmVoaWNsZURhdGFSZXN1bHRDb2RlLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9WZWhpY2xlRGF0YVR5cGUuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvVmVoaWNsZURhdGFSZXN1bHQuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1N1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1Vuc3Vic2NyaWJlVmVoaWNsZURhdGEuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1Vuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvR2V0VmVoaWNsZURhdGEuanMiLCIuLi90bXAvcnBjL2VudW1zL1ZlaGljbGVEYXRhRXZlbnRTdGF0dXMuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvQWlyYmFnU3RhdHVzLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9Qb3dlck1vZGVTdGF0dXMuanMiLCIuLi90bXAvcnBjL2VudW1zL0Nhck1vZGVTdGF0dXMuanMiLCIuLi90bXAvcnBjL2VudW1zL1Bvd2VyTW9kZVF1YWxpZmljYXRpb25TdGF0dXMuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvQ2x1c3Rlck1vZGVTdGF0dXMuanMiLCIuLi90bXAvcnBjL2VudW1zL0Z1ZWxDdXRvZmZTdGF0dXMuanMiLCIuLi90bXAvcnBjL2VudW1zL0VtZXJnZW5jeUV2ZW50VHlwZS5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9FbWVyZ2VuY3lFdmVudC5qcyIsIi4uL3RtcC9ycGMvZW51bXMvVHVyblNpZ25hbC5qcyIsIi4uL3RtcC9ycGMvZW51bXMvQW1iaWVudExpZ2h0U3RhdHVzLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL0hlYWRMYW1wU3RhdHVzLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9QcmltYXJ5QXVkaW9Tb3VyY2UuanMiLCIuLi90bXAvcnBjL2VudW1zL0RldmljZUxldmVsU3RhdHVzLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL0RldmljZVN0YXR1cy5qcyIsIi4uL3RtcC9ycGMvZW51bXMvV2lwZXJTdGF0dXMuanMiLCIuLi90bXAvcnBjL2VudW1zL0VsZWN0cm9uaWNQYXJrQnJha2VTdGF0dXMuanMiLCIuLi90bXAvcnBjL2VudW1zL1ZlaGljbGVEYXRhU3RhdHVzLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL015S2V5LmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9Db21wYXNzRGlyZWN0aW9uLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9EaW1lbnNpb24uanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvR1BTRGF0YS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvUFJOREwuanMiLCIuLi90bXAvcnBjL2VudW1zL0Z1ZWxUeXBlLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL0Z1ZWxSYW5nZS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvVmVoaWNsZURhdGFOb3RpZmljYXRpb25TdGF0dXMuanMiLCIuLi90bXAvcnBjL2VudW1zL0VDYWxsQ29uZmlybWF0aW9uU3RhdHVzLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL0VDYWxsSW5mby5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9CZWx0U3RhdHVzLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9Db21wb25lbnRWb2x1bWVTdGF0dXMuanMiLCIuLi90bXAvcnBjL2VudW1zL0lnbml0aW9uU3RhdHVzLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9JZ25pdGlvblN0YWJsZVN0YXR1cy5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9Cb2R5SW5mb3JtYXRpb24uanMiLCIuLi90bXAvcnBjL2VudW1zL1RQTVMuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvU2luZ2xlVGlyZVN0YXR1cy5qcyIsIi4uL3RtcC9ycGMvZW51bXMvV2FybmluZ0xpZ2h0U3RhdHVzLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1RpcmVTdGF0dXMuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL0dldFZlaGljbGVEYXRhUmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1JlYWRESUQuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvRElEUmVzdWx0LmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9SZWFkRElEUmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL0dldERUQ3MuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL0dldERUQ3NSZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvRGlhZ25vc3RpY01lc3NhZ2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL0RpYWdub3N0aWNNZXNzYWdlUmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1Njcm9sbGFibGVNZXNzYWdlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9TY3JvbGxhYmxlTWVzc2FnZVJlc3BvbnNlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9TbGlkZXIuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1NsaWRlclJlc3BvbnNlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9TaG93Q29uc3RhbnRUQlQuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1Nob3dDb25zdGFudFRCVFJlc3BvbnNlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9BbGVydE1hbmV1dmVyLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9BbGVydE1hbmV1dmVyUmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvVHVybi5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvVXBkYXRlVHVybkxpc3QuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1VwZGF0ZVR1cm5MaXN0UmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL0NoYW5nZVJlZ2lzdHJhdGlvbi5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvQ2hhbmdlUmVnaXN0cmF0aW9uUmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL0dlbmVyaWNSZXNwb25zZVJlc3BvbnNlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9QdXRGaWxlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9QdXRGaWxlUmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL0dldEZpbGUuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL0dldEZpbGVSZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvRGVsZXRlRmlsZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvRGVsZXRlRmlsZVJlc3BvbnNlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9MaXN0RmlsZXMuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL0xpc3RGaWxlc1Jlc3BvbnNlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9TZXRBcHBJY29uLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9TZXRBcHBJY29uUmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1NldERpc3BsYXlMYXlvdXQuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1NldERpc3BsYXlMYXlvdXRSZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvUmVxdWVzdFR5cGUuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1N5c3RlbVJlcXVlc3QuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1N5c3RlbVJlcXVlc3RSZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvRGVsaXZlcnlNb2RlLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL0RhdGVUaW1lLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL09BU0lTQWRkcmVzcy5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvU2VuZExvY2F0aW9uLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9TZW5kTG9jYXRpb25SZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvRGlhbE51bWJlci5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvRGlhbE51bWJlclJlc3BvbnNlLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9CdXR0b25QcmVzc01vZGUuanMiLCIuLi90bXAvcnBjL2VudW1zL01vZHVsZVR5cGUuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL0J1dHRvblByZXNzLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9CdXR0b25QcmVzc1Jlc3BvbnNlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9HZXRJbnRlcmlvclZlaGljbGVEYXRhLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9EaXNwbGF5TW9kZS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvRGlzdGFuY2VVbml0LmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9UZW1wZXJhdHVyZVVuaXQuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvSE1JU2V0dGluZ3NDb250cm9sRGF0YS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvUmFkaW9CYW5kLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1Jkc0RhdGEuanMiLCIuLi90bXAvcnBjL2VudW1zL1JhZGlvU3RhdGUuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvU3RhdGlvbklETnVtYmVyLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1Npc0RhdGEuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvUmFkaW9Db250cm9sRGF0YS5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9UZW1wZXJhdHVyZS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvVmVudGlsYXRpb25Nb2RlLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9EZWZyb3N0Wm9uZS5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9DbGltYXRlQ29udHJvbERhdGEuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvRXF1YWxpemVyU2V0dGluZ3MuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvQXVkaW9Db250cm9sRGF0YS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvTWFzc2FnZUN1c2hpb24uanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvTWFzc2FnZUN1c2hpb25GaXJtbmVzcy5qcyIsIi4uL3RtcC9ycGMvZW51bXMvU3VwcG9ydGVkU2VhdC5qcyIsIi4uL3RtcC9ycGMvZW51bXMvU2VhdE1lbW9yeUFjdGlvblR5cGUuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvU2VhdE1lbW9yeUFjdGlvbi5qcyIsIi4uL3RtcC9ycGMvZW51bXMvTWFzc2FnZVpvbmUuanMiLCIuLi90bXAvcnBjL2VudW1zL01hc3NhZ2VNb2RlLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL01hc3NhZ2VNb2RlRGF0YS5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9TZWF0Q29udHJvbERhdGEuanMiLCIuLi90bXAvcnBjL2VudW1zL0xpZ2h0U3RhdHVzLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9MaWdodE5hbWUuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvTGlnaHRTdGF0ZS5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9MaWdodENvbnRyb2xEYXRhLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL01vZHVsZURhdGEuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL0dldEludGVyaW9yVmVoaWNsZURhdGFSZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvR2V0SW50ZXJpb3JWZWhpY2xlRGF0YUNvbnNlbnQuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL0dldEludGVyaW9yVmVoaWNsZURhdGFDb25zZW50UmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1JlbGVhc2VJbnRlcmlvclZlaGljbGVEYXRhTW9kdWxlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9SZWxlYXNlSW50ZXJpb3JWZWhpY2xlRGF0YU1vZHVsZVJlc3BvbnNlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9TZXRJbnRlcmlvclZlaGljbGVEYXRhLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9TZXRJbnRlcmlvclZlaGljbGVEYXRhUmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1N1YnNjcmliZVdheVBvaW50cy5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvU3Vic2NyaWJlV2F5UG9pbnRzUmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL2VudW1zL1dheVBvaW50VHlwZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvR2V0V2F5UG9pbnRzLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL0Nvb3JkaW5hdGUuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvTG9jYXRpb25EZXRhaWxzLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9HZXRXYXlQb2ludHNSZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvVW5zdWJzY3JpYmVXYXlQb2ludHMuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1Vuc3Vic2NyaWJlV2F5UG9pbnRzUmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL2VudW1zL1N5c3RlbUNhcGFiaWxpdHlUeXBlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9HZXRTeXN0ZW1DYXBhYmlsaXR5LmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9WaWRlb1N0cmVhbWluZ0NvZGVjLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9WaWRlb1N0cmVhbWluZ1Byb3RvY29sLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1ZpZGVvU3RyZWFtaW5nRm9ybWF0LmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1ZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eS5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9QaG9uZUNhcGFiaWxpdHkuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvV2luZG93VHlwZUNhcGFiaWxpdGllcy5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9XaW5kb3dDYXBhYmlsaXR5LmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL0Rpc3BsYXlDYXBhYmlsaXR5LmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL0F1ZGlvQ29udHJvbENhcGFiaWxpdGllcy5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9MaWdodENhcGFiaWxpdGllcy5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9MaWdodENvbnRyb2xDYXBhYmlsaXRpZXMuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvU2VhdENvbnRyb2xDYXBhYmlsaXRpZXMuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvUmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL0hNSVNldHRpbmdzQ29udHJvbENhcGFiaWxpdGllcy5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9SZW1vdGVDb250cm9sQ2FwYWJpbGl0aWVzLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1NlYXRMb2NhdGlvbkNhcGFiaWxpdHkuanMiLCIuLi90bXAvcnBjL2VudW1zL1NlcnZpY2VVcGRhdGVSZWFzb24uanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvTmF2aWdhdGlvblNlcnZpY2VNYW5pZmVzdC5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9XZWF0aGVyU2VydmljZU1hbmlmZXN0LmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL01lZGlhU2VydmljZU1hbmlmZXN0LmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL0FwcFNlcnZpY2VNYW5pZmVzdC5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9BcHBTZXJ2aWNlUmVjb3JkLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL0FwcFNlcnZpY2VDYXBhYmlsaXR5LmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL0FwcFNlcnZpY2VzQ2FwYWJpbGl0aWVzLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL05hdmlnYXRpb25DYXBhYmlsaXR5LmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1N5c3RlbUNhcGFiaWxpdHkuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL0dldFN5c3RlbUNhcGFiaWxpdHlSZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9SZWN0YW5nbGUuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvSGFwdGljUmVjdC5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvU2VuZEhhcHRpY0RhdGEuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1NlbmRIYXB0aWNEYXRhUmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL2VudW1zL0h5YnJpZEFwcFByZWZlcmVuY2UuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvQ2xvdWRBcHBQcm9wZXJ0aWVzLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9TZXRDbG91ZEFwcFByb3BlcnRpZXMuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL1NldENsb3VkQXBwUHJvcGVydGllc1Jlc3BvbnNlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9HZXRDbG91ZEFwcFByb3BlcnRpZXMuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL0dldENsb3VkQXBwUHJvcGVydGllc1Jlc3BvbnNlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9QdWJsaXNoQXBwU2VydmljZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvUHVibGlzaEFwcFNlcnZpY2VSZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvVW5wdWJsaXNoQXBwU2VydmljZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvVW5wdWJsaXNoQXBwU2VydmljZVJlc3BvbnNlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9HZXRBcHBTZXJ2aWNlRGF0YS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvTmF2aWdhdGlvbkp1bmN0aW9uLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9EaXJlY3Rpb24uanMiLCIuLi90bXAvcnBjL2VudW1zL05hdmlnYXRpb25BY3Rpb24uanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvTmF2aWdhdGlvbkluc3RydWN0aW9uLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL05hdmlnYXRpb25TZXJ2aWNlRGF0YS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvTWVkaWFUeXBlLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL01lZGlhU2VydmljZURhdGEuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvV2VhdGhlckRhdGEuanMiLCIuLi90bXAvcnBjL3N0cnVjdHMvV2VhdGhlckFsZXJ0LmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1dlYXRoZXJTZXJ2aWNlRGF0YS5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9BcHBTZXJ2aWNlRGF0YS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvR2V0QXBwU2VydmljZURhdGFSZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvUGVyZm9ybUFwcFNlcnZpY2VJbnRlcmFjdGlvbi5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvUGVyZm9ybUFwcFNlcnZpY2VJbnRlcmFjdGlvblJlc3BvbnNlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9DYW5jZWxJbnRlcmFjdGlvbi5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvQ2FuY2VsSW50ZXJhY3Rpb25SZXNwb25zZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvQ2xvc2VBcHBsaWNhdGlvbi5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvQ2xvc2VBcHBsaWNhdGlvblJlc3BvbnNlLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9TeXN0ZW1Db250ZXh0LmpzIiwiLi4vdG1wL3JwYy9ScGNOb3RpZmljYXRpb24uanMiLCIuLi90bXAvcnBjL2VudW1zL0F1ZGlvU3RyZWFtaW5nU3RhdGUuanMiLCIuLi90bXAvcnBjL2VudW1zL0hNSUxldmVsLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9WaWRlb1N0cmVhbWluZ1N0YXRlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9PbkhNSVN0YXR1cy5qcyIsIi4uL3RtcC9ycGMvZW51bXMvQXBwSW50ZXJmYWNlVW5yZWdpc3RlcmVkUmVhc29uLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9PbkFwcEludGVyZmFjZVVucmVnaXN0ZXJlZC5qcyIsIi4uL3RtcC9ycGMvZW51bXMvQnV0dG9uRXZlbnRNb2RlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9PbkJ1dHRvbkV2ZW50LmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9PbkJ1dHRvblByZXNzLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9PblZlaGljbGVEYXRhLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9PbkNvbW1hbmQuanMiLCIuLi90bXAvcnBjL2VudW1zL1RCVFN0YXRlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9PblRCVENsaWVudFN0YXRlLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9Ecml2ZXJEaXN0cmFjdGlvblN0YXRlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9PbkRyaXZlckRpc3RyYWN0aW9uLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL0hNSVBlcm1pc3Npb25zLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1BhcmFtZXRlclBlcm1pc3Npb25zLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1Blcm1pc3Npb25JdGVtLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9PblBlcm1pc3Npb25zQ2hhbmdlLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9PbkF1ZGlvUGFzc1RocnUuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL09uTGFuZ3VhZ2VDaGFuZ2UuanMiLCIuLi90bXAvcnBjL2VudW1zL0tleWJvYXJkRXZlbnQuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL09uS2V5Ym9hcmRJbnB1dC5qcyIsIi4uL3RtcC9ycGMvc3RydWN0cy9Ub3VjaENvb3JkLmpzIiwiLi4vdG1wL3JwYy9zdHJ1Y3RzL1RvdWNoRXZlbnQuanMiLCIuLi90bXAvcnBjL2VudW1zL1RvdWNoVHlwZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvT25Ub3VjaEV2ZW50LmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9PblN5c3RlbVJlcXVlc3QuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL09uSGFzaENoYW5nZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvT25XYXlQb2ludENoYW5nZS5qcyIsIi4uL3RtcC9ycGMvbWVzc2FnZXMvT25JbnRlcmlvclZlaGljbGVEYXRhLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9PblJDU3RhdHVzLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9PbkFwcFNlcnZpY2VEYXRhLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9PblN5c3RlbUNhcGFiaWxpdHlVcGRhdGVkLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9FbmNvZGVkU3luY1BEYXRhLmpzIiwiLi4vdG1wL3JwYy9tZXNzYWdlcy9FbmNvZGVkU3luY1BEYXRhUmVzcG9uc2UuanMiLCIuLi90bXAvcnBjL21lc3NhZ2VzL09uRW5jb2RlZFN5bmNQRGF0YS5qcyIsIi4uL3RtcC9ycGMvUnBjQ3JlYXRvci5qcyIsIi4uL3RtcC9wcm90b2NvbC9TZGxQcm90b2NvbEJhc2UuanMiLCIuLi90bXAvdHJhbnNwb3J0L2VudW1zL1RyYW5zcG9ydFR5cGUuanMiLCIuLi90bXAvdHJhbnNwb3J0L1NkbFBzbS5qcyIsIi4uL3RtcC90cmFuc3BvcnQvVHJhbnNwb3J0QmFzZS5qcyIsIi4uL3RtcC90cmFuc3BvcnQvV2ViU29ja2V0Q2xpZW50LmpzIiwiLi4vdG1wL3RyYW5zcG9ydC9UcmFuc3BvcnRDYWxsYmFjay5qcyIsIi4uL3RtcC90cmFuc3BvcnQvVHJhbnNwb3J0TWFuYWdlckJhc2UuanMiLCIuLi90bXAvdHJhbnNwb3J0L1NzbENvbmZpZy5qcyIsIi4uL3RtcC90cmFuc3BvcnQvV2ViU29ja2V0U2VydmVyLmpzIiwiLi4vdG1wL3RyYW5zcG9ydC9UcmFuc3BvcnRNYW5hZ2VyLmpzIiwiLi4vdG1wL3Byb3RvY29sL1NkbFByb3RvY29sLmpzIiwiLi4vdG1wL3Nlc3Npb24vU2VydmljZUxpc3RlbmVyTWFwLmpzIiwiLi4vdG1wL3N0cmVhbWluZy92aWRlby9WaWRlb1N0cmVhbWluZ1BhcmFtZXRlcnMuanMiLCIuLi90bXAvc2Vzc2lvbi9TZGxTZXNzaW9uLmpzIiwiLi4vdG1wL3Nlc3Npb24vU2RsU2Vzc2lvbkxpc3RlbmVyLmpzIiwiLi4vdG1wL3V0aWwvQXJyYXlUb29scy5qcyIsIi4uL3RtcC9tYW5hZ2VyL2xpZmVjeWNsZS9MaWZlY3ljbGVNYW5hZ2VyLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9BcHBTZXJ2aWNlVHlwZS5qcyIsIi4uL3RtcC9ycGMvZW51bXMvTWFpbnRlbmFuY2VNb2RlU3RhdHVzLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9QZXJtaXNzaW9uU3RhdHVzLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9QcmVkZWZpbmVkTGF5b3V0LmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9QcmVkZWZpbmVkV2luZG93cy5qcyIsIi4uL3RtcC9ycGMvZW51bXMvVGltZXJNb2RlLmpzIiwiLi4vdG1wL3JwYy9lbnVtcy9WZWhpY2xlRGF0YUFjdGl2ZVN0YXR1cy5qcyIsIi4uL3RtcC9ycGMvZW51bXMvbWVzc2FnZVR5cGUuanMiLCIuLi90bXAvc2Vzc2lvbi9TZGxTZXJ2aWNlTGlzdGVuZXIuanMiLCIuLi90bXAvdHJhbnNwb3J0L0N1c3RvbVRyYW5zcG9ydC5qcyIsIi4uL3RtcC90cmFuc3BvcnQvVHJhbnNwb3J0Q29uZmlnQmFzZS5qcyIsIi4uL3RtcC90cmFuc3BvcnQvQ3VzdG9tVHJhbnNwb3J0Q29uZmlnLmpzIiwiLi4vdG1wL3RyYW5zcG9ydC9XZWJTb2NrZXRDbGllbnRDb25maWcuanMiLCIuLi90bXAvdHJhbnNwb3J0L3V0aWwvVHJhbnNwb3J0UmVjb3JkLmpzIiwiLi4vdG1wL3RyYW5zcG9ydC9XZWJTb2NrZXRTZXJ2ZXJDb25maWcuanMiLCIuLi9pbmRleC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuLy8gVE9ETyBUaGlzIGNsYXNzIG1heSBvciBtYXkgbm90IGJlIGluY2x1ZGVkIGluIHRoZSByZWxlYXNlLiBXZSBzaG91bGQgZGV0ZXJtaW5lIGlmXG4vLyB0aGVyZSBpcyBhIGJldHRlciBjb2RpbmcgcGF0dGVybiBmb3IgdGhpcyBmb3IgamF2YXNjcmlwdC5cblxuY2xhc3MgQXBwQ29uZmlnIHtcbiAgICAvKipcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICB0aGlzLl90cmFuc3BvcnRDb25maWcgPSBudWxsO1xuICAgICAgICB0aGlzLl9hcHBJZCA9IG51bGw7XG4gICAgICAgIHRoaXMuX2FwcE5hbWUgPSBudWxsO1xuICAgICAgICB0aGlzLl9pY29uTmFtZSA9IG51bGw7XG4gICAgICAgIHRoaXMuX2ljb25GaWxlID0gbnVsbDtcbiAgICAgICAgdGhpcy5fc2hvcnRBcHBOYW1lID0gbnVsbDtcbiAgICAgICAgdGhpcy5fdHRzTmFtZSA9IG51bGw7XG4gICAgICAgIHRoaXMuX3ZyU3lub255bXMgPSBudWxsO1xuICAgICAgICB0aGlzLl9pc01lZGlhQXBwID0gbnVsbDtcbiAgICAgICAgdGhpcy5fbGFuZ3VhZ2VEZXNpcmVkID0gbnVsbDtcbiAgICAgICAgdGhpcy5faG1pRGlzcGxheUxhbmd1YWdlRGVzaXJlZCA9IG51bGw7XG4gICAgICAgIHRoaXMuX2FwcFR5cGVzID0gbnVsbDtcbiAgICAgICAgdGhpcy5fZGF5Q29sb3JTY2hlbWUgPSBudWxsO1xuICAgICAgICB0aGlzLl9uaWdodENvbG9yU2NoZW1lID0gbnVsbDtcbiAgICAgICAgdGhpcy5fbWluaW11bVJQQ1ZlcnNpb24gPSBudWxsO1xuICAgICAgICB0aGlzLl9taW5pbXVtUHJvdG9jb2xWZXJzaW9uID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7VHJhbnNwb3J0Q29uZmlnQmFzZX0gdHJhbnNwb3J0Q29uZmlnXG4gICAgKiBAcmV0dXJuIHtBcHBDb25maWd9XG4gICAgKi9cbiAgICBzZXRUcmFuc3BvcnRDb25maWcgKHRyYW5zcG9ydENvbmZpZykge1xuICAgICAgICB0aGlzLl90cmFuc3BvcnRDb25maWcgPSB0cmFuc3BvcnRDb25maWc7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7VHJhbnNwb3J0Q29uZmlnQmFzZX1cbiAgICAqL1xuICAgIGdldFRyYW5zcG9ydENvbmZpZyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnRDb25maWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gYXBwSWRcbiAgICAqIEByZXR1cm4ge0FwcENvbmZpZ31cbiAgICAqL1xuICAgIHNldEFwcElkIChhcHBJZCkge1xuICAgICAgICB0aGlzLl9hcHBJZCA9IGFwcElkO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIGdldEFwcElkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcElkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IGFwcE5hbWVcbiAgICAqIEByZXR1cm4ge0FwcENvbmZpZ31cbiAgICAqL1xuICAgIHNldEFwcE5hbWUgKGFwcE5hbWUpIHtcbiAgICAgICAgdGhpcy5fYXBwTmFtZSA9IGFwcE5hbWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgZ2V0QXBwTmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hcHBOYW1lO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IGljb25OYW1lXG4gICAgKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGZpbGVEYXRhXG4gICAgKiBAcmV0dXJuIHtBcHBDb25maWd9XG4gICAgKi9cbiAgICBzZXRBcHBJY29uIChpY29uTmFtZSA9ICdpY29uLnBuZycsIGZpbGVEYXRhKSB7XG4gICAgICAgIC8vIFRPRE8gY3JlYXRlIFNkbEFydHdvcmtcbiAgICAgICAgdGhpcy5faWNvbk5hbWUgPSBpY29uTmFtZTtcbiAgICAgICAgdGhpcy5faWNvbkZpbGUgPSBmaWxlRGF0YTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAqL1xuICAgIGdldEFwcEljb25OYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ljb25OYW1lO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7VWludDhBcnJheX1cbiAgICAqL1xuICAgIGdldEFwcEljb25GaWxlRGF0YSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pY29uRmlsZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBzaG9ydEFwcE5hbWVcbiAgICAqIEByZXR1cm4ge0FwcENvbmZpZ31cbiAgICAqL1xuICAgIHNldFNob3J0QXBwTmFtZSAoc2hvcnRBcHBOYW1lKSB7XG4gICAgICAgIHRoaXMuX3Nob3J0QXBwTmFtZSA9IHNob3J0QXBwTmFtZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBnZXRTaG9ydEFwcE5hbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2hvcnRBcHBOYW1lO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtBcnJheTxUVFNDaHVuaz59IHR0c05hbWVcbiAgICAqIEByZXR1cm4ge0FwcENvbmZpZ31cbiAgICAqL1xuICAgIHNldFR0c05hbWUgKHR0c05hbWUpIHtcbiAgICAgICAgdGhpcy5fdHRzTmFtZSA9IHR0c05hbWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7QXJyYXk8VFRTQ2h1bms+fVxuICAgICovXG4gICAgZ2V0VHRzTmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90dHNOYW1lO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtBcnJheTxTdHJpbmc+fSB2clN5bm9ueW1zXG4gICAgKiBAcmV0dXJuIHtBcHBDb25maWd9XG4gICAgKi9cbiAgICBzZXRWclN5bm9ueW1zICh2clN5bm9ueW1zKSB7XG4gICAgICAgIHRoaXMuX3ZyU3lub255bXMgPSB2clN5bm9ueW1zO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0FycmF5PFN0cmluZz59XG4gICAgKi9cbiAgICBnZXRWclN5bm9ueW1zICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZyU3lub255bXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0Jvb2xlYW59IGlzTWVkaWFBcHBcbiAgICAqIEByZXR1cm4ge0FwcENvbmZpZ31cbiAgICAqL1xuICAgIHNldElzTWVkaWFBcHAgKGlzTWVkaWFBcHApIHtcbiAgICAgICAgdGhpcy5faXNNZWRpYUFwcCA9IGlzTWVkaWFBcHA7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAqL1xuICAgIGlzTWVkaWFBcHAgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faXNNZWRpYUFwcDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7TGFuZ3VhZ2V9IGxhbmd1YWdlRGVzaXJlZFxuICAgICogQHJldHVybiB7QXBwQ29uZmlnfVxuICAgICovXG4gICAgc2V0TGFuZ3VhZ2VEZXNpcmVkIChsYW5ndWFnZURlc2lyZWQpIHtcbiAgICAgICAgdGhpcy5fbGFuZ3VhZ2VEZXNpcmVkID0gbGFuZ3VhZ2VEZXNpcmVkO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0xhbmd1YWdlfVxuICAgICovXG4gICAgZ2V0TGFuZ3VhZ2VEZXNpcmVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xhbmd1YWdlRGVzaXJlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7TGFuZ3VhZ2V9IGhtaURpc3BsYXlMYW5ndWFnZURlc2lyZWRcbiAgICAqIEByZXR1cm4ge0FwcENvbmZpZ31cbiAgICAqL1xuICAgIHNldEhtaURpc3BsYXlMYW5ndWFnZURlc2lyZWQgKGhtaURpc3BsYXlMYW5ndWFnZURlc2lyZWQpIHtcbiAgICAgICAgdGhpcy5faG1pRGlzcGxheUxhbmd1YWdlRGVzaXJlZCA9IGhtaURpc3BsYXlMYW5ndWFnZURlc2lyZWQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TGFuZ3VhZ2V9XG4gICAgKi9cbiAgICBnZXRIbWlEaXNwbGF5TGFuZ3VhZ2VEZXNpcmVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2htaURpc3BsYXlMYW5ndWFnZURlc2lyZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0FycmF5PEFwcEhNSVR5cGU+fSBhcHBUeXBlcyBhbiBhcnJheSBvZiBvcmRlcmVkIGFwcCB0eXBlc1xuICAgICogQHJldHVybiB7QXBwQ29uZmlnfVxuICAgICovXG4gICAgc2V0QXBwVHlwZXMgKGFwcFR5cGVzKSB7XG4gICAgICAgIHRoaXMuX2FwcFR5cGVzID0gYXBwVHlwZXM7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7QXJyYXk8QXBwSE1JVHlwZT59XG4gICAgKi9cbiAgICBnZXRBcHBUeXBlcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hcHBUeXBlcztcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtUZW1wbGF0ZUNvbG9yU2NoZW1lfSBkYXlDb2xvclNjaGVtZVxuICAgICogQHJldHVybiB7QXBwQ29uZmlnfVxuICAgICovXG4gICAgc2V0RGF5Q29sb3JTY2hlbWUgKGRheUNvbG9yU2NoZW1lKSB7XG4gICAgICAgIHRoaXMuX2RheUNvbG9yU2NoZW1lID0gZGF5Q29sb3JTY2hlbWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7VGVtcGxhdGVDb2xvclNjaGVtZX1cbiAgICAqL1xuICAgIGdldERheUNvbG9yU2NoZW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RheUNvbG9yU2NoZW1lO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtUZW1wbGF0ZUNvbG9yU2NoZW1lfSBuaWdodENvbG9yU2NoZW1lXG4gICAgKiBAcmV0dXJuIHtBcHBDb25maWd9XG4gICAgKi9cbiAgICBzZXROaWdodENvbG9yU2NoZW1lIChuaWdodENvbG9yU2NoZW1lKSB7XG4gICAgICAgIHRoaXMuX25pZ2h0Q29sb3JTY2hlbWUgPSBuaWdodENvbG9yU2NoZW1lO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1RlbXBsYXRlQ29sb3JTY2hlbWV9XG4gICAgKi9cbiAgICBnZXROaWdodENvbG9yU2NoZW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX25pZ2h0Q29sb3JTY2hlbWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBUaGUgbWluaW11bSBSUEMgdmVyc2lvbiB0aGF0IHdpbGwgYmUgcGVybWl0dGVkIHRvIGNvbm5lY3QuXG4gICAgKiBJZiB0aGUgUlBDIHZlcnNpb24gb2YgdGhlIGhlYWQgdW5pdCBjb25uZWN0ZWQgaXMgYmVsb3cgdGhpcyB2ZXJzaW9uLCBhbiBVbnJlZ2lzdGVyQXBwSW50ZXJmYWNlIHdpbGwgYmUgc2VudC5cbiAgICAqXG4gICAgKiBAcGFyYW0ge1ZlcnNpb259IG1pbmltdW1SUENWZXJzaW9uXG4gICAgKiBAcmV0dXJuIHtBcHBDb25maWd9XG4gICAgKi9cbiAgICBzZXRNaW5pbXVtUlBDVmVyc2lvbiAobWluaW11bVJQQ1ZlcnNpb24pIHtcbiAgICAgICAgdGhpcy5fbWluaW11bVJQQ1ZlcnNpb24gPSBtaW5pbXVtUlBDVmVyc2lvbjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAqIEByZXR1cm4ge1ZlcnNpb259XG4gICAgKi9cbiAgICBnZXRNaW5pbXVtUlBDVmVyc2lvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9taW5pbXVtUlBDVmVyc2lvbjtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICogU2V0cyB0aGUgbWluaW11bSBwcm90b2NvbCB2ZXJzaW9uIHRoYXQgd2lsbCBiZSBwZXJtaXR0ZWQgdG8gY29ubmVjdC5cbiAgICAqIElmIHRoZSBwcm90b2NvbCB2ZXJzaW9uIG9mIHRoZSBoZWFkIHVuaXQgY29ubmVjdGVkIGlzIGJlbG93IHRoaXMgdmVyc2lvbixcbiAgICAqIHRoZSBhcHAgd2lsbCBkaXNjb25uZWN0IHdpdGggYW4gRW5kU2VydmljZSBwcm90b2NvbCBtZXNzYWdlIGFuZCB3aWxsIG5vdCByZWdpc3Rlci5cbiAgICAqIEBwYXJhbSB7VmVyc2lvbn0gbWluaW11bVByb3RvY29sVmVyc2lvblxuICAgICogQHJldHVybiB7QXBwQ29uZmlnfVxuICAgICovXG4gICAgc2V0TWluaW11bVByb3RvY29sVmVyc2lvbiAobWluaW11bVByb3RvY29sVmVyc2lvbikge1xuICAgICAgICB0aGlzLl9taW5pbXVtUHJvdG9jb2xWZXJzaW9uID0gbWluaW11bVByb3RvY29sVmVyc2lvbjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtWZXJzaW9ufVxuICAgICovXG4gICAgZ2V0TWluaW11bVByb3RvY29sVmVyc2lvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9taW5pbXVtUHJvdG9jb2xWZXJzaW9uO1xuICAgIH1cbn1cblxuZXhwb3J0IHsgQXBwQ29uZmlnIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gTGlmZWN5Y2xlTGlzdGVuZXJcbiAqL1xuY2xhc3MgTGlmZWN5Y2xlTGlzdGVuZXIge1xuICAgIC8qKlxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICB0aGlzLl9vblByb3h5Q29ubmVjdGVkID0gbnVsbDtcbiAgICAgICAgdGhpcy5fb25Qcm94eUNsb3NlZCA9IG51bGw7XG4gICAgICAgIHRoaXMuX29uU2VydmljZVN0YXJ0ZWQgPSBudWxsO1xuICAgICAgICB0aGlzLl9vblNlcnZpY2VFbmRlZCA9IG51bGw7XG4gICAgICAgIHRoaXMuX29uRXJyb3IgPSBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyXG4gICAgICovXG4gICAgc2V0T25Qcm94eUNvbm5lY3RlZCAobGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5fb25Qcm94eUNvbm5lY3RlZCA9IGxpc3RlbmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyXG4gICAgICovXG4gICAgc2V0T25Qcm94eUNsb3NlZCAobGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5fb25Qcm94eUNsb3NlZCA9IGxpc3RlbmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyXG4gICAgICovXG4gICAgc2V0T25TZXJ2aWNlU3RhcnRlZCAobGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5fb25TZXJ2aWNlU3RhcnRlZCA9IGxpc3RlbmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyXG4gICAgICovXG4gICAgc2V0T25TZXJ2aWNlRW5kZWQgKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMuX29uU2VydmljZUVuZGVkID0gbGlzdGVuZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBzZXRPbkVycm9yIChsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLl9vbkVycm9yID0gbGlzdGVuZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtMaWZlY3ljbGVNYW5hZ2VyfSBsaWZlY3ljbGVNYW5hZ2VyXG5cbiAgICAgKi9cbiAgICBvblByb3h5Q29ubmVjdGVkIChsaWZlY3ljbGVNYW5hZ2VyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fb25Qcm94eUNvbm5lY3RlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5fb25Qcm94eUNvbm5lY3RlZChsaWZlY3ljbGVNYW5hZ2VyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TGlmZWN5Y2xlTWFuYWdlcn0gbGlmZWN5Y2xlTWFuYWdlclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBpbmZvXG4gICAgICogQHBhcmFtIHtTZGxEaXNjb25uZWN0ZWRSZWFzb259IHJlYXNvblxuICAgICAqL1xuICAgIG9uUHJveHlDbG9zZWQgKGxpZmVjeWNsZU1hbmFnZXIsIGluZm8sIHJlYXNvbikge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX29uUHJveHlDbG9zZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuX29uUHJveHlDbG9zZWQobGlmZWN5Y2xlTWFuYWdlciwgaW5mbywgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICovXG4gICAgb25TZXJ2aWNlU3RhcnRlZCAoc2VydmljZVR5cGUsIHNlc3Npb25JRCwgY29ycmVsYXRpb25JRCkge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX29uUHJvdG9jb2xTZXNzaW9uRW5kZWROQUNLZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuX29uU2VydmljZVN0YXJ0ZWQoc2VydmljZVR5cGUsIHNlc3Npb25JRCwgY29ycmVsYXRpb25JRCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZVxuICAgICAqL1xuICAgIG9uU2VydmljZUVuZGVkIChzZXJ2aWNlVHlwZSkge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX29uU2VydmljZUVuZGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9vblNlcnZpY2VFbmRlZChzZXJ2aWNlVHlwZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0xpZmVjeWNsZU1hbmFnZXJ9IGxpZmVjeWNsZU1hbmFnZXJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gaW5mb1xuICAgICAqL1xuICAgIG9uRXJyb3IgKGxpZmVjeWNsZU1hbmFnZXIsIGluZm8pIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9vbkVycm9yID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9vbkVycm9yKGxpZmVjeWNsZU1hbmFnZXIsIGluZm8pO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgeyBMaWZlY3ljbGVMaXN0ZW5lciB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5jbGFzcyBFbnVtIHtcbiAgICAvKipcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICAvLyBpbnRlbnRpb25hbGx5IGVtcHR5XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBSZXR1cm5zIHRoZSBrZXkgZm9yIGEgZ2l2ZW4gdmFsdWUgaWYgdGhlIHZhbHVlIGlzIGZvdW5kIHdpdGhpbiB0aGUga2V5OnZhbHVlIG1hcFxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCBpbiB0aGUgbWFwXG4gICAgKiBAcGFyYW0gbWFwIHtPYmplY3R9IC0gQW4gbWFwIG9mIHN0cmluZyBwcm9wZXJ0aWVzIHRvIHByaW1pdGl2ZSB2YWx1ZXNcbiAgICAqIEByZXR1cm4ge251bGx8U3RyaW5nfSAtIFJldHVybnMgbnVsbCBpZiBub3QgZm91bmRcbiAgICAqL1xuICAgIHN0YXRpYyBfa2V5Rm9yVmFsdWUgKHZhbHVlLCBtYXApIHtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gbWFwKSB7XG4gICAgICAgICAgICBpZiAobWFwW2tleV0gPT09IHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGtleTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQSBtZXRob2QgZm9yIHN1YmNsYXNzZXMgdG8gaW1wbGVtZW50IHRoYXQgZG9lcyB3aGF0IF9rZXlGb3JWYWx1ZSBkb2VzXG4gICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtZXRob2QgbXVzdCBiZSBvdmVycmlkZGVuJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGtleSBpZiB0aGUga2V5IGlzIGZvdW5kIHdpdGhpbiB0aGUga2V5OnZhbHVlIG1hcFxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCBpbiB0aGUgbWFwXG4gICAgKiBAcGFyYW0gbWFwIHtPYmplY3R9IC0gQW4gbWFwIG9mIHN0cmluZyBwcm9wZXJ0aWVzIHRvIHByaW1pdGl2ZSB2YWx1ZXNcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIF92YWx1ZUZvcktleSAoa2V5LCBtYXApIHtcbiAgICAgICAgcmV0dXJuIG1hcFtrZXldIHx8IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBBIG1ldGhvZCBmb3Igc3ViY2xhc3NlcyB0byBpbXBsZW1lbnQgdGhhdCBkb2VzIHdoYXQgX3ZhbHVlRm9yS2V5IGRvZXNcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ21ldGhvZCBtdXN0IGJlIG92ZXJyaWRkZW4nKTtcbiAgICB9XG59XG5cbmV4cG9ydCB7IEVudW0gfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uL3V0aWwvRW51bS5qcyc7XG5cbmNsYXNzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzID0ge30pIHtcbiAgICAgICAgdGhpcy5faXNGb3JtYXRSZXF1ZXN0ZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fcnBjU3BlY1ZlcnNpb24gPSBudWxsO1xuICAgICAgICB0aGlzLl9wYXJhbWV0ZXJzID0gcGFyYW1ldGVycyB8fCB7fTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge09iamVjdH1cbiAgICAqL1xuICAgIGdldFBhcmFtZXRlcnMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW1ldGVycztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAgICAqIEByZXR1cm4geyp9XG4gICAgKi9cbiAgICBnZXRQYXJhbWV0ZXIgKGtleSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW1ldGVyc1trZXldO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICAgICogQHBhcmFtIHsqfSB2YWx1ZVxuICAgICogQHJldHVybiB7UnBjU3RydWN0fVxuICAgICovXG4gICAgc2V0UGFyYW1ldGVyIChrZXksIHZhbHVlKSB7XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuX3BhcmFtZXRlcnNba2V5XTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3BhcmFtZXRlcnNba2V5XSA9IHZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSB0Q2xhc3NcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAgICAqIEByZXR1cm4ge09iamVjdH1cbiAgICAqL1xuICAgIGdldE9iamVjdCAodENsYXNzLCBrZXkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0T2JqZWN0KHRDbGFzcywgdGhpcy5nZXRQYXJhbWV0ZXIoa2V5KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSB0Q2xhc3NcbiAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAgICAqIEByZXR1cm4ge251bGx8T2JqZWN0fVxuICAgICovXG4gICAgZm9ybWF0T2JqZWN0ICh0Q2xhc3MsIG9iaikge1xuICAgICAgICBpZiAob2JqID09PSBudWxsIHx8IG9iaiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfSBlbHNlIGlmIChvYmouY29uc3RydWN0b3IgPT09IHRDbGFzcykge1xuICAgICAgICAgICAgLy8gaWYgdENsYXNzIGlzIFN0cmluZyBhbmQgb2JqIGlzIGEgU3RyaW5nLCB0aGlzIHNob3VsZCBleGVjdXRlXG4gICAgICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgICB9IGVsc2UgaWYgKG9iai5jb25zdHJ1Y3RvciA9PT0gU3RyaW5nKSB7IC8vIHRoaXMgY292ZXJzIHRoZSBFbnVtIGNhc2UgdG9vXG4gICAgICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgICB9IGVsc2UgaWYgKG9iai5jb25zdHJ1Y3RvciA9PT0gT2JqZWN0KSB7XG4gICAgICAgICAgICBpZiAodENsYXNzLnByb3RvdHlwZSBpbnN0YW5jZW9mIFJwY1N0cnVjdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgdENsYXNzKG9iaik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfSBlbHNlIGlmIChvYmouY29uc3RydWN0b3IgPT09IEFycmF5KSB7XG4gICAgICAgICAgICBpZiAob2JqLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvdXRBcnJheSA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBvYmopIHtcbiAgICAgICAgICAgICAgICAgICAgb3V0QXJyYXkucHVzaCh0aGlzLmZvcm1hdE9iamVjdCh0Q2xhc3MsIGl0ZW0pKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG91dEFycmF5O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtGdW5jdGlvbn0gdENsYXNzXG4gICAgKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gICAgKiBAcGFyYW0ge0Jvb2xlYW59IGlzQXJyYXkgKGZhbHNlKVxuICAgICovXG4gICAgdmFsaWRhdGVUeXBlICh0Q2xhc3MsIG9iaiwgaXNBcnJheSA9IGZhbHNlKSB7XG4gICAgICAgIGlmIChpc0FycmF5KSB7XG4gICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmoubmFtZX0gbXVzdCBiZSBhbiBhcnJheSBjb250YWluaW5nIGl0ZW1zIG9mIHR5cGUgJHt0Q2xhc3MubmFtZX1gKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIG9iaikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZSh0Q2xhc3MsIGl0ZW0sIGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAodENsYXNzLnByb3RvdHlwZSBpbnN0YW5jZW9mIEVudW0gJiYgdENsYXNzLmtleUZvclZhbHVlKG9iaikgPT09IG51bGwpXG4gICAgICAgICAgICB8fCAodENsYXNzLnByb3RvdHlwZSBpbnN0YW5jZW9mIFJwY1N0cnVjdCAmJiBvYmogIT09IG51bGwgJiYgb2JqLmNvbnN0cnVjdG9yICE9PSB0Q2xhc3MpXG4gICAgICAgICkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iai5uYW1lfSBtdXN0IGJlIG9mIHR5cGUgJHt0Q2xhc3MubmFtZX1gKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IHsgUnBjU3RydWN0IH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcblxuLyoqXG4gKiBDb250YWlucyBkZXRhaWxlZCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcmVnaXN0ZXJlZCBhcHBsaWNhdGlvbi5cbiAqL1xuY2xhc3MgQXBwSW5mbyBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSBkaXNwbGF5ZWQgZm9yIHRoZSBtb2JpbGUgYXBwbGljYXRpb24gb24gdGhlIG1vYmlsZSBkZXZpY2UgKGNhbiBkaWZmZXIgZnJvbSB0aGVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIGFwcCBuYW1lIHNldCBpbiB0aGUgaW5pdGlhbCBSQUkgcmVxdWVzdCkuXG4gICAgICogQHJldHVybiB7QXBwSW5mb31cbiAgICAgKi9cbiAgICBzZXRBcHBEaXNwbGF5TmFtZSAobmFtZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBcHBJbmZvLktFWV9BUFBfRElTUExBWV9OQU1FLCBuYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldEFwcERpc3BsYXlOYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEFwcEluZm8uS0VZX0FQUF9ESVNQTEFZX05BTUUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBpZCAtIFRoZSBBcHBCdW5kbGVJRCBvZiBhbiBpT1MgYXBwbGljYXRpb24gb3IgcGFja2FnZSBuYW1lIG9mIHRoZSBBbmRyb2lkIGFwcGxpY2F0aW9uLiBUaGlzXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgc3VwcG9ydHMgQXBwIExhdW5jaCBzdHJhdGVnaWVzIGZvciBlYWNoIHBsYXRmb3JtLlxuICAgICAqIEByZXR1cm4ge0FwcEluZm99XG4gICAgICovXG4gICAgc2V0QXBwQnVuZGxlSUQgKGlkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEFwcEluZm8uS0VZX0FQUF9CVU5ETEVfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldEFwcEJ1bmRsZUlEICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEFwcEluZm8uS0VZX0FQUF9CVU5ETEVfSUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB2ZXJzaW9uIC0gUmVwcmVzZW50cyB0aGUgYnVpbGQgdmVyc2lvbiBudW1iZXIgb2YgdGhpcyBwYXJ0aWN1bGFyIG1vYmlsZSBhcHAuXG4gICAgICogQHJldHVybiB7QXBwSW5mb31cbiAgICAgKi9cbiAgICBzZXRBcHBWZXJzaW9uICh2ZXJzaW9uKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEFwcEluZm8uS0VZX0FQUF9WRVJTSU9OLCB2ZXJzaW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldEFwcFZlcnNpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQXBwSW5mby5LRVlfQVBQX1ZFUlNJT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBpY29uIC0gQSBmaWxlIHJlZmVyZW5jZSB0byB0aGUgaWNvbiB1dGlsaXplZCBieSB0aGlzIGFwcCAoc2ltcGxpZmllcyB0aGUgcHJvY2VzcyBvZiBzZXR0aW5nIGFuXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICBhcHAgaWNvbiBkdXJpbmcgYXBwIHJlZ2lzdHJhdGlvbikuXG4gICAgICogQHJldHVybiB7QXBwSW5mb31cbiAgICAgKi9cbiAgICBzZXRBcHBJY29uIChpY29uKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEFwcEluZm8uS0VZX0FQUF9JQ09OLCBpY29uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldEFwcEljb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQXBwSW5mby5LRVlfQVBQX0lDT04pO1xuICAgIH1cbn1cblxuQXBwSW5mby5LRVlfQVBQX0RJU1BMQVlfTkFNRSA9ICdhcHBEaXNwbGF5TmFtZSc7XG5BcHBJbmZvLktFWV9BUFBfQlVORExFX0lEID0gJ2FwcEJ1bmRsZUlEJztcbkFwcEluZm8uS0VZX0FQUF9WRVJTSU9OID0gJ2FwcFZlcnNpb24nO1xuQXBwSW5mby5LRVlfQVBQX0lDT04gPSAnYXBwSWNvbic7XG5cbmV4cG9ydCB7IEFwcEluZm8gfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuXG5jbGFzcyBSR0JDb2xvciBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHJlZFxuICAgICAqIEByZXR1cm4ge1JHQkNvbG9yfVxuICAgICAqL1xuICAgIHNldFJlZCAocmVkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJHQkNvbG9yLktFWV9SRUQsIHJlZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRSZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUkdCQ29sb3IuS0VZX1JFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGdyZWVuXG4gICAgICogQHJldHVybiB7UkdCQ29sb3J9XG4gICAgICovXG4gICAgc2V0R3JlZW4gKGdyZWVuKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJHQkNvbG9yLktFWV9HUkVFTiwgZ3JlZW4pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0R3JlZW4gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUkdCQ29sb3IuS0VZX0dSRUVOKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYmx1ZVxuICAgICAqIEByZXR1cm4ge1JHQkNvbG9yfVxuICAgICAqL1xuICAgIHNldEJsdWUgKGJsdWUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUkdCQ29sb3IuS0VZX0JMVUUsIGJsdWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0Qmx1ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSR0JDb2xvci5LRVlfQkxVRSk7XG4gICAgfVxufVxuXG5SR0JDb2xvci5LRVlfUkVEID0gJ3JlZCc7XG5SR0JDb2xvci5LRVlfR1JFRU4gPSAnZ3JlZW4nO1xuUkdCQ29sb3IuS0VZX0JMVUUgPSAnYmx1ZSc7XG5cbmV4cG9ydCB7IFJHQkNvbG9yIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IFJHQkNvbG9yIH0gZnJvbSAnLi9SR0JDb2xvci5qcyc7XG5cbi8qKlxuICogQSBjb2xvciBzY2hlbWUgZm9yIGFsbCBkaXNwbGF5IGxheW91dCB0ZW1wbGF0ZXMuXG4gKi9cbmNsYXNzIFRlbXBsYXRlQ29sb3JTY2hlbWUgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7UkdCQ29sb3J9IGNvbG9yIC0gVGhlIHByaW1hcnkgXCJhY2NlbnRcIiBjb2xvclxuICAgICAqIEByZXR1cm4ge1RlbXBsYXRlQ29sb3JTY2hlbWV9XG4gICAgICovXG4gICAgc2V0UHJpbWFyeUNvbG9yIChjb2xvcikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShSR0JDb2xvciwgY29sb3IpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihUZW1wbGF0ZUNvbG9yU2NoZW1lLktFWV9QUklNQVJZX0NPTE9SLCBjb2xvcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1JHQkNvbG9yfVxuICAgICAqL1xuICAgIGdldFByaW1hcnlDb2xvciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChSR0JDb2xvciwgVGVtcGxhdGVDb2xvclNjaGVtZS5LRVlfUFJJTUFSWV9DT0xPUik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtSR0JDb2xvcn0gY29sb3IgLSBUaGUgc2Vjb25kYXJ5IFwiYWNjZW50XCIgY29sb3JcbiAgICAgKiBAcmV0dXJuIHtUZW1wbGF0ZUNvbG9yU2NoZW1lfVxuICAgICAqL1xuICAgIHNldFNlY29uZGFyeUNvbG9yIChjb2xvcikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShSR0JDb2xvciwgY29sb3IpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihUZW1wbGF0ZUNvbG9yU2NoZW1lLktFWV9TRUNPTkRBUllfQ09MT1IsIGNvbG9yKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7UkdCQ29sb3J9XG4gICAgICovXG4gICAgZ2V0U2Vjb25kYXJ5Q29sb3IgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoUkdCQ29sb3IsIFRlbXBsYXRlQ29sb3JTY2hlbWUuS0VZX1NFQ09OREFSWV9DT0xPUik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtSR0JDb2xvcn0gY29sb3IgLSBUaGUgY29sb3Igb2YgdGhlIGJhY2tncm91bmRcbiAgICAgKiBAcmV0dXJuIHtUZW1wbGF0ZUNvbG9yU2NoZW1lfVxuICAgICAqL1xuICAgIHNldEJhY2tncm91bmRDb2xvciAoY29sb3IpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoUkdCQ29sb3IsIGNvbG9yKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVGVtcGxhdGVDb2xvclNjaGVtZS5LRVlfQkFDS0dST1VORF9DT0xPUiwgY29sb3IpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtSR0JDb2xvcn1cbiAgICAgKi9cbiAgICBnZXRCYWNrZ3JvdW5kQ29sb3IgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoUkdCQ29sb3IsIFRlbXBsYXRlQ29sb3JTY2hlbWUuS0VZX0JBQ0tHUk9VTkRfQ09MT1IpO1xuICAgIH1cbn1cblxuVGVtcGxhdGVDb2xvclNjaGVtZS5LRVlfUFJJTUFSWV9DT0xPUiA9ICdwcmltYXJ5Q29sb3InO1xuVGVtcGxhdGVDb2xvclNjaGVtZS5LRVlfU0VDT05EQVJZX0NPTE9SID0gJ3NlY29uZGFyeUNvbG9yJztcblRlbXBsYXRlQ29sb3JTY2hlbWUuS0VZX0JBQ0tHUk9VTkRfQ09MT1IgPSAnYmFja2dyb3VuZENvbG9yJztcblxuZXhwb3J0IHsgVGVtcGxhdGVDb2xvclNjaGVtZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEVudW1lcmF0aW9uIGxpbmtpbmcgZnVuY3Rpb24gbmFtZXMgd2l0aCBmdW5jdGlvbiBJRHMgaW4gU21hcnREZXZpY2VMaW5rIHByb3RvY29sLiBBc3N1bWVzIGVudW1lcmF0aW9uIHN0YXJ0cyBhdFxuICogdmFsdWUgMC5cbiAqIEB0eXBlZGVmIHtFbnVtfSBGdW5jdGlvbklEXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBGdW5jdGlvbklEIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJFU0VSVkVEICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5SRVNFUlZFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSZWdpc3RlckFwcEludGVyZmFjZSAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuUmVnaXN0ZXJBcHBJbnRlcmZhY2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVW5yZWdpc3RlckFwcEludGVyZmFjZSAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuVW5yZWdpc3RlckFwcEludGVyZmFjZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTZXRHbG9iYWxQcm9wZXJ0aWVzICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5TZXRHbG9iYWxQcm9wZXJ0aWVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJlc2V0R2xvYmFsUHJvcGVydGllcyAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuUmVzZXRHbG9iYWxQcm9wZXJ0aWVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFkZENvbW1hbmQgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkFkZENvbW1hbmQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRGVsZXRlQ29tbWFuZCAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuRGVsZXRlQ29tbWFuZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBBZGRTdWJNZW51ICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5BZGRTdWJNZW51O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IERlbGV0ZVN1Yk1lbnUgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkRlbGV0ZVN1Yk1lbnU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ3JlYXRlSW50ZXJhY3Rpb25DaG9pY2VTZXQgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkNyZWF0ZUludGVyYWN0aW9uQ2hvaWNlU2V0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFBlcmZvcm1JbnRlcmFjdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuUGVyZm9ybUludGVyYWN0aW9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IERlbGV0ZUludGVyYWN0aW9uQ2hvaWNlU2V0ICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5EZWxldGVJbnRlcmFjdGlvbkNob2ljZVNldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBBbGVydCAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuQWxlcnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU2hvdyAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuU2hvdztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTcGVhayAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuU3BlYWs7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU2V0TWVkaWFDbG9ja1RpbWVyICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5TZXRNZWRpYUNsb2NrVGltZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUGVyZm9ybUF1ZGlvUGFzc1RocnUgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlBlcmZvcm1BdWRpb1Bhc3NUaHJ1O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEVuZEF1ZGlvUGFzc1RocnUgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkVuZEF1ZGlvUGFzc1RocnU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU3Vic2NyaWJlQnV0dG9uICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5TdWJzY3JpYmVCdXR0b247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVW5zdWJzY3JpYmVCdXR0b24gKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlVuc3Vic2NyaWJlQnV0dG9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFN1YnNjcmliZVZlaGljbGVEYXRhICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5TdWJzY3JpYmVWZWhpY2xlRGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBVbnN1YnNjcmliZVZlaGljbGVEYXRhICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5VbnN1YnNjcmliZVZlaGljbGVEYXRhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEdldFZlaGljbGVEYXRhICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5HZXRWZWhpY2xlRGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSZWFkRElEICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5SZWFkRElEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEdldERUQ3MgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkdldERUQ3M7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU2Nyb2xsYWJsZU1lc3NhZ2UgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlNjcm9sbGFibGVNZXNzYWdlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNsaWRlciAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuU2xpZGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNob3dDb25zdGFudFRCVCAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuU2hvd0NvbnN0YW50VEJUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFsZXJ0TWFuZXV2ZXIgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkFsZXJ0TWFuZXV2ZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVXBkYXRlVHVybkxpc3QgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlVwZGF0ZVR1cm5MaXN0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENoYW5nZVJlZ2lzdHJhdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuQ2hhbmdlUmVnaXN0cmF0aW9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEdlbmVyaWNSZXNwb25zZSAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuR2VuZXJpY1Jlc3BvbnNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFB1dEZpbGUgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlB1dEZpbGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRGVsZXRlRmlsZSAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuRGVsZXRlRmlsZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBMaXN0RmlsZXMgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkxpc3RGaWxlcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTZXRBcHBJY29uICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5TZXRBcHBJY29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNldERpc3BsYXlMYXlvdXQgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlNldERpc3BsYXlMYXlvdXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRGlhZ25vc3RpY01lc3NhZ2UgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkRpYWdub3N0aWNNZXNzYWdlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFN5c3RlbVJlcXVlc3QgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlN5c3RlbVJlcXVlc3Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU2VuZExvY2F0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5TZW5kTG9jYXRpb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRGlhbE51bWJlciAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuRGlhbE51bWJlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBCdXR0b25QcmVzcyAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuQnV0dG9uUHJlc3M7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgR2V0SW50ZXJpb3JWZWhpY2xlRGF0YSAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuR2V0SW50ZXJpb3JWZWhpY2xlRGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTZXRJbnRlcmlvclZlaGljbGVEYXRhICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5TZXRJbnRlcmlvclZlaGljbGVEYXRhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEdldFdheVBvaW50cyAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuR2V0V2F5UG9pbnRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFN1YnNjcmliZVdheVBvaW50cyAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuU3Vic2NyaWJlV2F5UG9pbnRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFVuc3Vic2NyaWJlV2F5UG9pbnRzICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5VbnN1YnNjcmliZVdheVBvaW50cztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBHZXRTeXN0ZW1DYXBhYmlsaXR5ICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5HZXRTeXN0ZW1DYXBhYmlsaXR5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNlbmRIYXB0aWNEYXRhICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5TZW5kSGFwdGljRGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTZXRDbG91ZEFwcFByb3BlcnRpZXMgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlNldENsb3VkQXBwUHJvcGVydGllcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBHZXRDbG91ZEFwcFByb3BlcnRpZXMgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkdldENsb3VkQXBwUHJvcGVydGllcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBQdWJsaXNoQXBwU2VydmljZSAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuUHVibGlzaEFwcFNlcnZpY2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgR2V0QXBwU2VydmljZURhdGEgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkdldEFwcFNlcnZpY2VEYXRhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEdldEZpbGUgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkdldEZpbGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUGVyZm9ybUFwcFNlcnZpY2VJbnRlcmFjdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuUGVyZm9ybUFwcFNlcnZpY2VJbnRlcmFjdGlvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBVbnB1Ymxpc2hBcHBTZXJ2aWNlICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5VbnB1Ymxpc2hBcHBTZXJ2aWNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENhbmNlbEludGVyYWN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5DYW5jZWxJbnRlcmFjdGlvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDbG9zZUFwcGxpY2F0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5DbG9zZUFwcGxpY2F0aW9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNob3dBcHBNZW51ICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5TaG93QXBwTWVudTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDcmVhdGVXaW5kb3cgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkNyZWF0ZVdpbmRvdztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBEZWxldGVXaW5kb3cgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkRlbGV0ZVdpbmRvdztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBHZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudCAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuR2V0SW50ZXJpb3JWZWhpY2xlRGF0YUNvbnNlbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUmVsZWFzZUludGVyaW9yVmVoaWNsZURhdGFNb2R1bGUgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlJlbGVhc2VJbnRlcmlvclZlaGljbGVEYXRhTW9kdWxlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE9uSE1JU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5PbkhNSVN0YXR1cztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBPbkFwcEludGVyZmFjZVVucmVnaXN0ZXJlZCAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuT25BcHBJbnRlcmZhY2VVbnJlZ2lzdGVyZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgT25CdXR0b25FdmVudCAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuT25CdXR0b25FdmVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBPbkJ1dHRvblByZXNzICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5PbkJ1dHRvblByZXNzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE9uVmVoaWNsZURhdGEgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLk9uVmVoaWNsZURhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgT25Db21tYW5kICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5PbkNvbW1hbmQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgT25UQlRDbGllbnRTdGF0ZSAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuT25UQlRDbGllbnRTdGF0ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBPbkRyaXZlckRpc3RyYWN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5PbkRyaXZlckRpc3RyYWN0aW9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE9uUGVybWlzc2lvbnNDaGFuZ2UgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLk9uUGVybWlzc2lvbnNDaGFuZ2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgT25BdWRpb1Bhc3NUaHJ1ICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5PbkF1ZGlvUGFzc1RocnU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgT25MYW5ndWFnZUNoYW5nZSAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuT25MYW5ndWFnZUNoYW5nZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBPbktleWJvYXJkSW5wdXQgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLk9uS2V5Ym9hcmRJbnB1dDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBPblRvdWNoRXZlbnQgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLk9uVG91Y2hFdmVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBPblN5c3RlbVJlcXVlc3QgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLk9uU3lzdGVtUmVxdWVzdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBPbkhhc2hDaGFuZ2UgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLk9uSGFzaENoYW5nZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBPbkludGVyaW9yVmVoaWNsZURhdGEgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLk9uSW50ZXJpb3JWZWhpY2xlRGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBPbldheVBvaW50Q2hhbmdlICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5PbldheVBvaW50Q2hhbmdlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE9uUkNTdGF0dXMgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLk9uUkNTdGF0dXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgT25BcHBTZXJ2aWNlRGF0YSAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuT25BcHBTZXJ2aWNlRGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBPblN5c3RlbUNhcGFiaWxpdHlVcGRhdGVkICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5PblN5c3RlbUNhcGFiaWxpdHlVcGRhdGVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEVuY29kZWRTeW5jUERhdGEgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLkVuY29kZWRTeW5jUERhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU2RsUERhdGEgKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25JRC5fTUFQLlNkbFBEYXRhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE9uRW5jb2RlZFN5bmNQRGF0YSAoKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9NQVAuT25FbmNvZGVkU3luY1BEYXRhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE9uU3luY1BEYXRhICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uSUQuX01BUC5PblN5bmNQRGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl92YWx1ZUZvcktleShrZXksIEZ1bmN0aW9uSUQuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbklELl9rZXlGb3JWYWx1ZSh2YWx1ZSwgRnVuY3Rpb25JRC5fTUFQKTtcbiAgICB9XG59XG5cbkZ1bmN0aW9uSUQuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdSRVNFUlZFRCc6IDAsXG4gICAgJ1JlZ2lzdGVyQXBwSW50ZXJmYWNlJzogMHgwMSxcbiAgICAnVW5yZWdpc3RlckFwcEludGVyZmFjZSc6IDB4MDIsXG4gICAgJ1NldEdsb2JhbFByb3BlcnRpZXMnOiAweDAzLFxuICAgICdSZXNldEdsb2JhbFByb3BlcnRpZXMnOiAweDA0LFxuICAgICdBZGRDb21tYW5kJzogMHgwNSxcbiAgICAnRGVsZXRlQ29tbWFuZCc6IDB4MDYsXG4gICAgJ0FkZFN1Yk1lbnUnOiAweDA3LFxuICAgICdEZWxldGVTdWJNZW51JzogMHgwOCxcbiAgICAnQ3JlYXRlSW50ZXJhY3Rpb25DaG9pY2VTZXQnOiAweDA5LFxuICAgICdQZXJmb3JtSW50ZXJhY3Rpb24nOiAweDBBLFxuICAgICdEZWxldGVJbnRlcmFjdGlvbkNob2ljZVNldCc6IDB4MEIsXG4gICAgJ0FsZXJ0JzogMHgwQyxcbiAgICAnU2hvdyc6IDB4MEQsXG4gICAgJ1NwZWFrJzogMHgwRSxcbiAgICAnU2V0TWVkaWFDbG9ja1RpbWVyJzogMHgwRixcbiAgICAnUGVyZm9ybUF1ZGlvUGFzc1RocnUnOiAweDEwLFxuICAgICdFbmRBdWRpb1Bhc3NUaHJ1JzogMHgxMSxcbiAgICAnU3Vic2NyaWJlQnV0dG9uJzogMHgxMixcbiAgICAnVW5zdWJzY3JpYmVCdXR0b24nOiAweDEzLFxuICAgICdTdWJzY3JpYmVWZWhpY2xlRGF0YSc6IDB4MTQsXG4gICAgJ1Vuc3Vic2NyaWJlVmVoaWNsZURhdGEnOiAweDE1LFxuICAgICdHZXRWZWhpY2xlRGF0YSc6IDB4MTYsXG4gICAgJ1JlYWRESUQnOiAweDE3LFxuICAgICdHZXREVENzJzogMHgxOCxcbiAgICAnU2Nyb2xsYWJsZU1lc3NhZ2UnOiAweDE5LFxuICAgICdTbGlkZXInOiAweDFBLFxuICAgICdTaG93Q29uc3RhbnRUQlQnOiAweDFCLFxuICAgICdBbGVydE1hbmV1dmVyJzogMHgxQyxcbiAgICAnVXBkYXRlVHVybkxpc3QnOiAweDFELFxuICAgICdDaGFuZ2VSZWdpc3RyYXRpb24nOiAweDFFLFxuICAgICdHZW5lcmljUmVzcG9uc2UnOiAweDFGLFxuICAgICdQdXRGaWxlJzogMHgyMCxcbiAgICAnRGVsZXRlRmlsZSc6IDB4MjEsXG4gICAgJ0xpc3RGaWxlcyc6IDB4MjIsXG4gICAgJ1NldEFwcEljb24nOiAweDIzLFxuICAgICdTZXREaXNwbGF5TGF5b3V0JzogMHgyNCxcbiAgICAnRGlhZ25vc3RpY01lc3NhZ2UnOiAweDI1LFxuICAgICdTeXN0ZW1SZXF1ZXN0JzogMHgyNixcbiAgICAnU2VuZExvY2F0aW9uJzogMHgyNyxcbiAgICAnRGlhbE51bWJlcic6IDB4MjgsXG4gICAgJ0J1dHRvblByZXNzJzogMHgyOSxcbiAgICAnR2V0SW50ZXJpb3JWZWhpY2xlRGF0YSc6IDB4MkIsXG4gICAgJ1NldEludGVyaW9yVmVoaWNsZURhdGEnOiAweDJDLFxuICAgICdHZXRXYXlQb2ludHMnOiAweDJELFxuICAgICdTdWJzY3JpYmVXYXlQb2ludHMnOiAweDJFLFxuICAgICdVbnN1YnNjcmliZVdheVBvaW50cyc6IDB4MkYsXG4gICAgJ0dldFN5c3RlbUNhcGFiaWxpdHknOiAweDMwLFxuICAgICdTZW5kSGFwdGljRGF0YSc6IDB4MzEsXG4gICAgJ1NldENsb3VkQXBwUHJvcGVydGllcyc6IDB4MzIsXG4gICAgJ0dldENsb3VkQXBwUHJvcGVydGllcyc6IDB4MzMsXG4gICAgJ1B1Ymxpc2hBcHBTZXJ2aWNlJzogMHgzNCxcbiAgICAnR2V0QXBwU2VydmljZURhdGEnOiAweDM1LFxuICAgICdHZXRGaWxlJzogMHgzNixcbiAgICAnUGVyZm9ybUFwcFNlcnZpY2VJbnRlcmFjdGlvbic6IDB4MzcsXG4gICAgJ1VucHVibGlzaEFwcFNlcnZpY2UnOiAweDM4LFxuICAgICdDYW5jZWxJbnRlcmFjdGlvbic6IDB4MzksXG4gICAgJ0Nsb3NlQXBwbGljYXRpb24nOiAweDNBLFxuICAgICdTaG93QXBwTWVudSc6IDB4M0IsXG4gICAgJ0NyZWF0ZVdpbmRvdyc6IDB4M0MsXG4gICAgJ0RlbGV0ZVdpbmRvdyc6IDB4M0QsXG4gICAgJ0dldEludGVyaW9yVmVoaWNsZURhdGFDb25zZW50JzogMHgzRSxcbiAgICAnUmVsZWFzZUludGVyaW9yVmVoaWNsZURhdGFNb2R1bGUnOiAweDNGLFxuICAgICdPbkhNSVN0YXR1cyc6IDB4ODAwMCxcbiAgICAnT25BcHBJbnRlcmZhY2VVbnJlZ2lzdGVyZWQnOiAweDgwMDEsXG4gICAgJ09uQnV0dG9uRXZlbnQnOiAweDgwMDIsXG4gICAgJ09uQnV0dG9uUHJlc3MnOiAweDgwMDMsXG4gICAgJ09uVmVoaWNsZURhdGEnOiAweDgwMDQsXG4gICAgJ09uQ29tbWFuZCc6IDB4ODAwNSxcbiAgICAnT25UQlRDbGllbnRTdGF0ZSc6IDB4ODAwNixcbiAgICAnT25Ecml2ZXJEaXN0cmFjdGlvbic6IDB4ODAwNyxcbiAgICAnT25QZXJtaXNzaW9uc0NoYW5nZSc6IDB4ODAwOCxcbiAgICAnT25BdWRpb1Bhc3NUaHJ1JzogMHg4MDA5LFxuICAgICdPbkxhbmd1YWdlQ2hhbmdlJzogMHg4MDBBLFxuICAgICdPbktleWJvYXJkSW5wdXQnOiAweDgwMEIsXG4gICAgJ09uVG91Y2hFdmVudCc6IDB4ODAwQyxcbiAgICAnT25TeXN0ZW1SZXF1ZXN0JzogMHg4MDBELFxuICAgICdPbkhhc2hDaGFuZ2UnOiAweDgwMEUsXG4gICAgJ09uSW50ZXJpb3JWZWhpY2xlRGF0YSc6IDB4ODAwRixcbiAgICAnT25XYXlQb2ludENoYW5nZSc6IDB4ODAxMCxcbiAgICAnT25SQ1N0YXR1cyc6IDB4ODAxMSxcbiAgICAnT25BcHBTZXJ2aWNlRGF0YSc6IDB4ODAxMixcbiAgICAnT25TeXN0ZW1DYXBhYmlsaXR5VXBkYXRlZCc6IDB4ODAxMyxcbiAgICAnRW5jb2RlZFN5bmNQRGF0YSc6IDB4MTAwMDAsXG4gICAgJ1N5bmNQRGF0YSc6IDB4MTAwMDEsXG4gICAgJ09uRW5jb2RlZFN5bmNQRGF0YSc6IDB4MTgwMDAsXG4gICAgJ09uU3luY1BEYXRhJzogMHgxODAwMSxcbn0pO1xuXG5leHBvcnQgeyBGdW5jdGlvbklEIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogQ29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIFRUUyBjYXBhYmlsaXRpZXMuXG4gKiBAdHlwZWRlZiB7RW51bX0gU3BlZWNoQ2FwYWJpbGl0aWVzXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBTcGVlY2hDYXBhYmlsaXRpZXMgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0NfVEVYVCAoKSB7XG4gICAgICAgIHJldHVybiBTcGVlY2hDYXBhYmlsaXRpZXMuX01BUC5TQ19URVhUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNBUElfUEhPTkVNRVMgKCkge1xuICAgICAgICByZXR1cm4gU3BlZWNoQ2FwYWJpbGl0aWVzLl9NQVAuU0FQSV9QSE9ORU1FUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBMSFBMVVNfUEhPTkVNRVMgKCkge1xuICAgICAgICByZXR1cm4gU3BlZWNoQ2FwYWJpbGl0aWVzLl9NQVAuTEhQTFVTX1BIT05FTUVTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFBSRV9SRUNPUkRFRCAoKSB7XG4gICAgICAgIHJldHVybiBTcGVlY2hDYXBhYmlsaXRpZXMuX01BUC5QUkVfUkVDT1JERUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0lMRU5DRSAoKSB7XG4gICAgICAgIHJldHVybiBTcGVlY2hDYXBhYmlsaXRpZXMuX01BUC5TSUxFTkNFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEZJTEUgKCkge1xuICAgICAgICByZXR1cm4gU3BlZWNoQ2FwYWJpbGl0aWVzLl9NQVAuRklMRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBTcGVlY2hDYXBhYmlsaXRpZXMuX3ZhbHVlRm9yS2V5KGtleSwgU3BlZWNoQ2FwYWJpbGl0aWVzLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gU3BlZWNoQ2FwYWJpbGl0aWVzLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgU3BlZWNoQ2FwYWJpbGl0aWVzLl9NQVApO1xuICAgIH1cbn1cblxuU3BlZWNoQ2FwYWJpbGl0aWVzLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnU0NfVEVYVCc6ICdURVhUJyxcbiAgICAnU0FQSV9QSE9ORU1FUyc6ICdTQVBJX1BIT05FTUVTJyxcbiAgICAnTEhQTFVTX1BIT05FTUVTJzogJ0xIUExVU19QSE9ORU1FUycsXG4gICAgJ1BSRV9SRUNPUkRFRCc6ICdQUkVfUkVDT1JERUQnLFxuICAgICdTSUxFTkNFJzogJ1NJTEVOQ0UnLFxuICAgICdGSUxFJzogJ0ZJTEUnLFxufSk7XG5cbmV4cG9ydCB7IFNwZWVjaENhcGFiaWxpdGllcyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBTcGVlY2hDYXBhYmlsaXRpZXMgfSBmcm9tICcuLi9lbnVtcy9TcGVlY2hDYXBhYmlsaXRpZXMuanMnO1xuXG4vKipcbiAqIEEgVFRTIGNodW5rLCB0aGF0IGNvbnNpc3RzIG9mIHRleHQvcGhvbmVtZXMgdG8gc3BlYWsgb3IgdGhlIG5hbWUgb2YgYSBmaWxlIHRvIHBsYXksIGFuZCBhIFRUUyB0eXBlIChsaWtlIHRleHQgb3JcbiAqIFNBUEkpXG4gKi9cbmNsYXNzIFRUU0NodW5rIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdGV4dCAtIFRoZSB0ZXh0IG9yIHBob25lbWVzIHRvIHNwZWFrLCBvciB0aGUgbmFtZSBvZiB0aGUgYXVkaW8gZmlsZSB0byBwbGF5LiBNYXkgbm90IGJlIGVtcHR5LlxuICAgICAqIEByZXR1cm4ge1RUU0NodW5rfVxuICAgICAqL1xuICAgIHNldFRleHQgKHRleHQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVFRTQ2h1bmsuS0VZX1RFWFQsIHRleHQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0VGV4dCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihUVFNDaHVuay5LRVlfVEVYVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTcGVlY2hDYXBhYmlsaXRpZXN9IHR5cGUgLSBEZXNjcmliZXMgd2hldGhlciB0aGUgVFRTIGNodW5rIGlzIHBsYWluIHRleHQsIGEgc3BlY2lmaWMgcGhvbmVtZSBzZXQsIG9yIGFuXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdWRpbyBmaWxlLiBTZWUgU3BlZWNoQ2FwYWJpbGl0aWVzXG4gICAgICogQHJldHVybiB7VFRTQ2h1bmt9XG4gICAgICovXG4gICAgc2V0VHlwZSAodHlwZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShTcGVlY2hDYXBhYmlsaXRpZXMsIHR5cGUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihUVFNDaHVuay5LRVlfVFlQRSwgdHlwZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1NwZWVjaENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBnZXRUeXBlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFNwZWVjaENhcGFiaWxpdGllcywgVFRTQ2h1bmsuS0VZX1RZUEUpO1xuICAgIH1cbn1cblxuVFRTQ2h1bmsuS0VZX1RFWFQgPSAndGV4dCc7XG5UVFNDaHVuay5LRVlfVFlQRSA9ICd0eXBlJztcblxuZXhwb3J0IHsgVFRTQ2h1bmsgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuXG4vKipcbiAqIFNwZWNpZmllcyB0aGUgdmVyc2lvbiBudW1iZXIgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBwcm90b2NvbCB0aGF0IGlzIHN1cHBvcnRlZCBieSB0aGUgbW9iaWxlIGFwcGxpY2F0aW9uXG4gKi9cbmNsYXNzIFNkbE1zZ1ZlcnNpb24gZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB2ZXJzaW9uIC0gVGhlIG1ham9yIHZlcnNpb24gaW5kaWNhdGVzIHZlcnNpb25zIHRoYXQgaXMgbm90LWNvbXBhdGlibGUgdG8gcHJldmlvdXMgdmVyc2lvbnMuXG4gICAgICogQHJldHVybiB7U2RsTXNnVmVyc2lvbn1cbiAgICAgKi9cbiAgICBzZXRNYWpvclZlcnNpb24gKHZlcnNpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2RsTXNnVmVyc2lvbi5LRVlfTUFKT1JfVkVSU0lPTiwgdmVyc2lvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRNYWpvclZlcnNpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2RsTXNnVmVyc2lvbi5LRVlfTUFKT1JfVkVSU0lPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHZlcnNpb24gLSBUaGUgbWlub3IgdmVyc2lvbiBpbmRpY2F0ZXMgYSBjaGFuZ2UgdG8gYSBwcmV2aW91cyB2ZXJzaW9uIHRoYXQgc2hvdWxkIHN0aWxsIGFsbG93IHRvXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICBiZSBydW4gb24gYW4gb2xkZXIgdmVyc2lvbiAod2l0aCBsaW1pdGVkIGZ1bmN0aW9uYWxpdHkpXG4gICAgICogQHJldHVybiB7U2RsTXNnVmVyc2lvbn1cbiAgICAgKi9cbiAgICBzZXRNaW5vclZlcnNpb24gKHZlcnNpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2RsTXNnVmVyc2lvbi5LRVlfTUlOT1JfVkVSU0lPTiwgdmVyc2lvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRNaW5vclZlcnNpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2RsTXNnVmVyc2lvbi5LRVlfTUlOT1JfVkVSU0lPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHZlcnNpb24gLSBUaGUgcGF0Y2ggdmVyc2lvbiBpbmRpY2F0ZXMgYSBmaXggdG8gZXhpc3RpbmcgZnVuY3Rpb25hbGl0eSBpbiBhIHByZXZpb3VzIHZlcnNpb24gdGhhdFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvdWxkIHN0aWxsIGJlIGFibGUgdG8gYmUgcnVuIG9uIGFuIG9sZGVyIHZlcnNpb25cbiAgICAgKiBAcmV0dXJuIHtTZGxNc2dWZXJzaW9ufVxuICAgICAqL1xuICAgIHNldFBhdGNoVmVyc2lvbiAodmVyc2lvbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZGxNc2dWZXJzaW9uLktFWV9QQVRDSF9WRVJTSU9OLCB2ZXJzaW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFBhdGNoVmVyc2lvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTZGxNc2dWZXJzaW9uLktFWV9QQVRDSF9WRVJTSU9OKTtcbiAgICB9XG59XG5cblNkbE1zZ1ZlcnNpb24uS0VZX01BSk9SX1ZFUlNJT04gPSAnbWFqb3JWZXJzaW9uJztcblNkbE1zZ1ZlcnNpb24uS0VZX01JTk9SX1ZFUlNJT04gPSAnbWlub3JWZXJzaW9uJztcblNkbE1zZ1ZlcnNpb24uS0VZX1BBVENIX1ZFUlNJT04gPSAncGF0Y2hWZXJzaW9uJztcblxuZXhwb3J0IHsgU2RsTXNnVmVyc2lvbiB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEVudW1lcmF0aW9uIGxpc3RpbmcgcG9zc2libGUgYXBwIHR5cGVzLlxuICogQHR5cGVkZWYge0VudW19IEFwcEhNSVR5cGVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIEFwcEhNSVR5cGUgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgREVGQVVMVCAoKSB7XG4gICAgICAgIHJldHVybiBBcHBITUlUeXBlLl9NQVAuREVGQVVMVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDT01NVU5JQ0FUSU9OICgpIHtcbiAgICAgICAgcmV0dXJuIEFwcEhNSVR5cGUuX01BUC5DT01NVU5JQ0FUSU9OO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE1FRElBICgpIHtcbiAgICAgICAgcmV0dXJuIEFwcEhNSVR5cGUuX01BUC5NRURJQTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBNRVNTQUdJTkcgKCkge1xuICAgICAgICByZXR1cm4gQXBwSE1JVHlwZS5fTUFQLk1FU1NBR0lORztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOQVZJR0FUSU9OICgpIHtcbiAgICAgICAgcmV0dXJuIEFwcEhNSVR5cGUuX01BUC5OQVZJR0FUSU9OO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IElORk9STUFUSU9OICgpIHtcbiAgICAgICAgcmV0dXJuIEFwcEhNSVR5cGUuX01BUC5JTkZPUk1BVElPTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTT0NJQUwgKCkge1xuICAgICAgICByZXR1cm4gQXBwSE1JVHlwZS5fTUFQLlNPQ0lBTDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBCQUNLR1JPVU5EX1BST0NFU1MgKCkge1xuICAgICAgICByZXR1cm4gQXBwSE1JVHlwZS5fTUFQLkJBQ0tHUk9VTkRfUFJPQ0VTUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBURVNUSU5HICgpIHtcbiAgICAgICAgcmV0dXJuIEFwcEhNSVR5cGUuX01BUC5URVNUSU5HO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNZU1RFTSAoKSB7XG4gICAgICAgIHJldHVybiBBcHBITUlUeXBlLl9NQVAuU1lTVEVNO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFBST0pFQ1RJT04gKCkge1xuICAgICAgICByZXR1cm4gQXBwSE1JVHlwZS5fTUFQLlBST0pFQ1RJT047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUkVNT1RFX0NPTlRST0wgKCkge1xuICAgICAgICByZXR1cm4gQXBwSE1JVHlwZS5fTUFQLlJFTU9URV9DT05UUk9MO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIEFwcEhNSVR5cGUuX3ZhbHVlRm9yS2V5KGtleSwgQXBwSE1JVHlwZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIEFwcEhNSVR5cGUuX2tleUZvclZhbHVlKHZhbHVlLCBBcHBITUlUeXBlLl9NQVApO1xuICAgIH1cbn1cblxuQXBwSE1JVHlwZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0RFRkFVTFQnOiAnREVGQVVMVCcsXG4gICAgJ0NPTU1VTklDQVRJT04nOiAnQ09NTVVOSUNBVElPTicsXG4gICAgJ01FRElBJzogJ01FRElBJyxcbiAgICAnTUVTU0FHSU5HJzogJ01FU1NBR0lORycsXG4gICAgJ05BVklHQVRJT04nOiAnTkFWSUdBVElPTicsXG4gICAgJ0lORk9STUFUSU9OJzogJ0lORk9STUFUSU9OJyxcbiAgICAnU09DSUFMJzogJ1NPQ0lBTCcsXG4gICAgJ0JBQ0tHUk9VTkRfUFJPQ0VTUyc6ICdCQUNLR1JPVU5EX1BST0NFU1MnLFxuICAgICdURVNUSU5HJzogJ1RFU1RJTkcnLFxuICAgICdTWVNURU0nOiAnU1lTVEVNJyxcbiAgICAnUFJPSkVDVElPTic6ICdQUk9KRUNUSU9OJyxcbiAgICAnUkVNT1RFX0NPTlRST0wnOiAnUkVNT1RFX0NPTlRST0wnLFxufSk7XG5cbmV4cG9ydCB7IEFwcEhNSVR5cGUgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gTGFuZ3VhZ2VcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIExhbmd1YWdlIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVuZ2xpc2ggLSBVU1xuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEVOX1VTICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuRU5fVVM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3BhbmlzaCAtIE1leGljb1xuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEVTX01YICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuRVNfTVg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRnJlbmNoIC0gQ2FuYWRhXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRlJfQ0EgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5GUl9DQTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXJtYW4gLSBHZXJtYW55XG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgREVfREUgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5ERV9ERTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTcGFuaXNoIC0gU3BhaW5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFU19FUyAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLkVTX0VTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVuZ2xpc2ggLSBHQlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEVOX0dCICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuRU5fR0I7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUnVzc2lhbiAtIFJ1c3NpYVxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJVX1JVICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuUlVfUlU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHVya2lzaCAtIFR1cmtleVxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFRSX1RSICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuVFJfVFI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUG9saXNoIC0gUG9sYW5kXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUExfUEwgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5QTF9QTDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGcmVuY2ggLSBGcmFuY2VcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBGUl9GUiAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLkZSX0ZSO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEl0YWxpYW4gLSBJdGFseVxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IElUX0lUICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuSVRfSVQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3dlZGlzaCAtIFN3ZWRlblxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNWX1NFICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuU1ZfU0U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUG9ydHVndWVzZSAtIFBvcnR1Z2FsXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUFRfUFQgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5QVF9QVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEdXRjaCAoU3RhbmRhcmQpIC0gTmV0aGVybGFuZHNcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOTF9OTCAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLk5MX05MO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVuZ2xpc2ggLSBBdXN0cmFsaWFcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFTl9BVSAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLkVOX0FVO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1hbmRhcmluIC0gQ2hpbmFcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBaSF9DTiAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLlpIX0NOO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1hbmRhcmluIC0gVGFpd2FuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgWkhfVFcgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5aSF9UVztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBKYXBhbmVzZSAtIEphcGFuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSkFfSlAgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5KQV9KUDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBcmFiaWMgLSBTYXVkaSBBcmFiaWFcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBBUl9TQSAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLkFSX1NBO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEtvcmVhbiAtIFNvdXRoIEtvcmVhXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgS09fS1IgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5LT19LUjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQb3J0dWd1ZXNlIC0gQnJhemlsXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUFRfQlIgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5QVF9CUjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDemVjaCAtIEN6ZWNoIFJlcHVibGljXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ1NfQ1ogKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5DU19DWjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEYW5pc2ggLSBEZW5tYXJrXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgREFfREsgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5EQV9ESztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBOb3J3ZWdpYW4gLSBOb3J3YXlcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOT19OTyAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLk5PX05PO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIER1dGNoIChGbGVtaXNoKSAtIEJlbGdpdW1cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOTF9CRSAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLk5MX0JFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdyZWVrIC0gR3JlZWNlXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRUxfR1IgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5FTF9HUjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIdW5nYXJpYW4gLSBIdW5nYXJ5XG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSFVfSFUgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5IVV9IVTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGaW5uaXNoIC0gRmlubGFuZFxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEZJX0ZJICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuRklfRkk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2xvdmFrIC0gU2xvdmFraWFcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTS19TSyAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLlNLX1NLO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVuZ2xpc2ggLSBJbmRpYVxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEVOX0lOICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuRU5fSU47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhhaSAtIFRoYWlsYW5kXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVEhfVEggKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5USF9USDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFbmdsaXNoIC0gTWlkZGxlIEVhc3RcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFTl9TQSAoKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fTUFQLkVOX1NBO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhlYnJldyAtIElzcmFlbFxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEhFX0lMICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuSEVfSUw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUm9tYW5pYW4gLSBSb21hbmlhXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUk9fUk8gKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5ST19STztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVa3JhaW5pYW4gLSBVa3JhaW5lXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVUtfVUEgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5VS19VQTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbmRvbmVzaWFuIC0gSW5kb25lc2lhXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSURfSUQgKCkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX01BUC5JRF9JRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBWaWV0bmFtZXNlIC0gVmlldG5hbVxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZJX1ZOICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuVklfVk47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWFsYXkgLSBNYWxheXNpYVxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE1TX01ZICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuTVNfTVk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGluZGkgLSBJbmRpYVxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEhJX0lOICgpIHtcbiAgICAgICAgcmV0dXJuIExhbmd1YWdlLl9NQVAuSElfSU47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gTGFuZ3VhZ2UuX3ZhbHVlRm9yS2V5KGtleSwgTGFuZ3VhZ2UuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBMYW5ndWFnZS5fa2V5Rm9yVmFsdWUodmFsdWUsIExhbmd1YWdlLl9NQVApO1xuICAgIH1cbn1cblxuTGFuZ3VhZ2UuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdFTl9VUyc6ICdFTi1VUycsXG4gICAgJ0VTX01YJzogJ0VTLU1YJyxcbiAgICAnRlJfQ0EnOiAnRlItQ0EnLFxuICAgICdERV9ERSc6ICdERS1ERScsXG4gICAgJ0VTX0VTJzogJ0VTLUVTJyxcbiAgICAnRU5fR0InOiAnRU4tR0InLFxuICAgICdSVV9SVSc6ICdSVS1SVScsXG4gICAgJ1RSX1RSJzogJ1RSLVRSJyxcbiAgICAnUExfUEwnOiAnUEwtUEwnLFxuICAgICdGUl9GUic6ICdGUi1GUicsXG4gICAgJ0lUX0lUJzogJ0lULUlUJyxcbiAgICAnU1ZfU0UnOiAnU1YtU0UnLFxuICAgICdQVF9QVCc6ICdQVC1QVCcsXG4gICAgJ05MX05MJzogJ05MLU5MJyxcbiAgICAnRU5fQVUnOiAnRU4tQVUnLFxuICAgICdaSF9DTic6ICdaSC1DTicsXG4gICAgJ1pIX1RXJzogJ1pILVRXJyxcbiAgICAnSkFfSlAnOiAnSkEtSlAnLFxuICAgICdBUl9TQSc6ICdBUi1TQScsXG4gICAgJ0tPX0tSJzogJ0tPLUtSJyxcbiAgICAnUFRfQlInOiAnUFQtQlInLFxuICAgICdDU19DWic6ICdDUy1DWicsXG4gICAgJ0RBX0RLJzogJ0RBLURLJyxcbiAgICAnTk9fTk8nOiAnTk8tTk8nLFxuICAgICdOTF9CRSc6ICdOTC1CRScsXG4gICAgJ0VMX0dSJzogJ0VMLUdSJyxcbiAgICAnSFVfSFUnOiAnSFUtSFUnLFxuICAgICdGSV9GSSc6ICdGSS1GSScsXG4gICAgJ1NLX1NLJzogJ1NLLVNLJyxcbiAgICAnRU5fSU4nOiAnRU4tSU4nLFxuICAgICdUSF9USCc6ICdUSC1USCcsXG4gICAgJ0VOX1NBJzogJ0VOLVNBJyxcbiAgICAnSEVfSUwnOiAnSEUtSUwnLFxuICAgICdST19STyc6ICdSTy1STycsXG4gICAgJ1VLX1VBJzogJ1VLLVVBJyxcbiAgICAnSURfSUQnOiAnSUQtSUQnLFxuICAgICdWSV9WTic6ICdWSS1WTicsXG4gICAgJ01TX01ZJzogJ01TLU1ZJyxcbiAgICAnSElfSU4nOiAnSEktSU4nLFxufSk7XG5cbmV4cG9ydCB7IExhbmd1YWdlIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFJwY01lc3NhZ2VcbiAqIEBwcm9wZXJ0eSB7UnBjVHlwZX0gcnBjVHlwZVxuICovXG5jbGFzcyBScGNNZXNzYWdlIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKlxuICAgIHtcbiAgICAgICAgXCJycGNUeXBlXCI6IFwiUmVxdWVzdFwiLFxuICAgICAgICBcImZ1bmN0aW9uTmFtZVwiOiBcIlJlZ2lzdGVyQXBwSW50ZXJmYWNlXCIsXG4gICAgICAgIFwiY29vcmVsYXRpb25JRFwiOiBcIjMyMDk0OFwiLFxuICAgICAgICBcImlzRW5jcnlwdGVkXCI6IGZhbHNlLFxuICAgICAgICBcInBhcmFtZXRlcnNcIjoge1xuICAgICAgICAgICAgXCJhcHBOYW1lXCI6IFwiSGVsbG9cIlxuICAgICAgICB9LFxuICAgICAgICBcImJ1bGtEYXRhXCI6IFwiLi4uXCIsXG4gICAgfVxuICAgICovXG5cbiAgICAvKipcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlID0ge30pIHtcbiAgICAgICAgc3VwZXIoc3RvcmUucGFyYW1ldGVycyk7XG4gICAgICAgIHRoaXMuX2lzRW5jcnlwdGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3JwY1R5cGUgPSBzdG9yZS5ycGNUeXBlO1xuICAgICAgICB0aGlzLl9mdW5jdGlvbk5hbWUgPSBzdG9yZS5mdW5jdGlvbk5hbWU7XG4gICAgICAgIHRoaXMuX2NvcnJlbGF0aW9uSUQgPSBzdG9yZS5jb3JyZWxhdGlvbklEO1xuICAgICAgICB0aGlzLnNldEJ1bGtEYXRhKHN0b3JlLmJ1bGtEYXRhKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1JwY1R5cGV9XG4gICAgKi9cbiAgICBnZXRSUENUeXBlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JwY1R5cGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1JwY1R5cGV9IHR5cGVcbiAgICAqIEByZXR1cm4ge1JwY01lc3NhZ2V9XG4gICAgKi9cbiAgICBzZXRSUENUeXBlICh0eXBlKSB7XG4gICAgICAgIHRoaXMuX3JwY1R5cGUgPSB0eXBlO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7RnVuY3Rpb25JRH0gdHlwZVxuICAgICovXG4gICAgZ2V0RnVuY3Rpb25OYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Z1bmN0aW9uTmFtZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7RnVuY3Rpb25JRH0gbmFtZVxuICAgICogQHJldHVybiB7UnBjTWVzc2FnZX1cbiAgICAqL1xuICAgIHNldEZ1bmN0aW9uTmFtZSAobmFtZSkge1xuICAgICAgICBpZiAodHlwZW9mIG5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLl9mdW5jdGlvbk5hbWUgPSBGdW5jdGlvbklELmtleUZvclZhbHVlKG5hbWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fZnVuY3Rpb25OYW1lID0gbmFtZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfSB0eXBlXG4gICAgKi9cbiAgICBnZXRDb3JyZWxhdGlvbklkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvcnJlbGF0aW9uSUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICAgICogQHJldHVybiB7UnBjTWVzc2FnZX1cbiAgICAqL1xuICAgIHNldENvcnJlbGF0aW9uSWQgKGlkKSB7XG4gICAgICAgIHRoaXMuX2NvcnJlbGF0aW9uSUQgPSBpZDtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1VpbnQ4QXJyYXl9IGRhdGFcbiAgICAqL1xuICAgIGdldEJ1bGtEYXRhICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1bGtEYXRhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtVSW50OEFycmF5fSBkYXRhXG4gICAgKiBAcmV0dXJuIHtScGNNZXNzYWdlfVxuICAgICovXG4gICAgc2V0QnVsa0RhdGEgKGRhdGEgPSBudWxsKSB7XG4gICAgICAgIGlmIChkYXRhICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl9idWxrRGF0YSA9IGRhdGEuc2xpY2UoMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9idWxrRGF0YSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgKi9cbiAgICBnZXRJc0VuY3J5cHRlZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc0VuY3J5cHRlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYm9vbFxuICAgICogQHJldHVybiB7UnBjTWVzc2FnZX1cbiAgICAqL1xuICAgIHNldElzRW5jcnlwdGVkIChib29sKSB7XG4gICAgICAgIHRoaXMuX2lzRW5jcnlwdGVkID0gYm9vbDtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5cbmV4cG9ydCB7IFJwY01lc3NhZ2UgfTtcbiIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gUnBjVHlwZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgUnBjVHlwZSBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTk9USUZJQ0FUSU9OICgpIHtcbiAgICAgICAgcmV0dXJuIFJwY1R5cGUuX01BUC5OT1RJRklDQVRJT047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUkVTUE9OU0UgKCkge1xuICAgICAgICByZXR1cm4gUnBjVHlwZS5fTUFQLlJFU1BPTlNFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJFUVVFU1QgKCkge1xuICAgICAgICByZXR1cm4gUnBjVHlwZS5fTUFQLlJFUVVFU1Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFJwY1R5cGUuX3ZhbHVlRm9yS2V5KGtleSwgUnBjVHlwZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gUnBjVHlwZS5fa2V5Rm9yVmFsdWUodmFsdWUsIFJwY1R5cGUuX01BUCk7XG4gICAgfVxufVxuXG5ScGNUeXBlLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnTk9USUZJQ0FUSU9OJzogMHgyLFxuICAgICdSRVNQT05TRSc6IDB4MSxcbiAgICAnUkVRVUVTVCc6IDB4MCxcbn0pO1xuXG5leHBvcnQgeyBScGNUeXBlIH07XG4iLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuXG5pbXBvcnQgeyBScGNNZXNzYWdlIH0gZnJvbSAnLi9ScGNNZXNzYWdlLmpzJztcbmltcG9ydCB7IFJwY1R5cGUgfSBmcm9tICcuL2VudW1zL1JwY1R5cGUuanMnO1xuXG5jbGFzcyBScGNSZXF1ZXN0IGV4dGVuZHMgUnBjTWVzc2FnZSB7XG4gICAgLyoqXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0UlBDVHlwZShScGNUeXBlLlJFUVVFU1QpO1xuICAgICAgICB0aGlzLl9wcm9taXNlID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAgKi9cbiAgICBnZXRPblJQQ1Jlc3BvbnNlUHJvbWlzZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wcm9taXNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtQcm9taXNlfSBwcm9taXNlXG4gICAgKiBAcmV0dXJuIHtScGNNZXNzYWdlfVxuICAgICovXG4gICAgc2V0T25SUENSZXNwb25zZVByb21pc2UgKHByb21pc2UpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoUHJvbWlzZSwgcHJvbWlzZSk7XG5cbiAgICAgICAgdGhpcy5fcHJvbWlzZSA9IHByb21pc2U7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cblxuZXhwb3J0IHsgUnBjUmVxdWVzdCB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5cbi8qKlxuICogVmFyaW91cyBpbmZvcm1hdGlvbiBhYm91dCBjb25uZWN0aW5nIGRldmljZS5cbiAqL1xuY2xhc3MgRGV2aWNlSW5mbyBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGhhcmR3YXJlIC0gRGV2aWNlIG1vZGVsXG4gICAgICogQHJldHVybiB7RGV2aWNlSW5mb31cbiAgICAgKi9cbiAgICBzZXRIYXJkd2FyZSAoaGFyZHdhcmUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGV2aWNlSW5mby5LRVlfSEFSRFdBUkUsIGhhcmR3YXJlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldEhhcmR3YXJlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKERldmljZUluZm8uS0VZX0hBUkRXQVJFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gcmV2IC0gRGV2aWNlIGZpcm13YXJlIHJldmlzaW9uXG4gICAgICogQHJldHVybiB7RGV2aWNlSW5mb31cbiAgICAgKi9cbiAgICBzZXRGaXJtd2FyZVJldiAocmV2KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKERldmljZUluZm8uS0VZX0ZJUk1XQVJFX1JFViwgcmV2KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldEZpcm13YXJlUmV2ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKERldmljZUluZm8uS0VZX0ZJUk1XQVJFX1JFVik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG9zIC0gRGV2aWNlIE9TXG4gICAgICogQHJldHVybiB7RGV2aWNlSW5mb31cbiAgICAgKi9cbiAgICBzZXRPcyAob3MpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGV2aWNlSW5mby5LRVlfT1MsIG9zKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldE9zICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKERldmljZUluZm8uS0VZX09TKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdmVyc2lvbiAtIERldmljZSBPUyB2ZXJzaW9uXG4gICAgICogQHJldHVybiB7RGV2aWNlSW5mb31cbiAgICAgKi9cbiAgICBzZXRPc1ZlcnNpb24gKHZlcnNpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGV2aWNlSW5mby5LRVlfT1NfVkVSU0lPTiwgdmVyc2lvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRPc1ZlcnNpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoRGV2aWNlSW5mby5LRVlfT1NfVkVSU0lPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGNhcnJpZXIgLSBEZXZpY2UgbW9iaWxlIGNhcnJpZXIgKGlmIGFwcGxpY2FibGUpXG4gICAgICogQHJldHVybiB7RGV2aWNlSW5mb31cbiAgICAgKi9cbiAgICBzZXRDYXJyaWVyIChjYXJyaWVyKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKERldmljZUluZm8uS0VZX0NBUlJJRVIsIGNhcnJpZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0Q2FycmllciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihEZXZpY2VJbmZvLktFWV9DQVJSSUVSKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gcG9ydHMgLSBPbWl0dGVkIGlmIGNvbm5lY3RlZCBub3QgdmlhIEJULlxuICAgICAqIEByZXR1cm4ge0RldmljZUluZm99XG4gICAgICovXG4gICAgc2V0TWF4TnVtYmVyUkZDT01NUG9ydHMgKHBvcnRzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKERldmljZUluZm8uS0VZX01BWF9OVU1CRVJfUkZDT01NX1BPUlRTLCBwb3J0cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRNYXhOdW1iZXJSRkNPTU1Qb3J0cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihEZXZpY2VJbmZvLktFWV9NQVhfTlVNQkVSX1JGQ09NTV9QT1JUUyk7XG4gICAgfVxufVxuXG5EZXZpY2VJbmZvLktFWV9IQVJEV0FSRSA9ICdoYXJkd2FyZSc7XG5EZXZpY2VJbmZvLktFWV9GSVJNV0FSRV9SRVYgPSAnZmlybXdhcmVSZXYnO1xuRGV2aWNlSW5mby5LRVlfT1MgPSAnb3MnO1xuRGV2aWNlSW5mby5LRVlfT1NfVkVSU0lPTiA9ICdvc1ZlcnNpb24nO1xuRGV2aWNlSW5mby5LRVlfQ0FSUklFUiA9ICdjYXJyaWVyJztcbkRldmljZUluZm8uS0VZX01BWF9OVU1CRVJfUkZDT01NX1BPUlRTID0gJ21heE51bWJlclJGQ09NTVBvcnRzJztcblxuZXhwb3J0IHsgRGV2aWNlSW5mbyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEFwcEluZm8gfSBmcm9tICcuLi9zdHJ1Y3RzL0FwcEluZm8uanMnO1xuaW1wb3J0IHsgVGVtcGxhdGVDb2xvclNjaGVtZSB9IGZyb20gJy4uL3N0cnVjdHMvVGVtcGxhdGVDb2xvclNjaGVtZS5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBUVFNDaHVuayB9IGZyb20gJy4uL3N0cnVjdHMvVFRTQ2h1bmsuanMnO1xuaW1wb3J0IHsgU2RsTXNnVmVyc2lvbiB9IGZyb20gJy4uL3N0cnVjdHMvU2RsTXNnVmVyc2lvbi5qcyc7XG5pbXBvcnQgeyBBcHBITUlUeXBlIH0gZnJvbSAnLi4vZW51bXMvQXBwSE1JVHlwZS5qcyc7XG5pbXBvcnQgeyBMYW5ndWFnZSB9IGZyb20gJy4uL2VudW1zL0xhbmd1YWdlLmpzJztcbmltcG9ydCB7IFJwY1JlcXVlc3QgfSBmcm9tICcuLi9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IERldmljZUluZm8gfSBmcm9tICcuLi9zdHJ1Y3RzL0RldmljZUluZm8uanMnO1xuXG4vKipcbiAqIEVzdGFibGlzaGVzIGFuIGludGVyZmFjZSB3aXRoIGEgbW9iaWxlIGFwcGxpY2F0aW9uLiBCZWZvcmUgcmVnaXN0ZXJBcHBJbnRlcmZhY2Ugbm8gb3RoZXIgY29tbWFuZHMgd2lsbCBiZVxuICogYWNjZXB0ZWQvZXhlY3V0ZWQuXG4gKi9cbmNsYXNzIFJlZ2lzdGVyQXBwSW50ZXJmYWNlIGV4dGVuZHMgUnBjUmVxdWVzdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5SZWdpc3RlckFwcEludGVyZmFjZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGZ1bGxBcHBJZFxuICAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlfVxuICAgICAqL1xuICAgIHNldEZ1bGxBcHBJZCAoZnVsbEFwcElkKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFN0cmluZywgZnVsbEFwcElkKTtcblxuICAgICAgICBpZiAoZnVsbEFwcElkICE9PSBudWxsKSB7XG4gICAgICAgICAgICBmdWxsQXBwSWQgPSBmdWxsQXBwSWQudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9GVUxMX0FQUF9JRCwgZnVsbEFwcElkKTtcbiAgICAgICAgICAgIGxldCBhcHBJRDtcbiAgICAgICAgICAgIGlmIChmdWxsQXBwSWQubGVuZ3RoIDw9IFJlZ2lzdGVyQXBwSW50ZXJmYWNlLkFQUF9JRF9NQVhfTEVOR1RIKSB7XG4gICAgICAgICAgICAgICAgYXBwSUQgPSBmdWxsQXBwSWQ7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGFwcElEID0gZnVsbEFwcElkLnJlcGxhY2UoJy0nLCAnJykuc3Vic3RyaW5nKDAsIFJlZ2lzdGVyQXBwSW50ZXJmYWNlLkFQUF9JRF9NQVhfTEVOR1RIKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX3NldEFwcElkKGFwcElEKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9GVUxMX0FQUF9JRCwgbnVsbCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9IHRoZSBhcHAgaWRcbiAgICAgKi9cbiAgICBnZXRGdWxsQXBwSWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0ZVTExfQVBQX0lEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gYXBwSWQgLSBUaGlzIG1ldGhvZCBzaG91bGQgbm90IGJlIGFjY2Vzc2VkIGRpcmVjdGx5IGJ5IGRldmVsb3BlcnMuIE9ubHkgc2V0IHRoZSBmdWxsIElEIGFuZCB0aGlzXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW0gd2lsbCBiZSBzZXQuXG4gICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2V9XG4gICAgICovXG4gICAgX3NldEFwcElkIChhcHBJZCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShTdHJpbmcsIGFwcElkKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZS5LRVlfQVBQX0lELCBhcHBJZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ30gdGhlIGFwcCBpZFxuICAgICAqL1xuICAgIGdldEFwcElkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9BUFBfSUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2RsTXNnVmVyc2lvbn0gdmVyc2lvbiAtIFNlZSBTeW5jTXNnVmVyc2lvblxuICAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlfVxuICAgICAqL1xuICAgIHNldFNkbE1zZ1ZlcnNpb24gKHZlcnNpb24pIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoU2RsTXNnVmVyc2lvbiwgdmVyc2lvbik7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9TRExfTVNHX1ZFUlNJT04sIHZlcnNpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTZGxNc2dWZXJzaW9ufVxuICAgICAqL1xuICAgIGdldFNkbE1zZ1ZlcnNpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoU2RsTXNnVmVyc2lvbiwgUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX1NETF9NU0dfVkVSU0lPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBUaGUgbW9iaWxlIGFwcGxpY2F0aW9uIG5hbWUsIGUuZy4gXCJNeSBTREwgQXBwXCIuIE5lZWRzIHRvIGJlIHVuaXF1ZSBvdmVyIGFsbCBhcHBsaWNhdGlvbnNcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIGZyb20gdGhlIHNhbWUgZGV2aWNlLiBNYXkgbm90IGJlIGVtcHR5LiBNYXkgbm90IHN0YXJ0IHdpdGggYSBuZXcgbGluZSBjaGFyYWN0ZXIuIE1heSBub3RcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIGludGVyZmVyZSB3aXRoIGFueSBuYW1lIG9yIHN5bm9ueW0gb2YgcHJldmlvdXNseSByZWdpc3RlcmVkIGFwcGxpY2F0aW9ucyBmcm9tIHRoZSBzYW1lXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2UgYW5kIGFueSBwcmVkZWZpbmVkIGJsYWNrbGlzdCBvZiB3b3JkcyAoZ2xvYmFsIGNvbW1hbmRzKSBBZGRpdGlvbmFsIGFwcGxpY2F0aW9uc1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgd2l0aCB0aGUgc2FtZSBuYW1lIGZyb20gdGhlIHNhbWUgZGV2aWNlIHdpbGwgYmUgcmVqZWN0ZWQuIE9ubHkgY2hhcmFjdGVycyBmcm9tIGNoYXIgc2V0XG4gICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2V9XG4gICAgICovXG4gICAgc2V0QXBwTmFtZSAobmFtZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZS5LRVlfQVBQX05BTUUsIG5hbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0QXBwTmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZS5LRVlfQVBQX05BTUUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VFRTQ2h1bmtbXX0gbmFtZSAtIFRUUyBzdHJpbmcgZm9yIFZSIHJlY29nbml0aW9uIG9mIHRoZSBtb2JpbGUgYXBwbGljYXRpb24gbmFtZSwgZS5nLiBcIk15IFMgRCBMIEFwcFwiLlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lYW50IHRvIG92ZXJjb21lIGFueSBmYWlsaW5nIG9uIHNwZWVjaCBlbmdpbmUgaW4gcHJvcGVybHkgcHJvbm91bmNpbmcgLyB1bmRlcnN0YW5kaW5nXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwIG5hbWUuIE5lZWRzIHRvIGJlIHVuaXF1ZSBvdmVyIGFsbCBhcHBsaWNhdGlvbnMgZnJvbSB0aGUgc2FtZSBkZXZpY2UuIE1heSBub3QgYmVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbXB0eS4gTWF5IG5vdCBzdGFydCB3aXRoIGEgbmV3IGxpbmUgY2hhcmFjdGVyLiBPbmx5IGNoYXJhY3RlcnMgZnJvbSBjaGFyIHNldFxuICAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlfVxuICAgICAqL1xuICAgIHNldFR0c05hbWUgKG5hbWUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVFRTQ2h1bmssIG5hbWUsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZS5LRVlfVFRTX05BTUUsIG5hbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtUVFNDaHVua1tdfVxuICAgICAqL1xuICAgIGdldFR0c05hbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVFRTQ2h1bmssIFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9UVFNfTkFNRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBQcm92aWRlcyBhbiBhYmJyZXZpYXRlZCB2ZXJzaW9uIG9mIHRoZSBhcHAgbmFtZSAoaWYgbmVlZGVkKSwgdGhhdCB3aWxsIGJlIGRpc3BsYXllZCBvbiB0aGVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIE5HTiBtZWRpYSBzY3JlZW4uIElmIG5vdCBwcm92aWRlZCwgdGhlIGFwcE5hbWUgaXMgdXNlZCBpbnN0ZWFkIChhbmQgd2lsbCBiZSB0cnVuY2F0ZWQgaWZcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHRvbyBsb25nKSBPbmx5IGNoYXJhY3RlcnMgZnJvbSBjaGFyIHNldFxuICAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlfVxuICAgICAqL1xuICAgIHNldE5nbk1lZGlhU2NyZWVuQXBwTmFtZSAobmFtZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZS5LRVlfTkdOX01FRElBX1NDUkVFTl9BUFBfTkFNRSwgbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXROZ25NZWRpYVNjcmVlbkFwcE5hbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX05HTl9NRURJQV9TQ1JFRU5fQVBQX05BTUUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nW119IHN5bm9ueW1zIC0gRGVmaW5lcyBhbiBhZGRpdGlvbmFsIHZvaWNlIHJlY29nbml0aW9uIGNvbW1hbmQuIE1heSBub3QgaW50ZXJmZXJlIHdpdGggYW55IGFwcCBuYW1lXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZiBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgYXBwbGljYXRpb25zIGZyb20gdGhlIHNhbWUgZGV2aWNlIGFuZCBhbnkgcHJlZGVmaW5lZFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmxhY2tsaXN0IG9mIHdvcmRzIChnbG9iYWwgY29tbWFuZHMpIE9ubHkgY2hhcmFjdGVycyBmcm9tIGNoYXIgc2V0XG4gICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2V9XG4gICAgICovXG4gICAgc2V0VnJTeW5vbnltcyAoc3lub255bXMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX1ZSX1NZTk9OWU1TLCBzeW5vbnltcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ1tdfVxuICAgICAqL1xuICAgIGdldFZyU3lub255bXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX1ZSX1NZTk9OWU1TKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGFwcGxpY2F0aW9uIC0gSW5kaWNhdGVzIGlmIHRoZSBhcHBsaWNhdGlvbiBpcyBhIG1lZGlhIG9yIGEgbm9uLW1lZGlhIGFwcGxpY2F0aW9uLiBPbmx5IG1lZGlhXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGxpY2F0aW9ucyB3aWxsIGJlIGFibGUgdG8gc3RyZWFtIGF1ZGlvIHRvIHRoZSBtb2R1bGUgdGhhdCBpcyBhdWRpYmxlIG91dHNpZGUgb2ZcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIEJUIG1lZGlhIHNvdXJjZS5cbiAgICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZX1cbiAgICAgKi9cbiAgICBzZXRJc01lZGlhQXBwbGljYXRpb24gKGFwcGxpY2F0aW9uKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9JU19NRURJQV9BUFBMSUNBVElPTiwgYXBwbGljYXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldElzTWVkaWFBcHBsaWNhdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZS5LRVlfSVNfTUVESUFfQVBQTElDQVRJT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TGFuZ3VhZ2V9IGRlc2lyZWQgLSBTZWUgTGFuZ3VhZ2UgQ3VycmVudCBhcHAncyBleHBlY3RlZCBWUitUVFMgbGFuZ3VhZ2UgSWYgdGhlcmUgaXMgYSBtaXNtYXRjaCB3aXRoIHRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2R1bGUsIHRoZSBhcHAgd2lsbCBiZSBhYmxlIHRvIGNoYW5nZSB0aGlzIHJlZ2lzdHJhdGlvbiB3aXRoIGNoYW5nZVJlZ2lzdHJhdGlvblxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmlvciB0byBhcHAgYmVpbmcgYnJvdWdodCBpbnRvIGZvY3VzLlxuICAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlfVxuICAgICAqL1xuICAgIHNldExhbmd1YWdlRGVzaXJlZCAoZGVzaXJlZCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShMYW5ndWFnZSwgZGVzaXJlZCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9MQU5HVUFHRV9ERVNJUkVELCBkZXNpcmVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TGFuZ3VhZ2V9XG4gICAgICovXG4gICAgZ2V0TGFuZ3VhZ2VEZXNpcmVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KExhbmd1YWdlLCBSZWdpc3RlckFwcEludGVyZmFjZS5LRVlfTEFOR1VBR0VfREVTSVJFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtMYW5ndWFnZX0gZGVzaXJlZCAtIFNlZSBMYW5ndWFnZSBDdXJyZW50IGFwcCdzIGV4cGVjdGVkIGRpc3BsYXkgbGFuZ3VhZ2UgSWYgdGhlcmUgaXMgYSBtaXNtYXRjaCB3aXRoIHRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2R1bGUsIHRoZSBhcHAgd2lsbCBiZSBhYmxlIHRvIGNoYW5nZSB0aGlzIHJlZ2lzdHJhdGlvbiB3aXRoIGNoYW5nZVJlZ2lzdHJhdGlvblxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmlvciB0byBhcHAgYmVpbmcgYnJvdWdodCBpbnRvIGZvY3VzLlxuICAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlfVxuICAgICAqL1xuICAgIHNldEhtaURpc3BsYXlMYW5ndWFnZURlc2lyZWQgKGRlc2lyZWQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTGFuZ3VhZ2UsIGRlc2lyZWQpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZS5LRVlfSE1JX0RJU1BMQVlfTEFOR1VBR0VfREVTSVJFRCwgZGVzaXJlZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0xhbmd1YWdlfVxuICAgICAqL1xuICAgIGdldEhtaURpc3BsYXlMYW5ndWFnZURlc2lyZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTGFuZ3VhZ2UsIFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9ITUlfRElTUExBWV9MQU5HVUFHRV9ERVNJUkVEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0FwcEhNSVR5cGVbXX0gdHlwZSAtIFNlZSBBcHBITUlUeXBlIExpc3Qgb2YgYWxsIGFwcGxpY2FibGUgYXBwIEhNSSB0eXBlcyBzdGF0aW5nIHdoaWNoIEhNSVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NpZmljYXRpb25zIHRvIGJlIGdpdmVuIHRvIHRoZSBhcHAuXG4gICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2V9XG4gICAgICovXG4gICAgc2V0QXBwSE1JVHlwZSAodHlwZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShBcHBITUlUeXBlLCB0eXBlLCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0FQUF9ITUlfVFlQRSwgdHlwZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0FwcEhNSVR5cGVbXX1cbiAgICAgKi9cbiAgICBnZXRBcHBITUlUeXBlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEFwcEhNSVR5cGUsIFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9BUFBfSE1JX1RZUEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBpZCAtIElEIHVzZWQgdG8gdW5pcXVlbHkgaWRlbnRpZnkgY3VycmVudCBzdGF0ZSBvZiBhbGwgYXBwIGRhdGEgdGhhdCBjYW4gcGVyc2lzdCB0aHJvdWdoXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbiBjeWNsZXMgKGUuZy4gaWduaXRpb24gY3ljbGVzKS4gVGhpcyByZWdpc3RlcmVkIGRhdGEgKGNvbW1hbmRzLCBzdWJtZW51cywgY2hvaWNlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgc2V0cywgZXRjLikgY2FuIGJlIHJlZXN0YWJsaXNoZWQgd2l0aG91dCBuZWVkaW5nIHRvIGV4cGxpY2l0bHkgcmVyZWdpc3RlciBlYWNoIHBpZWNlLiBJZlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIG9taXR0ZWQsIHRoZW4gdGhlIHByZXZpb3VzIHN0YXRlIG9mIGFuIGFwcCdzIGNvbW1hbmRzLCBldGMuIHdpbGwgbm90IGJlIHJlc3RvcmVkLiBXaGVuXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgc2VuZGluZyBoYXNoSUQsIGFsbCBSZWdpc3RlckFwcEludGVyZmFjZSBwYXJhbWV0ZXJzIHNob3VsZCBzdGlsbCBiZSBwcm92aWRlZCAoZS5nLiB0dHNOYW1lLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIGV0Yy4pLlxuICAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlfVxuICAgICAqL1xuICAgIHNldEhhc2hJRCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0hBU0hfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldEhhc2hJRCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZS5LRVlfSEFTSF9JRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtEZXZpY2VJbmZvfSBpbmZvIC0gU2VlIERldmljZUluZm8uXG4gICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2V9XG4gICAgICovXG4gICAgc2V0RGV2aWNlSW5mbyAoaW5mbykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShEZXZpY2VJbmZvLCBpbmZvKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0RFVklDRV9JTkZPLCBpbmZvKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7RGV2aWNlSW5mb31cbiAgICAgKi9cbiAgICBnZXREZXZpY2VJbmZvICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KERldmljZUluZm8sIFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9ERVZJQ0VfSU5GTyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGlkIC0gSUQgdXNlZCB0byB2YWxpZGF0ZSBhcHAgd2l0aCBwb2xpY3kgdGFibGUgZW50cmllc1xuICAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlfVxuICAgICAqL1xuICAgIHNldEZ1bGxBcHBJRCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0ZVTExfQVBQX0lELCBpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRGdWxsQXBwSUQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0ZVTExfQVBQX0lEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0FwcEluZm99IGluZm8gLSBTZWUgQXBwSW5mby5cbiAgICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZX1cbiAgICAgKi9cbiAgICBzZXRBcHBJbmZvIChpbmZvKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEFwcEluZm8sIGluZm8pO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZS5LRVlfQVBQX0lORk8sIGluZm8pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtBcHBJbmZvfVxuICAgICAqL1xuICAgIGdldEFwcEluZm8gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQXBwSW5mbywgUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0FQUF9JTkZPKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1RlbXBsYXRlQ29sb3JTY2hlbWV9IHNjaGVtZSAtIEEgY29sb3Igc2NoZW1lIGZvciBhbGwgZGlzcGxheSBsYXlvdXQgdGVtcGxhdGVzLlxuICAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlfVxuICAgICAqL1xuICAgIHNldERheUNvbG9yU2NoZW1lIChzY2hlbWUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVGVtcGxhdGVDb2xvclNjaGVtZSwgc2NoZW1lKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0RBWV9DT0xPUl9TQ0hFTUUsIHNjaGVtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1RlbXBsYXRlQ29sb3JTY2hlbWV9XG4gICAgICovXG4gICAgZ2V0RGF5Q29sb3JTY2hlbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVGVtcGxhdGVDb2xvclNjaGVtZSwgUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0RBWV9DT0xPUl9TQ0hFTUUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VGVtcGxhdGVDb2xvclNjaGVtZX0gc2NoZW1lIC0gQSBjb2xvciBzY2hlbWUgZm9yIGFsbCBkaXNwbGF5IGxheW91dCB0ZW1wbGF0ZXMuXG4gICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2V9XG4gICAgICovXG4gICAgc2V0TmlnaHRDb2xvclNjaGVtZSAoc2NoZW1lKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFRlbXBsYXRlQ29sb3JTY2hlbWUsIHNjaGVtZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9OSUdIVF9DT0xPUl9TQ0hFTUUsIHNjaGVtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1RlbXBsYXRlQ29sb3JTY2hlbWV9XG4gICAgICovXG4gICAgZ2V0TmlnaHRDb2xvclNjaGVtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChUZW1wbGF0ZUNvbG9yU2NoZW1lLCBSZWdpc3RlckFwcEludGVyZmFjZS5LRVlfTklHSFRfQ09MT1JfU0NIRU1FKTtcbiAgICB9XG59XG5cblJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9TRExfTVNHX1ZFUlNJT04gPSAnc3luY01zZ1ZlcnNpb24nO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0FQUF9OQU1FID0gJ2FwcE5hbWUnO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX1RUU19OQU1FID0gJ3R0c05hbWUnO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX05HTl9NRURJQV9TQ1JFRU5fQVBQX05BTUUgPSAnbmduTWVkaWFTY3JlZW5BcHBOYW1lJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9WUl9TWU5PTllNUyA9ICd2clN5bm9ueW1zJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9JU19NRURJQV9BUFBMSUNBVElPTiA9ICdpc01lZGlhQXBwbGljYXRpb24nO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0xBTkdVQUdFX0RFU0lSRUQgPSAnbGFuZ3VhZ2VEZXNpcmVkJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9ITUlfRElTUExBWV9MQU5HVUFHRV9ERVNJUkVEID0gJ2htaURpc3BsYXlMYW5ndWFnZURlc2lyZWQnO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0FQUF9ITUlfVFlQRSA9ICdhcHBITUlUeXBlJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9IQVNIX0lEID0gJ2hhc2hJRCc7XG5SZWdpc3RlckFwcEludGVyZmFjZS5LRVlfREVWSUNFX0lORk8gPSAnZGV2aWNlSW5mbyc7XG5SZWdpc3RlckFwcEludGVyZmFjZS5LRVlfQVBQX0lEID0gJ2FwcElEJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlLktFWV9GVUxMX0FQUF9JRCA9ICdmdWxsQXBwSUQnO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0FQUF9JTkZPID0gJ2FwcEluZm8nO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX0RBWV9DT0xPUl9TQ0hFTUUgPSAnZGF5Q29sb3JTY2hlbWUnO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2UuS0VZX05JR0hUX0NPTE9SX1NDSEVNRSA9ICduaWdodENvbG9yU2NoZW1lJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlLkFQUF9JRF9NQVhfTEVOR1RIID0gMTA7XG5cbmV4cG9ydCB7IFJlZ2lzdGVyQXBwSW50ZXJmYWNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYge0VudW19IFJlc3VsdFxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgUmVzdWx0IGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSByZXF1ZXN0IHN1Y2NlZWRlZFxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNVQ0NFU1MgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuU1VDQ0VTUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVxdWVzdCBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBoZWFkdW5pdFxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFVOU1VQUE9SVEVEX1JFUVVFU1QgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuVU5TVVBQT1JURURfUkVRVUVTVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIGJ1dHRvbiB0aGF0IHdhcyByZXF1ZXN0ZWQgZm9yIHN1YnNjcmlwdGlvbiBpcyBub3Qgc3VwcG9ydGVkIHVuZGVyIHRoZSBjdXJyZW50IHN5c3RlbS5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBVTlNVUFBPUlRFRF9SRVNPVVJDRSAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5VTlNVUFBPUlRFRF9SRVNPVVJDRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSUEMgaXMgbm90IGF1dGhvcml6ZWQgaW4gbG9jYWwgcG9saWN5IHRhYmxlLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IERJU0FMTE9XRUQgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuRElTQUxMT1dFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVxdWVzdGVkIGNvbW1hbmQgd2FzIHJlamVjdGVkLCBlLmcuIGJlY2F1c2UgbW9iaWxlIGFwcCBpcyBpbiBiYWNrZ3JvdW5kIGFuZCBjYW5ub3QgcGVyZm9ybSBhbnkgSE1JXG4gICAgICogY29tbWFuZHMuIE9yIGFuIEhNSSBjb21tYW5kIChlLmcuIFNwZWFrKSBpcyByZWplY3RlZCBiZWNhdXNlIGEgaGlnaGVyIHByaW9yaXR5IEhNSSBjb21tYW5kIChlLmcuIEFsZXJ0KSBpc1xuICAgICAqIHBsYXlpbmcuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUkVKRUNURUQgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuUkVKRUNURUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBjb21tYW5kIHdhcyBhYm9ydGVkLCBmb3IgZXhhbXBsZSBkdWUgdG8gdXNlciBpbnRlcmFjdGlvbiAoZS5nLiB1c2VyIHByZXNzZWQgYnV0dG9uKS4gT3IgYW4gSE1JIGNvbW1hbmQgKGUuZy5cbiAgICAgKiBTcGVhaykgaXMgYWJvcnRlZCBiZWNhdXNlIGEgaGlnaGVyIHByaW9yaXR5IEhNSSBjb21tYW5kIChlLmcuIEFsZXJ0KSB3YXMgcmVxdWVzdGVkLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFCT1JURUQgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuQUJPUlRFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIGNvbW1hbmQgd2FzIGlnbm9yZWQsIGJlY2F1c2UgdGhlIGludGVuZGVkIHJlc3VsdCBpcyBhbHJlYWR5IGluIGVmZmVjdC4gRm9yIGV4YW1wbGUsIFNldE1lZGlhQ2xvY2tUaW1lciB3YXNcbiAgICAgKiB1c2VkIHRvIHBhdXNlIHRoZSBtZWRpYSBjbG9jayBhbHRob3VnaCB0aGUgY2xvY2sgaXMgcGF1c2VkIGFscmVhZHkuIE5PVEU6IHBvdGVudGlhbGx5IHJlcGxhY2VzXG4gICAgICogU1VCU0NSSUJFRF9BTFJFQURZXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSUdOT1JFRCAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5JR05PUkVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSB1c2VyIGludGVycnVwdGVkIHRoZSBSUEMgKGUuZy4gUGVyZm9ybUF1ZGlvUGFzc1RocnUpIGFuZCBpbmRpY2F0ZWQgdG8gc3RhcnQgb3Zlci4gTm90ZSwgdGhlIGFwcCBtdXN0IGlzc3VlXG4gICAgICogdGhlIG5ldyBSUEMuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUkVUUlkgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuUkVUUlk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGRhdGEgbWF5IG5vdCBiZSBjaGFuZ2VkLCBiZWNhdXNlIGl0IGlzIGN1cnJlbnRseSBpbiB1c2UuIEZvciBleGFtcGxlIHdoZW4gdHJ5aW5nIHRvIGRlbGV0ZSBhIGNvbW1hbmQgc2V0XG4gICAgICogdGhhdCBpcyBjdXJyZW50bHkgaW52b2x2ZWQgaW4gYW4gaW50ZXJhY3Rpb24uXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSU5fVVNFICgpIHtcbiAgICAgICAgcmV0dXJuIFJlc3VsdC5fTUFQLklOX1VTRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVxdWVzdGVkIHZlaGljbGUgZGF0YSBpcyBub3QgYXZhaWxhYmxlIG9uIHRoaXMgdmVoaWNsZSBvciBpcyBub3QgcHVibGlzaGVkLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZFSElDTEVfREFUQV9OT1RfQVZBSUxBQkxFICgpIHtcbiAgICAgICAgcmV0dXJuIFJlc3VsdC5fTUFQLlZFSElDTEVfREFUQV9OT1RfQVZBSUxBQkxFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE92ZXJsYXkgcmVhY2hlZCB0aGUgbWF4aW11bSB0aW1lb3V0IGFuZCBjbG9zZWQuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVElNRURfT1VUICgpIHtcbiAgICAgICAgcmV0dXJuIFJlc3VsdC5fTUFQLlRJTUVEX09VVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgZGF0YSBzZW50IGlzIGludmFsaWQuIEZvciBleGFtcGxlOiBJbnZhbGlkIEpzb24gc3ludGF4IFBhcmFtZXRlcnMgb3V0IG9mIGJvdW5kcyAobnVtYmVyIG9yIGVudW0gcmFuZ2UpXG4gICAgICogTWFuZGF0b3J5IHBhcmFtZXRlcnMgbm90IHByb3ZpZGVkIFBhcmFtZXRlciBwcm92aWRlZCB3aXRoIHdyb25nIHR5cGUgSW52YWxpZCBjaGFyYWN0ZXJzIEVtcHR5IHN0cmluZ1xuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IElOVkFMSURfREFUQSAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5JTlZBTElEX0RBVEE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ0hBUl9MSU1JVF9FWENFRURFRCAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5DSEFSX0xJTUlUX0VYQ0VFREVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9uZSBvZiB0aGUgcHJvdmlkZWQgSURzIGlzIG5vdCB2YWxpZC4gRm9yIGV4YW1wbGUgVGhpcyBhcHBsaWVzIHRvIENvcnJlbGF0aW9uSUQsIFN1YnNjcmlwdGlvbklELCBDb21tYW5kSUQsXG4gICAgICogTWVudUlELCBldGMuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSU5WQUxJRF9JRCAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5JTlZBTElEX0lEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZXJlIHdhcyBhIGNvbmZsaWN0IHdpdGggYW4gcmVnaXN0ZXJlZCBuYW1lIChhcHBsaWNhdGlvbiBvciBtZW51IGl0ZW0pIG9yIHZyIGNvbW1hbmRcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBEVVBMSUNBVEVfTkFNRSAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5EVVBMSUNBVEVfTkFNRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBbiBjb21tYW5kIGNhbiBub3QgYmUgZXhlY3V0ZWQgYmVjYXVzZSBubyBhcHBsaWNhdGlvbiBoYXMgYmVlbiByZWdpc3RlcmVkIHdpdGggUmVnaXN0ZXJBcHBsaWNhdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBBUFBMSUNBVElPTl9OT1RfUkVHSVNURVJFRCAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5BUFBMSUNBVElPTl9OT1RfUkVHSVNURVJFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVxdWVzdGVkIGxhbmd1YWdlIGlzIGN1cnJlbnRseSBub3Qgc3VwcG9ydGVkLiBNaWdodCBiZSBiZWNhdXNlIG9mIGEgbWlzbWF0Y2ggb2YgdGhlIGN1cnJlbnRseSBhY3RpdmVcbiAgICAgKiBsYW5ndWFnZSBvbiB0aGUgaGVhZHVuaXQgYW5kIHRoZSByZXF1ZXN0ZWQgbGFuZ3VhZ2VcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBXUk9OR19MQU5HVUFHRSAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5XUk9OR19MQU5HVUFHRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgc3lzdGVtIGNvdWxkIG5vdCBwcm9jZXNzIHRoZSByZXF1ZXN0IGJlY2F1c2UgdGhlIG5lY2Vzc2FyeSBtZW1vcnkgY291bGRuJ3QgYmUgYWxsb2NhdGVkXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgT1VUX09GX01FTU9SWSAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5PVVRfT0ZfTUVNT1JZO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZXJlIGFyZSB0b28gbWFueSByZXF1ZXN0cyBwZW5kaW5nIChtZWFucywgdGhhdCB0aGUgcmVzcG9uc2UgaGFzIG5vdCBiZWVuIGRlbGl2ZXJlZCwgeWV0KS5UaGVyZSBtYXkgYmUgYVxuICAgICAqIG1heGltdW0gb2YgMTAwMCBwZW5kaW5nIHJlcXVlc3RzIGF0IGEgdGltZS5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBUT09fTUFOWV9QRU5ESU5HX1JFUVVFU1RTICgpIHtcbiAgICAgICAgcmV0dXJuIFJlc3VsdC5fTUFQLlRPT19NQU5ZX1BFTkRJTkdfUkVRVUVTVFM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlcmUgYXJlIGFscmVhZHkgdG9vIG1hbnkgcmVnaXN0ZXJlZCBhcHBsaWNhdGlvbnNcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBUT09fTUFOWV9BUFBMSUNBVElPTlMgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuVE9PX01BTllfQVBQTElDQVRJT05TO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlZ2lzdGVyQXBwbGljYXRpb24gaGFzIGJlZW4gY2FsbGVkIGFnYWluLCBhZnRlciBhIFJlZ2lzdGVyQXBwbGljYXRpb24gd2FzIHN1Y2Nlc3NmdWwgYmVmb3JlLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFQUExJQ0FUSU9OX1JFR0lTVEVSRURfQUxSRUFEWSAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5BUFBMSUNBVElPTl9SRUdJU1RFUkVEX0FMUkVBRFk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIFJQQyAoZS5nLiBTdWJzY3JpYmVWZWhpY2xlRGF0YSkgZXhlY3V0ZWQgc3VjY2Vzc2Z1bGx5IGJ1dCBvbmUgb3IgbW9yZSBpdGVtcyBoYXZlIGEgd2FybmluZyBvciBmYWlsdXJlLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFdBUk5JTkdTICgpIHtcbiAgICAgICAgcmV0dXJuIFJlc3VsdC5fTUFQLldBUk5JTkdTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByb3ZpZGVkIGRhdGEgaXMgdmFsaWQgYnV0IHNvbWV0aGluZyB3ZW50IHdyb25nIGluIHRoZSBsb3dlciBsYXllcnMuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgR0VORVJJQ19FUlJPUiAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5HRU5FUklDX0VSUk9SO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJQQyBpcyBpbmNsdWRlZCBpbiBhIGZ1bmN0aW9uYWwgZ3JvdXAgZXhwbGljaXRseSBibG9ja2VkIGJ5IHRoZSB1c2VyLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFVTRVJfRElTQUxMT1dFRCAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5VU0VSX0RJU0FMTE9XRUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIFJQQyAoZS5nLiBSZWFkRElEKSBleGVjdXRlZCBzdWNjZXNzZnVsbHkgYnV0IHRoZSBkYXRhIGV4Y2VlZGVkIHRoZSBwbGF0Zm9ybSBtYXhpbXVtIHRocmVzaG9sZCBhbmQgdGh1cyxcbiAgICAgKiBvbmx5IHBhcnQgb2YgdGhlIGRhdGEgaXMgYXZhaWxhYmxlLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFRSVU5DQVRFRF9EQVRBICgpIHtcbiAgICAgICAgcmV0dXJuIFJlc3VsdC5fTUFQLlRSVU5DQVRFRF9EQVRBO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN5bmMgZG9lc24ndCBzdXBwb3J0IHRoZSBwcm90b2NvbCB0aGF0IGlzIHJlcXVlc3RlZCBieSB0aGUgbW9iaWxlIGFwcGxpY2F0aW9uXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVU5TVVBQT1JURURfVkVSU0lPTiAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5VTlNVUFBPUlRFRF9WRVJTSU9OO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSB1c2VyIGhhcyB0dXJuZWQgb2ZmIGFjY2VzcyB0byB2ZWhpY2xlIGRhdGEsIGFuZCBpdCBpcyBnbG9iYWxseSB1bmF2YWlsYWJsZSB0byBtb2JpbGUgYXBwbGljYXRpb25zLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZFSElDTEVfREFUQV9OT1RfQUxMT1dFRCAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5WRUhJQ0xFX0RBVEFfTk9UX0FMTE9XRUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWZpZWQgZmlsZSBjb3VsZCBub3QgYmUgZm91bmQgb24gdGhlIGhlYWR1bml0LlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEZJTEVfTk9UX0ZPVU5EICgpIHtcbiAgICAgICAgcmV0dXJuIFJlc3VsdC5fTUFQLkZJTEVfTk9UX0ZPVU5EO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVzZXIgc2VsZWN0ZWQgdG8gQ2FuY2VsIFJvdXRlLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENBTkNFTF9ST1VURSAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5DQU5DRUxfUk9VVEU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIFJQQyAoZS5nLiBTbGlkZXIpIGV4ZWN1dGVkIHN1Y2Nlc3NmdWxseSBhbmQgdGhlIHVzZXIgZWxlY3RlZCB0byBzYXZlIHRoZSBjdXJyZW50IHBvc2l0aW9uIC8gdmFsdWUuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0FWRUQgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuU0FWRUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGNlcnRpZmljYXRlIHByb3ZpZGVkIGR1cmluZyBhdXRoZW50aWNhdGlvbiBpcyBpbnZhbGlkLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IElOVkFMSURfQ0VSVCAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5JTlZBTElEX0NFUlQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGNlcnRpZmljYXRlIHByb3ZpZGVkIGR1cmluZyBhdXRoZW50aWNhdGlvbiBpcyBleHBpcmVkLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEVYUElSRURfQ0VSVCAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5FWFBJUkVEX0NFUlQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIHByb3ZpZGVkIGhhc2ggSUQgZG9lcyBub3QgbWF0Y2ggdGhlIGhhc2ggb2YgdGhlIGN1cnJlbnQgc2V0IG9mIHJlZ2lzdGVyZWQgZGF0YSBvciB0aGUgY29yZSBjb3VsZCBub3QgcmVzdW1lXG4gICAgICogdGhlIHByZXZpb3VzIGRhdGEuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUkVTVU1FX0ZBSUxFRCAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5SRVNVTUVfRkFJTEVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSByZXF1ZXN0ZWQgaW5mb3JtYXRpb24gaXMgY3VycmVudGx5IG5vdCBhdmFpbGFibGUuIFRoaXMgaXMgZGlmZmVyZW50IHRoYW4gVU5TVVBQT1JURURfUkVTT1VSQ0UgYmVjYXVzZSBpdFxuICAgICAqIGltcGxpZXMgdGhlIGRhdGEgaXMgYXQgc29tZSBwb2ludCBhdmFpbGFibGUuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgREFUQV9OT1RfQVZBSUxBQkxFICgpIHtcbiAgICAgICAgcmV0dXJuIFJlc3VsdC5fTUFQLkRBVEFfTk9UX0FWQUlMQUJMRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgdmFsdWUgYmVpbmcgc2V0IGlzIHJlYWQgb25seVxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJFQURfT05MWSAoKSB7XG4gICAgICAgIHJldHVybiBSZXN1bHQuX01BUC5SRUFEX09OTFk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGRhdGEgc2VudCBmYWlsZWQgdG8gcGFzcyBDUkMgY2hlY2sgaW4gcmVjZWl2ZXIgZW5kXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ09SUlVQVEVEX0RBVEEgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuQ09SUlVQVEVEX0RBVEE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU0RMIHJlY2VpdmVzIGFuIHVuLWVuY3J5cHRlZCBSUEMgcmVxdWVzdCB0aGF0IG5lZWRzIHByb3RlY3Rpb24uXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRU5DUllQVElPTl9ORUVERUQgKCkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll9NQVAuRU5DUllQVElPTl9ORUVERUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gUmVzdWx0Ll92YWx1ZUZvcktleShrZXksIFJlc3VsdC5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFJlc3VsdC5fa2V5Rm9yVmFsdWUodmFsdWUsIFJlc3VsdC5fTUFQKTtcbiAgICB9XG59XG5cblJlc3VsdC5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1NVQ0NFU1MnOiAnU1VDQ0VTUycsXG4gICAgJ1VOU1VQUE9SVEVEX1JFUVVFU1QnOiAnVU5TVVBQT1JURURfUkVRVUVTVCcsXG4gICAgJ1VOU1VQUE9SVEVEX1JFU09VUkNFJzogJ1VOU1VQUE9SVEVEX1JFU09VUkNFJyxcbiAgICAnRElTQUxMT1dFRCc6ICdESVNBTExPV0VEJyxcbiAgICAnUkVKRUNURUQnOiAnUkVKRUNURUQnLFxuICAgICdBQk9SVEVEJzogJ0FCT1JURUQnLFxuICAgICdJR05PUkVEJzogJ0lHTk9SRUQnLFxuICAgICdSRVRSWSc6ICdSRVRSWScsXG4gICAgJ0lOX1VTRSc6ICdJTl9VU0UnLFxuICAgICdWRUhJQ0xFX0RBVEFfTk9UX0FWQUlMQUJMRSc6ICdWRUhJQ0xFX0RBVEFfTk9UX0FWQUlMQUJMRScsXG4gICAgJ1RJTUVEX09VVCc6ICdUSU1FRF9PVVQnLFxuICAgICdJTlZBTElEX0RBVEEnOiAnSU5WQUxJRF9EQVRBJyxcbiAgICAnQ0hBUl9MSU1JVF9FWENFRURFRCc6ICdDSEFSX0xJTUlUX0VYQ0VFREVEJyxcbiAgICAnSU5WQUxJRF9JRCc6ICdJTlZBTElEX0lEJyxcbiAgICAnRFVQTElDQVRFX05BTUUnOiAnRFVQTElDQVRFX05BTUUnLFxuICAgICdBUFBMSUNBVElPTl9OT1RfUkVHSVNURVJFRCc6ICdBUFBMSUNBVElPTl9OT1RfUkVHSVNURVJFRCcsXG4gICAgJ1dST05HX0xBTkdVQUdFJzogJ1dST05HX0xBTkdVQUdFJyxcbiAgICAnT1VUX09GX01FTU9SWSc6ICdPVVRfT0ZfTUVNT1JZJyxcbiAgICAnVE9PX01BTllfUEVORElOR19SRVFVRVNUUyc6ICdUT09fTUFOWV9QRU5ESU5HX1JFUVVFU1RTJyxcbiAgICAnVE9PX01BTllfQVBQTElDQVRJT05TJzogJ1RPT19NQU5ZX0FQUExJQ0FUSU9OUycsXG4gICAgJ0FQUExJQ0FUSU9OX1JFR0lTVEVSRURfQUxSRUFEWSc6ICdBUFBMSUNBVElPTl9SRUdJU1RFUkVEX0FMUkVBRFknLFxuICAgICdXQVJOSU5HUyc6ICdXQVJOSU5HUycsXG4gICAgJ0dFTkVSSUNfRVJST1InOiAnR0VORVJJQ19FUlJPUicsXG4gICAgJ1VTRVJfRElTQUxMT1dFRCc6ICdVU0VSX0RJU0FMTE9XRUQnLFxuICAgICdUUlVOQ0FURURfREFUQSc6ICdUUlVOQ0FURURfREFUQScsXG4gICAgJ1VOU1VQUE9SVEVEX1ZFUlNJT04nOiAnVU5TVVBQT1JURURfVkVSU0lPTicsXG4gICAgJ1ZFSElDTEVfREFUQV9OT1RfQUxMT1dFRCc6ICdWRUhJQ0xFX0RBVEFfTk9UX0FMTE9XRUQnLFxuICAgICdGSUxFX05PVF9GT1VORCc6ICdGSUxFX05PVF9GT1VORCcsXG4gICAgJ0NBTkNFTF9ST1VURSc6ICdDQU5DRUxfUk9VVEUnLFxuICAgICdTQVZFRCc6ICdTQVZFRCcsXG4gICAgJ0lOVkFMSURfQ0VSVCc6ICdJTlZBTElEX0NFUlQnLFxuICAgICdFWFBJUkVEX0NFUlQnOiAnRVhQSVJFRF9DRVJUJyxcbiAgICAnUkVTVU1FX0ZBSUxFRCc6ICdSRVNVTUVfRkFJTEVEJyxcbiAgICAnREFUQV9OT1RfQVZBSUxBQkxFJzogJ0RBVEFfTk9UX0FWQUlMQUJMRScsXG4gICAgJ1JFQURfT05MWSc6ICdSRUFEX09OTFknLFxuICAgICdDT1JSVVBURURfREFUQSc6ICdDT1JSVVBURURfREFUQScsXG4gICAgJ0VOQ1JZUFRJT05fTkVFREVEJzogJ0VOQ1JZUFRJT05fTkVFREVEJyxcbn0pO1xuXG5leHBvcnQgeyBSZXN1bHQgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjTWVzc2FnZSB9IGZyb20gJy4vUnBjTWVzc2FnZS5qcyc7XG5pbXBvcnQgeyBScGNUeXBlIH0gZnJvbSAnLi9lbnVtcy9ScGNUeXBlLmpzJztcbmltcG9ydCB7IFJlc3VsdCB9IGZyb20gJy4vZW51bXMvUmVzdWx0LmpzJztcblxuY2xhc3MgUnBjUmVzcG9uc2UgZXh0ZW5kcyBScGNNZXNzYWdlIHtcbiAgICAvKipcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRSUENUeXBlKFJwY1R5cGUuUkVTUE9OU0UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAqL1xuICAgIGdldFN1Y2Nlc3MgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUnBjUmVzcG9uc2UuS0VZX1NVQ0NFU1MpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7UnBjUmVzcG9uc2V9XG4gICAgKi9cbiAgICBzZXRTdWNjZXNzIChzdWNjZXNzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJwY1Jlc3BvbnNlLktFWV9TVUNDRVNTLCBzdWNjZXNzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgKi9cbiAgICBnZXRJbmZvICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFJwY1Jlc3BvbnNlLktFWV9JTkZPKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1JwY1Jlc3BvbnNlfVxuICAgICovXG4gICAgc2V0SW5mbyAoaW5mbykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihScGNSZXNwb25zZS5LRVlfSU5GTywgaW5mbyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7UmVzdWx0fVxuICAgICovXG4gICAgZ2V0UmVzdWx0Q29kZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChSZXN1bHQsIFJwY1Jlc3BvbnNlLktFWV9SRVNVTFRfQ09ERSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtScGNSZXNwb25zZX1cbiAgICAqL1xuICAgIHNldFJlc3VsdENvZGUgKHJlc3VsdENvZGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoUmVzdWx0LCByZXN1bHRDb2RlKTtcblxuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihScGNSZXNwb25zZS5LRVlfUkVTVUxUX0NPREUsIHJlc3VsdENvZGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5cblJwY1Jlc3BvbnNlLktFWV9TVUNDRVNTICAgICA9ICdzdWNjZXNzJztcblJwY1Jlc3BvbnNlLktFWV9JTkZPICAgICAgICA9ICdpbmZvJztcblJwY1Jlc3BvbnNlLktFWV9SRVNVTFRfQ09ERSA9ICdyZXN1bHRDb2RlJztcblxuZXhwb3J0IHsgUnBjUmVzcG9uc2UgfTtcbiIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5jbGFzcyBScGNMaXN0ZW5lciB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICB0aGlzLl9vblJwY01lc3NhZ2UgPSBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmNcbiAgICAgKiBAcmV0dXJuIHtScGNMaXN0ZW5lcn1cbiAgICAgKi9cbiAgICBzZXRPblJwY01lc3NhZ2UgKGZ1bmMpIHtcbiAgICAgICAgdGhpcy5fb25ScGNNZXNzYWdlID0gZnVuYztcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7UnBjTWVzc2FnZX0gcnBjTWVzc2FnZVxuICAgICAqL1xuICAgIG9uUnBjTWVzc2FnZSAocnBjTWVzc2FnZSkge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX29uUnBjTWVzc2FnZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5fb25ScGNNZXNzYWdlKHJwY01lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgeyBScGNMaXN0ZW5lciB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gU2RsUHJvdG9jb2xMaXN0ZW5lclxuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gc2V0T25ScGNNZXNzYWdlUmVjZWl2ZWRcbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IG9uUnBjTWVzc2FnZVJlY2VpdmVkXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBzZXRPblByb3RvY29sU2Vzc2lvblN0YXJ0ZWRcbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IG9uUHJvdG9jb2xTZXNzaW9uU3RhcnRlZFxuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gc2V0T25Qcm90b2NvbFNlc3Npb25FbmRlZFxuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gb25Qcm90b2NvbFNlc3Npb25FbmRlZFxuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gc2V0T25Qcm90b2NvbFNlc3Npb25FbmRlZE5BQ0tlZFxuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gb25Qcm90b2NvbFNlc3Npb25FbmRlZE5BQ0tlZFxuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gc2V0R2V0U2Vzc2lvbklkXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBnZXRTZXNzaW9uSWRcbiAqL1xuY2xhc3MgU2RsUHJvdG9jb2xMaXN0ZW5lciB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICB0aGlzLl9vblJwY01lc3NhZ2VSZWNlaXZlZCA9IG51bGw7XG4gICAgICAgIHRoaXMuX29uUHJvdG9jb2xTZXNzaW9uU3RhcnRlZCA9IG51bGw7XG4gICAgICAgIHRoaXMuX29uUHJvdG9jb2xTZXNzaW9uRW5kZWQgPSBudWxsO1xuICAgICAgICB0aGlzLl9vblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkID0gbnVsbDtcbiAgICAgICAgdGhpcy5fZ2V0U2Vzc2lvbklkID0gbnVsbDtcbiAgICAgICAgdGhpcy5fb25UcmFuc3BvcnRDb25uZWN0ZWQgPSBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyXG4gICAgICovXG4gICAgc2V0T25UcmFuc3BvcnRDb25uZWN0ZWQgKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMuX29uVHJhbnNwb3J0Q29ubmVjdGVkID0gbGlzdGVuZXI7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyXG4gICAgICovXG4gICAgc2V0T25ScGNNZXNzYWdlUmVjZWl2ZWQgKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMuX29uUnBjTWVzc2FnZVJlY2VpdmVkID0gbGlzdGVuZXI7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7UnBjTWVzc2FnZX0gcnBjTWVzc2FnZVxuICAgICAqL1xuICAgIG9uUnBjTWVzc2FnZVJlY2VpdmVkIChycGNNZXNzYWdlKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fb25ScGNNZXNzYWdlUmVjZWl2ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuX29uUnBjTWVzc2FnZVJlY2VpdmVkKHJwY01lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBzZXRPblByb3RvY29sU2Vzc2lvblN0YXJ0ZWQgKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMuX29uUHJvdG9jb2xTZXNzaW9uU3RhcnRlZCA9IGxpc3RlbmVyO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cblxuICAgIG9uVHJhbnNwb3J0Q29ubmVjdGVkICgpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9vblRyYW5zcG9ydENvbm5lY3RlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5fb25UcmFuc3BvcnRDb25uZWN0ZWQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEludm9rZSB0aGUgb25Qcm90b2NvbFNlc3Npb25TdGFydGVkIGxpc3RlbmVyIHdpdGggdGhlIGV2ZW50IGRhdGFcbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzZXNzaW9uSWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gdmVyc2lvblxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBjb3JyZWxhdGlvbklkXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGhhc2hJZFxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNFbmNyeXB0ZWRcbiAgICAgKi9cbiAgICBvblByb3RvY29sU2Vzc2lvblN0YXJ0ZWQgKHNlcnZpY2VUeXBlLCBzZXNzaW9uSWQsIHZlcnNpb24sIGNvcnJlbGF0aW9uSWQsIGhhc2hJZCwgaXNFbmNyeXB0ZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9vblByb3RvY29sU2Vzc2lvblN0YXJ0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuX29uUHJvdG9jb2xTZXNzaW9uU3RhcnRlZChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklkLCB2ZXJzaW9uLCBjb3JyZWxhdGlvbklkLCBoYXNoSWQsIGlzRW5jcnlwdGVkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyXG4gICAgICovXG4gICAgc2V0T25Qcm90b2NvbFNlc3Npb25FbmRlZCAobGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5fb25Qcm90b2NvbFNlc3Npb25FbmRlZCA9IGxpc3RlbmVyO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbnZva2UgdGhlIG9uUHJvdG9jb2xTZXNzaW9uRW5kZWQgbGlzdGVuZXIgd2l0aCB0aGUgZXZlbnQgZGF0YVxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlc3Npb25JZFxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBjb3JyZWxhdGlvbklkXG4gICAgICovXG4gICAgb25Qcm90b2NvbFNlc3Npb25FbmRlZCAoc2VydmljZVR5cGUsIHNlc3Npb25JZCwgY29ycmVsYXRpb25JZCkge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX29uUHJvdG9jb2xTZXNzaW9uRW5kZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuX29uUHJvdG9jb2xTZXNzaW9uRW5kZWQoc2VydmljZVR5cGUsIHNlc3Npb25JZCwgY29ycmVsYXRpb25JZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBsaXN0ZW5lclxuICAgICAqL1xuICAgIHNldE9uUHJvdG9jb2xTZXNzaW9uRW5kZWROQUNLZWQgKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMuX29uUHJvdG9jb2xTZXNzaW9uRW5kZWROQUNLZWQgPSBsaXN0ZW5lcjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW52b2tlIHRoZSBvblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkIGxpc3RlbmVyIHdpdGggdGhlIGV2ZW50IGRhdGFcbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzZXNzaW9uSWRcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gY29ycmVsYXRpb25JZFxuICAgICAqL1xuICAgIG9uUHJvdG9jb2xTZXNzaW9uRW5kZWROQUNLZWQgKHNlcnZpY2VUeXBlLCBzZXNzaW9uSWQsIGNvcnJlbGF0aW9uSWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9vblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9vblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkKHNlcnZpY2VUeXBlLCBzZXNzaW9uSWQsIGNvcnJlbGF0aW9uSWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gZ2V0dGVyXG4gICAgICovXG4gICAgc2V0R2V0U2Vzc2lvbklkIChnZXR0ZXIpIHtcbiAgICAgICAgdGhpcy5fZ2V0U2Vzc2lvbklkID0gZ2V0dGVyO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbnZva2UgdGhlIGdldFNlc3Npb25JZCBnZXR0ZXJcbiAgICAgKiBAcmV0dXJucyB7TnVtYmVyfSBzZXNzaW9uSWRcbiAgICAgKi9cbiAgICBnZXRTZXNzaW9uSWQgKCkge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX2dldFNlc3Npb25JZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dldFNlc3Npb25JZCgpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBnZXREZXNpcmVkVmlkZW9QYXJhbXMgZ2V0dGVyXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gZ2V0dGVyXG4gICAgICovXG4gICAgc2V0R2V0RGVzaXJlZFZpZGVvUGFyYW1zIChnZXR0ZXIpIHtcbiAgICAgICAgdGhpcy5fZ2V0RGVzaXJlZFZpZGVvUGFyYW1zID0gZ2V0dGVyO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbnZva2UgdGhlIGdldERlc2lyZWRWaWRlb1BhcmFtcyBnZXR0ZXJcbiAgICAgKiBAcmV0dXJucyB7VmlkZW9TdHJlYW1pbmdQYXJhbWV0ZXJzfVxuICAgICAqL1xuICAgIGdldERlc2lyZWRWaWRlb1BhcmFtcyAoKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fZ2V0RGVzaXJlZFZpZGVvUGFyYW1zID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0RGVzaXJlZFZpZGVvUGFyYW1zKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBzZXRTZXRBY2NlcHRlZFZpZGVvUGFyYW1zIHNldHRlclxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IHNldHRlclxuICAgICAqL1xuICAgIHNldFNldEFjY2VwdGVkVmlkZW9QYXJhbXMgKHNldHRlcikge1xuICAgICAgICB0aGlzLl9zZXRBY2NlcHRlZFZpZGVvUGFyYW1zID0gc2V0dGVyO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEludm9rZSB0aGUgc2V0QWNjZXB0ZWRWaWRlb1BhcmFtcyBzZXR0ZXJcbiAgICAgKiBAcGFyYW0ge1ZpZGVvU3RyZWFtaW5nUGFyYW1ldGVyc30gcGFyYW1zXG4gICAgICovXG4gICAgc2V0QWNjZXB0ZWRWaWRlb1BhcmFtcyAocGFyYW1zKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fc2V0QWNjZXB0ZWRWaWRlb1BhcmFtcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5fc2V0QWNjZXB0ZWRWaWRlb1BhcmFtcyhwYXJhbXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cblxuZXhwb3J0IHsgU2RsUHJvdG9jb2xMaXN0ZW5lciB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gRnJhbWVUeXBlXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBGcmFtZVR5cGUgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBDT05UUk9MICgpIHtcbiAgICAgICAgcmV0dXJuIEZyYW1lVHlwZS5fTUFQLkNPTlRST0w7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IEZJUlNUICgpIHtcbiAgICAgICAgcmV0dXJuIEZyYW1lVHlwZS5fTUFQLkZJUlNUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgc3RhdGljIGdldCBDT05TRUNVVElWRSAoKSB7XG4gICAgICAgIHJldHVybiBGcmFtZVR5cGUuX01BUC5DT05TRUNVVElWRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0lOR0xFICgpIHtcbiAgICAgICAgcmV0dXJuIEZyYW1lVHlwZS5fTUFQLlNJTkdMRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gRnJhbWVUeXBlLl92YWx1ZUZvcktleShrZXksIEZyYW1lVHlwZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gRnJhbWVUeXBlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgRnJhbWVUeXBlLl9NQVApO1xuICAgIH1cbn1cblxuRnJhbWVUeXBlLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnQ09OVFJPTCc6IDB4MDAsXG4gICAgJ0ZJUlNUJzogMHgwMixcbiAgICAnQ09OU0VDVVRJVkUnOiAweDAzLFxuICAgICdTSU5HTEUnOiAweDAxLFxufSk7XG5cbmV4cG9ydCB7IEZyYW1lVHlwZSB9O1xuIiwiZXhwb3J0c1tcImJzb25cIl0gPVxuLyoqKioqKi8gKGZ1bmN0aW9uKG1vZHVsZXMpIHsgLy8gd2VicGFja0Jvb3RzdHJhcFxuLyoqKioqKi8gXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4vKioqKioqLyBcdHZhciBpbnN0YWxsZWRNb2R1bGVzID0ge307XG4vKioqKioqL1xuLyoqKioqKi8gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuLyoqKioqKi8gXHRmdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG4vKioqKioqL1xuLyoqKioqKi8gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuLyoqKioqKi8gXHRcdGlmKGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdKSB7XG4vKioqKioqLyBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcbi8qKioqKiovIFx0XHR9XG4vKioqKioqLyBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbi8qKioqKiovIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4vKioqKioqLyBcdFx0XHRpOiBtb2R1bGVJZCxcbi8qKioqKiovIFx0XHRcdGw6IGZhbHNlLFxuLyoqKioqKi8gXHRcdFx0ZXhwb3J0czoge31cbi8qKioqKiovIFx0XHR9O1xuLyoqKioqKi9cbi8qKioqKiovIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbi8qKioqKiovIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcbi8qKioqKiovXG4vKioqKioqLyBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuLyoqKioqKi8gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcbi8qKioqKiovXG4vKioqKioqLyBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbi8qKioqKiovIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4vKioqKioqLyBcdH1cbi8qKioqKiovXG4vKioqKioqL1xuLyoqKioqKi8gXHQvLyBleHBvc2UgdGhlIG1vZHVsZXMgb2JqZWN0IChfX3dlYnBhY2tfbW9kdWxlc19fKVxuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGVcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIGRlZmluZSBnZXR0ZXIgZnVuY3Rpb24gZm9yIGhhcm1vbnkgZXhwb3J0c1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSBmdW5jdGlvbihleHBvcnRzLCBuYW1lLCBnZXR0ZXIpIHtcbi8qKioqKiovIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4vKioqKioqLyBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgbmFtZSwge1xuLyoqKioqKi8gXHRcdFx0XHRjb25maWd1cmFibGU6IGZhbHNlLFxuLyoqKioqKi8gXHRcdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuLyoqKioqKi8gXHRcdFx0XHRnZXQ6IGdldHRlclxuLyoqKioqKi8gXHRcdFx0fSk7XG4vKioqKioqLyBcdFx0fVxuLyoqKioqKi8gXHR9O1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gZ2V0RGVmYXVsdEV4cG9ydCBmdW5jdGlvbiBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIG5vbi1oYXJtb255IG1vZHVsZXNcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5uID0gZnVuY3Rpb24obW9kdWxlKSB7XG4vKioqKioqLyBcdFx0dmFyIGdldHRlciA9IG1vZHVsZSAmJiBtb2R1bGUuX19lc01vZHVsZSA/XG4vKioqKioqLyBcdFx0XHRmdW5jdGlvbiBnZXREZWZhdWx0KCkgeyByZXR1cm4gbW9kdWxlWydkZWZhdWx0J107IH0gOlxuLyoqKioqKi8gXHRcdFx0ZnVuY3Rpb24gZ2V0TW9kdWxlRXhwb3J0cygpIHsgcmV0dXJuIG1vZHVsZTsgfTtcbi8qKioqKiovIFx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQoZ2V0dGVyLCAnYScsIGdldHRlcik7XG4vKioqKioqLyBcdFx0cmV0dXJuIGdldHRlcjtcbi8qKioqKiovIFx0fTtcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbFxuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XG4vKioqKioqL1xuLyoqKioqKi8gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4vKioqKioqLyBcdHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKF9fd2VicGFja19yZXF1aXJlX18ucyA9IDIpO1xuLyoqKioqKi8gfSlcbi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKioqKioqLyAoW1xuLyogMCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG52YXIgZztcblxuLy8gVGhpcyB3b3JrcyBpbiBub24tc3RyaWN0IG1vZGVcbmcgPSAoZnVuY3Rpb24oKSB7XG5cdHJldHVybiB0aGlzO1xufSkoKTtcblxudHJ5IHtcblx0Ly8gVGhpcyB3b3JrcyBpZiBldmFsIGlzIGFsbG93ZWQgKHNlZSBDU1ApXG5cdGcgPSBnIHx8IEZ1bmN0aW9uKFwicmV0dXJuIHRoaXNcIikoKSB8fCAoMSxldmFsKShcInRoaXNcIik7XG59IGNhdGNoKGUpIHtcblx0Ly8gVGhpcyB3b3JrcyBpZiB0aGUgd2luZG93IHJlZmVyZW5jZSBpcyBhdmFpbGFibGVcblx0aWYodHlwZW9mIHdpbmRvdyA9PT0gXCJvYmplY3RcIilcblx0XHRnID0gd2luZG93O1xufVxuXG4vLyBnIGNhbiBzdGlsbCBiZSB1bmRlZmluZWQsIGJ1dCBub3RoaW5nIHRvIGRvIGFib3V0IGl0Li4uXG4vLyBXZSByZXR1cm4gdW5kZWZpbmVkLCBpbnN0ZWFkIG9mIG5vdGhpbmcgaGVyZSwgc28gaXQnc1xuLy8gZWFzaWVyIHRvIGhhbmRsZSB0aGlzIGNhc2UuIGlmKCFnbG9iYWwpIHsgLi4ufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGc7XG5cblxuLyoqKi8gfSksXG4vKiAxICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblwidXNlIHN0cmljdFwiO1xuLyogV0VCUEFDSyBWQVIgSU5KRUNUSU9OICovKGZ1bmN0aW9uKGdsb2JhbCkgey8qIVxuICogVGhlIGJ1ZmZlciBtb2R1bGUgZnJvbSBub2RlLmpzLCBmb3IgdGhlIGJyb3dzZXIuXG4gKlxuICogQGF1dGhvciAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGh0dHA6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1wcm90byAqL1xuXG5cblxudmFyIGJhc2U2NCA9IF9fd2VicGFja19yZXF1aXJlX18oMylcbnZhciBpZWVlNzU0ID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0KVxudmFyIGlzQXJyYXkgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDUpXG5cbmV4cG9ydHMuQnVmZmVyID0gQnVmZmVyXG5leHBvcnRzLlNsb3dCdWZmZXIgPSBTbG93QnVmZmVyXG5leHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTID0gNTBcblxuLyoqXG4gKiBJZiBgQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRgOlxuICogICA9PT0gdHJ1ZSAgICBVc2UgVWludDhBcnJheSBpbXBsZW1lbnRhdGlvbiAoZmFzdGVzdClcbiAqICAgPT09IGZhbHNlICAgVXNlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiAobW9zdCBjb21wYXRpYmxlLCBldmVuIElFNilcbiAqXG4gKiBCcm93c2VycyB0aGF0IHN1cHBvcnQgdHlwZWQgYXJyYXlzIGFyZSBJRSAxMCssIEZpcmVmb3ggNCssIENocm9tZSA3KywgU2FmYXJpIDUuMSssXG4gKiBPcGVyYSAxMS42KywgaU9TIDQuMisuXG4gKlxuICogRHVlIHRvIHZhcmlvdXMgYnJvd3NlciBidWdzLCBzb21ldGltZXMgdGhlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiB3aWxsIGJlIHVzZWQgZXZlblxuICogd2hlbiB0aGUgYnJvd3NlciBzdXBwb3J0cyB0eXBlZCBhcnJheXMuXG4gKlxuICogTm90ZTpcbiAqXG4gKiAgIC0gRmlyZWZveCA0LTI5IGxhY2tzIHN1cHBvcnQgZm9yIGFkZGluZyBuZXcgcHJvcGVydGllcyB0byBgVWludDhBcnJheWAgaW5zdGFuY2VzLFxuICogICAgIFNlZTogaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9Njk1NDM4LlxuICpcbiAqICAgLSBDaHJvbWUgOS0xMCBpcyBtaXNzaW5nIHRoZSBgVHlwZWRBcnJheS5wcm90b3R5cGUuc3ViYXJyYXlgIGZ1bmN0aW9uLlxuICpcbiAqICAgLSBJRTEwIGhhcyBhIGJyb2tlbiBgVHlwZWRBcnJheS5wcm90b3R5cGUuc3ViYXJyYXlgIGZ1bmN0aW9uIHdoaWNoIHJldHVybnMgYXJyYXlzIG9mXG4gKiAgICAgaW5jb3JyZWN0IGxlbmd0aCBpbiBzb21lIHNpdHVhdGlvbnMuXG5cbiAqIFdlIGRldGVjdCB0aGVzZSBidWdneSBicm93c2VycyBhbmQgc2V0IGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGAgdG8gYGZhbHNlYCBzbyB0aGV5XG4gKiBnZXQgdGhlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiwgd2hpY2ggaXMgc2xvd2VyIGJ1dCBiZWhhdmVzIGNvcnJlY3RseS5cbiAqL1xuQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgPSBnbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVCAhPT0gdW5kZWZpbmVkXG4gID8gZ2xvYmFsLlRZUEVEX0FSUkFZX1NVUFBPUlRcbiAgOiB0eXBlZEFycmF5U3VwcG9ydCgpXG5cbi8qXG4gKiBFeHBvcnQga01heExlbmd0aCBhZnRlciB0eXBlZCBhcnJheSBzdXBwb3J0IGlzIGRldGVybWluZWQuXG4gKi9cbmV4cG9ydHMua01heExlbmd0aCA9IGtNYXhMZW5ndGgoKVxuXG5mdW5jdGlvbiB0eXBlZEFycmF5U3VwcG9ydCAoKSB7XG4gIHRyeSB7XG4gICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KDEpXG4gICAgYXJyLl9fcHJvdG9fXyA9IHtfX3Byb3RvX186IFVpbnQ4QXJyYXkucHJvdG90eXBlLCBmb286IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDQyIH19XG4gICAgcmV0dXJuIGFyci5mb28oKSA9PT0gNDIgJiYgLy8gdHlwZWQgYXJyYXkgaW5zdGFuY2VzIGNhbiBiZSBhdWdtZW50ZWRcbiAgICAgICAgdHlwZW9mIGFyci5zdWJhcnJheSA9PT0gJ2Z1bmN0aW9uJyAmJiAvLyBjaHJvbWUgOS0xMCBsYWNrIGBzdWJhcnJheWBcbiAgICAgICAgYXJyLnN1YmFycmF5KDEsIDEpLmJ5dGVMZW5ndGggPT09IDAgLy8gaWUxMCBoYXMgYnJva2VuIGBzdWJhcnJheWBcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbmZ1bmN0aW9uIGtNYXhMZW5ndGggKCkge1xuICByZXR1cm4gQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRcbiAgICA/IDB4N2ZmZmZmZmZcbiAgICA6IDB4M2ZmZmZmZmZcbn1cblxuZnVuY3Rpb24gY3JlYXRlQnVmZmVyICh0aGF0LCBsZW5ndGgpIHtcbiAgaWYgKGtNYXhMZW5ndGgoKSA8IGxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbnZhbGlkIHR5cGVkIGFycmF5IGxlbmd0aCcpXG4gIH1cbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UsIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgdGhhdCA9IG5ldyBVaW50OEFycmF5KGxlbmd0aClcbiAgICB0aGF0Ll9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgfSBlbHNlIHtcbiAgICAvLyBGYWxsYmFjazogUmV0dXJuIGFuIG9iamVjdCBpbnN0YW5jZSBvZiB0aGUgQnVmZmVyIGNsYXNzXG4gICAgaWYgKHRoYXQgPT09IG51bGwpIHtcbiAgICAgIHRoYXQgPSBuZXcgQnVmZmVyKGxlbmd0aClcbiAgICB9XG4gICAgdGhhdC5sZW5ndGggPSBsZW5ndGhcbiAgfVxuXG4gIHJldHVybiB0aGF0XG59XG5cbi8qKlxuICogVGhlIEJ1ZmZlciBjb25zdHJ1Y3RvciByZXR1cm5zIGluc3RhbmNlcyBvZiBgVWludDhBcnJheWAgdGhhdCBoYXZlIHRoZWlyXG4gKiBwcm90b3R5cGUgY2hhbmdlZCB0byBgQnVmZmVyLnByb3RvdHlwZWAuIEZ1cnRoZXJtb3JlLCBgQnVmZmVyYCBpcyBhIHN1YmNsYXNzIG9mXG4gKiBgVWludDhBcnJheWAsIHNvIHRoZSByZXR1cm5lZCBpbnN0YW5jZXMgd2lsbCBoYXZlIGFsbCB0aGUgbm9kZSBgQnVmZmVyYCBtZXRob2RzXG4gKiBhbmQgdGhlIGBVaW50OEFycmF5YCBtZXRob2RzLiBTcXVhcmUgYnJhY2tldCBub3RhdGlvbiB3b3JrcyBhcyBleHBlY3RlZCAtLSBpdFxuICogcmV0dXJucyBhIHNpbmdsZSBvY3RldC5cbiAqXG4gKiBUaGUgYFVpbnQ4QXJyYXlgIHByb3RvdHlwZSByZW1haW5zIHVubW9kaWZpZWQuXG4gKi9cblxuZnVuY3Rpb24gQnVmZmVyIChhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUICYmICEodGhpcyBpbnN0YW5jZW9mIEJ1ZmZlcikpIHtcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcihhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIC8vIENvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICBpZiAodHlwZW9mIGVuY29kaW5nT3JPZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdJZiBlbmNvZGluZyBpcyBzcGVjaWZpZWQgdGhlbiB0aGUgZmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZydcbiAgICAgIClcbiAgICB9XG4gICAgcmV0dXJuIGFsbG9jVW5zYWZlKHRoaXMsIGFyZylcbiAgfVxuICByZXR1cm4gZnJvbSh0aGlzLCBhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuQnVmZmVyLnBvb2xTaXplID0gODE5MiAvLyBub3QgdXNlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uXG5cbi8vIFRPRE86IExlZ2FjeSwgbm90IG5lZWRlZCBhbnltb3JlLiBSZW1vdmUgaW4gbmV4dCBtYWpvciB2ZXJzaW9uLlxuQnVmZmVyLl9hdWdtZW50ID0gZnVuY3Rpb24gKGFycikge1xuICBhcnIuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICByZXR1cm4gYXJyXG59XG5cbmZ1bmN0aW9uIGZyb20gKHRoYXQsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgYSBudW1iZXInKVxuICB9XG5cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcgJiYgdmFsdWUgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgIHJldHVybiBmcm9tQXJyYXlCdWZmZXIodGhhdCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGZyb21TdHJpbmcodGhhdCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQpXG4gIH1cblxuICByZXR1cm4gZnJvbU9iamVjdCh0aGF0LCB2YWx1ZSlcbn1cblxuLyoqXG4gKiBGdW5jdGlvbmFsbHkgZXF1aXZhbGVudCB0byBCdWZmZXIoYXJnLCBlbmNvZGluZykgYnV0IHRocm93cyBhIFR5cGVFcnJvclxuICogaWYgdmFsdWUgaXMgYSBudW1iZXIuXG4gKiBCdWZmZXIuZnJvbShzdHJbLCBlbmNvZGluZ10pXG4gKiBCdWZmZXIuZnJvbShhcnJheSlcbiAqIEJ1ZmZlci5mcm9tKGJ1ZmZlcilcbiAqIEJ1ZmZlci5mcm9tKGFycmF5QnVmZmVyWywgYnl0ZU9mZnNldFssIGxlbmd0aF1dKVxuICoqL1xuQnVmZmVyLmZyb20gPSBmdW5jdGlvbiAodmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gZnJvbShudWxsLCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG5pZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgQnVmZmVyLnByb3RvdHlwZS5fX3Byb3RvX18gPSBVaW50OEFycmF5LnByb3RvdHlwZVxuICBCdWZmZXIuX19wcm90b19fID0gVWludDhBcnJheVxuICBpZiAodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnNwZWNpZXMgJiZcbiAgICAgIEJ1ZmZlcltTeW1ib2wuc3BlY2llc10gPT09IEJ1ZmZlcikge1xuICAgIC8vIEZpeCBzdWJhcnJheSgpIGluIEVTMjAxNi4gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlci9wdWxsLzk3XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEJ1ZmZlciwgU3ltYm9sLnNwZWNpZXMsIHtcbiAgICAgIHZhbHVlOiBudWxsLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSlcbiAgfVxufVxuXG5mdW5jdGlvbiBhc3NlcnRTaXplIChzaXplKSB7XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcInNpemVcIiBhcmd1bWVudCBtdXN0IGJlIGEgbnVtYmVyJylcbiAgfSBlbHNlIGlmIChzaXplIDwgMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcInNpemVcIiBhcmd1bWVudCBtdXN0IG5vdCBiZSBuZWdhdGl2ZScpXG4gIH1cbn1cblxuZnVuY3Rpb24gYWxsb2MgKHRoYXQsIHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIGFzc2VydFNpemUoc2l6ZSlcbiAgaWYgKHNpemUgPD0gMCkge1xuICAgIHJldHVybiBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSlcbiAgfVxuICBpZiAoZmlsbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gT25seSBwYXkgYXR0ZW50aW9uIHRvIGVuY29kaW5nIGlmIGl0J3MgYSBzdHJpbmcuIFRoaXNcbiAgICAvLyBwcmV2ZW50cyBhY2NpZGVudGFsbHkgc2VuZGluZyBpbiBhIG51bWJlciB0aGF0IHdvdWxkXG4gICAgLy8gYmUgaW50ZXJwcmV0dGVkIGFzIGEgc3RhcnQgb2Zmc2V0LlxuICAgIHJldHVybiB0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnXG4gICAgICA/IGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKS5maWxsKGZpbGwsIGVuY29kaW5nKVxuICAgICAgOiBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSkuZmlsbChmaWxsKVxuICB9XG4gIHJldHVybiBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSlcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKiBhbGxvYyhzaXplWywgZmlsbFssIGVuY29kaW5nXV0pXG4gKiovXG5CdWZmZXIuYWxsb2MgPSBmdW5jdGlvbiAoc2l6ZSwgZmlsbCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGFsbG9jKG51bGwsIHNpemUsIGZpbGwsIGVuY29kaW5nKVxufVxuXG5mdW5jdGlvbiBhbGxvY1Vuc2FmZSAodGhhdCwgc2l6ZSkge1xuICBhc3NlcnRTaXplKHNpemUpXG4gIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSA8IDAgPyAwIDogY2hlY2tlZChzaXplKSB8IDApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpemU7ICsraSkge1xuICAgICAgdGhhdFtpXSA9IDBcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuLyoqXG4gKiBFcXVpdmFsZW50IHRvIEJ1ZmZlcihudW0pLCBieSBkZWZhdWx0IGNyZWF0ZXMgYSBub24temVyby1maWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICogKi9cbkJ1ZmZlci5hbGxvY1Vuc2FmZSA9IGZ1bmN0aW9uIChzaXplKSB7XG4gIHJldHVybiBhbGxvY1Vuc2FmZShudWxsLCBzaXplKVxufVxuLyoqXG4gKiBFcXVpdmFsZW50IHRvIFNsb3dCdWZmZXIobnVtKSwgYnkgZGVmYXVsdCBjcmVhdGVzIGEgbm9uLXplcm8tZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqL1xuQnVmZmVyLmFsbG9jVW5zYWZlU2xvdyA9IGZ1bmN0aW9uIChzaXplKSB7XG4gIHJldHVybiBhbGxvY1Vuc2FmZShudWxsLCBzaXplKVxufVxuXG5mdW5jdGlvbiBmcm9tU3RyaW5nICh0aGF0LCBzdHJpbmcsIGVuY29kaW5nKSB7XG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgIT09ICdzdHJpbmcnIHx8IGVuY29kaW5nID09PSAnJykge1xuICAgIGVuY29kaW5nID0gJ3V0ZjgnXG4gIH1cblxuICBpZiAoIUJ1ZmZlci5pc0VuY29kaW5nKGVuY29kaW5nKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiZW5jb2RpbmdcIiBtdXN0IGJlIGEgdmFsaWQgc3RyaW5nIGVuY29kaW5nJylcbiAgfVxuXG4gIHZhciBsZW5ndGggPSBieXRlTGVuZ3RoKHN0cmluZywgZW5jb2RpbmcpIHwgMFxuICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIGxlbmd0aClcblxuICB2YXIgYWN0dWFsID0gdGhhdC53cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuXG4gIGlmIChhY3R1YWwgIT09IGxlbmd0aCkge1xuICAgIC8vIFdyaXRpbmcgYSBoZXggc3RyaW5nLCBmb3IgZXhhbXBsZSwgdGhhdCBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcnMgd2lsbFxuICAgIC8vIGNhdXNlIGV2ZXJ5dGhpbmcgYWZ0ZXIgdGhlIGZpcnN0IGludmFsaWQgY2hhcmFjdGVyIHRvIGJlIGlnbm9yZWQuIChlLmcuXG4gICAgLy8gJ2FieHhjZCcgd2lsbCBiZSB0cmVhdGVkIGFzICdhYicpXG4gICAgdGhhdCA9IHRoYXQuc2xpY2UoMCwgYWN0dWFsKVxuICB9XG5cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5TGlrZSAodGhhdCwgYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCA8IDAgPyAwIDogY2hlY2tlZChhcnJheS5sZW5ndGgpIHwgMFxuICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIGxlbmd0aClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUJ1ZmZlciAodGhhdCwgYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICBhcnJheS5ieXRlTGVuZ3RoIC8vIHRoaXMgdGhyb3dzIGlmIGBhcnJheWAgaXMgbm90IGEgdmFsaWQgQXJyYXlCdWZmZXJcblxuICBpZiAoYnl0ZU9mZnNldCA8IDAgfHwgYXJyYXkuYnl0ZUxlbmd0aCA8IGJ5dGVPZmZzZXQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXFwnb2Zmc2V0XFwnIGlzIG91dCBvZiBib3VuZHMnKVxuICB9XG5cbiAgaWYgKGFycmF5LmJ5dGVMZW5ndGggPCBieXRlT2Zmc2V0ICsgKGxlbmd0aCB8fCAwKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcXCdsZW5ndGhcXCcgaXMgb3V0IG9mIGJvdW5kcycpXG4gIH1cblxuICBpZiAoYnl0ZU9mZnNldCA9PT0gdW5kZWZpbmVkICYmIGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgYXJyYXkgPSBuZXcgVWludDhBcnJheShhcnJheSlcbiAgfSBlbHNlIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXksIGJ5dGVPZmZzZXQpXG4gIH0gZWxzZSB7XG4gICAgYXJyYXkgPSBuZXcgVWludDhBcnJheShhcnJheSwgYnl0ZU9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UsIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgdGhhdCA9IGFycmF5XG4gICAgdGhhdC5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIH0gZWxzZSB7XG4gICAgLy8gRmFsbGJhY2s6IFJldHVybiBhbiBvYmplY3QgaW5zdGFuY2Ugb2YgdGhlIEJ1ZmZlciBjbGFzc1xuICAgIHRoYXQgPSBmcm9tQXJyYXlMaWtlKHRoYXQsIGFycmF5KVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21PYmplY3QgKHRoYXQsIG9iaikge1xuICBpZiAoQnVmZmVyLmlzQnVmZmVyKG9iaikpIHtcbiAgICB2YXIgbGVuID0gY2hlY2tlZChvYmoubGVuZ3RoKSB8IDBcbiAgICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIGxlbilcblxuICAgIGlmICh0aGF0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRoYXRcbiAgICB9XG5cbiAgICBvYmouY29weSh0aGF0LCAwLCAwLCBsZW4pXG4gICAgcmV0dXJuIHRoYXRcbiAgfVxuXG4gIGlmIChvYmopIHtcbiAgICBpZiAoKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICAgb2JqLmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB8fCAnbGVuZ3RoJyBpbiBvYmopIHtcbiAgICAgIGlmICh0eXBlb2Ygb2JqLmxlbmd0aCAhPT0gJ251bWJlcicgfHwgaXNuYW4ob2JqLmxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LCAwKVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZyb21BcnJheUxpa2UodGhhdCwgb2JqKVxuICAgIH1cblxuICAgIGlmIChvYmoudHlwZSA9PT0gJ0J1ZmZlcicgJiYgaXNBcnJheShvYmouZGF0YSkpIHtcbiAgICAgIHJldHVybiBmcm9tQXJyYXlMaWtlKHRoYXQsIG9iai5kYXRhKVxuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcsIEJ1ZmZlciwgQXJyYXlCdWZmZXIsIEFycmF5LCBvciBhcnJheS1saWtlIG9iamVjdC4nKVxufVxuXG5mdW5jdGlvbiBjaGVja2VkIChsZW5ndGgpIHtcbiAgLy8gTm90ZTogY2Fubm90IHVzZSBgbGVuZ3RoIDwga01heExlbmd0aCgpYCBoZXJlIGJlY2F1c2UgdGhhdCBmYWlscyB3aGVuXG4gIC8vIGxlbmd0aCBpcyBOYU4gKHdoaWNoIGlzIG90aGVyd2lzZSBjb2VyY2VkIHRvIHplcm8uKVxuICBpZiAobGVuZ3RoID49IGtNYXhMZW5ndGgoKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIGFsbG9jYXRlIEJ1ZmZlciBsYXJnZXIgdGhhbiBtYXhpbXVtICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICdzaXplOiAweCcgKyBrTWF4TGVuZ3RoKCkudG9TdHJpbmcoMTYpICsgJyBieXRlcycpXG4gIH1cbiAgcmV0dXJuIGxlbmd0aCB8IDBcbn1cblxuZnVuY3Rpb24gU2xvd0J1ZmZlciAobGVuZ3RoKSB7XG4gIGlmICgrbGVuZ3RoICE9IGxlbmd0aCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGVxZXFlcVxuICAgIGxlbmd0aCA9IDBcbiAgfVxuICByZXR1cm4gQnVmZmVyLmFsbG9jKCtsZW5ndGgpXG59XG5cbkJ1ZmZlci5pc0J1ZmZlciA9IGZ1bmN0aW9uIGlzQnVmZmVyIChiKSB7XG4gIHJldHVybiAhIShiICE9IG51bGwgJiYgYi5faXNCdWZmZXIpXG59XG5cbkJ1ZmZlci5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZSAoYSwgYikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihhKSB8fCAhQnVmZmVyLmlzQnVmZmVyKGIpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnRzIG11c3QgYmUgQnVmZmVycycpXG4gIH1cblxuICBpZiAoYSA9PT0gYikgcmV0dXJuIDBcblxuICB2YXIgeCA9IGEubGVuZ3RoXG4gIHZhciB5ID0gYi5sZW5ndGhcblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gTWF0aC5taW4oeCwgeSk7IGkgPCBsZW47ICsraSkge1xuICAgIGlmIChhW2ldICE9PSBiW2ldKSB7XG4gICAgICB4ID0gYVtpXVxuICAgICAgeSA9IGJbaV1cbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG5cbiAgaWYgKHggPCB5KSByZXR1cm4gLTFcbiAgaWYgKHkgPCB4KSByZXR1cm4gMVxuICByZXR1cm4gMFxufVxuXG5CdWZmZXIuaXNFbmNvZGluZyA9IGZ1bmN0aW9uIGlzRW5jb2RpbmcgKGVuY29kaW5nKSB7XG4gIHN3aXRjaCAoU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgY2FzZSAnYXNjaWknOlxuICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5CdWZmZXIuY29uY2F0ID0gZnVuY3Rpb24gY29uY2F0IChsaXN0LCBsZW5ndGgpIHtcbiAgaWYgKCFpc0FycmF5KGxpc3QpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJylcbiAgfVxuXG4gIGlmIChsaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBCdWZmZXIuYWxsb2MoMClcbiAgfVxuXG4gIHZhciBpXG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGxlbmd0aCA9IDBcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgICAgbGVuZ3RoICs9IGxpc3RbaV0ubGVuZ3RoXG4gICAgfVxuICB9XG5cbiAgdmFyIGJ1ZmZlciA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShsZW5ndGgpXG4gIHZhciBwb3MgPSAwXG4gIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgdmFyIGJ1ZiA9IGxpc3RbaV1cbiAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RcIiBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMnKVxuICAgIH1cbiAgICBidWYuY29weShidWZmZXIsIHBvcylcbiAgICBwb3MgKz0gYnVmLmxlbmd0aFxuICB9XG4gIHJldHVybiBidWZmZXJcbn1cblxuZnVuY3Rpb24gYnl0ZUxlbmd0aCAoc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHN0cmluZykpIHtcbiAgICByZXR1cm4gc3RyaW5nLmxlbmd0aFxuICB9XG4gIGlmICh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBBcnJheUJ1ZmZlci5pc1ZpZXcgPT09ICdmdW5jdGlvbicgJiZcbiAgICAgIChBcnJheUJ1ZmZlci5pc1ZpZXcoc3RyaW5nKSB8fCBzdHJpbmcgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikpIHtcbiAgICByZXR1cm4gc3RyaW5nLmJ5dGVMZW5ndGhcbiAgfVxuICBpZiAodHlwZW9mIHN0cmluZyAhPT0gJ3N0cmluZycpIHtcbiAgICBzdHJpbmcgPSAnJyArIHN0cmluZ1xuICB9XG5cbiAgdmFyIGxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKGxlbiA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBVc2UgYSBmb3IgbG9vcCB0byBhdm9pZCByZWN1cnNpb25cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGVuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgIGNhc2UgdW5kZWZpbmVkOlxuICAgICAgICByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiBsZW4gKiAyXG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gbGVuID4+PiAxXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGggLy8gYXNzdW1lIHV0ZjhcbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cbkJ1ZmZlci5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuXG5mdW5jdGlvbiBzbG93VG9TdHJpbmcgKGVuY29kaW5nLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG5cbiAgLy8gTm8gbmVlZCB0byB2ZXJpZnkgdGhhdCBcInRoaXMubGVuZ3RoIDw9IE1BWF9VSU5UMzJcIiBzaW5jZSBpdCdzIGEgcmVhZC1vbmx5XG4gIC8vIHByb3BlcnR5IG9mIGEgdHlwZWQgYXJyYXkuXG5cbiAgLy8gVGhpcyBiZWhhdmVzIG5laXRoZXIgbGlrZSBTdHJpbmcgbm9yIFVpbnQ4QXJyYXkgaW4gdGhhdCB3ZSBzZXQgc3RhcnQvZW5kXG4gIC8vIHRvIHRoZWlyIHVwcGVyL2xvd2VyIGJvdW5kcyBpZiB0aGUgdmFsdWUgcGFzc2VkIGlzIG91dCBvZiByYW5nZS5cbiAgLy8gdW5kZWZpbmVkIGlzIGhhbmRsZWQgc3BlY2lhbGx5IGFzIHBlciBFQ01BLTI2MiA2dGggRWRpdGlvbixcbiAgLy8gU2VjdGlvbiAxMy4zLjMuNyBSdW50aW1lIFNlbWFudGljczogS2V5ZWRCaW5kaW5nSW5pdGlhbGl6YXRpb24uXG4gIGlmIChzdGFydCA9PT0gdW5kZWZpbmVkIHx8IHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ID0gMFxuICB9XG4gIC8vIFJldHVybiBlYXJseSBpZiBzdGFydCA+IHRoaXMubGVuZ3RoLiBEb25lIGhlcmUgdG8gcHJldmVudCBwb3RlbnRpYWwgdWludDMyXG4gIC8vIGNvZXJjaW9uIGZhaWwgYmVsb3cuXG4gIGlmIChzdGFydCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBpZiAoZW5kID09PSB1bmRlZmluZWQgfHwgZW5kID4gdGhpcy5sZW5ndGgpIHtcbiAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICB9XG5cbiAgaWYgKGVuZCA8PSAwKSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICAvLyBGb3JjZSBjb2Vyc2lvbiB0byB1aW50MzIuIFRoaXMgd2lsbCBhbHNvIGNvZXJjZSBmYWxzZXkvTmFOIHZhbHVlcyB0byAwLlxuICBlbmQgPj4+PSAwXG4gIHN0YXJ0ID4+Pj0gMFxuXG4gIGlmIChlbmQgPD0gc3RhcnQpIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxhdGluMVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdXRmMTZsZVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9IChlbmNvZGluZyArICcnKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG4vLyBUaGUgcHJvcGVydHkgaXMgdXNlZCBieSBgQnVmZmVyLmlzQnVmZmVyYCBhbmQgYGlzLWJ1ZmZlcmAgKGluIFNhZmFyaSA1LTcpIHRvIGRldGVjdFxuLy8gQnVmZmVyIGluc3RhbmNlcy5cbkJ1ZmZlci5wcm90b3R5cGUuX2lzQnVmZmVyID0gdHJ1ZVxuXG5mdW5jdGlvbiBzd2FwIChiLCBuLCBtKSB7XG4gIHZhciBpID0gYltuXVxuICBiW25dID0gYlttXVxuICBiW21dID0gaVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXAxNiA9IGZ1bmN0aW9uIHN3YXAxNiAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgMiAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgMTYtYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gMikge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDEpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwMzIgPSBmdW5jdGlvbiBzd2FwMzIgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDQgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDMyLWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDQpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyAzKVxuICAgIHN3YXAodGhpcywgaSArIDEsIGkgKyAyKVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDY0ID0gZnVuY3Rpb24gc3dhcDY0ICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSA4ICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA2NC1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA4KSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgNylcbiAgICBzd2FwKHRoaXMsIGkgKyAxLCBpICsgNilcbiAgICBzd2FwKHRoaXMsIGkgKyAyLCBpICsgNSlcbiAgICBzd2FwKHRoaXMsIGkgKyAzLCBpICsgNClcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcgKCkge1xuICB2YXIgbGVuZ3RoID0gdGhpcy5sZW5ndGggfCAwXG4gIGlmIChsZW5ndGggPT09IDApIHJldHVybiAnJ1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCAwLCBsZW5ndGgpXG4gIHJldHVybiBzbG93VG9TdHJpbmcuYXBwbHkodGhpcywgYXJndW1lbnRzKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIGVxdWFscyAoYikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihiKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlcicpXG4gIGlmICh0aGlzID09PSBiKSByZXR1cm4gdHJ1ZVxuICByZXR1cm4gQnVmZmVyLmNvbXBhcmUodGhpcywgYikgPT09IDBcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCAoKSB7XG4gIHZhciBzdHIgPSAnJ1xuICB2YXIgbWF4ID0gZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFU1xuICBpZiAodGhpcy5sZW5ndGggPiAwKSB7XG4gICAgc3RyID0gdGhpcy50b1N0cmluZygnaGV4JywgMCwgbWF4KS5tYXRjaCgvLnsyfS9nKS5qb2luKCcgJylcbiAgICBpZiAodGhpcy5sZW5ndGggPiBtYXgpIHN0ciArPSAnIC4uLiAnXG4gIH1cbiAgcmV0dXJuICc8QnVmZmVyICcgKyBzdHIgKyAnPidcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZSAodGFyZ2V0LCBzdGFydCwgZW5kLCB0aGlzU3RhcnQsIHRoaXNFbmQpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIodGFyZ2V0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICB9XG5cbiAgaWYgKHN0YXJ0ID09PSB1bmRlZmluZWQpIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICBpZiAoZW5kID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmQgPSB0YXJnZXQgPyB0YXJnZXQubGVuZ3RoIDogMFxuICB9XG4gIGlmICh0aGlzU3RhcnQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRoaXNTdGFydCA9IDBcbiAgfVxuICBpZiAodGhpc0VuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhpc0VuZCA9IHRoaXMubGVuZ3RoXG4gIH1cblxuICBpZiAoc3RhcnQgPCAwIHx8IGVuZCA+IHRhcmdldC5sZW5ndGggfHwgdGhpc1N0YXJ0IDwgMCB8fCB0aGlzRW5kID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb3V0IG9mIHJhbmdlIGluZGV4JylcbiAgfVxuXG4gIGlmICh0aGlzU3RhcnQgPj0gdGhpc0VuZCAmJiBzdGFydCA+PSBlbmQpIHtcbiAgICByZXR1cm4gMFxuICB9XG4gIGlmICh0aGlzU3RhcnQgPj0gdGhpc0VuZCkge1xuICAgIHJldHVybiAtMVxuICB9XG4gIGlmIChzdGFydCA+PSBlbmQpIHtcbiAgICByZXR1cm4gMVxuICB9XG5cbiAgc3RhcnQgPj4+PSAwXG4gIGVuZCA+Pj49IDBcbiAgdGhpc1N0YXJ0ID4+Pj0gMFxuICB0aGlzRW5kID4+Pj0gMFxuXG4gIGlmICh0aGlzID09PSB0YXJnZXQpIHJldHVybiAwXG5cbiAgdmFyIHggPSB0aGlzRW5kIC0gdGhpc1N0YXJ0XG4gIHZhciB5ID0gZW5kIC0gc3RhcnRcbiAgdmFyIGxlbiA9IE1hdGgubWluKHgsIHkpXG5cbiAgdmFyIHRoaXNDb3B5ID0gdGhpcy5zbGljZSh0aGlzU3RhcnQsIHRoaXNFbmQpXG4gIHZhciB0YXJnZXRDb3B5ID0gdGFyZ2V0LnNsaWNlKHN0YXJ0LCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgIGlmICh0aGlzQ29weVtpXSAhPT0gdGFyZ2V0Q29weVtpXSkge1xuICAgICAgeCA9IHRoaXNDb3B5W2ldXG4gICAgICB5ID0gdGFyZ2V0Q29weVtpXVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbi8vIEZpbmRzIGVpdGhlciB0aGUgZmlyc3QgaW5kZXggb2YgYHZhbGAgaW4gYGJ1ZmZlcmAgYXQgb2Zmc2V0ID49IGBieXRlT2Zmc2V0YCxcbi8vIE9SIHRoZSBsYXN0IGluZGV4IG9mIGB2YWxgIGluIGBidWZmZXJgIGF0IG9mZnNldCA8PSBgYnl0ZU9mZnNldGAuXG4vL1xuLy8gQXJndW1lbnRzOlxuLy8gLSBidWZmZXIgLSBhIEJ1ZmZlciB0byBzZWFyY2hcbi8vIC0gdmFsIC0gYSBzdHJpbmcsIEJ1ZmZlciwgb3IgbnVtYmVyXG4vLyAtIGJ5dGVPZmZzZXQgLSBhbiBpbmRleCBpbnRvIGBidWZmZXJgOyB3aWxsIGJlIGNsYW1wZWQgdG8gYW4gaW50MzJcbi8vIC0gZW5jb2RpbmcgLSBhbiBvcHRpb25hbCBlbmNvZGluZywgcmVsZXZhbnQgaXMgdmFsIGlzIGEgc3RyaW5nXG4vLyAtIGRpciAtIHRydWUgZm9yIGluZGV4T2YsIGZhbHNlIGZvciBsYXN0SW5kZXhPZlxuZnVuY3Rpb24gYmlkaXJlY3Rpb25hbEluZGV4T2YgKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKSB7XG4gIC8vIEVtcHR5IGJ1ZmZlciBtZWFucyBubyBtYXRjaFxuICBpZiAoYnVmZmVyLmxlbmd0aCA9PT0gMCkgcmV0dXJuIC0xXG5cbiAgLy8gTm9ybWFsaXplIGJ5dGVPZmZzZXRcbiAgaWYgKHR5cGVvZiBieXRlT2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gYnl0ZU9mZnNldFxuICAgIGJ5dGVPZmZzZXQgPSAwXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA+IDB4N2ZmZmZmZmYpIHtcbiAgICBieXRlT2Zmc2V0ID0gMHg3ZmZmZmZmZlxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAtMHg4MDAwMDAwMCkge1xuICAgIGJ5dGVPZmZzZXQgPSAtMHg4MDAwMDAwMFxuICB9XG4gIGJ5dGVPZmZzZXQgPSArYnl0ZU9mZnNldCAgLy8gQ29lcmNlIHRvIE51bWJlci5cbiAgaWYgKGlzTmFOKGJ5dGVPZmZzZXQpKSB7XG4gICAgLy8gYnl0ZU9mZnNldDogaXQgaXQncyB1bmRlZmluZWQsIG51bGwsIE5hTiwgXCJmb29cIiwgZXRjLCBzZWFyY2ggd2hvbGUgYnVmZmVyXG4gICAgYnl0ZU9mZnNldCA9IGRpciA/IDAgOiAoYnVmZmVyLmxlbmd0aCAtIDEpXG4gIH1cblxuICAvLyBOb3JtYWxpemUgYnl0ZU9mZnNldDogbmVnYXRpdmUgb2Zmc2V0cyBzdGFydCBmcm9tIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlclxuICBpZiAoYnl0ZU9mZnNldCA8IDApIGJ5dGVPZmZzZXQgPSBidWZmZXIubGVuZ3RoICsgYnl0ZU9mZnNldFxuICBpZiAoYnl0ZU9mZnNldCA+PSBidWZmZXIubGVuZ3RoKSB7XG4gICAgaWYgKGRpcikgcmV0dXJuIC0xXG4gICAgZWxzZSBieXRlT2Zmc2V0ID0gYnVmZmVyLmxlbmd0aCAtIDFcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0IDwgMCkge1xuICAgIGlmIChkaXIpIGJ5dGVPZmZzZXQgPSAwXG4gICAgZWxzZSByZXR1cm4gLTFcbiAgfVxuXG4gIC8vIE5vcm1hbGl6ZSB2YWxcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFsID0gQnVmZmVyLmZyb20odmFsLCBlbmNvZGluZylcbiAgfVxuXG4gIC8vIEZpbmFsbHksIHNlYXJjaCBlaXRoZXIgaW5kZXhPZiAoaWYgZGlyIGlzIHRydWUpIG9yIGxhc3RJbmRleE9mXG4gIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsKSkge1xuICAgIC8vIFNwZWNpYWwgY2FzZTogbG9va2luZyBmb3IgZW1wdHkgc3RyaW5nL2J1ZmZlciBhbHdheXMgZmFpbHNcbiAgICBpZiAodmFsLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIC0xXG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpXG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICB2YWwgPSB2YWwgJiAweEZGIC8vIFNlYXJjaCBmb3IgYSBieXRlIHZhbHVlIFswLTI1NV1cbiAgICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiZcbiAgICAgICAgdHlwZW9mIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGlmIChkaXIpIHtcbiAgICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YuY2FsbChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBVaW50OEFycmF5LnByb3RvdHlwZS5sYXN0SW5kZXhPZi5jYWxsKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0KVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlciwgWyB2YWwgXSwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcilcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoJ3ZhbCBtdXN0IGJlIHN0cmluZywgbnVtYmVyIG9yIEJ1ZmZlcicpXG59XG5cbmZ1bmN0aW9uIGFycmF5SW5kZXhPZiAoYXJyLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpIHtcbiAgdmFyIGluZGV4U2l6ZSA9IDFcbiAgdmFyIGFyckxlbmd0aCA9IGFyci5sZW5ndGhcbiAgdmFyIHZhbExlbmd0aCA9IHZhbC5sZW5ndGhcblxuICBpZiAoZW5jb2RpbmcgIT09IHVuZGVmaW5lZCkge1xuICAgIGVuY29kaW5nID0gU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgaWYgKGVuY29kaW5nID09PSAndWNzMicgfHwgZW5jb2RpbmcgPT09ICd1Y3MtMicgfHxcbiAgICAgICAgZW5jb2RpbmcgPT09ICd1dGYxNmxlJyB8fCBlbmNvZGluZyA9PT0gJ3V0Zi0xNmxlJykge1xuICAgICAgaWYgKGFyci5sZW5ndGggPCAyIHx8IHZhbC5sZW5ndGggPCAyKSB7XG4gICAgICAgIHJldHVybiAtMVxuICAgICAgfVxuICAgICAgaW5kZXhTaXplID0gMlxuICAgICAgYXJyTGVuZ3RoIC89IDJcbiAgICAgIHZhbExlbmd0aCAvPSAyXG4gICAgICBieXRlT2Zmc2V0IC89IDJcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZWFkIChidWYsIGkpIHtcbiAgICBpZiAoaW5kZXhTaXplID09PSAxKSB7XG4gICAgICByZXR1cm4gYnVmW2ldXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBidWYucmVhZFVJbnQxNkJFKGkgKiBpbmRleFNpemUpXG4gICAgfVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGRpcikge1xuICAgIHZhciBmb3VuZEluZGV4ID0gLTFcbiAgICBmb3IgKGkgPSBieXRlT2Zmc2V0OyBpIDwgYXJyTGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChyZWFkKGFyciwgaSkgPT09IHJlYWQodmFsLCBmb3VuZEluZGV4ID09PSAtMSA/IDAgOiBpIC0gZm91bmRJbmRleCkpIHtcbiAgICAgICAgaWYgKGZvdW5kSW5kZXggPT09IC0xKSBmb3VuZEluZGV4ID0gaVxuICAgICAgICBpZiAoaSAtIGZvdW5kSW5kZXggKyAxID09PSB2YWxMZW5ndGgpIHJldHVybiBmb3VuZEluZGV4ICogaW5kZXhTaXplXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZm91bmRJbmRleCAhPT0gLTEpIGkgLT0gaSAtIGZvdW5kSW5kZXhcbiAgICAgICAgZm91bmRJbmRleCA9IC0xXG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChieXRlT2Zmc2V0ICsgdmFsTGVuZ3RoID4gYXJyTGVuZ3RoKSBieXRlT2Zmc2V0ID0gYXJyTGVuZ3RoIC0gdmFsTGVuZ3RoXG4gICAgZm9yIChpID0gYnl0ZU9mZnNldDsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHZhciBmb3VuZCA9IHRydWVcbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdmFsTGVuZ3RoOyBqKyspIHtcbiAgICAgICAgaWYgKHJlYWQoYXJyLCBpICsgaikgIT09IHJlYWQodmFsLCBqKSkge1xuICAgICAgICAgIGZvdW5kID0gZmFsc2VcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZm91bmQpIHJldHVybiBpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIC0xXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5jbHVkZXMgPSBmdW5jdGlvbiBpbmNsdWRlcyAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gdGhpcy5pbmRleE9mKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpICE9PSAtMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluZGV4T2YgPSBmdW5jdGlvbiBpbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiBiaWRpcmVjdGlvbmFsSW5kZXhPZih0aGlzLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCB0cnVlKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmxhc3RJbmRleE9mID0gZnVuY3Rpb24gbGFzdEluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGJpZGlyZWN0aW9uYWxJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGZhbHNlKVxufVxuXG5mdW5jdGlvbiBoZXhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIG9mZnNldCA9IE51bWJlcihvZmZzZXQpIHx8IDBcbiAgdmFyIHJlbWFpbmluZyA9IGJ1Zi5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgfSBlbHNlIHtcbiAgICBsZW5ndGggPSBOdW1iZXIobGVuZ3RoKVxuICAgIGlmIChsZW5ndGggPiByZW1haW5pbmcpIHtcbiAgICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICAgIH1cbiAgfVxuXG4gIC8vIG11c3QgYmUgYW4gZXZlbiBudW1iZXIgb2YgZGlnaXRzXG4gIHZhciBzdHJMZW4gPSBzdHJpbmcubGVuZ3RoXG4gIGlmIChzdHJMZW4gJSAyICE9PSAwKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIGhleCBzdHJpbmcnKVxuXG4gIGlmIChsZW5ndGggPiBzdHJMZW4gLyAyKSB7XG4gICAgbGVuZ3RoID0gc3RyTGVuIC8gMlxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgcGFyc2VkID0gcGFyc2VJbnQoc3RyaW5nLnN1YnN0cihpICogMiwgMiksIDE2KVxuICAgIGlmIChpc05hTihwYXJzZWQpKSByZXR1cm4gaVxuICAgIGJ1ZltvZmZzZXQgKyBpXSA9IHBhcnNlZFxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIHV0ZjhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjhUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGFzY2lpV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihhc2NpaVRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gbGF0aW4xV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYXNjaWlXcml0ZShidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGJhc2U2NFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYmFzZTY0VG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiB1Y3MyV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGYxNmxlVG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gd3JpdGUgKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKSB7XG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcpXG4gIGlmIChvZmZzZXQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBvZmZzZXRcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgb2Zmc2V0WywgbGVuZ3RoXVssIGVuY29kaW5nXSlcbiAgfSBlbHNlIGlmIChpc0Zpbml0ZShvZmZzZXQpKSB7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICAgIGlmIChpc0Zpbml0ZShsZW5ndGgpKSB7XG4gICAgICBsZW5ndGggPSBsZW5ndGggfCAwXG4gICAgICBpZiAoZW5jb2RpbmcgPT09IHVuZGVmaW5lZCkgZW5jb2RpbmcgPSAndXRmOCdcbiAgICB9IGVsc2Uge1xuICAgICAgZW5jb2RpbmcgPSBsZW5ndGhcbiAgICAgIGxlbmd0aCA9IHVuZGVmaW5lZFxuICAgIH1cbiAgLy8gbGVnYWN5IHdyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldCwgbGVuZ3RoKSAtIHJlbW92ZSBpbiB2MC4xM1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICdCdWZmZXIud3JpdGUoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0WywgbGVuZ3RoXSkgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZCdcbiAgICApXG4gIH1cblxuICB2YXIgcmVtYWluaW5nID0gdGhpcy5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkIHx8IGxlbmd0aCA+IHJlbWFpbmluZykgbGVuZ3RoID0gcmVtYWluaW5nXG5cbiAgaWYgKChzdHJpbmcubGVuZ3RoID4gMCAmJiAobGVuZ3RoIDwgMCB8fCBvZmZzZXQgPCAwKSkgfHwgb2Zmc2V0ID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXR0ZW1wdCB0byB3cml0ZSBvdXRzaWRlIGJ1ZmZlciBib3VuZHMnKVxuICB9XG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsYXRpbjFXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICAvLyBXYXJuaW5nOiBtYXhMZW5ndGggbm90IHRha2VuIGludG8gYWNjb3VudCBpbiBiYXNlNjRXcml0ZVxuICAgICAgICByZXR1cm4gYmFzZTY0V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHVjczJXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04gKCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6ICdCdWZmZXInLFxuICAgIGRhdGE6IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKHRoaXMuX2FyciB8fCB0aGlzLCAwKVxuICB9XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKHN0YXJ0ID09PSAwICYmIGVuZCA9PT0gYnVmLmxlbmd0aCkge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1Zi5zbGljZShzdGFydCwgZW5kKSlcbiAgfVxufVxuXG5mdW5jdGlvbiB1dGY4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG4gIHZhciByZXMgPSBbXVxuXG4gIHZhciBpID0gc3RhcnRcbiAgd2hpbGUgKGkgPCBlbmQpIHtcbiAgICB2YXIgZmlyc3RCeXRlID0gYnVmW2ldXG4gICAgdmFyIGNvZGVQb2ludCA9IG51bGxcbiAgICB2YXIgYnl0ZXNQZXJTZXF1ZW5jZSA9IChmaXJzdEJ5dGUgPiAweEVGKSA/IDRcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4REYpID8gM1xuICAgICAgOiAoZmlyc3RCeXRlID4gMHhCRikgPyAyXG4gICAgICA6IDFcblxuICAgIGlmIChpICsgYnl0ZXNQZXJTZXF1ZW5jZSA8PSBlbmQpIHtcbiAgICAgIHZhciBzZWNvbmRCeXRlLCB0aGlyZEJ5dGUsIGZvdXJ0aEJ5dGUsIHRlbXBDb2RlUG9pbnRcblxuICAgICAgc3dpdGNoIChieXRlc1BlclNlcXVlbmNlKSB7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICBpZiAoZmlyc3RCeXRlIDwgMHg4MCkge1xuICAgICAgICAgICAgY29kZVBvaW50ID0gZmlyc3RCeXRlXG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4MUYpIDw8IDB4NiB8IChzZWNvbmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3Rikge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIHRoaXJkQnl0ZSA9IGJ1ZltpICsgMl1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweEMgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4NiB8ICh0aGlyZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGRiAmJiAodGVtcENvZGVQb2ludCA8IDB4RDgwMCB8fCB0ZW1wQ29kZVBvaW50ID4gMHhERkZGKSkge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIHRoaXJkQnl0ZSA9IGJ1ZltpICsgMl1cbiAgICAgICAgICBmb3VydGhCeXRlID0gYnVmW2kgKyAzXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAoZm91cnRoQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHgxMiB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHhDIHwgKHRoaXJkQnl0ZSAmIDB4M0YpIDw8IDB4NiB8IChmb3VydGhCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHhGRkZGICYmIHRlbXBDb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjb2RlUG9pbnQgPT09IG51bGwpIHtcbiAgICAgIC8vIHdlIGRpZCBub3QgZ2VuZXJhdGUgYSB2YWxpZCBjb2RlUG9pbnQgc28gaW5zZXJ0IGFcbiAgICAgIC8vIHJlcGxhY2VtZW50IGNoYXIgKFUrRkZGRCkgYW5kIGFkdmFuY2Ugb25seSAxIGJ5dGVcbiAgICAgIGNvZGVQb2ludCA9IDB4RkZGRFxuICAgICAgYnl0ZXNQZXJTZXF1ZW5jZSA9IDFcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA+IDB4RkZGRikge1xuICAgICAgLy8gZW5jb2RlIHRvIHV0ZjE2IChzdXJyb2dhdGUgcGFpciBkYW5jZSlcbiAgICAgIGNvZGVQb2ludCAtPSAweDEwMDAwXG4gICAgICByZXMucHVzaChjb2RlUG9pbnQgPj4+IDEwICYgMHgzRkYgfCAweEQ4MDApXG4gICAgICBjb2RlUG9pbnQgPSAweERDMDAgfCBjb2RlUG9pbnQgJiAweDNGRlxuICAgIH1cblxuICAgIHJlcy5wdXNoKGNvZGVQb2ludClcbiAgICBpICs9IGJ5dGVzUGVyU2VxdWVuY2VcbiAgfVxuXG4gIHJldHVybiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkocmVzKVxufVxuXG4vLyBCYXNlZCBvbiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yMjc0NzI3Mi82ODA3NDIsIHRoZSBicm93c2VyIHdpdGhcbi8vIHRoZSBsb3dlc3QgbGltaXQgaXMgQ2hyb21lLCB3aXRoIDB4MTAwMDAgYXJncy5cbi8vIFdlIGdvIDEgbWFnbml0dWRlIGxlc3MsIGZvciBzYWZldHlcbnZhciBNQVhfQVJHVU1FTlRTX0xFTkdUSCA9IDB4MTAwMFxuXG5mdW5jdGlvbiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkgKGNvZGVQb2ludHMpIHtcbiAgdmFyIGxlbiA9IGNvZGVQb2ludHMubGVuZ3RoXG4gIGlmIChsZW4gPD0gTUFYX0FSR1VNRU5UU19MRU5HVEgpIHtcbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNvZGVQb2ludHMpIC8vIGF2b2lkIGV4dHJhIHNsaWNlKClcbiAgfVxuXG4gIC8vIERlY29kZSBpbiBjaHVua3MgdG8gYXZvaWQgXCJjYWxsIHN0YWNrIHNpemUgZXhjZWVkZWRcIi5cbiAgdmFyIHJlcyA9ICcnXG4gIHZhciBpID0gMFxuICB3aGlsZSAoaSA8IGxlbikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFxuICAgICAgU3RyaW5nLFxuICAgICAgY29kZVBvaW50cy5zbGljZShpLCBpICs9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKVxuICAgIClcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldICYgMHg3RilcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIGxhdGluMVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIGhleFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcblxuICBpZiAoIXN0YXJ0IHx8IHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIGlmICghZW5kIHx8IGVuZCA8IDAgfHwgZW5kID4gbGVuKSBlbmQgPSBsZW5cblxuICB2YXIgb3V0ID0gJydcbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICBvdXQgKz0gdG9IZXgoYnVmW2ldKVxuICB9XG4gIHJldHVybiBvdXRcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGJ5dGVzID0gYnVmLnNsaWNlKHN0YXJ0LCBlbmQpXG4gIHZhciByZXMgPSAnJ1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0gKyBieXRlc1tpICsgMV0gKiAyNTYpXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24gc2xpY2UgKHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIHN0YXJ0ID0gfn5zdGFydFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IGxlbiA6IH5+ZW5kXG5cbiAgaWYgKHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ICs9IGxlblxuICAgIGlmIChzdGFydCA8IDApIHN0YXJ0ID0gMFxuICB9IGVsc2UgaWYgKHN0YXJ0ID4gbGVuKSB7XG4gICAgc3RhcnQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCAwKSB7XG4gICAgZW5kICs9IGxlblxuICAgIGlmIChlbmQgPCAwKSBlbmQgPSAwXG4gIH0gZWxzZSBpZiAoZW5kID4gbGVuKSB7XG4gICAgZW5kID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgdmFyIG5ld0J1ZlxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICBuZXdCdWYgPSB0aGlzLnN1YmFycmF5KHN0YXJ0LCBlbmQpXG4gICAgbmV3QnVmLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgfSBlbHNlIHtcbiAgICB2YXIgc2xpY2VMZW4gPSBlbmQgLSBzdGFydFxuICAgIG5ld0J1ZiA9IG5ldyBCdWZmZXIoc2xpY2VMZW4sIHVuZGVmaW5lZClcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNsaWNlTGVuOyArK2kpIHtcbiAgICAgIG5ld0J1ZltpXSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuZXdCdWZcbn1cblxuLypcbiAqIE5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgYnVmZmVyIGlzbid0IHRyeWluZyB0byB3cml0ZSBvdXQgb2YgYm91bmRzLlxuICovXG5mdW5jdGlvbiBjaGVja09mZnNldCAob2Zmc2V0LCBleHQsIGxlbmd0aCkge1xuICBpZiAoKG9mZnNldCAlIDEpICE9PSAwIHx8IG9mZnNldCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdvZmZzZXQgaXMgbm90IHVpbnQnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gbGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVHJ5aW5nIHRvIGFjY2VzcyBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRMRSA9IGZ1bmN0aW9uIHJlYWRVSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRCRSA9IGZ1bmN0aW9uIHJlYWRVSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG4gIH1cblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdXG4gIHZhciBtdWwgPSAxXG4gIHdoaWxlIChieXRlTGVuZ3RoID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDggPSBmdW5jdGlvbiByZWFkVUludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2QkUgPSBmdW5jdGlvbiByZWFkVUludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgOCkgfCB0aGlzW29mZnNldCArIDFdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkxFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICgodGhpc1tvZmZzZXRdKSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikpICtcbiAgICAgICh0aGlzW29mZnNldCArIDNdICogMHgxMDAwMDAwKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdICogMHgxMDAwMDAwKSArXG4gICAgKCh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgIHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludExFID0gZnVuY3Rpb24gcmVhZEludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG4gIG11bCAqPSAweDgwXG5cbiAgaWYgKHZhbCA+PSBtdWwpIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludEJFID0gZnVuY3Rpb24gcmVhZEludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoXG4gIHZhciBtdWwgPSAxXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0taV1cbiAgd2hpbGUgKGkgPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1pXSAqIG11bFxuICB9XG4gIG11bCAqPSAweDgwXG5cbiAgaWYgKHZhbCA+PSBtdWwpIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDggPSBmdW5jdGlvbiByZWFkSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICBpZiAoISh0aGlzW29mZnNldF0gJiAweDgwKSkgcmV0dXJuICh0aGlzW29mZnNldF0pXG4gIHJldHVybiAoKDB4ZmYgLSB0aGlzW29mZnNldF0gKyAxKSAqIC0xKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkxFID0gZnVuY3Rpb24gcmVhZEludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIDFdIHwgKHRoaXNbb2Zmc2V0XSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyTEUgPSBmdW5jdGlvbiByZWFkSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdKSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgM10gPDwgMjQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyQkUgPSBmdW5jdGlvbiByZWFkSW50MzJCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDI0KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0TEUgPSBmdW5jdGlvbiByZWFkRmxvYXRMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgdHJ1ZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0QkUgPSBmdW5jdGlvbiByZWFkRmxvYXRCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVMRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgdHJ1ZSwgNTIsIDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUJFID0gZnVuY3Rpb24gcmVhZERvdWJsZUJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgNTIsIDgpXG59XG5cbmZ1bmN0aW9uIGNoZWNrSW50IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJidWZmZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyIGluc3RhbmNlJylcbiAgaWYgKHZhbHVlID4gbWF4IHx8IHZhbHVlIDwgbWluKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IGlzIG91dCBvZiBib3VuZHMnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBtYXhCeXRlcyA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSAtIDFcbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBtYXhCeXRlcywgMClcbiAgfVxuXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBtYXhCeXRlcyA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSAtIDFcbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBtYXhCeXRlcywgMClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50OCA9IGZ1bmN0aW9uIHdyaXRlVUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHhmZiwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkgdmFsdWUgPSBNYXRoLmZsb29yKHZhbHVlKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQxNiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCAyKTsgaSA8IGo7ICsraSkge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSAmICgweGZmIDw8ICg4ICogKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkpKSkgPj4+XG4gICAgICAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSAqIDhcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQzMiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4oYnVmLmxlbmd0aCAtIG9mZnNldCwgNCk7IGkgPCBqOyArK2kpIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSAodmFsdWUgPj4+IChsaXR0bGVFbmRpYW4gPyBpIDogMyAtIGkpICogOCkgJiAweGZmXG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50TEUgPSBmdW5jdGlvbiB3cml0ZUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gMFxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICBpZiAodmFsdWUgPCAwICYmIHN1YiA9PT0gMCAmJiB0aGlzW29mZnNldCArIGkgLSAxXSAhPT0gMCkge1xuICAgICAgc3ViID0gMVxuICAgIH1cbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50QkUgPSBmdW5jdGlvbiB3cml0ZUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IDBcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICBpZiAodmFsdWUgPCAwICYmIHN1YiA9PT0gMCAmJiB0aGlzW29mZnNldCArIGkgKyAxXSAhPT0gMCkge1xuICAgICAgc3ViID0gMVxuICAgIH1cbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50OCA9IGZ1bmN0aW9uIHdyaXRlSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweDdmLCAtMHg4MClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkgdmFsdWUgPSBNYXRoLmZsb29yKHZhbHVlKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmYgKyB2YWx1ZSArIDFcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmZmZmZiArIHZhbHVlICsgMVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuZnVuY3Rpb24gY2hlY2tJRUVFNzU0IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxuICBpZiAob2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvYXQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgNCwgMy40MDI4MjM0NjYzODUyODg2ZSszOCwgLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFID0gZnVuY3Rpb24gd3JpdGVGbG9hdExFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gd3JpdGVEb3VibGUgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgOCwgMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgsIC0xLjc5NzY5MzEzNDg2MjMxNTdFKzMwOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCA1MiwgOClcbiAgcmV0dXJuIG9mZnNldCArIDhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUxFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG4vLyBjb3B5KHRhcmdldEJ1ZmZlciwgdGFyZ2V0U3RhcnQ9MCwgc291cmNlU3RhcnQ9MCwgc291cmNlRW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiBjb3B5ICh0YXJnZXQsIHRhcmdldFN0YXJ0LCBzdGFydCwgZW5kKSB7XG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCAmJiBlbmQgIT09IDApIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXRTdGFydCA+PSB0YXJnZXQubGVuZ3RoKSB0YXJnZXRTdGFydCA9IHRhcmdldC5sZW5ndGhcbiAgaWYgKCF0YXJnZXRTdGFydCkgdGFyZ2V0U3RhcnQgPSAwXG4gIGlmIChlbmQgPiAwICYmIGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIC8vIENvcHkgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuIDBcbiAgaWYgKHRhcmdldC5sZW5ndGggPT09IDAgfHwgdGhpcy5sZW5ndGggPT09IDApIHJldHVybiAwXG5cbiAgLy8gRmF0YWwgZXJyb3IgY29uZGl0aW9uc1xuICBpZiAodGFyZ2V0U3RhcnQgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICB9XG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VFbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgLy8gQXJlIHdlIG9vYj9cbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0IDwgZW5kIC0gc3RhcnQpIHtcbiAgICBlbmQgPSB0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgKyBzdGFydFxuICB9XG5cbiAgdmFyIGxlbiA9IGVuZCAtIHN0YXJ0XG4gIHZhciBpXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCAmJiBzdGFydCA8IHRhcmdldFN0YXJ0ICYmIHRhcmdldFN0YXJ0IDwgZW5kKSB7XG4gICAgLy8gZGVzY2VuZGluZyBjb3B5IGZyb20gZW5kXG4gICAgZm9yIChpID0gbGVuIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2UgaWYgKGxlbiA8IDEwMDAgfHwgIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gYXNjZW5kaW5nIGNvcHkgZnJvbSBzdGFydFxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgVWludDhBcnJheS5wcm90b3R5cGUuc2V0LmNhbGwoXG4gICAgICB0YXJnZXQsXG4gICAgICB0aGlzLnN1YmFycmF5KHN0YXJ0LCBzdGFydCArIGxlbiksXG4gICAgICB0YXJnZXRTdGFydFxuICAgIClcbiAgfVxuXG4gIHJldHVybiBsZW5cbn1cblxuLy8gVXNhZ2U6XG4vLyAgICBidWZmZXIuZmlsbChudW1iZXJbLCBvZmZzZXRbLCBlbmRdXSlcbi8vICAgIGJ1ZmZlci5maWxsKGJ1ZmZlclssIG9mZnNldFssIGVuZF1dKVxuLy8gICAgYnVmZmVyLmZpbGwoc3RyaW5nWywgb2Zmc2V0WywgZW5kXV1bLCBlbmNvZGluZ10pXG5CdWZmZXIucHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbiBmaWxsICh2YWwsIHN0YXJ0LCBlbmQsIGVuY29kaW5nKSB7XG4gIC8vIEhhbmRsZSBzdHJpbmcgY2FzZXM6XG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIGlmICh0eXBlb2Ygc3RhcnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IHN0YXJ0XG4gICAgICBzdGFydCA9IDBcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZW5kID09PSAnc3RyaW5nJykge1xuICAgICAgZW5jb2RpbmcgPSBlbmRcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfVxuICAgIGlmICh2YWwubGVuZ3RoID09PSAxKSB7XG4gICAgICB2YXIgY29kZSA9IHZhbC5jaGFyQ29kZUF0KDApXG4gICAgICBpZiAoY29kZSA8IDI1Nikge1xuICAgICAgICB2YWwgPSBjb2RlXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2VuY29kaW5nIG11c3QgYmUgYSBzdHJpbmcnKVxuICAgIH1cbiAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJyAmJiAhQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgdmFsID0gdmFsICYgMjU1XG4gIH1cblxuICAvLyBJbnZhbGlkIHJhbmdlcyBhcmUgbm90IHNldCB0byBhIGRlZmF1bHQsIHNvIGNhbiByYW5nZSBjaGVjayBlYXJseS5cbiAgaWYgKHN0YXJ0IDwgMCB8fCB0aGlzLmxlbmd0aCA8IHN0YXJ0IHx8IHRoaXMubGVuZ3RoIDwgZW5kKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ091dCBvZiByYW5nZSBpbmRleCcpXG4gIH1cblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIHN0YXJ0ID0gc3RhcnQgPj4+IDBcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyB0aGlzLmxlbmd0aCA6IGVuZCA+Pj4gMFxuXG4gIGlmICghdmFsKSB2YWwgPSAwXG5cbiAgdmFyIGlcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgICAgdGhpc1tpXSA9IHZhbFxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgYnl0ZXMgPSBCdWZmZXIuaXNCdWZmZXIodmFsKVxuICAgICAgPyB2YWxcbiAgICAgIDogdXRmOFRvQnl0ZXMobmV3IEJ1ZmZlcih2YWwsIGVuY29kaW5nKS50b1N0cmluZygpKVxuICAgIHZhciBsZW4gPSBieXRlcy5sZW5ndGhcbiAgICBmb3IgKGkgPSAwOyBpIDwgZW5kIC0gc3RhcnQ7ICsraSkge1xuICAgICAgdGhpc1tpICsgc3RhcnRdID0gYnl0ZXNbaSAlIGxlbl1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpc1xufVxuXG4vLyBIRUxQRVIgRlVOQ1RJT05TXG4vLyA9PT09PT09PT09PT09PT09XG5cbnZhciBJTlZBTElEX0JBU0U2NF9SRSA9IC9bXitcXC8wLTlBLVphLXotX10vZ1xuXG5mdW5jdGlvbiBiYXNlNjRjbGVhbiAoc3RyKSB7XG4gIC8vIE5vZGUgc3RyaXBzIG91dCBpbnZhbGlkIGNoYXJhY3RlcnMgbGlrZSBcXG4gYW5kIFxcdCBmcm9tIHRoZSBzdHJpbmcsIGJhc2U2NC1qcyBkb2VzIG5vdFxuICBzdHIgPSBzdHJpbmd0cmltKHN0cikucmVwbGFjZShJTlZBTElEX0JBU0U2NF9SRSwgJycpXG4gIC8vIE5vZGUgY29udmVydHMgc3RyaW5ncyB3aXRoIGxlbmd0aCA8IDIgdG8gJydcbiAgaWYgKHN0ci5sZW5ndGggPCAyKSByZXR1cm4gJydcbiAgLy8gTm9kZSBhbGxvd3MgZm9yIG5vbi1wYWRkZWQgYmFzZTY0IHN0cmluZ3MgKG1pc3NpbmcgdHJhaWxpbmcgPT09KSwgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHdoaWxlIChzdHIubGVuZ3RoICUgNCAhPT0gMCkge1xuICAgIHN0ciA9IHN0ciArICc9J1xuICB9XG4gIHJldHVybiBzdHJcbn1cblxuZnVuY3Rpb24gc3RyaW5ndHJpbSAoc3RyKSB7XG4gIGlmIChzdHIudHJpbSkgcmV0dXJuIHN0ci50cmltKClcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCAnJylcbn1cblxuZnVuY3Rpb24gdG9IZXggKG4pIHtcbiAgaWYgKG4gPCAxNikgcmV0dXJuICcwJyArIG4udG9TdHJpbmcoMTYpXG4gIHJldHVybiBuLnRvU3RyaW5nKDE2KVxufVxuXG5mdW5jdGlvbiB1dGY4VG9CeXRlcyAoc3RyaW5nLCB1bml0cykge1xuICB1bml0cyA9IHVuaXRzIHx8IEluZmluaXR5XG4gIHZhciBjb2RlUG9pbnRcbiAgdmFyIGxlbmd0aCA9IHN0cmluZy5sZW5ndGhcbiAgdmFyIGxlYWRTdXJyb2dhdGUgPSBudWxsXG4gIHZhciBieXRlcyA9IFtdXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGNvZGVQb2ludCA9IHN0cmluZy5jaGFyQ29kZUF0KGkpXG5cbiAgICAvLyBpcyBzdXJyb2dhdGUgY29tcG9uZW50XG4gICAgaWYgKGNvZGVQb2ludCA+IDB4RDdGRiAmJiBjb2RlUG9pbnQgPCAweEUwMDApIHtcbiAgICAgIC8vIGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoIWxlYWRTdXJyb2dhdGUpIHtcbiAgICAgICAgLy8gbm8gbGVhZCB5ZXRcbiAgICAgICAgaWYgKGNvZGVQb2ludCA+IDB4REJGRikge1xuICAgICAgICAgIC8vIHVuZXhwZWN0ZWQgdHJhaWxcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9IGVsc2UgaWYgKGkgKyAxID09PSBsZW5ndGgpIHtcbiAgICAgICAgICAvLyB1bnBhaXJlZCBsZWFkXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHZhbGlkIGxlYWRcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIDIgbGVhZHMgaW4gYSByb3dcbiAgICAgIGlmIChjb2RlUG9pbnQgPCAweERDMDApIHtcbiAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gdmFsaWQgc3Vycm9nYXRlIHBhaXJcbiAgICAgIGNvZGVQb2ludCA9IChsZWFkU3Vycm9nYXRlIC0gMHhEODAwIDw8IDEwIHwgY29kZVBvaW50IC0gMHhEQzAwKSArIDB4MTAwMDBcbiAgICB9IGVsc2UgaWYgKGxlYWRTdXJyb2dhdGUpIHtcbiAgICAgIC8vIHZhbGlkIGJtcCBjaGFyLCBidXQgbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgIH1cblxuICAgIGxlYWRTdXJyb2dhdGUgPSBudWxsXG5cbiAgICAvLyBlbmNvZGUgdXRmOFxuICAgIGlmIChjb2RlUG9pbnQgPCAweDgwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDEpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goY29kZVBvaW50KVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHg4MDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiB8IDB4QzAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDMpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgfCAweEUwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSA0KSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHgxMiB8IDB4RjAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29kZSBwb2ludCcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7ICsraSkge1xuICAgIC8vIE5vZGUncyBjb2RlIHNlZW1zIHRvIGJlIGRvaW5nIHRoaXMgYW5kIG5vdCAmIDB4N0YuLlxuICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpICYgMHhGRilcbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVUb0J5dGVzIChzdHIsIHVuaXRzKSB7XG4gIHZhciBjLCBoaSwgbG9cbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG5cbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSlcbiAgICBoaSA9IGMgPj4gOFxuICAgIGxvID0gYyAlIDI1NlxuICAgIGJ5dGVBcnJheS5wdXNoKGxvKVxuICAgIGJ5dGVBcnJheS5wdXNoKGhpKVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiBiYXNlNjRUb0J5dGVzIChzdHIpIHtcbiAgcmV0dXJuIGJhc2U2NC50b0J5dGVBcnJheShiYXNlNjRjbGVhbihzdHIpKVxufVxuXG5mdW5jdGlvbiBibGl0QnVmZmVyIChzcmMsIGRzdCwgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGlmICgoaSArIG9mZnNldCA+PSBkc3QubGVuZ3RoKSB8fCAoaSA+PSBzcmMubGVuZ3RoKSkgYnJlYWtcbiAgICBkc3RbaSArIG9mZnNldF0gPSBzcmNbaV1cbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiBpc25hbiAodmFsKSB7XG4gIHJldHVybiB2YWwgIT09IHZhbCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNlbGYtY29tcGFyZVxufVxuXG4vKiBXRUJQQUNLIFZBUiBJTkpFQ1RJT04gKi99LmNhbGwoZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXygwKSkpXG5cbi8qKiovIH0pLFxuLyogMiAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG4vKiBXRUJQQUNLIFZBUiBJTkpFQ1RJT04gKi8oZnVuY3Rpb24oZ2xvYmFsLCBCdWZmZXIpIHsoZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xuXHQgdHJ1ZSA/IGZhY3RvcnkoZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyg2KSwgX193ZWJwYWNrX3JlcXVpcmVfXygxKSkgOlxuXHR0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoWydleHBvcnRzJywgJ2xvbmcnLCAnYnVmZmVyJ10sIGZhY3RvcnkpIDpcblx0KGZhY3RvcnkoKGdsb2JhbC5CU09OID0ge30pLGdsb2JhbC5sb25nLGdsb2JhbC5CdWZmZXIpKTtcbn0odGhpcywgKGZ1bmN0aW9uIChleHBvcnRzLGxvbmcsYnVmZmVyKSB7ICd1c2Ugc3RyaWN0JztcblxuXHRsb25nID0gbG9uZyAmJiBsb25nLmhhc093blByb3BlcnR5KCdkZWZhdWx0JykgPyBsb25nWydkZWZhdWx0J10gOiBsb25nO1xuXHRidWZmZXIgPSBidWZmZXIgJiYgYnVmZmVyLmhhc093blByb3BlcnR5KCdkZWZhdWx0JykgPyBidWZmZXJbJ2RlZmF1bHQnXSA6IGJ1ZmZlcjtcblxuXHR2YXIgY29tbW9uanNHbG9iYWwgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6IHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09ICd1bmRlZmluZWQnID8gc2VsZiA6IHt9O1xuXG5cdGZ1bmN0aW9uIGNyZWF0ZUNvbW1vbmpzTW9kdWxlKGZuLCBtb2R1bGUpIHtcblx0XHRyZXR1cm4gbW9kdWxlID0geyBleHBvcnRzOiB7fSB9LCBmbihtb2R1bGUsIG1vZHVsZS5leHBvcnRzKSwgbW9kdWxlLmV4cG9ydHM7XG5cdH1cblxuXHRmdW5jdGlvbiBnZXRDanNFeHBvcnRGcm9tTmFtZXNwYWNlIChuKSB7XG5cdFx0cmV0dXJuIG4gJiYgbi5kZWZhdWx0IHx8IG47XG5cdH1cblxuXHR2YXIgbWFwID0gY3JlYXRlQ29tbW9uanNNb2R1bGUoZnVuY3Rpb24gKG1vZHVsZSkge1xuXG5cdCAgaWYgKHR5cGVvZiBjb21tb25qc0dsb2JhbC5NYXAgIT09ICd1bmRlZmluZWQnKSB7XG5cdCAgICBtb2R1bGUuZXhwb3J0cyA9IGNvbW1vbmpzR2xvYmFsLk1hcDtcblx0ICAgIG1vZHVsZS5leHBvcnRzLk1hcCA9IGNvbW1vbmpzR2xvYmFsLk1hcDtcblx0ICB9IGVsc2Uge1xuXHQgICAgLy8gV2Ugd2lsbCByZXR1cm4gYSBwb2x5ZmlsbFxuXHQgICAgdmFyIE1hcCA9IGZ1bmN0aW9uIE1hcChhcnJheSkge1xuXHQgICAgICB0aGlzLl9rZXlzID0gW107XG5cdCAgICAgIHRoaXMuX3ZhbHVlcyA9IHt9O1xuXG5cdCAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICBpZiAoYXJyYXlbaV0gPT0gbnVsbCkgY29udGludWU7IC8vIHNraXAgbnVsbCBhbmQgdW5kZWZpbmVkXG5cblx0ICAgICAgICB2YXIgZW50cnkgPSBhcnJheVtpXTtcblx0ICAgICAgICB2YXIga2V5ID0gZW50cnlbMF07XG5cdCAgICAgICAgdmFyIHZhbHVlID0gZW50cnlbMV07IC8vIEFkZCB0aGUga2V5IHRvIHRoZSBsaXN0IG9mIGtleXMgaW4gb3JkZXJcblxuXHQgICAgICAgIHRoaXMuX2tleXMucHVzaChrZXkpOyAvLyBBZGQgdGhlIGtleSBhbmQgdmFsdWUgdG8gdGhlIHZhbHVlcyBkaWN0aW9uYXJ5IHdpdGggYSBwb2ludFxuXHQgICAgICAgIC8vIHRvIHRoZSBsb2NhdGlvbiBpbiB0aGUgb3JkZXJlZCBrZXlzIGxpc3RcblxuXG5cdCAgICAgICAgdGhpcy5fdmFsdWVzW2tleV0gPSB7XG5cdCAgICAgICAgICB2OiB2YWx1ZSxcblx0ICAgICAgICAgIGk6IHRoaXMuX2tleXMubGVuZ3RoIC0gMVxuXHQgICAgICAgIH07XG5cdCAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIE1hcC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgIHRoaXMuX2tleXMgPSBbXTtcblx0ICAgICAgdGhpcy5fdmFsdWVzID0ge307XG5cdCAgICB9O1xuXG5cdCAgICBNYXAucHJvdG90eXBlLmRlbGV0ZSA9IGZ1bmN0aW9uIChrZXkpIHtcblx0ICAgICAgdmFyIHZhbHVlID0gdGhpcy5fdmFsdWVzW2tleV07XG5cdCAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSByZXR1cm4gZmFsc2U7IC8vIERlbGV0ZSBlbnRyeVxuXG5cdCAgICAgIGRlbGV0ZSB0aGlzLl92YWx1ZXNba2V5XTsgLy8gUmVtb3ZlIHRoZSBrZXkgZnJvbSB0aGUgb3JkZXJlZCBrZXlzIGxpc3RcblxuXHQgICAgICB0aGlzLl9rZXlzLnNwbGljZSh2YWx1ZS5pLCAxKTtcblxuXHQgICAgICByZXR1cm4gdHJ1ZTtcblx0ICAgIH07XG5cblx0ICAgIE1hcC5wcm90b3R5cGUuZW50cmllcyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuXHQgICAgICB2YXIgaW5kZXggPSAwO1xuXHQgICAgICByZXR1cm4ge1xuXHQgICAgICAgIG5leHQ6IGZ1bmN0aW9uIG5leHQoKSB7XG5cdCAgICAgICAgICB2YXIga2V5ID0gc2VsZi5fa2V5c1tpbmRleCsrXTtcblx0ICAgICAgICAgIHJldHVybiB7XG5cdCAgICAgICAgICAgIHZhbHVlOiBrZXkgIT09IHVuZGVmaW5lZCA/IFtrZXksIHNlbGYuX3ZhbHVlc1trZXldLnZdIDogdW5kZWZpbmVkLFxuXHQgICAgICAgICAgICBkb25lOiBrZXkgIT09IHVuZGVmaW5lZCA/IGZhbHNlIDogdHJ1ZVxuXHQgICAgICAgICAgfTtcblx0ICAgICAgICB9XG5cdCAgICAgIH07XG5cdCAgICB9O1xuXG5cdCAgICBNYXAucHJvdG90eXBlLmZvckVhY2ggPSBmdW5jdGlvbiAoY2FsbGJhY2ssIHNlbGYpIHtcblx0ICAgICAgc2VsZiA9IHNlbGYgfHwgdGhpcztcblxuXHQgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuX2tleXMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICB2YXIga2V5ID0gdGhpcy5fa2V5c1tpXTsgLy8gQ2FsbCB0aGUgZm9yRWFjaCBjYWxsYmFja1xuXG5cdCAgICAgICAgY2FsbGJhY2suY2FsbChzZWxmLCB0aGlzLl92YWx1ZXNba2V5XS52LCBrZXksIHNlbGYpO1xuXHQgICAgICB9XG5cdCAgICB9O1xuXG5cdCAgICBNYXAucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChrZXkpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlc1trZXldID8gdGhpcy5fdmFsdWVzW2tleV0udiA6IHVuZGVmaW5lZDtcblx0ICAgIH07XG5cblx0ICAgIE1hcC5wcm90b3R5cGUuaGFzID0gZnVuY3Rpb24gKGtleSkge1xuXHQgICAgICByZXR1cm4gdGhpcy5fdmFsdWVzW2tleV0gIT0gbnVsbDtcblx0ICAgIH07XG5cblx0ICAgIE1hcC5wcm90b3R5cGUua2V5cyA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuXHQgICAgICB2YXIgaW5kZXggPSAwO1xuXHQgICAgICByZXR1cm4ge1xuXHQgICAgICAgIG5leHQ6IGZ1bmN0aW9uIG5leHQoKSB7XG5cdCAgICAgICAgICB2YXIga2V5ID0gc2VsZi5fa2V5c1tpbmRleCsrXTtcblx0ICAgICAgICAgIHJldHVybiB7XG5cdCAgICAgICAgICAgIHZhbHVlOiBrZXkgIT09IHVuZGVmaW5lZCA/IGtleSA6IHVuZGVmaW5lZCxcblx0ICAgICAgICAgICAgZG9uZToga2V5ICE9PSB1bmRlZmluZWQgPyBmYWxzZSA6IHRydWVcblx0ICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXHQgICAgICB9O1xuXHQgICAgfTtcblxuXHQgICAgTWFwLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuXHQgICAgICBpZiAodGhpcy5fdmFsdWVzW2tleV0pIHtcblx0ICAgICAgICB0aGlzLl92YWx1ZXNba2V5XS52ID0gdmFsdWU7XG5cdCAgICAgICAgcmV0dXJuIHRoaXM7XG5cdCAgICAgIH0gLy8gQWRkIHRoZSBrZXkgdG8gdGhlIGxpc3Qgb2Yga2V5cyBpbiBvcmRlclxuXG5cblx0ICAgICAgdGhpcy5fa2V5cy5wdXNoKGtleSk7IC8vIEFkZCB0aGUga2V5IGFuZCB2YWx1ZSB0byB0aGUgdmFsdWVzIGRpY3Rpb25hcnkgd2l0aCBhIHBvaW50XG5cdCAgICAgIC8vIHRvIHRoZSBsb2NhdGlvbiBpbiB0aGUgb3JkZXJlZCBrZXlzIGxpc3RcblxuXG5cdCAgICAgIHRoaXMuX3ZhbHVlc1trZXldID0ge1xuXHQgICAgICAgIHY6IHZhbHVlLFxuXHQgICAgICAgIGk6IHRoaXMuX2tleXMubGVuZ3RoIC0gMVxuXHQgICAgICB9O1xuXHQgICAgICByZXR1cm4gdGhpcztcblx0ICAgIH07XG5cblx0ICAgIE1hcC5wcm90b3R5cGUudmFsdWVzID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICB2YXIgc2VsZiA9IHRoaXM7XG5cdCAgICAgIHZhciBpbmRleCA9IDA7XG5cdCAgICAgIHJldHVybiB7XG5cdCAgICAgICAgbmV4dDogZnVuY3Rpb24gbmV4dCgpIHtcblx0ICAgICAgICAgIHZhciBrZXkgPSBzZWxmLl9rZXlzW2luZGV4KytdO1xuXHQgICAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgdmFsdWU6IGtleSAhPT0gdW5kZWZpbmVkID8gc2VsZi5fdmFsdWVzW2tleV0udiA6IHVuZGVmaW5lZCxcblx0ICAgICAgICAgICAgZG9uZToga2V5ICE9PSB1bmRlZmluZWQgPyBmYWxzZSA6IHRydWVcblx0ICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXHQgICAgICB9O1xuXHQgICAgfTsgLy8gTGFzdCBpc21hc3RlclxuXG5cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShNYXAucHJvdG90eXBlLCAnc2l6ZScsIHtcblx0ICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcblx0ICAgICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX2tleXMubGVuZ3RoO1xuXHQgICAgICB9XG5cdCAgICB9KTtcblx0ICAgIG1vZHVsZS5leHBvcnRzID0gTWFwO1xuXHQgIH1cblx0fSk7XG5cdHZhciBtYXBfMSA9IG1hcC5NYXA7XG5cblx0LyoqXG5cdCAqIEBpZ25vcmVcblx0ICovXG5cblxuXHRsb25nLnByb3RvdHlwZS50b0V4dGVuZGVkSlNPTiA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG5cdCAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5yZWxheGVkKSByZXR1cm4gdGhpcy50b051bWJlcigpO1xuXHQgIHJldHVybiB7XG5cdCAgICAkbnVtYmVyTG9uZzogdGhpcy50b1N0cmluZygpXG5cdCAgfTtcblx0fTtcblx0LyoqXG5cdCAqIEBpZ25vcmVcblx0ICovXG5cblxuXHRsb25nLmZyb21FeHRlbmRlZEpTT04gPSBmdW5jdGlvbiAoZG9jLCBvcHRpb25zKSB7XG5cdCAgdmFyIHJlc3VsdCA9IGxvbmcuZnJvbVN0cmluZyhkb2MuJG51bWJlckxvbmcpO1xuXHQgIHJldHVybiBvcHRpb25zICYmIG9wdGlvbnMucmVsYXhlZCA/IHJlc3VsdC50b051bWJlcigpIDogcmVzdWx0O1xuXHR9O1xuXG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShsb25nLnByb3RvdHlwZSwgJ19ic29udHlwZScsIHtcblx0ICB2YWx1ZTogJ0xvbmcnXG5cdH0pO1xuXHR2YXIgbG9uZ18xID0gbG9uZztcblxuXHQvKipcblx0ICogQSBjbGFzcyByZXByZXNlbnRhdGlvbiBvZiB0aGUgQlNPTiBEb3VibGUgdHlwZS5cblx0ICovXG5cblx0ZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxuXHRmdW5jdGlvbiBfZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9XG5cblx0ZnVuY3Rpb24gX2NyZWF0ZUNsYXNzKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgX2RlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH1cblxuXHR2YXIgRG91YmxlID1cblx0LyojX19QVVJFX18qL1xuXHRmdW5jdGlvbiAoKSB7XG5cdCAgLyoqXG5cdCAgICogQ3JlYXRlIGEgRG91YmxlIHR5cGVcblx0ICAgKlxuXHQgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSB0aGUgbnVtYmVyIHdlIHdhbnQgdG8gcmVwcmVzZW50IGFzIGEgZG91YmxlLlxuXHQgICAqIEByZXR1cm4ge0RvdWJsZX1cblx0ICAgKi9cblx0ICBmdW5jdGlvbiBEb3VibGUodmFsdWUpIHtcblx0ICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBEb3VibGUpO1xuXG5cdCAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG5cdCAgfVxuXHQgIC8qKlxuXHQgICAqIEFjY2VzcyB0aGUgbnVtYmVyIHZhbHVlLlxuXHQgICAqXG5cdCAgICogQG1ldGhvZFxuXHQgICAqIEByZXR1cm4ge251bWJlcn0gcmV0dXJucyB0aGUgd3JhcHBlZCBkb3VibGUgbnVtYmVyLlxuXHQgICAqL1xuXG5cblx0ICBfY3JlYXRlQ2xhc3MoRG91YmxlLCBbe1xuXHQgICAga2V5OiBcInZhbHVlT2ZcIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB2YWx1ZU9mKCkge1xuXHQgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwidG9KU09OXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gdG9KU09OKCkge1xuXHQgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwidG9FeHRlbmRlZEpTT05cIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB0b0V4dGVuZGVkSlNPTihvcHRpb25zKSB7XG5cdCAgICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMucmVsYXhlZCAmJiBpc0Zpbml0ZSh0aGlzLnZhbHVlKSkgcmV0dXJuIHRoaXMudmFsdWU7XG5cdCAgICAgIHJldHVybiB7XG5cdCAgICAgICAgJG51bWJlckRvdWJsZTogdGhpcy52YWx1ZS50b1N0cmluZygpXG5cdCAgICAgIH07XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEBpZ25vcmVcblx0ICAgICAqL1xuXG5cdCAgfV0sIFt7XG5cdCAgICBrZXk6IFwiZnJvbUV4dGVuZGVkSlNPTlwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIGZyb21FeHRlbmRlZEpTT04oZG9jLCBvcHRpb25zKSB7XG5cdCAgICAgIHJldHVybiBvcHRpb25zICYmIG9wdGlvbnMucmVsYXhlZCA/IHBhcnNlRmxvYXQoZG9jLiRudW1iZXJEb3VibGUpIDogbmV3IERvdWJsZShwYXJzZUZsb2F0KGRvYy4kbnVtYmVyRG91YmxlKSk7XG5cdCAgICB9XG5cdCAgfV0pO1xuXG5cdCAgcmV0dXJuIERvdWJsZTtcblx0fSgpO1xuXG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShEb3VibGUucHJvdG90eXBlLCAnX2Jzb250eXBlJywge1xuXHQgIHZhbHVlOiAnRG91YmxlJ1xuXHR9KTtcblx0dmFyIGRvdWJsZV8xID0gRG91YmxlO1xuXG5cdGZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7IGlmICh0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIikgeyBfdHlwZW9mID0gZnVuY3Rpb24gX3R5cGVvZihvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH07IH0gZWxzZSB7IF90eXBlb2YgPSBmdW5jdGlvbiBfdHlwZW9mKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajsgfTsgfSByZXR1cm4gX3R5cGVvZihvYmopOyB9XG5cblx0ZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrJDEoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG5cdGZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzJDEodGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfVxuXG5cdGZ1bmN0aW9uIF9jcmVhdGVDbGFzcyQxKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgX2RlZmluZVByb3BlcnRpZXMkMShDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzJDEoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9XG5cblx0ZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoY2FsbCAmJiAoX3R5cGVvZihjYWxsKSA9PT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgY2FsbCA9PT0gXCJmdW5jdGlvblwiKSkgeyByZXR1cm4gY2FsbDsgfSByZXR1cm4gX2Fzc2VydFRoaXNJbml0aWFsaXplZChzZWxmKTsgfVxuXG5cdGZ1bmN0aW9uIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoc2VsZikgeyBpZiAoc2VsZiA9PT0gdm9pZCAwKSB7IHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcihcInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZFwiKTsgfSByZXR1cm4gc2VsZjsgfVxuXG5cdGZ1bmN0aW9uIF9nZXRQcm90b3R5cGVPZihvKSB7IF9nZXRQcm90b3R5cGVPZiA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5nZXRQcm90b3R5cGVPZiA6IGZ1bmN0aW9uIF9nZXRQcm90b3R5cGVPZihvKSB7IHJldHVybiBvLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2Yobyk7IH07IHJldHVybiBfZ2V0UHJvdG90eXBlT2Yobyk7IH1cblxuXHRmdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSBcImZ1bmN0aW9uXCIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb25cIik7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgX3NldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKTsgfVxuXG5cdGZ1bmN0aW9uIF9zZXRQcm90b3R5cGVPZihvLCBwKSB7IF9zZXRQcm90b3R5cGVPZiA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCBmdW5jdGlvbiBfc2V0UHJvdG90eXBlT2YobywgcCkgeyBvLl9fcHJvdG9fXyA9IHA7IHJldHVybiBvOyB9OyByZXR1cm4gX3NldFByb3RvdHlwZU9mKG8sIHApOyB9XG5cdC8qKlxuXHQgKiBAY2xhc3Ncblx0ICogQHBhcmFtIHtudW1iZXJ9IGxvdyAgdGhlIGxvdyAoc2lnbmVkKSAzMiBiaXRzIG9mIHRoZSBUaW1lc3RhbXAuXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBoaWdoIHRoZSBoaWdoIChzaWduZWQpIDMyIGJpdHMgb2YgdGhlIFRpbWVzdGFtcC5cblx0ICogQHJldHVybiB7VGltZXN0YW1wfVxuXHQgKi9cblxuXG5cdHZhciBUaW1lc3RhbXAgPVxuXHQvKiNfX1BVUkVfXyovXG5cdGZ1bmN0aW9uIChfTG9uZykge1xuXHQgIF9pbmhlcml0cyhUaW1lc3RhbXAsIF9Mb25nKTtcblxuXHQgIGZ1bmN0aW9uIFRpbWVzdGFtcChsb3csIGhpZ2gpIHtcblx0ICAgIHZhciBfdGhpcztcblxuXHQgICAgX2NsYXNzQ2FsbENoZWNrJDEodGhpcywgVGltZXN0YW1wKTtcblxuXHQgICAgaWYgKGxvbmdfMS5pc0xvbmcobG93KSkge1xuXHQgICAgICBfdGhpcyA9IF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIF9nZXRQcm90b3R5cGVPZihUaW1lc3RhbXApLmNhbGwodGhpcywgbG93LmxvdywgbG93LmhpZ2gpKTtcblx0ICAgIH0gZWxzZSB7XG5cdCAgICAgIF90aGlzID0gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgX2dldFByb3RvdHlwZU9mKFRpbWVzdGFtcCkuY2FsbCh0aGlzLCBsb3csIGhpZ2gpKTtcblx0ICAgIH1cblxuXHQgICAgcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKF90aGlzKTtcblx0ICB9XG5cdCAgLyoqXG5cdCAgICogUmV0dXJuIHRoZSBKU09OIHZhbHVlLlxuXHQgICAqXG5cdCAgICogQG1ldGhvZFxuXHQgICAqIEByZXR1cm4ge1N0cmluZ30gdGhlIEpTT04gcmVwcmVzZW50YXRpb24uXG5cdCAgICovXG5cblxuXHQgIF9jcmVhdGVDbGFzcyQxKFRpbWVzdGFtcCwgW3tcblx0ICAgIGtleTogXCJ0b0pTT05cIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB0b0pTT04oKSB7XG5cdCAgICAgIHJldHVybiB7XG5cdCAgICAgICAgJHRpbWVzdGFtcDogdGhpcy50b1N0cmluZygpXG5cdCAgICAgIH07XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgYSBUaW1lc3RhbXAgcmVwcmVzZW50ZWQgYnkgdGhlIGdpdmVuICgzMi1iaXQpIGludGVnZXIgdmFsdWUuXG5cdCAgICAgKlxuXHQgICAgICogQG1ldGhvZFxuXHQgICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIHRoZSAzMi1iaXQgaW50ZWdlciBpbiBxdWVzdGlvbi5cblx0ICAgICAqIEByZXR1cm4ge1RpbWVzdGFtcH0gdGhlIHRpbWVzdGFtcC5cblx0ICAgICAqL1xuXG5cdCAgfSwge1xuXHQgICAga2V5OiBcInRvRXh0ZW5kZWRKU09OXCIsXG5cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gdG9FeHRlbmRlZEpTT04oKSB7XG5cdCAgICAgIHJldHVybiB7XG5cdCAgICAgICAgJHRpbWVzdGFtcDoge1xuXHQgICAgICAgICAgdDogdGhpcy5oaWdoLFxuXHQgICAgICAgICAgaTogdGhpcy5sb3dcblx0ICAgICAgICB9XG5cdCAgICAgIH07XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEBpZ25vcmVcblx0ICAgICAqL1xuXG5cdCAgfV0sIFt7XG5cdCAgICBrZXk6IFwiZnJvbUludFwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIGZyb21JbnQodmFsdWUpIHtcblx0ICAgICAgcmV0dXJuIG5ldyBUaW1lc3RhbXAobG9uZ18xLmZyb21JbnQodmFsdWUpKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0dXJucyBhIFRpbWVzdGFtcCByZXByZXNlbnRpbmcgdGhlIGdpdmVuIG51bWJlciB2YWx1ZSwgcHJvdmlkZWQgdGhhdCBpdCBpcyBhIGZpbml0ZSBudW1iZXIuIE90aGVyd2lzZSwgemVybyBpcyByZXR1cm5lZC5cblx0ICAgICAqXG5cdCAgICAgKiBAbWV0aG9kXG5cdCAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgdGhlIG51bWJlciBpbiBxdWVzdGlvbi5cblx0ICAgICAqIEByZXR1cm4ge1RpbWVzdGFtcH0gdGhlIHRpbWVzdGFtcC5cblx0ICAgICAqL1xuXG5cdCAgfSwge1xuXHQgICAga2V5OiBcImZyb21OdW1iZXJcIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tTnVtYmVyKHZhbHVlKSB7XG5cdCAgICAgIHJldHVybiBuZXcgVGltZXN0YW1wKGxvbmdfMS5mcm9tTnVtYmVyKHZhbHVlKSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgYSBUaW1lc3RhbXAgZm9yIHRoZSBnaXZlbiBoaWdoIGFuZCBsb3cgYml0cy4gRWFjaCBpcyBhc3N1bWVkIHRvIHVzZSAzMiBiaXRzLlxuXHQgICAgICpcblx0ICAgICAqIEBtZXRob2Rcblx0ICAgICAqIEBwYXJhbSB7bnVtYmVyfSBsb3dCaXRzIHRoZSBsb3cgMzItYml0cy5cblx0ICAgICAqIEBwYXJhbSB7bnVtYmVyfSBoaWdoQml0cyB0aGUgaGlnaCAzMi1iaXRzLlxuXHQgICAgICogQHJldHVybiB7VGltZXN0YW1wfSB0aGUgdGltZXN0YW1wLlxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwiZnJvbUJpdHNcIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tQml0cyhsb3dCaXRzLCBoaWdoQml0cykge1xuXHQgICAgICByZXR1cm4gbmV3IFRpbWVzdGFtcChsb3dCaXRzLCBoaWdoQml0cyk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgYSBUaW1lc3RhbXAgZnJvbSB0aGUgZ2l2ZW4gc3RyaW5nLCBvcHRpb25hbGx5IHVzaW5nIHRoZSBnaXZlbiByYWRpeC5cblx0ICAgICAqXG5cdCAgICAgKiBAbWV0aG9kXG5cdCAgICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIHRoZSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBUaW1lc3RhbXAuXG5cdCAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdF9yYWRpeF0gdGhlIHJhZGl4IGluIHdoaWNoIHRoZSB0ZXh0IGlzIHdyaXR0ZW4uXG5cdCAgICAgKiBAcmV0dXJuIHtUaW1lc3RhbXB9IHRoZSB0aW1lc3RhbXAuXG5cdCAgICAgKi9cblxuXHQgIH0sIHtcblx0ICAgIGtleTogXCJmcm9tU3RyaW5nXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gZnJvbVN0cmluZyhzdHIsIG9wdF9yYWRpeCkge1xuXHQgICAgICByZXR1cm4gbmV3IFRpbWVzdGFtcChsb25nXzEuZnJvbVN0cmluZyhzdHIsIG9wdF9yYWRpeCkpO1xuXHQgICAgfVxuXHQgIH0sIHtcblx0ICAgIGtleTogXCJmcm9tRXh0ZW5kZWRKU09OXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gZnJvbUV4dGVuZGVkSlNPTihkb2MpIHtcblx0ICAgICAgcmV0dXJuIG5ldyBUaW1lc3RhbXAoZG9jLiR0aW1lc3RhbXAuaSwgZG9jLiR0aW1lc3RhbXAudCk7XG5cdCAgICB9XG5cdCAgfV0pO1xuXG5cdCAgcmV0dXJuIFRpbWVzdGFtcDtcblx0fShsb25nXzEpO1xuXG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUaW1lc3RhbXAucHJvdG90eXBlLCAnX2Jzb250eXBlJywge1xuXHQgIHZhbHVlOiAnVGltZXN0YW1wJ1xuXHR9KTtcblx0dmFyIHRpbWVzdGFtcCA9IFRpbWVzdGFtcDtcblxuXHR2YXIgZW1wdHkgPSB7fTtcblxuXHR2YXIgZW1wdHkkMSA9IC8qI19fUFVSRV9fKi9PYmplY3QuZnJlZXplKHtcblx0XHRkZWZhdWx0OiBlbXB0eVxuXHR9KTtcblxuXHR2YXIgcmVxdWlyZSQkMCA9IGdldENqc0V4cG9ydEZyb21OYW1lc3BhY2UoZW1wdHkkMSk7XG5cblx0LyogZ2xvYmFsIHdpbmRvdyAqL1xuXG5cdC8qKlxuXHQgKiBOb3JtYWxpemVzIG91ciBleHBlY3RlZCBzdHJpbmdpZmllZCBmb3JtIG9mIGEgZnVuY3Rpb24gYWNyb3NzIHZlcnNpb25zIG9mIG5vZGVcblx0ICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIHN0cmluZ2lmeVxuXHQgKi9cblxuXG5cdGZ1bmN0aW9uIG5vcm1hbGl6ZWRGdW5jdGlvblN0cmluZyhmbikge1xuXHQgIHJldHVybiBmbi50b1N0cmluZygpLnJlcGxhY2UoJ2Z1bmN0aW9uKCcsICdmdW5jdGlvbiAoJyk7XG5cdH1cblxuXHRmdW5jdGlvbiBpbnNlY3VyZVJhbmRvbUJ5dGVzKHNpemUpIHtcblx0ICB2YXIgcmVzdWx0ID0gbmV3IFVpbnQ4QXJyYXkoc2l6ZSk7XG5cblx0ICBmb3IgKHZhciBpID0gMDsgaSA8IHNpemU7ICsraSkge1xuXHQgICAgcmVzdWx0W2ldID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMjU2KTtcblx0ICB9XG5cblx0ICByZXR1cm4gcmVzdWx0O1xuXHR9XG5cblx0dmFyIHJhbmRvbUJ5dGVzID0gaW5zZWN1cmVSYW5kb21CeXRlcztcblxuXHRpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93LmNyeXB0byAmJiB3aW5kb3cuY3J5cHRvLmdldFJhbmRvbVZhbHVlcykge1xuXHQgIHJhbmRvbUJ5dGVzID0gZnVuY3Rpb24gcmFuZG9tQnl0ZXMoc2l6ZSkge1xuXHQgICAgcmV0dXJuIHdpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKG5ldyBVaW50OEFycmF5KHNpemUpKTtcblx0ICB9O1xuXHR9IGVsc2Uge1xuXHQgIHRyeSB7XG5cdCAgICByYW5kb21CeXRlcyA9IHJlcXVpcmUkJDAucmFuZG9tQnl0ZXM7XG5cdCAgfSBjYXRjaCAoZSkge30gLy8ga2VlcCB0aGUgZmFsbGJhY2tcblx0ICAvLyBOT1RFOiBpbiB0cmFuc3BpbGVkIGNhc2VzIHRoZSBhYm92ZSByZXF1aXJlIG1pZ2h0IHJldHVybiBudWxsL3VuZGVmaW5lZFxuXG5cblx0ICBpZiAocmFuZG9tQnl0ZXMgPT0gbnVsbCkge1xuXHQgICAgcmFuZG9tQnl0ZXMgPSBpbnNlY3VyZVJhbmRvbUJ5dGVzO1xuXHQgIH1cblx0fVxuXG5cdHZhciB1dGlscyA9IHtcblx0ICBub3JtYWxpemVkRnVuY3Rpb25TdHJpbmc6IG5vcm1hbGl6ZWRGdW5jdGlvblN0cmluZyxcblx0ICByYW5kb21CeXRlczogcmFuZG9tQnl0ZXNcblx0fTtcblxuXHQvLyBzaGltIGZvciB1c2luZyBwcm9jZXNzIGluIGJyb3dzZXJcblx0Ly8gYmFzZWQgb2ZmIGh0dHBzOi8vZ2l0aHViLmNvbS9kZWZ1bmN0em9tYmllL25vZGUtcHJvY2Vzcy9ibG9iL21hc3Rlci9icm93c2VyLmpzXG5cdGZ1bmN0aW9uIGRlZmF1bHRTZXRUaW1vdXQoKSB7XG5cdCAgdGhyb3cgbmV3IEVycm9yKCdzZXRUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG5cdH1cblxuXHRmdW5jdGlvbiBkZWZhdWx0Q2xlYXJUaW1lb3V0KCkge1xuXHQgIHRocm93IG5ldyBFcnJvcignY2xlYXJUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG5cdH1cblxuXHR2YXIgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG5cdHZhciBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuXG5cdGlmICh0eXBlb2YgZ2xvYmFsLnNldFRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcblx0ICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcblx0fVxuXG5cdGlmICh0eXBlb2YgZ2xvYmFsLmNsZWFyVGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuXHQgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcblx0fVxuXG5cdGZ1bmN0aW9uIHJ1blRpbWVvdXQoZnVuKSB7XG5cdCAgaWYgKGNhY2hlZFNldFRpbWVvdXQgPT09IHNldFRpbWVvdXQpIHtcblx0ICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuXHQgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcblx0ICB9IC8vIGlmIHNldFRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG5cblxuXHQgIGlmICgoY2FjaGVkU2V0VGltZW91dCA9PT0gZGVmYXVsdFNldFRpbW91dCB8fCAhY2FjaGVkU2V0VGltZW91dCkgJiYgc2V0VGltZW91dCkge1xuXHQgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG5cdCAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuXHQgIH1cblxuXHQgIHRyeSB7XG5cdCAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG5cdCAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dChmdW4sIDApO1xuXHQgIH0gY2F0Y2ggKGUpIHtcblx0ICAgIHRyeSB7XG5cdCAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCB0cnVzdCB0aGUgZ2xvYmFsIG9iamVjdCB3aGVuIGNhbGxlZCBub3JtYWxseVxuXHQgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKG51bGwsIGZ1biwgMCk7XG5cdCAgICB9IGNhdGNoIChlKSB7XG5cdCAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yXG5cdCAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwodGhpcywgZnVuLCAwKTtcblx0ICAgIH1cblx0ICB9XG5cdH1cblxuXHRmdW5jdGlvbiBydW5DbGVhclRpbWVvdXQobWFya2VyKSB7XG5cdCAgaWYgKGNhY2hlZENsZWFyVGltZW91dCA9PT0gY2xlYXJUaW1lb3V0KSB7XG5cdCAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcblx0ICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcblx0ICB9IC8vIGlmIGNsZWFyVGltZW91dCB3YXNuJ3QgYXZhaWxhYmxlIGJ1dCB3YXMgbGF0dGVyIGRlZmluZWRcblxuXG5cdCAgaWYgKChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGRlZmF1bHRDbGVhclRpbWVvdXQgfHwgIWNhY2hlZENsZWFyVGltZW91dCkgJiYgY2xlYXJUaW1lb3V0KSB7XG5cdCAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG5cdCAgICByZXR1cm4gY2xlYXJUaW1lb3V0KG1hcmtlcik7XG5cdCAgfVxuXG5cdCAgdHJ5IHtcblx0ICAgIC8vIHdoZW4gd2hlbiBzb21lYm9keSBoYXMgc2NyZXdlZCB3aXRoIHNldFRpbWVvdXQgYnV0IG5vIEkuRS4gbWFkZG5lc3Ncblx0ICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQobWFya2VyKTtcblx0ICB9IGNhdGNoIChlKSB7XG5cdCAgICB0cnkge1xuXHQgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgIHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG5cdCAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbChudWxsLCBtYXJrZXIpO1xuXHQgICAgfSBjYXRjaCAoZSkge1xuXHQgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvci5cblx0ICAgICAgLy8gU29tZSB2ZXJzaW9ucyBvZiBJLkUuIGhhdmUgZGlmZmVyZW50IHJ1bGVzIGZvciBjbGVhclRpbWVvdXQgdnMgc2V0VGltZW91dFxuXHQgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwodGhpcywgbWFya2VyKTtcblx0ICAgIH1cblx0ICB9XG5cdH1cblxuXHR2YXIgcXVldWUgPSBbXTtcblx0dmFyIGRyYWluaW5nID0gZmFsc2U7XG5cdHZhciBjdXJyZW50UXVldWU7XG5cdHZhciBxdWV1ZUluZGV4ID0gLTE7XG5cblx0ZnVuY3Rpb24gY2xlYW5VcE5leHRUaWNrKCkge1xuXHQgIGlmICghZHJhaW5pbmcgfHwgIWN1cnJlbnRRdWV1ZSkge1xuXHQgICAgcmV0dXJuO1xuXHQgIH1cblxuXHQgIGRyYWluaW5nID0gZmFsc2U7XG5cblx0ICBpZiAoY3VycmVudFF1ZXVlLmxlbmd0aCkge1xuXHQgICAgcXVldWUgPSBjdXJyZW50UXVldWUuY29uY2F0KHF1ZXVlKTtcblx0ICB9IGVsc2Uge1xuXHQgICAgcXVldWVJbmRleCA9IC0xO1xuXHQgIH1cblxuXHQgIGlmIChxdWV1ZS5sZW5ndGgpIHtcblx0ICAgIGRyYWluUXVldWUoKTtcblx0ICB9XG5cdH1cblxuXHRmdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuXHQgIGlmIChkcmFpbmluZykge1xuXHQgICAgcmV0dXJuO1xuXHQgIH1cblxuXHQgIHZhciB0aW1lb3V0ID0gcnVuVGltZW91dChjbGVhblVwTmV4dFRpY2spO1xuXHQgIGRyYWluaW5nID0gdHJ1ZTtcblx0ICB2YXIgbGVuID0gcXVldWUubGVuZ3RoO1xuXG5cdCAgd2hpbGUgKGxlbikge1xuXHQgICAgY3VycmVudFF1ZXVlID0gcXVldWU7XG5cdCAgICBxdWV1ZSA9IFtdO1xuXG5cdCAgICB3aGlsZSAoKytxdWV1ZUluZGV4IDwgbGVuKSB7XG5cdCAgICAgIGlmIChjdXJyZW50UXVldWUpIHtcblx0ICAgICAgICBjdXJyZW50UXVldWVbcXVldWVJbmRleF0ucnVuKCk7XG5cdCAgICAgIH1cblx0ICAgIH1cblxuXHQgICAgcXVldWVJbmRleCA9IC0xO1xuXHQgICAgbGVuID0gcXVldWUubGVuZ3RoO1xuXHQgIH1cblxuXHQgIGN1cnJlbnRRdWV1ZSA9IG51bGw7XG5cdCAgZHJhaW5pbmcgPSBmYWxzZTtcblx0ICBydW5DbGVhclRpbWVvdXQodGltZW91dCk7XG5cdH1cblxuXHRmdW5jdGlvbiBuZXh0VGljayhmdW4pIHtcblx0ICB2YXIgYXJncyA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoIC0gMSk7XG5cblx0ICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcblx0ICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuXHQgICAgfVxuXHQgIH1cblxuXHQgIHF1ZXVlLnB1c2gobmV3IEl0ZW0oZnVuLCBhcmdzKSk7XG5cblx0ICBpZiAocXVldWUubGVuZ3RoID09PSAxICYmICFkcmFpbmluZykge1xuXHQgICAgcnVuVGltZW91dChkcmFpblF1ZXVlKTtcblx0ICB9XG5cdH0gLy8gdjggbGlrZXMgcHJlZGljdGlibGUgb2JqZWN0c1xuXG5cdGZ1bmN0aW9uIEl0ZW0oZnVuLCBhcnJheSkge1xuXHQgIHRoaXMuZnVuID0gZnVuO1xuXHQgIHRoaXMuYXJyYXkgPSBhcnJheTtcblx0fVxuXG5cdEl0ZW0ucHJvdG90eXBlLnJ1biA9IGZ1bmN0aW9uICgpIHtcblx0ICB0aGlzLmZ1bi5hcHBseShudWxsLCB0aGlzLmFycmF5KTtcblx0fTtcblxuXHR2YXIgdGl0bGUgPSAnYnJvd3Nlcic7XG5cdHZhciBwbGF0Zm9ybSA9ICdicm93c2VyJztcblx0dmFyIGJyb3dzZXIgPSB0cnVlO1xuXHR2YXIgZW52ID0ge307XG5cdHZhciBhcmd2ID0gW107XG5cdHZhciB2ZXJzaW9uID0gJyc7IC8vIGVtcHR5IHN0cmluZyB0byBhdm9pZCByZWdleHAgaXNzdWVzXG5cblx0dmFyIHZlcnNpb25zID0ge307XG5cdHZhciByZWxlYXNlID0ge307XG5cdHZhciBjb25maWcgPSB7fTtcblxuXHRmdW5jdGlvbiBub29wKCkge31cblxuXHR2YXIgb24gPSBub29wO1xuXHR2YXIgYWRkTGlzdGVuZXIgPSBub29wO1xuXHR2YXIgb25jZSA9IG5vb3A7XG5cdHZhciBvZmYgPSBub29wO1xuXHR2YXIgcmVtb3ZlTGlzdGVuZXIgPSBub29wO1xuXHR2YXIgcmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcblx0dmFyIGVtaXQgPSBub29wO1xuXHRmdW5jdGlvbiBiaW5kaW5nKG5hbWUpIHtcblx0ICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuYmluZGluZyBpcyBub3Qgc3VwcG9ydGVkJyk7XG5cdH1cblx0ZnVuY3Rpb24gY3dkKCkge1xuXHQgIHJldHVybiAnLyc7XG5cdH1cblx0ZnVuY3Rpb24gY2hkaXIoZGlyKSB7XG5cdCAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcblx0fVxuXHRmdW5jdGlvbiB1bWFzaygpIHtcblx0ICByZXR1cm4gMDtcblx0fSAvLyBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9rdW1hdmlzL2Jyb3dzZXItcHJvY2Vzcy1ocnRpbWUvYmxvYi9tYXN0ZXIvaW5kZXguanNcblxuXHR2YXIgcGVyZm9ybWFuY2UgPSBnbG9iYWwucGVyZm9ybWFuY2UgfHwge307XG5cblx0dmFyIHBlcmZvcm1hbmNlTm93ID0gcGVyZm9ybWFuY2Uubm93IHx8IHBlcmZvcm1hbmNlLm1vek5vdyB8fCBwZXJmb3JtYW5jZS5tc05vdyB8fCBwZXJmb3JtYW5jZS5vTm93IHx8IHBlcmZvcm1hbmNlLndlYmtpdE5vdyB8fCBmdW5jdGlvbiAoKSB7XG5cdCAgcmV0dXJuIG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuXHR9OyAvLyBnZW5lcmF0ZSB0aW1lc3RhbXAgb3IgZGVsdGFcblx0Ly8gc2VlIGh0dHA6Ly9ub2RlanMub3JnL2FwaS9wcm9jZXNzLmh0bWwjcHJvY2Vzc19wcm9jZXNzX2hydGltZVxuXG5cblx0ZnVuY3Rpb24gaHJ0aW1lKHByZXZpb3VzVGltZXN0YW1wKSB7XG5cdCAgdmFyIGNsb2NrdGltZSA9IHBlcmZvcm1hbmNlTm93LmNhbGwocGVyZm9ybWFuY2UpICogMWUtMztcblx0ICB2YXIgc2Vjb25kcyA9IE1hdGguZmxvb3IoY2xvY2t0aW1lKTtcblx0ICB2YXIgbmFub3NlY29uZHMgPSBNYXRoLmZsb29yKGNsb2NrdGltZSAlIDEgKiAxZTkpO1xuXG5cdCAgaWYgKHByZXZpb3VzVGltZXN0YW1wKSB7XG5cdCAgICBzZWNvbmRzID0gc2Vjb25kcyAtIHByZXZpb3VzVGltZXN0YW1wWzBdO1xuXHQgICAgbmFub3NlY29uZHMgPSBuYW5vc2Vjb25kcyAtIHByZXZpb3VzVGltZXN0YW1wWzFdO1xuXG5cdCAgICBpZiAobmFub3NlY29uZHMgPCAwKSB7XG5cdCAgICAgIHNlY29uZHMtLTtcblx0ICAgICAgbmFub3NlY29uZHMgKz0gMWU5O1xuXHQgICAgfVxuXHQgIH1cblxuXHQgIHJldHVybiBbc2Vjb25kcywgbmFub3NlY29uZHNdO1xuXHR9XG5cdHZhciBzdGFydFRpbWUgPSBuZXcgRGF0ZSgpO1xuXHRmdW5jdGlvbiB1cHRpbWUoKSB7XG5cdCAgdmFyIGN1cnJlbnRUaW1lID0gbmV3IERhdGUoKTtcblx0ICB2YXIgZGlmID0gY3VycmVudFRpbWUgLSBzdGFydFRpbWU7XG5cdCAgcmV0dXJuIGRpZiAvIDEwMDA7XG5cdH1cblx0dmFyIHByb2Nlc3MgPSB7XG5cdCAgbmV4dFRpY2s6IG5leHRUaWNrLFxuXHQgIHRpdGxlOiB0aXRsZSxcblx0ICBicm93c2VyOiBicm93c2VyLFxuXHQgIGVudjogZW52LFxuXHQgIGFyZ3Y6IGFyZ3YsXG5cdCAgdmVyc2lvbjogdmVyc2lvbixcblx0ICB2ZXJzaW9uczogdmVyc2lvbnMsXG5cdCAgb246IG9uLFxuXHQgIGFkZExpc3RlbmVyOiBhZGRMaXN0ZW5lcixcblx0ICBvbmNlOiBvbmNlLFxuXHQgIG9mZjogb2ZmLFxuXHQgIHJlbW92ZUxpc3RlbmVyOiByZW1vdmVMaXN0ZW5lcixcblx0ICByZW1vdmVBbGxMaXN0ZW5lcnM6IHJlbW92ZUFsbExpc3RlbmVycyxcblx0ICBlbWl0OiBlbWl0LFxuXHQgIGJpbmRpbmc6IGJpbmRpbmcsXG5cdCAgY3dkOiBjd2QsXG5cdCAgY2hkaXI6IGNoZGlyLFxuXHQgIHVtYXNrOiB1bWFzayxcblx0ICBocnRpbWU6IGhydGltZSxcblx0ICBwbGF0Zm9ybTogcGxhdGZvcm0sXG5cdCAgcmVsZWFzZTogcmVsZWFzZSxcblx0ICBjb25maWc6IGNvbmZpZyxcblx0ICB1cHRpbWU6IHVwdGltZVxuXHR9O1xuXG5cdHZhciBpbmhlcml0cztcblxuXHRpZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcblx0ICBpbmhlcml0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuXHQgICAgLy8gaW1wbGVtZW50YXRpb24gZnJvbSBzdGFuZGFyZCBub2RlLmpzICd1dGlsJyBtb2R1bGVcblx0ICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yO1xuXHQgICAgY3Rvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ3Rvci5wcm90b3R5cGUsIHtcblx0ICAgICAgY29uc3RydWN0b3I6IHtcblx0ICAgICAgICB2YWx1ZTogY3Rvcixcblx0ICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcblx0ICAgICAgICB3cml0YWJsZTogdHJ1ZSxcblx0ICAgICAgICBjb25maWd1cmFibGU6IHRydWVcblx0ICAgICAgfVxuXHQgICAgfSk7XG5cdCAgfTtcblx0fSBlbHNlIHtcblx0ICBpbmhlcml0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuXHQgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3I7XG5cblx0ICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uIFRlbXBDdG9yKCkge307XG5cblx0ICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGU7XG5cdCAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpO1xuXHQgICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yO1xuXHQgIH07XG5cdH1cblxuXHR2YXIgaW5oZXJpdHMkMSA9IGluaGVyaXRzO1xuXG5cdGZ1bmN0aW9uIF90eXBlb2YkMShvYmopIHsgaWYgKHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSBcInN5bWJvbFwiKSB7IF90eXBlb2YkMSA9IGZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9OyB9IGVsc2UgeyBfdHlwZW9mJDEgPSBmdW5jdGlvbiBfdHlwZW9mKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajsgfTsgfSByZXR1cm4gX3R5cGVvZiQxKG9iaik7IH1cblx0dmFyIGZvcm1hdFJlZ0V4cCA9IC8lW3NkaiVdL2c7XG5cdGZ1bmN0aW9uIGZvcm1hdChmKSB7XG5cdCAgaWYgKCFpc1N0cmluZyhmKSkge1xuXHQgICAgdmFyIG9iamVjdHMgPSBbXTtcblxuXHQgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgb2JqZWN0cy5wdXNoKGluc3BlY3QoYXJndW1lbnRzW2ldKSk7XG5cdCAgICB9XG5cblx0ICAgIHJldHVybiBvYmplY3RzLmpvaW4oJyAnKTtcblx0ICB9XG5cblx0ICB2YXIgaSA9IDE7XG5cdCAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG5cdCAgdmFyIGxlbiA9IGFyZ3MubGVuZ3RoO1xuXHQgIHZhciBzdHIgPSBTdHJpbmcoZikucmVwbGFjZShmb3JtYXRSZWdFeHAsIGZ1bmN0aW9uICh4KSB7XG5cdCAgICBpZiAoeCA9PT0gJyUlJykgcmV0dXJuICclJztcblx0ICAgIGlmIChpID49IGxlbikgcmV0dXJuIHg7XG5cblx0ICAgIHN3aXRjaCAoeCkge1xuXHQgICAgICBjYXNlICclcyc6XG5cdCAgICAgICAgcmV0dXJuIFN0cmluZyhhcmdzW2krK10pO1xuXG5cdCAgICAgIGNhc2UgJyVkJzpcblx0ICAgICAgICByZXR1cm4gTnVtYmVyKGFyZ3NbaSsrXSk7XG5cblx0ICAgICAgY2FzZSAnJWonOlxuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoYXJnc1tpKytdKTtcblx0ICAgICAgICB9IGNhdGNoIChfKSB7XG5cdCAgICAgICAgICByZXR1cm4gJ1tDaXJjdWxhcl0nO1xuXHQgICAgICAgIH1cblxuXHQgICAgICBkZWZhdWx0OlxuXHQgICAgICAgIHJldHVybiB4O1xuXHQgICAgfVxuXHQgIH0pO1xuXG5cdCAgZm9yICh2YXIgeCA9IGFyZ3NbaV07IGkgPCBsZW47IHggPSBhcmdzWysraV0pIHtcblx0ICAgIGlmIChpc051bGwoeCkgfHwgIWlzT2JqZWN0KHgpKSB7XG5cdCAgICAgIHN0ciArPSAnICcgKyB4O1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgc3RyICs9ICcgJyArIGluc3BlY3QoeCk7XG5cdCAgICB9XG5cdCAgfVxuXG5cdCAgcmV0dXJuIHN0cjtcblx0fVxuXHQvLyBSZXR1cm5zIGEgbW9kaWZpZWQgZnVuY3Rpb24gd2hpY2ggd2FybnMgb25jZSBieSBkZWZhdWx0LlxuXHQvLyBJZiAtLW5vLWRlcHJlY2F0aW9uIGlzIHNldCwgdGhlbiBpdCBpcyBhIG5vLW9wLlxuXG5cdGZ1bmN0aW9uIGRlcHJlY2F0ZShmbiwgbXNnKSB7XG5cdCAgLy8gQWxsb3cgZm9yIGRlcHJlY2F0aW5nIHRoaW5ncyBpbiB0aGUgcHJvY2VzcyBvZiBzdGFydGluZyB1cC5cblx0ICBpZiAoaXNVbmRlZmluZWQoZ2xvYmFsLnByb2Nlc3MpKSB7XG5cdCAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuXHQgICAgICByZXR1cm4gZGVwcmVjYXRlKGZuLCBtc2cpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cdCAgICB9O1xuXHQgIH1cblxuXHQgIHZhciB3YXJuZWQgPSBmYWxzZTtcblxuXHQgIGZ1bmN0aW9uIGRlcHJlY2F0ZWQoKSB7XG5cdCAgICBpZiAoIXdhcm5lZCkge1xuXHQgICAgICB7XG5cdCAgICAgICAgY29uc29sZS5lcnJvcihtc2cpO1xuXHQgICAgICB9XG5cblx0ICAgICAgd2FybmVkID0gdHJ1ZTtcblx0ICAgIH1cblxuXHQgICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cdCAgfVxuXG5cdCAgcmV0dXJuIGRlcHJlY2F0ZWQ7XG5cdH1cblx0dmFyIGRlYnVncyA9IHt9O1xuXHR2YXIgZGVidWdFbnZpcm9uO1xuXHRmdW5jdGlvbiBkZWJ1Z2xvZyhzZXQpIHtcblx0ICBpZiAoaXNVbmRlZmluZWQoZGVidWdFbnZpcm9uKSkgZGVidWdFbnZpcm9uID0gcHJvY2Vzcy5lbnYuTk9ERV9ERUJVRyB8fCAnJztcblx0ICBzZXQgPSBzZXQudG9VcHBlckNhc2UoKTtcblxuXHQgIGlmICghZGVidWdzW3NldF0pIHtcblx0ICAgIGlmIChuZXcgUmVnRXhwKCdcXFxcYicgKyBzZXQgKyAnXFxcXGInLCAnaScpLnRlc3QoZGVidWdFbnZpcm9uKSkge1xuXHQgICAgICB2YXIgcGlkID0gMDtcblxuXHQgICAgICBkZWJ1Z3Nbc2V0XSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICB2YXIgbXNnID0gZm9ybWF0LmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG5cdCAgICAgICAgY29uc29sZS5lcnJvcignJXMgJWQ6ICVzJywgc2V0LCBwaWQsIG1zZyk7XG5cdCAgICAgIH07XG5cdCAgICB9IGVsc2Uge1xuXHQgICAgICBkZWJ1Z3Nbc2V0XSA9IGZ1bmN0aW9uICgpIHt9O1xuXHQgICAgfVxuXHQgIH1cblxuXHQgIHJldHVybiBkZWJ1Z3Nbc2V0XTtcblx0fVxuXHQvKipcblx0ICogRWNob3MgdGhlIHZhbHVlIG9mIGEgdmFsdWUuIFRyeXMgdG8gcHJpbnQgdGhlIHZhbHVlIG91dFxuXHQgKiBpbiB0aGUgYmVzdCB3YXkgcG9zc2libGUgZ2l2ZW4gdGhlIGRpZmZlcmVudCB0eXBlcy5cblx0ICpcblx0ICogQHBhcmFtIHtPYmplY3R9IG9iaiBUaGUgb2JqZWN0IHRvIHByaW50IG91dC5cblx0ICogQHBhcmFtIHtPYmplY3R9IG9wdHMgT3B0aW9uYWwgb3B0aW9ucyBvYmplY3QgdGhhdCBhbHRlcnMgdGhlIG91dHB1dC5cblx0ICovXG5cblx0LyogbGVnYWN5OiBvYmosIHNob3dIaWRkZW4sIGRlcHRoLCBjb2xvcnMqL1xuXG5cdGZ1bmN0aW9uIGluc3BlY3Qob2JqLCBvcHRzKSB7XG5cdCAgLy8gZGVmYXVsdCBvcHRpb25zXG5cdCAgdmFyIGN0eCA9IHtcblx0ICAgIHNlZW46IFtdLFxuXHQgICAgc3R5bGl6ZTogc3R5bGl6ZU5vQ29sb3Jcblx0ICB9OyAvLyBsZWdhY3kuLi5cblxuXHQgIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDMpIGN0eC5kZXB0aCA9IGFyZ3VtZW50c1syXTtcblx0ICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSA0KSBjdHguY29sb3JzID0gYXJndW1lbnRzWzNdO1xuXG5cdCAgaWYgKGlzQm9vbGVhbihvcHRzKSkge1xuXHQgICAgLy8gbGVnYWN5Li4uXG5cdCAgICBjdHguc2hvd0hpZGRlbiA9IG9wdHM7XG5cdCAgfSBlbHNlIGlmIChvcHRzKSB7XG5cdCAgICAvLyBnb3QgYW4gXCJvcHRpb25zXCIgb2JqZWN0XG5cdCAgICBfZXh0ZW5kKGN0eCwgb3B0cyk7XG5cdCAgfSAvLyBzZXQgZGVmYXVsdCBvcHRpb25zXG5cblxuXHQgIGlmIChpc1VuZGVmaW5lZChjdHguc2hvd0hpZGRlbikpIGN0eC5zaG93SGlkZGVuID0gZmFsc2U7XG5cdCAgaWYgKGlzVW5kZWZpbmVkKGN0eC5kZXB0aCkpIGN0eC5kZXB0aCA9IDI7XG5cdCAgaWYgKGlzVW5kZWZpbmVkKGN0eC5jb2xvcnMpKSBjdHguY29sb3JzID0gZmFsc2U7XG5cdCAgaWYgKGlzVW5kZWZpbmVkKGN0eC5jdXN0b21JbnNwZWN0KSkgY3R4LmN1c3RvbUluc3BlY3QgPSB0cnVlO1xuXHQgIGlmIChjdHguY29sb3JzKSBjdHguc3R5bGl6ZSA9IHN0eWxpemVXaXRoQ29sb3I7XG5cdCAgcmV0dXJuIGZvcm1hdFZhbHVlKGN0eCwgb2JqLCBjdHguZGVwdGgpO1xuXHR9IC8vIGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQU5TSV9lc2NhcGVfY29kZSNncmFwaGljc1xuXG5cdGluc3BlY3QuY29sb3JzID0ge1xuXHQgICdib2xkJzogWzEsIDIyXSxcblx0ICAnaXRhbGljJzogWzMsIDIzXSxcblx0ICAndW5kZXJsaW5lJzogWzQsIDI0XSxcblx0ICAnaW52ZXJzZSc6IFs3LCAyN10sXG5cdCAgJ3doaXRlJzogWzM3LCAzOV0sXG5cdCAgJ2dyZXknOiBbOTAsIDM5XSxcblx0ICAnYmxhY2snOiBbMzAsIDM5XSxcblx0ICAnYmx1ZSc6IFszNCwgMzldLFxuXHQgICdjeWFuJzogWzM2LCAzOV0sXG5cdCAgJ2dyZWVuJzogWzMyLCAzOV0sXG5cdCAgJ21hZ2VudGEnOiBbMzUsIDM5XSxcblx0ICAncmVkJzogWzMxLCAzOV0sXG5cdCAgJ3llbGxvdyc6IFszMywgMzldXG5cdH07IC8vIERvbid0IHVzZSAnYmx1ZScgbm90IHZpc2libGUgb24gY21kLmV4ZVxuXG5cdGluc3BlY3Quc3R5bGVzID0ge1xuXHQgICdzcGVjaWFsJzogJ2N5YW4nLFxuXHQgICdudW1iZXInOiAneWVsbG93Jyxcblx0ICAnYm9vbGVhbic6ICd5ZWxsb3cnLFxuXHQgICd1bmRlZmluZWQnOiAnZ3JleScsXG5cdCAgJ251bGwnOiAnYm9sZCcsXG5cdCAgJ3N0cmluZyc6ICdncmVlbicsXG5cdCAgJ2RhdGUnOiAnbWFnZW50YScsXG5cdCAgLy8gXCJuYW1lXCI6IGludGVudGlvbmFsbHkgbm90IHN0eWxpbmdcblx0ICAncmVnZXhwJzogJ3JlZCdcblx0fTtcblxuXHRmdW5jdGlvbiBzdHlsaXplV2l0aENvbG9yKHN0ciwgc3R5bGVUeXBlKSB7XG5cdCAgdmFyIHN0eWxlID0gaW5zcGVjdC5zdHlsZXNbc3R5bGVUeXBlXTtcblxuXHQgIGlmIChzdHlsZSkge1xuXHQgICAgcmV0dXJuIFwiXFx4MUJbXCIgKyBpbnNwZWN0LmNvbG9yc1tzdHlsZV1bMF0gKyAnbScgKyBzdHIgKyBcIlxceDFCW1wiICsgaW5zcGVjdC5jb2xvcnNbc3R5bGVdWzFdICsgJ20nO1xuXHQgIH0gZWxzZSB7XG5cdCAgICByZXR1cm4gc3RyO1xuXHQgIH1cblx0fVxuXG5cdGZ1bmN0aW9uIHN0eWxpemVOb0NvbG9yKHN0ciwgc3R5bGVUeXBlKSB7XG5cdCAgcmV0dXJuIHN0cjtcblx0fVxuXG5cdGZ1bmN0aW9uIGFycmF5VG9IYXNoKGFycmF5KSB7XG5cdCAgdmFyIGhhc2ggPSB7fTtcblx0ICBhcnJheS5mb3JFYWNoKGZ1bmN0aW9uICh2YWwsIGlkeCkge1xuXHQgICAgaGFzaFt2YWxdID0gdHJ1ZTtcblx0ICB9KTtcblx0ICByZXR1cm4gaGFzaDtcblx0fVxuXG5cdGZ1bmN0aW9uIGZvcm1hdFZhbHVlKGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcykge1xuXHQgIC8vIFByb3ZpZGUgYSBob29rIGZvciB1c2VyLXNwZWNpZmllZCBpbnNwZWN0IGZ1bmN0aW9ucy5cblx0ICAvLyBDaGVjayB0aGF0IHZhbHVlIGlzIGFuIG9iamVjdCB3aXRoIGFuIGluc3BlY3QgZnVuY3Rpb24gb24gaXRcblx0ICBpZiAoY3R4LmN1c3RvbUluc3BlY3QgJiYgdmFsdWUgJiYgaXNGdW5jdGlvbih2YWx1ZS5pbnNwZWN0KSAmJiAvLyBGaWx0ZXIgb3V0IHRoZSB1dGlsIG1vZHVsZSwgaXQncyBpbnNwZWN0IGZ1bmN0aW9uIGlzIHNwZWNpYWxcblx0ICB2YWx1ZS5pbnNwZWN0ICE9PSBpbnNwZWN0ICYmIC8vIEFsc28gZmlsdGVyIG91dCBhbnkgcHJvdG90eXBlIG9iamVjdHMgdXNpbmcgdGhlIGNpcmN1bGFyIGNoZWNrLlxuXHQgICEodmFsdWUuY29uc3RydWN0b3IgJiYgdmFsdWUuY29uc3RydWN0b3IucHJvdG90eXBlID09PSB2YWx1ZSkpIHtcblx0ICAgIHZhciByZXQgPSB2YWx1ZS5pbnNwZWN0KHJlY3Vyc2VUaW1lcywgY3R4KTtcblxuXHQgICAgaWYgKCFpc1N0cmluZyhyZXQpKSB7XG5cdCAgICAgIHJldCA9IGZvcm1hdFZhbHVlKGN0eCwgcmV0LCByZWN1cnNlVGltZXMpO1xuXHQgICAgfVxuXG5cdCAgICByZXR1cm4gcmV0O1xuXHQgIH0gLy8gUHJpbWl0aXZlIHR5cGVzIGNhbm5vdCBoYXZlIHByb3BlcnRpZXNcblxuXG5cdCAgdmFyIHByaW1pdGl2ZSA9IGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKTtcblxuXHQgIGlmIChwcmltaXRpdmUpIHtcblx0ICAgIHJldHVybiBwcmltaXRpdmU7XG5cdCAgfSAvLyBMb29rIHVwIHRoZSBrZXlzIG9mIHRoZSBvYmplY3QuXG5cblxuXHQgIHZhciBrZXlzID0gT2JqZWN0LmtleXModmFsdWUpO1xuXHQgIHZhciB2aXNpYmxlS2V5cyA9IGFycmF5VG9IYXNoKGtleXMpO1xuXG5cdCAgaWYgKGN0eC5zaG93SGlkZGVuKSB7XG5cdCAgICBrZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModmFsdWUpO1xuXHQgIH0gLy8gSUUgZG9lc24ndCBtYWtlIGVycm9yIGZpZWxkcyBub24tZW51bWVyYWJsZVxuXHQgIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9pZS9kd3c1MnNidCh2PXZzLjk0KS5hc3B4XG5cblxuXHQgIGlmIChpc0Vycm9yKHZhbHVlKSAmJiAoa2V5cy5pbmRleE9mKCdtZXNzYWdlJykgPj0gMCB8fCBrZXlzLmluZGV4T2YoJ2Rlc2NyaXB0aW9uJykgPj0gMCkpIHtcblx0ICAgIHJldHVybiBmb3JtYXRFcnJvcih2YWx1ZSk7XG5cdCAgfSAvLyBTb21lIHR5cGUgb2Ygb2JqZWN0IHdpdGhvdXQgcHJvcGVydGllcyBjYW4gYmUgc2hvcnRjdXR0ZWQuXG5cblxuXHQgIGlmIChrZXlzLmxlbmd0aCA9PT0gMCkge1xuXHQgICAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG5cdCAgICAgIHZhciBuYW1lID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG5cdCAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnW0Z1bmN0aW9uJyArIG5hbWUgKyAnXScsICdzcGVjaWFsJyk7XG5cdCAgICB9XG5cblx0ICAgIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcblx0ICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdyZWdleHAnKTtcblx0ICAgIH1cblxuXHQgICAgaWYgKGlzRGF0ZSh2YWx1ZSkpIHtcblx0ICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKERhdGUucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAnZGF0ZScpO1xuXHQgICAgfVxuXG5cdCAgICBpZiAoaXNFcnJvcih2YWx1ZSkpIHtcblx0ICAgICAgcmV0dXJuIGZvcm1hdEVycm9yKHZhbHVlKTtcblx0ICAgIH1cblx0ICB9XG5cblx0ICB2YXIgYmFzZSA9ICcnLFxuXHQgICAgICBhcnJheSA9IGZhbHNlLFxuXHQgICAgICBicmFjZXMgPSBbJ3snLCAnfSddOyAvLyBNYWtlIEFycmF5IHNheSB0aGF0IHRoZXkgYXJlIEFycmF5XG5cblx0ICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcblx0ICAgIGFycmF5ID0gdHJ1ZTtcblx0ICAgIGJyYWNlcyA9IFsnWycsICddJ107XG5cdCAgfSAvLyBNYWtlIGZ1bmN0aW9ucyBzYXkgdGhhdCB0aGV5IGFyZSBmdW5jdGlvbnNcblxuXG5cdCAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG5cdCAgICB2YXIgbiA9IHZhbHVlLm5hbWUgPyAnOiAnICsgdmFsdWUubmFtZSA6ICcnO1xuXHQgICAgYmFzZSA9ICcgW0Z1bmN0aW9uJyArIG4gKyAnXSc7XG5cdCAgfSAvLyBNYWtlIFJlZ0V4cHMgc2F5IHRoYXQgdGhleSBhcmUgUmVnRXhwc1xuXG5cblx0ICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG5cdCAgICBiYXNlID0gJyAnICsgUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKTtcblx0ICB9IC8vIE1ha2UgZGF0ZXMgd2l0aCBwcm9wZXJ0aWVzIGZpcnN0IHNheSB0aGUgZGF0ZVxuXG5cblx0ICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuXHQgICAgYmFzZSA9ICcgJyArIERhdGUucHJvdG90eXBlLnRvVVRDU3RyaW5nLmNhbGwodmFsdWUpO1xuXHQgIH0gLy8gTWFrZSBlcnJvciB3aXRoIG1lc3NhZ2UgZmlyc3Qgc2F5IHRoZSBlcnJvclxuXG5cblx0ICBpZiAoaXNFcnJvcih2YWx1ZSkpIHtcblx0ICAgIGJhc2UgPSAnICcgKyBmb3JtYXRFcnJvcih2YWx1ZSk7XG5cdCAgfVxuXG5cdCAgaWYgKGtleXMubGVuZ3RoID09PSAwICYmICghYXJyYXkgfHwgdmFsdWUubGVuZ3RoID09IDApKSB7XG5cdCAgICByZXR1cm4gYnJhY2VzWzBdICsgYmFzZSArIGJyYWNlc1sxXTtcblx0ICB9XG5cblx0ICBpZiAocmVjdXJzZVRpbWVzIDwgMCkge1xuXHQgICAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuXHQgICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCdbT2JqZWN0XScsICdzcGVjaWFsJyk7XG5cdCAgICB9XG5cdCAgfVxuXG5cdCAgY3R4LnNlZW4ucHVzaCh2YWx1ZSk7XG5cdCAgdmFyIG91dHB1dDtcblxuXHQgIGlmIChhcnJheSkge1xuXHQgICAgb3V0cHV0ID0gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cyk7XG5cdCAgfSBlbHNlIHtcblx0ICAgIG91dHB1dCA9IGtleXMubWFwKGZ1bmN0aW9uIChrZXkpIHtcblx0ICAgICAgcmV0dXJuIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpO1xuXHQgICAgfSk7XG5cdCAgfVxuXG5cdCAgY3R4LnNlZW4ucG9wKCk7XG5cdCAgcmV0dXJuIHJlZHVjZVRvU2luZ2xlU3RyaW5nKG91dHB1dCwgYmFzZSwgYnJhY2VzKTtcblx0fVxuXG5cdGZ1bmN0aW9uIGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKSB7XG5cdCAgaWYgKGlzVW5kZWZpbmVkKHZhbHVlKSkgcmV0dXJuIGN0eC5zdHlsaXplKCd1bmRlZmluZWQnLCAndW5kZWZpbmVkJyk7XG5cblx0ICBpZiAoaXNTdHJpbmcodmFsdWUpKSB7XG5cdCAgICB2YXIgc2ltcGxlID0gJ1xcJycgKyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkucmVwbGFjZSgvXlwifFwiJC9nLCAnJykucmVwbGFjZSgvJy9nLCBcIlxcXFwnXCIpLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKSArICdcXCcnO1xuXHQgICAgcmV0dXJuIGN0eC5zdHlsaXplKHNpbXBsZSwgJ3N0cmluZycpO1xuXHQgIH1cblxuXHQgIGlmIChpc051bWJlcih2YWx1ZSkpIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnbnVtYmVyJyk7XG5cdCAgaWYgKGlzQm9vbGVhbih2YWx1ZSkpIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnYm9vbGVhbicpOyAvLyBGb3Igc29tZSByZWFzb24gdHlwZW9mIG51bGwgaXMgXCJvYmplY3RcIiwgc28gc3BlY2lhbCBjYXNlIGhlcmUuXG5cblx0ICBpZiAoaXNOdWxsKHZhbHVlKSkgcmV0dXJuIGN0eC5zdHlsaXplKCdudWxsJywgJ251bGwnKTtcblx0fVxuXG5cdGZ1bmN0aW9uIGZvcm1hdEVycm9yKHZhbHVlKSB7XG5cdCAgcmV0dXJuICdbJyArIEVycm9yLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSArICddJztcblx0fVxuXG5cdGZ1bmN0aW9uIGZvcm1hdEFycmF5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleXMpIHtcblx0ICB2YXIgb3V0cHV0ID0gW107XG5cblx0ICBmb3IgKHZhciBpID0gMCwgbCA9IHZhbHVlLmxlbmd0aDsgaSA8IGw7ICsraSkge1xuXHQgICAgaWYgKGhhc093blByb3BlcnR5KHZhbHVlLCBTdHJpbmcoaSkpKSB7XG5cdCAgICAgIG91dHB1dC5wdXNoKGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIFN0cmluZyhpKSwgdHJ1ZSkpO1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgb3V0cHV0LnB1c2goJycpO1xuXHQgICAgfVxuXHQgIH1cblxuXHQgIGtleXMuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG5cdCAgICBpZiAoIWtleS5tYXRjaCgvXlxcZCskLykpIHtcblx0ICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5LCB0cnVlKSk7XG5cdCAgICB9XG5cdCAgfSk7XG5cdCAgcmV0dXJuIG91dHB1dDtcblx0fVxuXG5cdGZ1bmN0aW9uIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpIHtcblx0ICB2YXIgbmFtZSwgc3RyLCBkZXNjO1xuXHQgIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHZhbHVlLCBrZXkpIHx8IHtcblx0ICAgIHZhbHVlOiB2YWx1ZVtrZXldXG5cdCAgfTtcblxuXHQgIGlmIChkZXNjLmdldCkge1xuXHQgICAgaWYgKGRlc2Muc2V0KSB7XG5cdCAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbR2V0dGVyL1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tHZXR0ZXJdJywgJ3NwZWNpYWwnKTtcblx0ICAgIH1cblx0ICB9IGVsc2Uge1xuXHQgICAgaWYgKGRlc2Muc2V0KSB7XG5cdCAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbU2V0dGVyXScsICdzcGVjaWFsJyk7XG5cdCAgICB9XG5cdCAgfVxuXG5cdCAgaWYgKCFoYXNPd25Qcm9wZXJ0eSh2aXNpYmxlS2V5cywga2V5KSkge1xuXHQgICAgbmFtZSA9ICdbJyArIGtleSArICddJztcblx0ICB9XG5cblx0ICBpZiAoIXN0cikge1xuXHQgICAgaWYgKGN0eC5zZWVuLmluZGV4T2YoZGVzYy52YWx1ZSkgPCAwKSB7XG5cdCAgICAgIGlmIChpc051bGwocmVjdXJzZVRpbWVzKSkge1xuXHQgICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgbnVsbCk7XG5cdCAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCBkZXNjLnZhbHVlLCByZWN1cnNlVGltZXMgLSAxKTtcblx0ICAgICAgfVxuXG5cdCAgICAgIGlmIChzdHIuaW5kZXhPZignXFxuJykgPiAtMSkge1xuXHQgICAgICAgIGlmIChhcnJheSkge1xuXHQgICAgICAgICAgc3RyID0gc3RyLnNwbGl0KCdcXG4nKS5tYXAoZnVuY3Rpb24gKGxpbmUpIHtcblx0ICAgICAgICAgICAgcmV0dXJuICcgICcgKyBsaW5lO1xuXHQgICAgICAgICAgfSkuam9pbignXFxuJykuc3Vic3RyKDIpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICBzdHIgPSAnXFxuJyArIHN0ci5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uIChsaW5lKSB7XG5cdCAgICAgICAgICAgIHJldHVybiAnICAgJyArIGxpbmU7XG5cdCAgICAgICAgICB9KS5qb2luKCdcXG4nKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH0gZWxzZSB7XG5cdCAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbQ2lyY3VsYXJdJywgJ3NwZWNpYWwnKTtcblx0ICAgIH1cblx0ICB9XG5cblx0ICBpZiAoaXNVbmRlZmluZWQobmFtZSkpIHtcblx0ICAgIGlmIChhcnJheSAmJiBrZXkubWF0Y2goL15cXGQrJC8pKSB7XG5cdCAgICAgIHJldHVybiBzdHI7XG5cdCAgICB9XG5cblx0ICAgIG5hbWUgPSBKU09OLnN0cmluZ2lmeSgnJyArIGtleSk7XG5cblx0ICAgIGlmIChuYW1lLm1hdGNoKC9eXCIoW2EtekEtWl9dW2EtekEtWl8wLTldKilcIiQvKSkge1xuXHQgICAgICBuYW1lID0gbmFtZS5zdWJzdHIoMSwgbmFtZS5sZW5ndGggLSAyKTtcblx0ICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICduYW1lJyk7XG5cdCAgICB9IGVsc2Uge1xuXHQgICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIikucmVwbGFjZSgvXFxcXFwiL2csICdcIicpLnJlcGxhY2UoLyheXCJ8XCIkKS9nLCBcIidcIik7XG5cdCAgICAgIG5hbWUgPSBjdHguc3R5bGl6ZShuYW1lLCAnc3RyaW5nJyk7XG5cdCAgICB9XG5cdCAgfVxuXG5cdCAgcmV0dXJuIG5hbWUgKyAnOiAnICsgc3RyO1xuXHR9XG5cblx0ZnVuY3Rpb24gcmVkdWNlVG9TaW5nbGVTdHJpbmcob3V0cHV0LCBiYXNlLCBicmFjZXMpIHtcblx0ICB2YXIgbGVuZ3RoID0gb3V0cHV0LnJlZHVjZShmdW5jdGlvbiAocHJldiwgY3VyKSB7XG5cdCAgICBpZiAoY3VyLmluZGV4T2YoJ1xcbicpID49IDApIDtcblx0ICAgIHJldHVybiBwcmV2ICsgY3VyLnJlcGxhY2UoL1xcdTAwMWJcXFtcXGRcXGQ/bS9nLCAnJykubGVuZ3RoICsgMTtcblx0ICB9LCAwKTtcblxuXHQgIGlmIChsZW5ndGggPiA2MCkge1xuXHQgICAgcmV0dXJuIGJyYWNlc1swXSArIChiYXNlID09PSAnJyA/ICcnIDogYmFzZSArICdcXG4gJykgKyAnICcgKyBvdXRwdXQuam9pbignLFxcbiAgJykgKyAnICcgKyBicmFjZXNbMV07XG5cdCAgfVxuXG5cdCAgcmV0dXJuIGJyYWNlc1swXSArIGJhc2UgKyAnICcgKyBvdXRwdXQuam9pbignLCAnKSArICcgJyArIGJyYWNlc1sxXTtcblx0fSAvLyBOT1RFOiBUaGVzZSB0eXBlIGNoZWNraW5nIGZ1bmN0aW9ucyBpbnRlbnRpb25hbGx5IGRvbid0IHVzZSBgaW5zdGFuY2VvZmBcblx0Ly8gYmVjYXVzZSBpdCBpcyBmcmFnaWxlIGFuZCBjYW4gYmUgZWFzaWx5IGZha2VkIHdpdGggYE9iamVjdC5jcmVhdGUoKWAuXG5cblxuXHRmdW5jdGlvbiBpc0FycmF5KGFyKSB7XG5cdCAgcmV0dXJuIEFycmF5LmlzQXJyYXkoYXIpO1xuXHR9XG5cdGZ1bmN0aW9uIGlzQm9vbGVhbihhcmcpIHtcblx0ICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nO1xuXHR9XG5cdGZ1bmN0aW9uIGlzTnVsbChhcmcpIHtcblx0ICByZXR1cm4gYXJnID09PSBudWxsO1xuXHR9XG5cdGZ1bmN0aW9uIGlzTnVsbE9yVW5kZWZpbmVkKGFyZykge1xuXHQgIHJldHVybiBhcmcgPT0gbnVsbDtcblx0fVxuXHRmdW5jdGlvbiBpc051bWJlcihhcmcpIHtcblx0ICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ251bWJlcic7XG5cdH1cblx0ZnVuY3Rpb24gaXNTdHJpbmcoYXJnKSB7XG5cdCAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xuXHR9XG5cdGZ1bmN0aW9uIGlzU3ltYm9sKGFyZykge1xuXHQgIHJldHVybiBfdHlwZW9mJDEoYXJnKSA9PT0gJ3N5bWJvbCc7XG5cdH1cblx0ZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG5cdCAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xuXHR9XG5cdGZ1bmN0aW9uIGlzUmVnRXhwKHJlKSB7XG5cdCAgcmV0dXJuIGlzT2JqZWN0KHJlKSAmJiBvYmplY3RUb1N0cmluZyhyZSkgPT09ICdbb2JqZWN0IFJlZ0V4cF0nO1xuXHR9XG5cdGZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuXHQgIHJldHVybiBfdHlwZW9mJDEoYXJnKSA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xuXHR9XG5cdGZ1bmN0aW9uIGlzRGF0ZShkKSB7XG5cdCAgcmV0dXJuIGlzT2JqZWN0KGQpICYmIG9iamVjdFRvU3RyaW5nKGQpID09PSAnW29iamVjdCBEYXRlXSc7XG5cdH1cblx0ZnVuY3Rpb24gaXNFcnJvcihlKSB7XG5cdCAgcmV0dXJuIGlzT2JqZWN0KGUpICYmIChvYmplY3RUb1N0cmluZyhlKSA9PT0gJ1tvYmplY3QgRXJyb3JdJyB8fCBlIGluc3RhbmNlb2YgRXJyb3IpO1xuXHR9XG5cdGZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG5cdCAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbic7XG5cdH1cblx0ZnVuY3Rpb24gaXNQcmltaXRpdmUoYXJnKSB7XG5cdCAgcmV0dXJuIGFyZyA9PT0gbnVsbCB8fCB0eXBlb2YgYXJnID09PSAnYm9vbGVhbicgfHwgdHlwZW9mIGFyZyA9PT0gJ251bWJlcicgfHwgdHlwZW9mIGFyZyA9PT0gJ3N0cmluZycgfHwgX3R5cGVvZiQxKGFyZykgPT09ICdzeW1ib2wnIHx8IC8vIEVTNiBzeW1ib2xcblx0ICB0eXBlb2YgYXJnID09PSAndW5kZWZpbmVkJztcblx0fVxuXHRmdW5jdGlvbiBpc0J1ZmZlcihtYXliZUJ1Zikge1xuXHQgIHJldHVybiBCdWZmZXIuaXNCdWZmZXIobWF5YmVCdWYpO1xuXHR9XG5cblx0ZnVuY3Rpb24gb2JqZWN0VG9TdHJpbmcobykge1xuXHQgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyk7XG5cdH1cblxuXHRmdW5jdGlvbiBwYWQobikge1xuXHQgIHJldHVybiBuIDwgMTAgPyAnMCcgKyBuLnRvU3RyaW5nKDEwKSA6IG4udG9TdHJpbmcoMTApO1xuXHR9XG5cblx0dmFyIG1vbnRocyA9IFsnSmFuJywgJ0ZlYicsICdNYXInLCAnQXByJywgJ01heScsICdKdW4nLCAnSnVsJywgJ0F1ZycsICdTZXAnLCAnT2N0JywgJ05vdicsICdEZWMnXTsgLy8gMjYgRmViIDE2OjE5OjM0XG5cblx0ZnVuY3Rpb24gdGltZXN0YW1wJDEoKSB7XG5cdCAgdmFyIGQgPSBuZXcgRGF0ZSgpO1xuXHQgIHZhciB0aW1lID0gW3BhZChkLmdldEhvdXJzKCkpLCBwYWQoZC5nZXRNaW51dGVzKCkpLCBwYWQoZC5nZXRTZWNvbmRzKCkpXS5qb2luKCc6Jyk7XG5cdCAgcmV0dXJuIFtkLmdldERhdGUoKSwgbW9udGhzW2QuZ2V0TW9udGgoKV0sIHRpbWVdLmpvaW4oJyAnKTtcblx0fSAvLyBsb2cgaXMganVzdCBhIHRoaW4gd3JhcHBlciB0byBjb25zb2xlLmxvZyB0aGF0IHByZXBlbmRzIGEgdGltZXN0YW1wXG5cblxuXHRmdW5jdGlvbiBsb2coKSB7XG5cdCAgY29uc29sZS5sb2coJyVzIC0gJXMnLCB0aW1lc3RhbXAkMSgpLCBmb3JtYXQuYXBwbHkobnVsbCwgYXJndW1lbnRzKSk7XG5cdH1cblx0ZnVuY3Rpb24gX2V4dGVuZChvcmlnaW4sIGFkZCkge1xuXHQgIC8vIERvbid0IGRvIGFueXRoaW5nIGlmIGFkZCBpc24ndCBhbiBvYmplY3Rcblx0ICBpZiAoIWFkZCB8fCAhaXNPYmplY3QoYWRkKSkgcmV0dXJuIG9yaWdpbjtcblx0ICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGFkZCk7XG5cdCAgdmFyIGkgPSBrZXlzLmxlbmd0aDtcblxuXHQgIHdoaWxlIChpLS0pIHtcblx0ICAgIG9yaWdpbltrZXlzW2ldXSA9IGFkZFtrZXlzW2ldXTtcblx0ICB9XG5cblx0ICByZXR1cm4gb3JpZ2luO1xuXHR9XG5cblx0ZnVuY3Rpb24gaGFzT3duUHJvcGVydHkob2JqLCBwcm9wKSB7XG5cdCAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApO1xuXHR9XG5cblx0dmFyIHV0aWwgPSB7XG5cdCAgaW5oZXJpdHM6IGluaGVyaXRzJDEsXG5cdCAgX2V4dGVuZDogX2V4dGVuZCxcblx0ICBsb2c6IGxvZyxcblx0ICBpc0J1ZmZlcjogaXNCdWZmZXIsXG5cdCAgaXNQcmltaXRpdmU6IGlzUHJpbWl0aXZlLFxuXHQgIGlzRnVuY3Rpb246IGlzRnVuY3Rpb24sXG5cdCAgaXNFcnJvcjogaXNFcnJvcixcblx0ICBpc0RhdGU6IGlzRGF0ZSxcblx0ICBpc09iamVjdDogaXNPYmplY3QsXG5cdCAgaXNSZWdFeHA6IGlzUmVnRXhwLFxuXHQgIGlzVW5kZWZpbmVkOiBpc1VuZGVmaW5lZCxcblx0ICBpc1N5bWJvbDogaXNTeW1ib2wsXG5cdCAgaXNTdHJpbmc6IGlzU3RyaW5nLFxuXHQgIGlzTnVtYmVyOiBpc051bWJlcixcblx0ICBpc051bGxPclVuZGVmaW5lZDogaXNOdWxsT3JVbmRlZmluZWQsXG5cdCAgaXNOdWxsOiBpc051bGwsXG5cdCAgaXNCb29sZWFuOiBpc0Jvb2xlYW4sXG5cdCAgaXNBcnJheTogaXNBcnJheSxcblx0ICBpbnNwZWN0OiBpbnNwZWN0LFxuXHQgIGRlcHJlY2F0ZTogZGVwcmVjYXRlLFxuXHQgIGZvcm1hdDogZm9ybWF0LFxuXHQgIGRlYnVnbG9nOiBkZWJ1Z2xvZ1xuXHR9O1xuXG5cdHZhciB1dGlsJDEgPSAvKiNfX1BVUkVfXyovT2JqZWN0LmZyZWV6ZSh7XG5cdFx0Zm9ybWF0OiBmb3JtYXQsXG5cdFx0ZGVwcmVjYXRlOiBkZXByZWNhdGUsXG5cdFx0ZGVidWdsb2c6IGRlYnVnbG9nLFxuXHRcdGluc3BlY3Q6IGluc3BlY3QsXG5cdFx0aXNBcnJheTogaXNBcnJheSxcblx0XHRpc0Jvb2xlYW46IGlzQm9vbGVhbixcblx0XHRpc051bGw6IGlzTnVsbCxcblx0XHRpc051bGxPclVuZGVmaW5lZDogaXNOdWxsT3JVbmRlZmluZWQsXG5cdFx0aXNOdW1iZXI6IGlzTnVtYmVyLFxuXHRcdGlzU3RyaW5nOiBpc1N0cmluZyxcblx0XHRpc1N5bWJvbDogaXNTeW1ib2wsXG5cdFx0aXNVbmRlZmluZWQ6IGlzVW5kZWZpbmVkLFxuXHRcdGlzUmVnRXhwOiBpc1JlZ0V4cCxcblx0XHRpc09iamVjdDogaXNPYmplY3QsXG5cdFx0aXNEYXRlOiBpc0RhdGUsXG5cdFx0aXNFcnJvcjogaXNFcnJvcixcblx0XHRpc0Z1bmN0aW9uOiBpc0Z1bmN0aW9uLFxuXHRcdGlzUHJpbWl0aXZlOiBpc1ByaW1pdGl2ZSxcblx0XHRpc0J1ZmZlcjogaXNCdWZmZXIsXG5cdFx0bG9nOiBsb2csXG5cdFx0aW5oZXJpdHM6IGluaGVyaXRzJDEsXG5cdFx0X2V4dGVuZDogX2V4dGVuZCxcblx0XHRkZWZhdWx0OiB1dGlsXG5cdH0pO1xuXG5cdHZhciB1dGlsJDIgPSBnZXRDanNFeHBvcnRGcm9tTmFtZXNwYWNlKHV0aWwkMSk7XG5cblx0ZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrJDIoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG5cdGZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzJDIodGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfVxuXG5cdGZ1bmN0aW9uIF9jcmVhdGVDbGFzcyQyKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgX2RlZmluZVByb3BlcnRpZXMkMihDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzJDIoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9XG5cblx0dmFyIEJ1ZmZlciQxID0gYnVmZmVyLkJ1ZmZlcjtcblx0dmFyIHJhbmRvbUJ5dGVzJDEgPSB1dGlscy5yYW5kb21CeXRlcztcblx0dmFyIGRlcHJlY2F0ZSQxID0gdXRpbCQyLmRlcHJlY2F0ZTsgLy8gY29uc3RhbnRzXG5cblx0dmFyIFBST0NFU1NfVU5JUVVFID0gcmFuZG9tQnl0ZXMkMSg1KTsgLy8gUmVndWxhciBleHByZXNzaW9uIHRoYXQgY2hlY2tzIGZvciBoZXggdmFsdWVcblxuXHR2YXIgY2hlY2tGb3JIZXhSZWdFeHAgPSBuZXcgUmVnRXhwKCdeWzAtOWEtZkEtRl17MjR9JCcpO1xuXHR2YXIgaGFzQnVmZmVyVHlwZSA9IGZhbHNlOyAvLyBDaGVjayBpZiBidWZmZXIgZXhpc3RzXG5cblx0dHJ5IHtcblx0ICBpZiAoQnVmZmVyJDEgJiYgQnVmZmVyJDEuZnJvbSkgaGFzQnVmZmVyVHlwZSA9IHRydWU7XG5cdH0gY2F0Y2ggKGVycikge1xuXHQgIGhhc0J1ZmZlclR5cGUgPSBmYWxzZTtcblx0fSAvLyBQcmVjb21wdXRlZCBoZXggdGFibGUgZW5hYmxlcyBzcGVlZHkgaGV4IHN0cmluZyBjb252ZXJzaW9uXG5cblxuXHR2YXIgaGV4VGFibGUgPSBbXTtcblxuXHRmb3IgKHZhciBfaSA9IDA7IF9pIDwgMjU2OyBfaSsrKSB7XG5cdCAgaGV4VGFibGVbX2ldID0gKF9pIDw9IDE1ID8gJzAnIDogJycpICsgX2kudG9TdHJpbmcoMTYpO1xuXHR9IC8vIExvb2t1cCB0YWJsZXNcblxuXG5cdHZhciBkZWNvZGVMb29rdXAgPSBbXTtcblx0dmFyIGkgPSAwO1xuXG5cdHdoaWxlIChpIDwgMTApIHtcblx0ICBkZWNvZGVMb29rdXBbMHgzMCArIGldID0gaSsrO1xuXHR9XG5cblx0d2hpbGUgKGkgPCAxNikge1xuXHQgIGRlY29kZUxvb2t1cFsweDQxIC0gMTAgKyBpXSA9IGRlY29kZUxvb2t1cFsweDYxIC0gMTAgKyBpXSA9IGkrKztcblx0fVxuXG5cdHZhciBfQnVmZmVyID0gQnVmZmVyJDE7XG5cblx0ZnVuY3Rpb24gY29udmVydFRvSGV4KGJ5dGVzKSB7XG5cdCAgcmV0dXJuIGJ5dGVzLnRvU3RyaW5nKCdoZXgnKTtcblx0fVxuXG5cdGZ1bmN0aW9uIG1ha2VPYmplY3RJZEVycm9yKGludmFsaWRTdHJpbmcsIGluZGV4KSB7XG5cdCAgdmFyIGludmFsaWRDaGFyYWN0ZXIgPSBpbnZhbGlkU3RyaW5nW2luZGV4XTtcblx0ICByZXR1cm4gbmV3IFR5cGVFcnJvcihcIk9iamVjdElkIHN0cmluZyBcXFwiXCIuY29uY2F0KGludmFsaWRTdHJpbmcsIFwiXFxcIiBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlciBcXFwiXCIpLmNvbmNhdChpbnZhbGlkQ2hhcmFjdGVyLCBcIlxcXCIgd2l0aCBjaGFyYWN0ZXIgY29kZSAoXCIpLmNvbmNhdChpbnZhbGlkU3RyaW5nLmNoYXJDb2RlQXQoaW5kZXgpLCBcIikuIEFsbCBjaGFyYWN0ZXIgY29kZXMgZm9yIGEgbm9uLWhleCBzdHJpbmcgbXVzdCBiZSBsZXNzIHRoYW4gMjU2LlwiKSk7XG5cdH1cblx0LyoqXG5cdCAqIEEgY2xhc3MgcmVwcmVzZW50YXRpb24gb2YgdGhlIEJTT04gT2JqZWN0SWQgdHlwZS5cblx0ICovXG5cblxuXHR2YXIgT2JqZWN0SWQgPVxuXHQvKiNfX1BVUkVfXyovXG5cdGZ1bmN0aW9uICgpIHtcblx0ICAvKipcblx0ICAgKiBDcmVhdGUgYW4gT2JqZWN0SWQgdHlwZVxuXHQgICAqXG5cdCAgICogQHBhcmFtIHsoc3RyaW5nfEJ1ZmZlcnxudW1iZXIpfSBpZCBDYW4gYmUgYSAyNCBieXRlIGhleCBzdHJpbmcsIDEyIGJ5dGUgYmluYXJ5IEJ1ZmZlciwgb3IgYSBOdW1iZXIuXG5cdCAgICogQHByb3BlcnR5IHtudW1iZXJ9IGdlbmVyYXRpb25UaW1lIFRoZSBnZW5lcmF0aW9uIHRpbWUgb2YgdGhpcyBPYmplY3RJZCBpbnN0YW5jZVxuXHQgICAqIEByZXR1cm4ge09iamVjdElkfSBpbnN0YW5jZSBvZiBPYmplY3RJZC5cblx0ICAgKi9cblx0ICBmdW5jdGlvbiBPYmplY3RJZChpZCkge1xuXHQgICAgX2NsYXNzQ2FsbENoZWNrJDIodGhpcywgT2JqZWN0SWQpO1xuXG5cdCAgICAvLyBEdWNrLXR5cGluZyB0byBzdXBwb3J0IE9iamVjdElkIGZyb20gZGlmZmVyZW50IG5wbSBwYWNrYWdlc1xuXHQgICAgaWYgKGlkIGluc3RhbmNlb2YgT2JqZWN0SWQpIHJldHVybiBpZDsgLy8gVGhlIG1vc3QgY29tbW9uIHVzZWNhc2UgKGJsYW5rIGlkLCBuZXcgb2JqZWN0SWQgaW5zdGFuY2UpXG5cblx0ICAgIGlmIChpZCA9PSBudWxsIHx8IHR5cGVvZiBpZCA9PT0gJ251bWJlcicpIHtcblx0ICAgICAgLy8gR2VuZXJhdGUgYSBuZXcgaWRcblx0ICAgICAgdGhpcy5pZCA9IE9iamVjdElkLmdlbmVyYXRlKGlkKTsgLy8gSWYgd2UgYXJlIGNhY2hpbmcgdGhlIGhleCBzdHJpbmdcblxuXHQgICAgICBpZiAoT2JqZWN0SWQuY2FjaGVIZXhTdHJpbmcpIHRoaXMuX19pZCA9IHRoaXMudG9TdHJpbmcoJ2hleCcpOyAvLyBSZXR1cm4gdGhlIG9iamVjdFxuXG5cdCAgICAgIHJldHVybjtcblx0ICAgIH0gLy8gQ2hlY2sgaWYgdGhlIHBhc3NlZCBpbiBpZCBpcyB2YWxpZFxuXG5cblx0ICAgIHZhciB2YWxpZCA9IE9iamVjdElkLmlzVmFsaWQoaWQpOyAvLyBUaHJvdyBhbiBlcnJvciBpZiBpdCdzIG5vdCBhIHZhbGlkIHNldHVwXG5cblx0ICAgIGlmICghdmFsaWQgJiYgaWQgIT0gbnVsbCkge1xuXHQgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBwYXNzZWQgaW4gbXVzdCBiZSBhIHNpbmdsZSBTdHJpbmcgb2YgMTIgYnl0ZXMgb3IgYSBzdHJpbmcgb2YgMjQgaGV4IGNoYXJhY3RlcnMnKTtcblx0ICAgIH0gZWxzZSBpZiAodmFsaWQgJiYgdHlwZW9mIGlkID09PSAnc3RyaW5nJyAmJiBpZC5sZW5ndGggPT09IDI0ICYmIGhhc0J1ZmZlclR5cGUpIHtcblx0ICAgICAgcmV0dXJuIG5ldyBPYmplY3RJZChCdWZmZXIkMS5mcm9tKGlkLCAnaGV4JykpO1xuXHQgICAgfSBlbHNlIGlmICh2YWxpZCAmJiB0eXBlb2YgaWQgPT09ICdzdHJpbmcnICYmIGlkLmxlbmd0aCA9PT0gMjQpIHtcblx0ICAgICAgcmV0dXJuIE9iamVjdElkLmNyZWF0ZUZyb21IZXhTdHJpbmcoaWQpO1xuXHQgICAgfSBlbHNlIGlmIChpZCAhPSBudWxsICYmIGlkLmxlbmd0aCA9PT0gMTIpIHtcblx0ICAgICAgLy8gYXNzdW1lIDEyIGJ5dGUgc3RyaW5nXG5cdCAgICAgIHRoaXMuaWQgPSBpZDtcblx0ICAgIH0gZWxzZSBpZiAoaWQgIT0gbnVsbCAmJiBpZC50b0hleFN0cmluZykge1xuXHQgICAgICAvLyBEdWNrLXR5cGluZyB0byBzdXBwb3J0IE9iamVjdElkIGZyb20gZGlmZmVyZW50IG5wbSBwYWNrYWdlc1xuXHQgICAgICByZXR1cm4gT2JqZWN0SWQuY3JlYXRlRnJvbUhleFN0cmluZyhpZC50b0hleFN0cmluZygpKTtcblx0ICAgIH0gZWxzZSB7XG5cdCAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IHBhc3NlZCBpbiBtdXN0IGJlIGEgc2luZ2xlIFN0cmluZyBvZiAxMiBieXRlcyBvciBhIHN0cmluZyBvZiAyNCBoZXggY2hhcmFjdGVycycpO1xuXHQgICAgfVxuXG5cdCAgICBpZiAoT2JqZWN0SWQuY2FjaGVIZXhTdHJpbmcpIHRoaXMuX19pZCA9IHRoaXMudG9TdHJpbmcoJ2hleCcpO1xuXHQgIH1cblx0ICAvKipcblx0ICAgKiBSZXR1cm4gdGhlIE9iamVjdElkIGlkIGFzIGEgMjQgYnl0ZSBoZXggc3RyaW5nIHJlcHJlc2VudGF0aW9uXG5cdCAgICpcblx0ICAgKiBAbWV0aG9kXG5cdCAgICogQHJldHVybiB7c3RyaW5nfSByZXR1cm4gdGhlIDI0IGJ5dGUgaGV4IHN0cmluZyByZXByZXNlbnRhdGlvbi5cblx0ICAgKi9cblxuXG5cdCAgX2NyZWF0ZUNsYXNzJDIoT2JqZWN0SWQsIFt7XG5cdCAgICBrZXk6IFwidG9IZXhTdHJpbmdcIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB0b0hleFN0cmluZygpIHtcblx0ICAgICAgaWYgKE9iamVjdElkLmNhY2hlSGV4U3RyaW5nICYmIHRoaXMuX19pZCkgcmV0dXJuIHRoaXMuX19pZDtcblx0ICAgICAgdmFyIGhleFN0cmluZyA9ICcnO1xuXG5cdCAgICAgIGlmICghdGhpcy5pZCB8fCAhdGhpcy5pZC5sZW5ndGgpIHtcblx0ICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIE9iamVjdElkLCBPYmplY3RJZC5pZCBtdXN0IGJlIGVpdGhlciBhIHN0cmluZyBvciBhIEJ1ZmZlciwgYnV0IGlzIFsnICsgSlNPTi5zdHJpbmdpZnkodGhpcy5pZCkgKyAnXScpO1xuXHQgICAgICB9XG5cblx0ICAgICAgaWYgKHRoaXMuaWQgaW5zdGFuY2VvZiBfQnVmZmVyKSB7XG5cdCAgICAgICAgaGV4U3RyaW5nID0gY29udmVydFRvSGV4KHRoaXMuaWQpO1xuXHQgICAgICAgIGlmIChPYmplY3RJZC5jYWNoZUhleFN0cmluZykgdGhpcy5fX2lkID0gaGV4U3RyaW5nO1xuXHQgICAgICAgIHJldHVybiBoZXhTdHJpbmc7XG5cdCAgICAgIH1cblxuXHQgICAgICBmb3IgKHZhciBfaTIgPSAwOyBfaTIgPCB0aGlzLmlkLmxlbmd0aDsgX2kyKyspIHtcblx0ICAgICAgICB2YXIgaGV4Q2hhciA9IGhleFRhYmxlW3RoaXMuaWQuY2hhckNvZGVBdChfaTIpXTtcblxuXHQgICAgICAgIGlmICh0eXBlb2YgaGV4Q2hhciAhPT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAgIHRocm93IG1ha2VPYmplY3RJZEVycm9yKHRoaXMuaWQsIF9pMik7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgaGV4U3RyaW5nICs9IGhleENoYXI7XG5cdCAgICAgIH1cblxuXHQgICAgICBpZiAoT2JqZWN0SWQuY2FjaGVIZXhTdHJpbmcpIHRoaXMuX19pZCA9IGhleFN0cmluZztcblx0ICAgICAgcmV0dXJuIGhleFN0cmluZztcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogVXBkYXRlIHRoZSBPYmplY3RJZCBpbmRleCB1c2VkIGluIGdlbmVyYXRpbmcgbmV3IE9iamVjdElkJ3Mgb24gdGhlIGRyaXZlclxuXHQgICAgICpcblx0ICAgICAqIEBtZXRob2Rcblx0ICAgICAqIEByZXR1cm4ge251bWJlcn0gcmV0dXJucyBuZXh0IGluZGV4IHZhbHVlLlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwidG9TdHJpbmdcIixcblxuXHQgICAgLyoqXG5cdCAgICAgKiBDb252ZXJ0cyB0aGUgaWQgaW50byBhIDI0IGJ5dGUgaGV4IHN0cmluZyBmb3IgcHJpbnRpbmdcblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0ge1N0cmluZ30gZm9ybWF0IFRoZSBCdWZmZXIgdG9TdHJpbmcgZm9ybWF0IHBhcmFtZXRlci5cblx0ICAgICAqIEByZXR1cm4ge1N0cmluZ30gcmV0dXJuIHRoZSAyNCBieXRlIGhleCBzdHJpbmcgcmVwcmVzZW50YXRpb24uXG5cdCAgICAgKiBAaWdub3JlXG5cdCAgICAgKi9cblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB0b1N0cmluZyhmb3JtYXQpIHtcblx0ICAgICAgLy8gSXMgdGhlIGlkIGEgYnVmZmVyIHRoZW4gdXNlIHRoZSBidWZmZXIgdG9TdHJpbmcgbWV0aG9kIHRvIHJldHVybiB0aGUgZm9ybWF0XG5cdCAgICAgIGlmICh0aGlzLmlkICYmIHRoaXMuaWQuY29weSkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLmlkLnRvU3RyaW5nKHR5cGVvZiBmb3JtYXQgPT09ICdzdHJpbmcnID8gZm9ybWF0IDogJ2hleCcpO1xuXHQgICAgICB9XG5cblx0ICAgICAgcmV0dXJuIHRoaXMudG9IZXhTdHJpbmcoKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQ29udmVydHMgdG8gaXRzIEpTT04gcmVwcmVzZW50YXRpb24uXG5cdCAgICAgKlxuXHQgICAgICogQHJldHVybiB7U3RyaW5nfSByZXR1cm4gdGhlIDI0IGJ5dGUgaGV4IHN0cmluZyByZXByZXNlbnRhdGlvbi5cblx0ICAgICAqIEBpZ25vcmVcblx0ICAgICAqL1xuXG5cdCAgfSwge1xuXHQgICAga2V5OiBcInRvSlNPTlwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHRvSlNPTigpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMudG9IZXhTdHJpbmcoKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQ29tcGFyZXMgdGhlIGVxdWFsaXR5IG9mIHRoaXMgT2JqZWN0SWQgd2l0aCBgb3RoZXJJRGAuXG5cdCAgICAgKlxuXHQgICAgICogQG1ldGhvZFxuXHQgICAgICogQHBhcmFtIHtvYmplY3R9IG90aGVySWQgT2JqZWN0SWQgaW5zdGFuY2UgdG8gY29tcGFyZSBhZ2FpbnN0LlxuXHQgICAgICogQHJldHVybiB7Ym9vbGVhbn0gdGhlIHJlc3VsdCBvZiBjb21wYXJpbmcgdHdvIE9iamVjdElkJ3Ncblx0ICAgICAqL1xuXG5cdCAgfSwge1xuXHQgICAga2V5OiBcImVxdWFsc1wiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIGVxdWFscyhvdGhlcklkKSB7XG5cdCAgICAgIGlmIChvdGhlcklkIGluc3RhbmNlb2YgT2JqZWN0SWQpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy50b1N0cmluZygpID09PSBvdGhlcklkLnRvU3RyaW5nKCk7XG5cdCAgICAgIH1cblxuXHQgICAgICBpZiAodHlwZW9mIG90aGVySWQgPT09ICdzdHJpbmcnICYmIE9iamVjdElkLmlzVmFsaWQob3RoZXJJZCkgJiYgb3RoZXJJZC5sZW5ndGggPT09IDEyICYmIHRoaXMuaWQgaW5zdGFuY2VvZiBfQnVmZmVyKSB7XG5cdCAgICAgICAgcmV0dXJuIG90aGVySWQgPT09IHRoaXMuaWQudG9TdHJpbmcoJ2JpbmFyeScpO1xuXHQgICAgICB9XG5cblx0ICAgICAgaWYgKHR5cGVvZiBvdGhlcklkID09PSAnc3RyaW5nJyAmJiBPYmplY3RJZC5pc1ZhbGlkKG90aGVySWQpICYmIG90aGVySWQubGVuZ3RoID09PSAyNCkge1xuXHQgICAgICAgIHJldHVybiBvdGhlcklkLnRvTG93ZXJDYXNlKCkgPT09IHRoaXMudG9IZXhTdHJpbmcoKTtcblx0ICAgICAgfVxuXG5cdCAgICAgIGlmICh0eXBlb2Ygb3RoZXJJZCA9PT0gJ3N0cmluZycgJiYgT2JqZWN0SWQuaXNWYWxpZChvdGhlcklkKSAmJiBvdGhlcklkLmxlbmd0aCA9PT0gMTIpIHtcblx0ICAgICAgICByZXR1cm4gb3RoZXJJZCA9PT0gdGhpcy5pZDtcblx0ICAgICAgfVxuXG5cdCAgICAgIGlmIChvdGhlcklkICE9IG51bGwgJiYgKG90aGVySWQgaW5zdGFuY2VvZiBPYmplY3RJZCB8fCBvdGhlcklkLnRvSGV4U3RyaW5nKSkge1xuXHQgICAgICAgIHJldHVybiBvdGhlcklkLnRvSGV4U3RyaW5nKCkgPT09IHRoaXMudG9IZXhTdHJpbmcoKTtcblx0ICAgICAgfVxuXG5cdCAgICAgIHJldHVybiBmYWxzZTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0dXJucyB0aGUgZ2VuZXJhdGlvbiBkYXRlIChhY2N1cmF0ZSB1cCB0byB0aGUgc2Vjb25kKSB0aGF0IHRoaXMgSUQgd2FzIGdlbmVyYXRlZC5cblx0ICAgICAqXG5cdCAgICAgKiBAbWV0aG9kXG5cdCAgICAgKiBAcmV0dXJuIHtEYXRlfSB0aGUgZ2VuZXJhdGlvbiBkYXRlXG5cdCAgICAgKi9cblxuXHQgIH0sIHtcblx0ICAgIGtleTogXCJnZXRUaW1lc3RhbXBcIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRUaW1lc3RhbXAoKSB7XG5cdCAgICAgIHZhciB0aW1lc3RhbXAgPSBuZXcgRGF0ZSgpO1xuXHQgICAgICB2YXIgdGltZSA9IHRoaXMuaWQucmVhZFVJbnQzMkJFKDApO1xuXHQgICAgICB0aW1lc3RhbXAuc2V0VGltZShNYXRoLmZsb29yKHRpbWUpICogMTAwMCk7XG5cdCAgICAgIHJldHVybiB0aW1lc3RhbXA7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEBpZ25vcmVcblx0ICAgICAqL1xuXG5cdCAgfSwge1xuXHQgICAga2V5OiBcInRvRXh0ZW5kZWRKU09OXCIsXG5cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gdG9FeHRlbmRlZEpTT04oKSB7XG5cdCAgICAgIGlmICh0aGlzLnRvSGV4U3RyaW5nKSByZXR1cm4ge1xuXHQgICAgICAgICRvaWQ6IHRoaXMudG9IZXhTdHJpbmcoKVxuXHQgICAgICB9O1xuXHQgICAgICByZXR1cm4ge1xuXHQgICAgICAgICRvaWQ6IHRoaXMudG9TdHJpbmcoJ2hleCcpXG5cdCAgICAgIH07XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEBpZ25vcmVcblx0ICAgICAqL1xuXG5cdCAgfV0sIFt7XG5cdCAgICBrZXk6IFwiZ2V0SW5jXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0SW5jKCkge1xuXHQgICAgICByZXR1cm4gT2JqZWN0SWQuaW5kZXggPSAoT2JqZWN0SWQuaW5kZXggKyAxKSAlIDB4ZmZmZmZmO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBHZW5lcmF0ZSBhIDEyIGJ5dGUgaWQgYnVmZmVyIHVzZWQgaW4gT2JqZWN0SWQnc1xuXHQgICAgICpcblx0ICAgICAqIEBtZXRob2Rcblx0ICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbdGltZV0gb3B0aW9uYWwgcGFyYW1ldGVyIGFsbG93aW5nIHRvIHBhc3MgaW4gYSBzZWNvbmQgYmFzZWQgdGltZXN0YW1wLlxuXHQgICAgICogQHJldHVybiB7QnVmZmVyfSByZXR1cm4gdGhlIDEyIGJ5dGUgaWQgYnVmZmVyIHN0cmluZy5cblx0ICAgICAqL1xuXG5cdCAgfSwge1xuXHQgICAga2V5OiBcImdlbmVyYXRlXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gZ2VuZXJhdGUodGltZSkge1xuXHQgICAgICBpZiAoJ251bWJlcicgIT09IHR5cGVvZiB0aW1lKSB7XG5cdCAgICAgICAgdGltZSA9IH5+KERhdGUubm93KCkgLyAxMDAwKTtcblx0ICAgICAgfVxuXG5cdCAgICAgIHZhciBpbmMgPSBPYmplY3RJZC5nZXRJbmMoKTtcblx0ICAgICAgdmFyIGJ1ZmZlciQkMSA9IEJ1ZmZlciQxLmFsbG9jKDEyKTsgLy8gNC1ieXRlIHRpbWVzdGFtcFxuXG5cdCAgICAgIGJ1ZmZlciQkMVszXSA9IHRpbWUgJiAweGZmO1xuXHQgICAgICBidWZmZXIkJDFbMl0gPSB0aW1lID4+IDggJiAweGZmO1xuXHQgICAgICBidWZmZXIkJDFbMV0gPSB0aW1lID4+IDE2ICYgMHhmZjtcblx0ICAgICAgYnVmZmVyJCQxWzBdID0gdGltZSA+PiAyNCAmIDB4ZmY7IC8vIDUtYnl0ZSBwcm9jZXNzIHVuaXF1ZVxuXG5cdCAgICAgIGJ1ZmZlciQkMVs0XSA9IFBST0NFU1NfVU5JUVVFWzBdO1xuXHQgICAgICBidWZmZXIkJDFbNV0gPSBQUk9DRVNTX1VOSVFVRVsxXTtcblx0ICAgICAgYnVmZmVyJCQxWzZdID0gUFJPQ0VTU19VTklRVUVbMl07XG5cdCAgICAgIGJ1ZmZlciQkMVs3XSA9IFBST0NFU1NfVU5JUVVFWzNdO1xuXHQgICAgICBidWZmZXIkJDFbOF0gPSBQUk9DRVNTX1VOSVFVRVs0XTsgLy8gMy1ieXRlIGNvdW50ZXJcblxuXHQgICAgICBidWZmZXIkJDFbMTFdID0gaW5jICYgMHhmZjtcblx0ICAgICAgYnVmZmVyJCQxWzEwXSA9IGluYyA+PiA4ICYgMHhmZjtcblx0ICAgICAgYnVmZmVyJCQxWzldID0gaW5jID4+IDE2ICYgMHhmZjtcblx0ICAgICAgcmV0dXJuIGJ1ZmZlciQkMTtcblx0ICAgIH1cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwiY3JlYXRlUGtcIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBjcmVhdGVQaygpIHtcblx0ICAgICAgcmV0dXJuIG5ldyBPYmplY3RJZCgpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBDcmVhdGVzIGFuIE9iamVjdElkIGZyb20gYSBzZWNvbmQgYmFzZWQgbnVtYmVyLCB3aXRoIHRoZSByZXN0IG9mIHRoZSBPYmplY3RJZCB6ZXJvZWQgb3V0LiBVc2VkIGZvciBjb21wYXJpc29ucyBvciBzb3J0aW5nIHRoZSBPYmplY3RJZC5cblx0ICAgICAqXG5cdCAgICAgKiBAbWV0aG9kXG5cdCAgICAgKiBAcGFyYW0ge251bWJlcn0gdGltZSBhbiBpbnRlZ2VyIG51bWJlciByZXByZXNlbnRpbmcgYSBudW1iZXIgb2Ygc2Vjb25kcy5cblx0ICAgICAqIEByZXR1cm4ge09iamVjdElkfSByZXR1cm4gdGhlIGNyZWF0ZWQgT2JqZWN0SWRcblx0ICAgICAqL1xuXG5cdCAgfSwge1xuXHQgICAga2V5OiBcImNyZWF0ZUZyb21UaW1lXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gY3JlYXRlRnJvbVRpbWUodGltZSkge1xuXHQgICAgICB2YXIgYnVmZmVyJCQxID0gQnVmZmVyJDEuZnJvbShbMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMF0pOyAvLyBFbmNvZGUgdGltZSBpbnRvIGZpcnN0IDQgYnl0ZXNcblxuXHQgICAgICBidWZmZXIkJDFbM10gPSB0aW1lICYgMHhmZjtcblx0ICAgICAgYnVmZmVyJCQxWzJdID0gdGltZSA+PiA4ICYgMHhmZjtcblx0ICAgICAgYnVmZmVyJCQxWzFdID0gdGltZSA+PiAxNiAmIDB4ZmY7XG5cdCAgICAgIGJ1ZmZlciQkMVswXSA9IHRpbWUgPj4gMjQgJiAweGZmOyAvLyBSZXR1cm4gdGhlIG5ldyBvYmplY3RJZFxuXG5cdCAgICAgIHJldHVybiBuZXcgT2JqZWN0SWQoYnVmZmVyJCQxKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQ3JlYXRlcyBhbiBPYmplY3RJZCBmcm9tIGEgaGV4IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhbiBPYmplY3RJZC5cblx0ICAgICAqXG5cdCAgICAgKiBAbWV0aG9kXG5cdCAgICAgKiBAcGFyYW0ge3N0cmluZ30gaGV4U3RyaW5nIGNyZWF0ZSBhIE9iamVjdElkIGZyb20gYSBwYXNzZWQgaW4gMjQgYnl0ZSBoZXhzdHJpbmcuXG5cdCAgICAgKiBAcmV0dXJuIHtPYmplY3RJZH0gcmV0dXJuIHRoZSBjcmVhdGVkIE9iamVjdElkXG5cdCAgICAgKi9cblxuXHQgIH0sIHtcblx0ICAgIGtleTogXCJjcmVhdGVGcm9tSGV4U3RyaW5nXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gY3JlYXRlRnJvbUhleFN0cmluZyhzdHJpbmcpIHtcblx0ICAgICAgLy8gVGhyb3cgYW4gZXJyb3IgaWYgaXQncyBub3QgYSB2YWxpZCBzZXR1cFxuXHQgICAgICBpZiAodHlwZW9mIHN0cmluZyA9PT0gJ3VuZGVmaW5lZCcgfHwgc3RyaW5nICE9IG51bGwgJiYgc3RyaW5nLmxlbmd0aCAhPT0gMjQpIHtcblx0ICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBwYXNzZWQgaW4gbXVzdCBiZSBhIHNpbmdsZSBTdHJpbmcgb2YgMTIgYnl0ZXMgb3IgYSBzdHJpbmcgb2YgMjQgaGV4IGNoYXJhY3RlcnMnKTtcblx0ICAgICAgfSAvLyBVc2UgQnVmZmVyLmZyb20gbWV0aG9kIGlmIGF2YWlsYWJsZVxuXG5cblx0ICAgICAgaWYgKGhhc0J1ZmZlclR5cGUpIHJldHVybiBuZXcgT2JqZWN0SWQoQnVmZmVyJDEuZnJvbShzdHJpbmcsICdoZXgnKSk7IC8vIENhbGN1bGF0ZSBsZW5ndGhzXG5cblx0ICAgICAgdmFyIGFycmF5ID0gbmV3IF9CdWZmZXIoMTIpO1xuXHQgICAgICB2YXIgbiA9IDA7XG5cdCAgICAgIHZhciBpID0gMDtcblxuXHQgICAgICB3aGlsZSAoaSA8IDI0KSB7XG5cdCAgICAgICAgYXJyYXlbbisrXSA9IGRlY29kZUxvb2t1cFtzdHJpbmcuY2hhckNvZGVBdChpKyspXSA8PCA0IHwgZGVjb2RlTG9va3VwW3N0cmluZy5jaGFyQ29kZUF0KGkrKyldO1xuXHQgICAgICB9XG5cblx0ICAgICAgcmV0dXJuIG5ldyBPYmplY3RJZChhcnJheSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIENoZWNrcyBpZiBhIHZhbHVlIGlzIGEgdmFsaWQgYnNvbiBPYmplY3RJZFxuXHQgICAgICpcblx0ICAgICAqIEBtZXRob2Rcblx0ICAgICAqIEByZXR1cm4ge2Jvb2xlYW59IHJldHVybiB0cnVlIGlmIHRoZSB2YWx1ZSBpcyBhIHZhbGlkIGJzb24gT2JqZWN0SWQsIHJldHVybiBmYWxzZSBvdGhlcndpc2UuXG5cdCAgICAgKi9cblxuXHQgIH0sIHtcblx0ICAgIGtleTogXCJpc1ZhbGlkXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gaXNWYWxpZChpZCkge1xuXHQgICAgICBpZiAoaWQgPT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuXG5cdCAgICAgIGlmICh0eXBlb2YgaWQgPT09ICdudW1iZXInKSB7XG5cdCAgICAgICAgcmV0dXJuIHRydWU7XG5cdCAgICAgIH1cblxuXHQgICAgICBpZiAodHlwZW9mIGlkID09PSAnc3RyaW5nJykge1xuXHQgICAgICAgIHJldHVybiBpZC5sZW5ndGggPT09IDEyIHx8IGlkLmxlbmd0aCA9PT0gMjQgJiYgY2hlY2tGb3JIZXhSZWdFeHAudGVzdChpZCk7XG5cdCAgICAgIH1cblxuXHQgICAgICBpZiAoaWQgaW5zdGFuY2VvZiBPYmplY3RJZCkge1xuXHQgICAgICAgIHJldHVybiB0cnVlO1xuXHQgICAgICB9XG5cblx0ICAgICAgaWYgKGlkIGluc3RhbmNlb2YgX0J1ZmZlciAmJiBpZC5sZW5ndGggPT09IDEyKSB7XG5cdCAgICAgICAgcmV0dXJuIHRydWU7XG5cdCAgICAgIH0gLy8gRHVjay1UeXBpbmcgZGV0ZWN0aW9uIG9mIE9iamVjdElkIGxpa2Ugb2JqZWN0c1xuXG5cblx0ICAgICAgaWYgKGlkLnRvSGV4U3RyaW5nKSB7XG5cdCAgICAgICAgcmV0dXJuIGlkLmlkLmxlbmd0aCA9PT0gMTIgfHwgaWQuaWQubGVuZ3RoID09PSAyNCAmJiBjaGVja0ZvckhleFJlZ0V4cC50ZXN0KGlkLmlkKTtcblx0ICAgICAgfVxuXG5cdCAgICAgIHJldHVybiBmYWxzZTtcblx0ICAgIH1cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwiZnJvbUV4dGVuZGVkSlNPTlwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIGZyb21FeHRlbmRlZEpTT04oZG9jKSB7XG5cdCAgICAgIHJldHVybiBuZXcgT2JqZWN0SWQoZG9jLiRvaWQpO1xuXHQgICAgfVxuXHQgIH1dKTtcblxuXHQgIHJldHVybiBPYmplY3RJZDtcblx0fSgpOyAvLyBEZXByZWNhdGVkIG1ldGhvZHNcblxuXG5cdE9iamVjdElkLmdldF9pbmMgPSBkZXByZWNhdGUkMShmdW5jdGlvbiAoKSB7XG5cdCAgcmV0dXJuIE9iamVjdElkLmdldEluYygpO1xuXHR9LCAnUGxlYXNlIHVzZSB0aGUgc3RhdGljIGBPYmplY3RJZC5nZXRJbmMoKWAgaW5zdGVhZCcpO1xuXHRPYmplY3RJZC5wcm90b3R5cGUuZ2V0X2luYyA9IGRlcHJlY2F0ZSQxKGZ1bmN0aW9uICgpIHtcblx0ICByZXR1cm4gT2JqZWN0SWQuZ2V0SW5jKCk7XG5cdH0sICdQbGVhc2UgdXNlIHRoZSBzdGF0aWMgYE9iamVjdElkLmdldEluYygpYCBpbnN0ZWFkJyk7XG5cdE9iamVjdElkLnByb3RvdHlwZS5nZXRJbmMgPSBkZXByZWNhdGUkMShmdW5jdGlvbiAoKSB7XG5cdCAgcmV0dXJuIE9iamVjdElkLmdldEluYygpO1xuXHR9LCAnUGxlYXNlIHVzZSB0aGUgc3RhdGljIGBPYmplY3RJZC5nZXRJbmMoKWAgaW5zdGVhZCcpO1xuXHRPYmplY3RJZC5wcm90b3R5cGUuZ2VuZXJhdGUgPSBkZXByZWNhdGUkMShmdW5jdGlvbiAodGltZSkge1xuXHQgIHJldHVybiBPYmplY3RJZC5nZW5lcmF0ZSh0aW1lKTtcblx0fSwgJ1BsZWFzZSB1c2UgdGhlIHN0YXRpYyBgT2JqZWN0SWQuZ2VuZXJhdGUodGltZSlgIGluc3RlYWQnKTtcblx0LyoqXG5cdCAqIEBpZ25vcmVcblx0ICovXG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KE9iamVjdElkLnByb3RvdHlwZSwgJ2dlbmVyYXRpb25UaW1lJywge1xuXHQgIGVudW1lcmFibGU6IHRydWUsXG5cdCAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG5cdCAgICByZXR1cm4gdGhpcy5pZFszXSB8IHRoaXMuaWRbMl0gPDwgOCB8IHRoaXMuaWRbMV0gPDwgMTYgfCB0aGlzLmlkWzBdIDw8IDI0O1xuXHQgIH0sXG5cdCAgc2V0OiBmdW5jdGlvbiBzZXQodmFsdWUpIHtcblx0ICAgIC8vIEVuY29kZSB0aW1lIGludG8gZmlyc3QgNCBieXRlc1xuXHQgICAgdGhpcy5pZFszXSA9IHZhbHVlICYgMHhmZjtcblx0ICAgIHRoaXMuaWRbMl0gPSB2YWx1ZSA+PiA4ICYgMHhmZjtcblx0ICAgIHRoaXMuaWRbMV0gPSB2YWx1ZSA+PiAxNiAmIDB4ZmY7XG5cdCAgICB0aGlzLmlkWzBdID0gdmFsdWUgPj4gMjQgJiAweGZmO1xuXHQgIH1cblx0fSk7XG5cdC8qKlxuXHQgKiBDb252ZXJ0cyB0byBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIElkLlxuXHQgKlxuXHQgKiBAcmV0dXJuIHtTdHJpbmd9IHJldHVybiB0aGUgMjQgYnl0ZSBoZXggc3RyaW5nIHJlcHJlc2VudGF0aW9uLlxuXHQgKiBAaWdub3JlXG5cdCAqL1xuXG5cdE9iamVjdElkLnByb3RvdHlwZVt1dGlsJDIuaW5zcGVjdC5jdXN0b20gfHwgJ2luc3BlY3QnXSA9IE9iamVjdElkLnByb3RvdHlwZS50b1N0cmluZztcblx0LyoqXG5cdCAqIEBpZ25vcmVcblx0ICovXG5cblx0T2JqZWN0SWQuaW5kZXggPSB+fihNYXRoLnJhbmRvbSgpICogMHhmZmZmZmYpOyAvLyBJbiA0LjAuMCBhbmQgNC4wLjEsIHRoaXMgcHJvcGVydHkgbmFtZSB3YXMgY2hhbmdlZCB0byBPYmplY3RJZCB0byBtYXRjaCB0aGUgY2xhc3MgbmFtZS5cblx0Ly8gVGhpcyBjYXVzZWQgaW50ZXJvcGVyYWJpbGl0eSBwcm9ibGVtcyB3aXRoIHByZXZpb3VzIHZlcnNpb25zIG9mIHRoZSBsaWJyYXJ5LCBzbyBpblxuXHQvLyBsYXRlciBidWlsZHMgd2UgY2hhbmdlZCBpdCBiYWNrIHRvIE9iamVjdElEIChjYXBpdGFsIEQpIHRvIG1hdGNoIGxlZ2FjeSBpbXBsZW1lbnRhdGlvbnMuXG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KE9iamVjdElkLnByb3RvdHlwZSwgJ19ic29udHlwZScsIHtcblx0ICB2YWx1ZTogJ09iamVjdElEJ1xuXHR9KTtcblx0dmFyIG9iamVjdGlkID0gT2JqZWN0SWQ7XG5cblx0ZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrJDMoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG5cdGZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzJDModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfVxuXG5cdGZ1bmN0aW9uIF9jcmVhdGVDbGFzcyQzKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgX2RlZmluZVByb3BlcnRpZXMkMyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzJDMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9XG5cblx0ZnVuY3Rpb24gYWxwaGFiZXRpemUoc3RyKSB7XG5cdCAgcmV0dXJuIHN0ci5zcGxpdCgnJykuc29ydCgpLmpvaW4oJycpO1xuXHR9XG5cdC8qKlxuXHQgKiBBIGNsYXNzIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBCU09OIFJlZ0V4cCB0eXBlLlxuXHQgKi9cblxuXG5cdHZhciBCU09OUmVnRXhwID1cblx0LyojX19QVVJFX18qL1xuXHRmdW5jdGlvbiAoKSB7XG5cdCAgLyoqXG5cdCAgICogQ3JlYXRlIGEgUmVnRXhwIHR5cGVcblx0ICAgKlxuXHQgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXR0ZXJuIFRoZSByZWd1bGFyIGV4cHJlc3Npb24gcGF0dGVybiB0byBtYXRjaFxuXHQgICAqIEBwYXJhbSB7c3RyaW5nfSBvcHRpb25zIFRoZSByZWd1bGFyIGV4cHJlc3Npb24gb3B0aW9uc1xuXHQgICAqL1xuXHQgIGZ1bmN0aW9uIEJTT05SZWdFeHAocGF0dGVybiwgb3B0aW9ucykge1xuXHQgICAgX2NsYXNzQ2FsbENoZWNrJDModGhpcywgQlNPTlJlZ0V4cCk7XG5cblx0ICAgIC8vIEV4ZWN1dGVcblx0ICAgIHRoaXMucGF0dGVybiA9IHBhdHRlcm4gfHwgJyc7XG5cdCAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zID8gYWxwaGFiZXRpemUob3B0aW9ucykgOiAnJzsgLy8gVmFsaWRhdGUgb3B0aW9uc1xuXG5cdCAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMub3B0aW9ucy5sZW5ndGg7IGkrKykge1xuXHQgICAgICBpZiAoISh0aGlzLm9wdGlvbnNbaV0gPT09ICdpJyB8fCB0aGlzLm9wdGlvbnNbaV0gPT09ICdtJyB8fCB0aGlzLm9wdGlvbnNbaV0gPT09ICd4JyB8fCB0aGlzLm9wdGlvbnNbaV0gPT09ICdsJyB8fCB0aGlzLm9wdGlvbnNbaV0gPT09ICdzJyB8fCB0aGlzLm9wdGlvbnNbaV0gPT09ICd1JykpIHtcblx0ICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgcmVndWxhciBleHByZXNzaW9uIG9wdGlvbiBbXCIuY29uY2F0KHRoaXMub3B0aW9uc1tpXSwgXCJdIGlzIG5vdCBzdXBwb3J0ZWRcIikpO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfVxuXHQgIC8qKlxuXHQgICAqIEBpZ25vcmVcblx0ICAgKi9cblxuXG5cdCAgX2NyZWF0ZUNsYXNzJDMoQlNPTlJlZ0V4cCwgW3tcblx0ICAgIGtleTogXCJ0b0V4dGVuZGVkSlNPTlwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHRvRXh0ZW5kZWRKU09OKCkge1xuXHQgICAgICByZXR1cm4ge1xuXHQgICAgICAgICRyZWd1bGFyRXhwcmVzc2lvbjoge1xuXHQgICAgICAgICAgcGF0dGVybjogdGhpcy5wYXR0ZXJuLFxuXHQgICAgICAgICAgb3B0aW9uczogdGhpcy5vcHRpb25zXG5cdCAgICAgICAgfVxuXHQgICAgICB9O1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBAaWdub3JlXG5cdCAgICAgKi9cblxuXHQgIH1dLCBbe1xuXHQgICAga2V5OiBcImZyb21FeHRlbmRlZEpTT05cIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tRXh0ZW5kZWRKU09OKGRvYykge1xuXHQgICAgICByZXR1cm4gbmV3IEJTT05SZWdFeHAoZG9jLiRyZWd1bGFyRXhwcmVzc2lvbi5wYXR0ZXJuLCBkb2MuJHJlZ3VsYXJFeHByZXNzaW9uLm9wdGlvbnMuc3BsaXQoJycpLnNvcnQoKS5qb2luKCcnKSk7XG5cdCAgICB9XG5cdCAgfV0pO1xuXG5cdCAgcmV0dXJuIEJTT05SZWdFeHA7XG5cdH0oKTtcblxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoQlNPTlJlZ0V4cC5wcm90b3R5cGUsICdfYnNvbnR5cGUnLCB7XG5cdCAgdmFsdWU6ICdCU09OUmVnRXhwJ1xuXHR9KTtcblx0dmFyIHJlZ2V4cCA9IEJTT05SZWdFeHA7XG5cblx0LyoqXG5cdCAqIEEgY2xhc3MgcmVwcmVzZW50YXRpb24gb2YgdGhlIEJTT04gU3ltYm9sIHR5cGUuXG5cdCAqL1xuXG5cdGZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayQ0KGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxuXHRmdW5jdGlvbiBfZGVmaW5lUHJvcGVydGllcyQ0KHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH1cblxuXHRmdW5jdGlvbiBfY3JlYXRlQ2xhc3MkNChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzJDQoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyQ0KENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfVxuXG5cdHZhciBCU09OU3ltYm9sID1cblx0LyojX19QVVJFX18qL1xuXHRmdW5jdGlvbiAoKSB7XG5cdCAgLyoqXG5cdCAgICogQ3JlYXRlIGEgU3ltYm9sIHR5cGVcblx0ICAgKlxuXHQgICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZSB0aGUgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgc3ltYm9sLlxuXHQgICAqL1xuXHQgIGZ1bmN0aW9uIEJTT05TeW1ib2wodmFsdWUpIHtcblx0ICAgIF9jbGFzc0NhbGxDaGVjayQ0KHRoaXMsIEJTT05TeW1ib2wpO1xuXG5cdCAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG5cdCAgfVxuXHQgIC8qKlxuXHQgICAqIEFjY2VzcyB0aGUgd3JhcHBlZCBzdHJpbmcgdmFsdWUuXG5cdCAgICpcblx0ICAgKiBAbWV0aG9kXG5cdCAgICogQHJldHVybiB7U3RyaW5nfSByZXR1cm5zIHRoZSB3cmFwcGVkIHN0cmluZy5cblx0ICAgKi9cblxuXG5cdCAgX2NyZWF0ZUNsYXNzJDQoQlNPTlN5bWJvbCwgW3tcblx0ICAgIGtleTogXCJ2YWx1ZU9mXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gdmFsdWVPZigpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEBpZ25vcmVcblx0ICAgICAqL1xuXG5cdCAgfSwge1xuXHQgICAga2V5OiBcInRvU3RyaW5nXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG5cdCAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBAaWdub3JlXG5cdCAgICAgKi9cblxuXHQgIH0sIHtcblx0ICAgIGtleTogXCJpbnNwZWN0XCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gaW5zcGVjdCgpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEBpZ25vcmVcblx0ICAgICAqL1xuXG5cdCAgfSwge1xuXHQgICAga2V5OiBcInRvSlNPTlwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHRvSlNPTigpIHtcblx0ICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEBpZ25vcmVcblx0ICAgICAqL1xuXG5cdCAgfSwge1xuXHQgICAga2V5OiBcInRvRXh0ZW5kZWRKU09OXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gdG9FeHRlbmRlZEpTT04oKSB7XG5cdCAgICAgIHJldHVybiB7XG5cdCAgICAgICAgJHN5bWJvbDogdGhpcy52YWx1ZVxuXHQgICAgICB9O1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBAaWdub3JlXG5cdCAgICAgKi9cblxuXHQgIH1dLCBbe1xuXHQgICAga2V5OiBcImZyb21FeHRlbmRlZEpTT05cIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tRXh0ZW5kZWRKU09OKGRvYykge1xuXHQgICAgICByZXR1cm4gbmV3IEJTT05TeW1ib2woZG9jLiRzeW1ib2wpO1xuXHQgICAgfVxuXHQgIH1dKTtcblxuXHQgIHJldHVybiBCU09OU3ltYm9sO1xuXHR9KCk7XG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KEJTT05TeW1ib2wucHJvdG90eXBlLCAnX2Jzb250eXBlJywge1xuXHQgIHZhbHVlOiAnU3ltYm9sJ1xuXHR9KTtcblx0dmFyIHN5bWJvbCA9IEJTT05TeW1ib2w7XG5cblx0LyoqXG5cdCAqIEEgY2xhc3MgcmVwcmVzZW50YXRpb24gb2YgYSBCU09OIEludDMyIHR5cGUuXG5cdCAqL1xuXG5cdGZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayQ1KGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxuXHRmdW5jdGlvbiBfZGVmaW5lUHJvcGVydGllcyQ1KHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH1cblxuXHRmdW5jdGlvbiBfY3JlYXRlQ2xhc3MkNShDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzJDUoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyQ1KENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfVxuXG5cdHZhciBJbnQzMiA9XG5cdC8qI19fUFVSRV9fKi9cblx0ZnVuY3Rpb24gKCkge1xuXHQgIC8qKlxuXHQgICAqIENyZWF0ZSBhbiBJbnQzMiB0eXBlXG5cdCAgICpcblx0ICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgdGhlIG51bWJlciB3ZSB3YW50IHRvIHJlcHJlc2VudCBhcyBhbiBpbnQzMi5cblx0ICAgKiBAcmV0dXJuIHtJbnQzMn1cblx0ICAgKi9cblx0ICBmdW5jdGlvbiBJbnQzMih2YWx1ZSkge1xuXHQgICAgX2NsYXNzQ2FsbENoZWNrJDUodGhpcywgSW50MzIpO1xuXG5cdCAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG5cdCAgfVxuXHQgIC8qKlxuXHQgICAqIEFjY2VzcyB0aGUgbnVtYmVyIHZhbHVlLlxuXHQgICAqXG5cdCAgICogQG1ldGhvZFxuXHQgICAqIEByZXR1cm4ge251bWJlcn0gcmV0dXJucyB0aGUgd3JhcHBlZCBpbnQzMiBudW1iZXIuXG5cdCAgICovXG5cblxuXHQgIF9jcmVhdGVDbGFzcyQ1KEludDMyLCBbe1xuXHQgICAga2V5OiBcInZhbHVlT2ZcIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB2YWx1ZU9mKCkge1xuXHQgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwidG9KU09OXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gdG9KU09OKCkge1xuXHQgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwidG9FeHRlbmRlZEpTT05cIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB0b0V4dGVuZGVkSlNPTihvcHRpb25zKSB7XG5cdCAgICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMucmVsYXhlZCkgcmV0dXJuIHRoaXMudmFsdWU7XG5cdCAgICAgIHJldHVybiB7XG5cdCAgICAgICAgJG51bWJlckludDogdGhpcy52YWx1ZS50b1N0cmluZygpXG5cdCAgICAgIH07XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEBpZ25vcmVcblx0ICAgICAqL1xuXG5cdCAgfV0sIFt7XG5cdCAgICBrZXk6IFwiZnJvbUV4dGVuZGVkSlNPTlwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIGZyb21FeHRlbmRlZEpTT04oZG9jLCBvcHRpb25zKSB7XG5cdCAgICAgIHJldHVybiBvcHRpb25zICYmIG9wdGlvbnMucmVsYXhlZCA/IHBhcnNlSW50KGRvYy4kbnVtYmVySW50LCAxMCkgOiBuZXcgSW50MzIoZG9jLiRudW1iZXJJbnQpO1xuXHQgICAgfVxuXHQgIH1dKTtcblxuXHQgIHJldHVybiBJbnQzMjtcblx0fSgpO1xuXG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShJbnQzMi5wcm90b3R5cGUsICdfYnNvbnR5cGUnLCB7XG5cdCAgdmFsdWU6ICdJbnQzMidcblx0fSk7XG5cdHZhciBpbnRfMzIgPSBJbnQzMjtcblxuXHQvKipcblx0ICogQSBjbGFzcyByZXByZXNlbnRhdGlvbiBvZiB0aGUgQlNPTiBDb2RlIHR5cGUuXG5cdCAqL1xuXG5cdGZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayQ2KGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxuXHRmdW5jdGlvbiBfZGVmaW5lUHJvcGVydGllcyQ2KHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH1cblxuXHRmdW5jdGlvbiBfY3JlYXRlQ2xhc3MkNihDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzJDYoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyQ2KENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfVxuXG5cdHZhciBDb2RlID1cblx0LyojX19QVVJFX18qL1xuXHRmdW5jdGlvbiAoKSB7XG5cdCAgLyoqXG5cdCAgICogQ3JlYXRlIGEgQ29kZSB0eXBlXG5cdCAgICpcblx0ICAgKiBAcGFyYW0geyhzdHJpbmd8ZnVuY3Rpb24pfSBjb2RlIGEgc3RyaW5nIG9yIGZ1bmN0aW9uLlxuXHQgICAqIEBwYXJhbSB7T2JqZWN0fSBbc2NvcGVdIGFuIG9wdGlvbmFsIHNjb3BlIGZvciB0aGUgZnVuY3Rpb24uXG5cdCAgICogQHJldHVybiB7Q29kZX1cblx0ICAgKi9cblx0ICBmdW5jdGlvbiBDb2RlKGNvZGUsIHNjb3BlKSB7XG5cdCAgICBfY2xhc3NDYWxsQ2hlY2skNih0aGlzLCBDb2RlKTtcblxuXHQgICAgdGhpcy5jb2RlID0gY29kZTtcblx0ICAgIHRoaXMuc2NvcGUgPSBzY29wZTtcblx0ICB9XG5cdCAgLyoqXG5cdCAgICogQGlnbm9yZVxuXHQgICAqL1xuXG5cblx0ICBfY3JlYXRlQ2xhc3MkNihDb2RlLCBbe1xuXHQgICAga2V5OiBcInRvSlNPTlwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHRvSlNPTigpIHtcblx0ICAgICAgcmV0dXJuIHtcblx0ICAgICAgICBzY29wZTogdGhpcy5zY29wZSxcblx0ICAgICAgICBjb2RlOiB0aGlzLmNvZGVcblx0ICAgICAgfTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwidG9FeHRlbmRlZEpTT05cIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB0b0V4dGVuZGVkSlNPTigpIHtcblx0ICAgICAgaWYgKHRoaXMuc2NvcGUpIHtcblx0ICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgJGNvZGU6IHRoaXMuY29kZSxcblx0ICAgICAgICAgICRzY29wZTogdGhpcy5zY29wZVxuXHQgICAgICAgIH07XG5cdCAgICAgIH1cblxuXHQgICAgICByZXR1cm4ge1xuXHQgICAgICAgICRjb2RlOiB0aGlzLmNvZGVcblx0ICAgICAgfTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9XSwgW3tcblx0ICAgIGtleTogXCJmcm9tRXh0ZW5kZWRKU09OXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gZnJvbUV4dGVuZGVkSlNPTihkb2MpIHtcblx0ICAgICAgcmV0dXJuIG5ldyBDb2RlKGRvYy4kY29kZSwgZG9jLiRzY29wZSk7XG5cdCAgICB9XG5cdCAgfV0pO1xuXG5cdCAgcmV0dXJuIENvZGU7XG5cdH0oKTtcblxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoQ29kZS5wcm90b3R5cGUsICdfYnNvbnR5cGUnLCB7XG5cdCAgdmFsdWU6ICdDb2RlJ1xuXHR9KTtcblx0dmFyIGNvZGUgPSBDb2RlO1xuXG5cdHZhciBCdWZmZXIkMiA9IGJ1ZmZlci5CdWZmZXI7XG5cdHZhciBQQVJTRV9TVFJJTkdfUkVHRVhQID0gL14oXFwrfC0pPyhcXGQrfChcXGQqXFwuXFxkKikpPyhFfGUpPyhbLStdKT8oXFxkKyk/JC87XG5cdHZhciBQQVJTRV9JTkZfUkVHRVhQID0gL14oXFwrfC0pPyhJbmZpbml0eXxpbmYpJC9pO1xuXHR2YXIgUEFSU0VfTkFOX1JFR0VYUCA9IC9eKFxcK3wtKT9OYU4kL2k7XG5cdHZhciBFWFBPTkVOVF9NQVggPSA2MTExO1xuXHR2YXIgRVhQT05FTlRfTUlOID0gLTYxNzY7XG5cdHZhciBFWFBPTkVOVF9CSUFTID0gNjE3Njtcblx0dmFyIE1BWF9ESUdJVFMgPSAzNDsgLy8gTmFuIHZhbHVlIGJpdHMgYXMgMzIgYml0IHZhbHVlcyAoZHVlIHRvIGxhY2sgb2YgbG9uZ3MpXG5cblx0dmFyIE5BTl9CVUZGRVIgPSBbMHg3YywgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMF0ucmV2ZXJzZSgpOyAvLyBJbmZpbml0eSB2YWx1ZSBiaXRzIDMyIGJpdCB2YWx1ZXMgKGR1ZSB0byBsYWNrIG9mIGxvbmdzKVxuXG5cdHZhciBJTkZfTkVHQVRJVkVfQlVGRkVSID0gWzB4ZjgsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDBdLnJldmVyc2UoKTtcblx0dmFyIElORl9QT1NJVElWRV9CVUZGRVIgPSBbMHg3OCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMF0ucmV2ZXJzZSgpO1xuXHR2YXIgRVhQT05FTlRfUkVHRVggPSAvXihbLStdKT8oXFxkKyk/JC87IC8vIERldGVjdCBpZiB0aGUgdmFsdWUgaXMgYSBkaWdpdFxuXG5cdGZ1bmN0aW9uIGlzRGlnaXQodmFsdWUpIHtcblx0ICByZXR1cm4gIWlzTmFOKHBhcnNlSW50KHZhbHVlLCAxMCkpO1xuXHR9IC8vIERpdmlkZSB0d28gdWludDEyOCB2YWx1ZXNcblxuXG5cdGZ1bmN0aW9uIGRpdmlkZXUxMjgodmFsdWUpIHtcblx0ICB2YXIgRElWSVNPUiA9IGxvbmdfMS5mcm9tTnVtYmVyKDEwMDAgKiAxMDAwICogMTAwMCk7XG5cblx0ICB2YXIgX3JlbSA9IGxvbmdfMS5mcm9tTnVtYmVyKDApO1xuXG5cdCAgaWYgKCF2YWx1ZS5wYXJ0c1swXSAmJiAhdmFsdWUucGFydHNbMV0gJiYgIXZhbHVlLnBhcnRzWzJdICYmICF2YWx1ZS5wYXJ0c1szXSkge1xuXHQgICAgcmV0dXJuIHtcblx0ICAgICAgcXVvdGllbnQ6IHZhbHVlLFxuXHQgICAgICByZW06IF9yZW1cblx0ICAgIH07XG5cdCAgfVxuXG5cdCAgZm9yICh2YXIgaSA9IDA7IGkgPD0gMzsgaSsrKSB7XG5cdCAgICAvLyBBZGp1c3QgcmVtYWluZGVyIHRvIG1hdGNoIHZhbHVlIG9mIG5leHQgZGl2aWRlbmRcblx0ICAgIF9yZW0gPSBfcmVtLnNoaWZ0TGVmdCgzMik7IC8vIEFkZCB0aGUgZGl2aWRlZCB0byBfcmVtXG5cblx0ICAgIF9yZW0gPSBfcmVtLmFkZChuZXcgbG9uZ18xKHZhbHVlLnBhcnRzW2ldLCAwKSk7XG5cdCAgICB2YWx1ZS5wYXJ0c1tpXSA9IF9yZW0uZGl2KERJVklTT1IpLmxvdztcblx0ICAgIF9yZW0gPSBfcmVtLm1vZHVsbyhESVZJU09SKTtcblx0ICB9XG5cblx0ICByZXR1cm4ge1xuXHQgICAgcXVvdGllbnQ6IHZhbHVlLFxuXHQgICAgcmVtOiBfcmVtXG5cdCAgfTtcblx0fSAvLyBNdWx0aXBseSB0d28gTG9uZyB2YWx1ZXMgYW5kIHJldHVybiB0aGUgMTI4IGJpdCB2YWx1ZVxuXG5cblx0ZnVuY3Rpb24gbXVsdGlwbHk2NHgyKGxlZnQsIHJpZ2h0KSB7XG5cdCAgaWYgKCFsZWZ0ICYmICFyaWdodCkge1xuXHQgICAgcmV0dXJuIHtcblx0ICAgICAgaGlnaDogbG9uZ18xLmZyb21OdW1iZXIoMCksXG5cdCAgICAgIGxvdzogbG9uZ18xLmZyb21OdW1iZXIoMClcblx0ICAgIH07XG5cdCAgfVxuXG5cdCAgdmFyIGxlZnRIaWdoID0gbGVmdC5zaGlmdFJpZ2h0VW5zaWduZWQoMzIpO1xuXHQgIHZhciBsZWZ0TG93ID0gbmV3IGxvbmdfMShsZWZ0LmdldExvd0JpdHMoKSwgMCk7XG5cdCAgdmFyIHJpZ2h0SGlnaCA9IHJpZ2h0LnNoaWZ0UmlnaHRVbnNpZ25lZCgzMik7XG5cdCAgdmFyIHJpZ2h0TG93ID0gbmV3IGxvbmdfMShyaWdodC5nZXRMb3dCaXRzKCksIDApO1xuXHQgIHZhciBwcm9kdWN0SGlnaCA9IGxlZnRIaWdoLm11bHRpcGx5KHJpZ2h0SGlnaCk7XG5cdCAgdmFyIHByb2R1Y3RNaWQgPSBsZWZ0SGlnaC5tdWx0aXBseShyaWdodExvdyk7XG5cdCAgdmFyIHByb2R1Y3RNaWQyID0gbGVmdExvdy5tdWx0aXBseShyaWdodEhpZ2gpO1xuXHQgIHZhciBwcm9kdWN0TG93ID0gbGVmdExvdy5tdWx0aXBseShyaWdodExvdyk7XG5cdCAgcHJvZHVjdEhpZ2ggPSBwcm9kdWN0SGlnaC5hZGQocHJvZHVjdE1pZC5zaGlmdFJpZ2h0VW5zaWduZWQoMzIpKTtcblx0ICBwcm9kdWN0TWlkID0gbmV3IGxvbmdfMShwcm9kdWN0TWlkLmdldExvd0JpdHMoKSwgMCkuYWRkKHByb2R1Y3RNaWQyKS5hZGQocHJvZHVjdExvdy5zaGlmdFJpZ2h0VW5zaWduZWQoMzIpKTtcblx0ICBwcm9kdWN0SGlnaCA9IHByb2R1Y3RIaWdoLmFkZChwcm9kdWN0TWlkLnNoaWZ0UmlnaHRVbnNpZ25lZCgzMikpO1xuXHQgIHByb2R1Y3RMb3cgPSBwcm9kdWN0TWlkLnNoaWZ0TGVmdCgzMikuYWRkKG5ldyBsb25nXzEocHJvZHVjdExvdy5nZXRMb3dCaXRzKCksIDApKTsgLy8gUmV0dXJuIHRoZSAxMjggYml0IHJlc3VsdFxuXG5cdCAgcmV0dXJuIHtcblx0ICAgIGhpZ2g6IHByb2R1Y3RIaWdoLFxuXHQgICAgbG93OiBwcm9kdWN0TG93XG5cdCAgfTtcblx0fVxuXG5cdGZ1bmN0aW9uIGxlc3NUaGFuKGxlZnQsIHJpZ2h0KSB7XG5cdCAgLy8gTWFrZSB2YWx1ZXMgdW5zaWduZWRcblx0ICB2YXIgdWhsZWZ0ID0gbGVmdC5oaWdoID4+PiAwO1xuXHQgIHZhciB1aHJpZ2h0ID0gcmlnaHQuaGlnaCA+Pj4gMDsgLy8gQ29tcGFyZSBoaWdoIGJpdHMgZmlyc3RcblxuXHQgIGlmICh1aGxlZnQgPCB1aHJpZ2h0KSB7XG5cdCAgICByZXR1cm4gdHJ1ZTtcblx0ICB9IGVsc2UgaWYgKHVobGVmdCA9PT0gdWhyaWdodCkge1xuXHQgICAgdmFyIHVsbGVmdCA9IGxlZnQubG93ID4+PiAwO1xuXHQgICAgdmFyIHVscmlnaHQgPSByaWdodC5sb3cgPj4+IDA7XG5cdCAgICBpZiAodWxsZWZ0IDwgdWxyaWdodCkgcmV0dXJuIHRydWU7XG5cdCAgfVxuXG5cdCAgcmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0ZnVuY3Rpb24gaW52YWxpZEVycihzdHJpbmcsIG1lc3NhZ2UpIHtcblx0ICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiXFxcIlwiLmNvbmNhdChzdHJpbmcsIFwiXFxcIiBpcyBub3QgYSB2YWxpZCBEZWNpbWFsMTI4IHN0cmluZyAtIFwiKS5jb25jYXQobWVzc2FnZSkpO1xuXHR9XG5cdC8qKlxuXHQgKiBBIGNsYXNzIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBCU09OIERlY2ltYWwxMjggdHlwZS5cblx0ICpcblx0ICogQGNsYXNzXG5cdCAqIEBwYXJhbSB7QnVmZmVyfSBieXRlcyBhIGJ1ZmZlciBjb250YWluaW5nIHRoZSByYXcgRGVjaW1hbDEyOCBieXRlcy5cblx0ICogQHJldHVybiB7RG91YmxlfVxuXHQgKi9cblxuXG5cdGZ1bmN0aW9uIERlY2ltYWwxMjgoYnl0ZXMpIHtcblx0ICB0aGlzLmJ5dGVzID0gYnl0ZXM7XG5cdH1cblx0LyoqXG5cdCAqIENyZWF0ZSBhIERlY2ltYWwxMjggaW5zdGFuY2UgZnJvbSBhIHN0cmluZyByZXByZXNlbnRhdGlvblxuXHQgKlxuXHQgKiBAbWV0aG9kXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgYSBudW1lcmljIHN0cmluZyByZXByZXNlbnRhdGlvbi5cblx0ICogQHJldHVybiB7RGVjaW1hbDEyOH0gcmV0dXJucyBhIERlY2ltYWwxMjggaW5zdGFuY2UuXG5cdCAqL1xuXG5cblx0RGVjaW1hbDEyOC5mcm9tU3RyaW5nID0gZnVuY3Rpb24gKHN0cmluZykge1xuXHQgIC8vIFBhcnNlIHN0YXRlIHRyYWNraW5nXG5cdCAgdmFyIGlzTmVnYXRpdmUgPSBmYWxzZTtcblx0ICB2YXIgc2F3UmFkaXggPSBmYWxzZTtcblx0ICB2YXIgZm91bmROb25aZXJvID0gZmFsc2U7IC8vIFRvdGFsIG51bWJlciBvZiBzaWduaWZpY2FudCBkaWdpdHMgKG5vIGxlYWRpbmcgb3IgdHJhaWxpbmcgemVybylcblxuXHQgIHZhciBzaWduaWZpY2FudERpZ2l0cyA9IDA7IC8vIFRvdGFsIG51bWJlciBvZiBzaWduaWZpY2FuZCBkaWdpdHMgcmVhZFxuXG5cdCAgdmFyIG5EaWdpdHNSZWFkID0gMDsgLy8gVG90YWwgbnVtYmVyIG9mIGRpZ2l0cyAobm8gbGVhZGluZyB6ZXJvcylcblxuXHQgIHZhciBuRGlnaXRzID0gMDsgLy8gVGhlIG51bWJlciBvZiB0aGUgZGlnaXRzIGFmdGVyIHJhZGl4XG5cblx0ICB2YXIgcmFkaXhQb3NpdGlvbiA9IDA7IC8vIFRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgbm9uLXplcm8gaW4gKnN0cipcblxuXHQgIHZhciBmaXJzdE5vblplcm8gPSAwOyAvLyBEaWdpdHMgQXJyYXlcblxuXHQgIHZhciBkaWdpdHMgPSBbMF07IC8vIFRoZSBudW1iZXIgb2YgZGlnaXRzIGluIGRpZ2l0c1xuXG5cdCAgdmFyIG5EaWdpdHNTdG9yZWQgPSAwOyAvLyBJbnNlcnRpb24gcG9pbnRlciBmb3IgZGlnaXRzXG5cblx0ICB2YXIgZGlnaXRzSW5zZXJ0ID0gMDsgLy8gVGhlIGluZGV4IG9mIHRoZSBmaXJzdCBub24temVybyBkaWdpdFxuXG5cdCAgdmFyIGZpcnN0RGlnaXQgPSAwOyAvLyBUaGUgaW5kZXggb2YgdGhlIGxhc3QgZGlnaXRcblxuXHQgIHZhciBsYXN0RGlnaXQgPSAwOyAvLyBFeHBvbmVudFxuXG5cdCAgdmFyIGV4cG9uZW50ID0gMDsgLy8gbG9vcCBpbmRleCBvdmVyIGFycmF5XG5cblx0ICB2YXIgaSA9IDA7IC8vIFRoZSBoaWdoIDE3IGRpZ2l0cyBvZiB0aGUgc2lnbmlmaWNhbmRcblxuXHQgIHZhciBzaWduaWZpY2FuZEhpZ2ggPSBbMCwgMF07IC8vIFRoZSBsb3cgMTcgZGlnaXRzIG9mIHRoZSBzaWduaWZpY2FuZFxuXG5cdCAgdmFyIHNpZ25pZmljYW5kTG93ID0gWzAsIDBdOyAvLyBUaGUgYmlhc2VkIGV4cG9uZW50XG5cblx0ICB2YXIgYmlhc2VkRXhwb25lbnQgPSAwOyAvLyBSZWFkIGluZGV4XG5cblx0ICB2YXIgaW5kZXggPSAwOyAvLyBOYWl2ZWx5IHByZXZlbnQgYWdhaW5zdCBSRURPUyBhdHRhY2tzLlxuXHQgIC8vIFRPRE86IGltcGxlbWVudGluZyBhIGN1c3RvbSBwYXJzaW5nIGZvciB0aGlzLCBvciByZWZhY3RvcmluZyB0aGUgcmVnZXggd291bGQgeWllbGRcblx0ICAvLyAgICAgICBmdXJ0aGVyIGdhaW5zLlxuXG5cdCAgaWYgKHN0cmluZy5sZW5ndGggPj0gNzAwMCkge1xuXHQgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignJyArIHN0cmluZyArICcgbm90IGEgdmFsaWQgRGVjaW1hbDEyOCBzdHJpbmcnKTtcblx0ICB9IC8vIFJlc3VsdHNcblxuXG5cdCAgdmFyIHN0cmluZ01hdGNoID0gc3RyaW5nLm1hdGNoKFBBUlNFX1NUUklOR19SRUdFWFApO1xuXHQgIHZhciBpbmZNYXRjaCA9IHN0cmluZy5tYXRjaChQQVJTRV9JTkZfUkVHRVhQKTtcblx0ICB2YXIgbmFuTWF0Y2ggPSBzdHJpbmcubWF0Y2goUEFSU0VfTkFOX1JFR0VYUCk7IC8vIFZhbGlkYXRlIHRoZSBzdHJpbmdcblxuXHQgIGlmICghc3RyaW5nTWF0Y2ggJiYgIWluZk1hdGNoICYmICFuYW5NYXRjaCB8fCBzdHJpbmcubGVuZ3RoID09PSAwKSB7XG5cdCAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCcnICsgc3RyaW5nICsgJyBub3QgYSB2YWxpZCBEZWNpbWFsMTI4IHN0cmluZycpO1xuXHQgIH1cblxuXHQgIGlmIChzdHJpbmdNYXRjaCkge1xuXHQgICAgLy8gZnVsbF9tYXRjaCA9IHN0cmluZ01hdGNoWzBdXG5cdCAgICAvLyBzaWduID0gc3RyaW5nTWF0Y2hbMV1cblx0ICAgIHZhciB1bnNpZ25lZE51bWJlciA9IHN0cmluZ01hdGNoWzJdOyAvLyBzdHJpbmdNYXRjaFszXSBpcyB1bmRlZmluZWQgaWYgYSB3aG9sZSBudW1iZXIgKGV4IFwiMVwiLCAxMlwiKVxuXHQgICAgLy8gYnV0IGRlZmluZWQgaWYgYSBudW1iZXIgdy8gZGVjaW1hbCBpbiBpdCAoZXggXCIxLjAsIDEyLjJcIilcblxuXHQgICAgdmFyIGUgPSBzdHJpbmdNYXRjaFs0XTtcblx0ICAgIHZhciBleHBTaWduID0gc3RyaW5nTWF0Y2hbNV07XG5cdCAgICB2YXIgZXhwTnVtYmVyID0gc3RyaW5nTWF0Y2hbNl07IC8vIHRoZXkgcHJvdmlkZWQgZSwgYnV0IGRpZG4ndCBnaXZlIGFuIGV4cG9uZW50IG51bWJlci4gZm9yIGV4IFwiMWVcIlxuXG5cdCAgICBpZiAoZSAmJiBleHBOdW1iZXIgPT09IHVuZGVmaW5lZCkgaW52YWxpZEVycihzdHJpbmcsICdtaXNzaW5nIGV4cG9uZW50IHBvd2VyJyk7IC8vIHRoZXkgcHJvdmlkZWQgZSwgYnV0IGRpZG4ndCBnaXZlIGEgbnVtYmVyIGJlZm9yZSBpdC4gZm9yIGV4IFwiZTFcIlxuXG5cdCAgICBpZiAoZSAmJiB1bnNpZ25lZE51bWJlciA9PT0gdW5kZWZpbmVkKSBpbnZhbGlkRXJyKHN0cmluZywgJ21pc3NpbmcgZXhwb25lbnQgYmFzZScpO1xuXG5cdCAgICBpZiAoZSA9PT0gdW5kZWZpbmVkICYmIChleHBTaWduIHx8IGV4cE51bWJlcikpIHtcblx0ICAgICAgaW52YWxpZEVycihzdHJpbmcsICdtaXNzaW5nIGUgYmVmb3JlIGV4cG9uZW50Jyk7XG5cdCAgICB9XG5cdCAgfSAvLyBHZXQgdGhlIG5lZ2F0aXZlIG9yIHBvc2l0aXZlIHNpZ25cblxuXG5cdCAgaWYgKHN0cmluZ1tpbmRleF0gPT09ICcrJyB8fCBzdHJpbmdbaW5kZXhdID09PSAnLScpIHtcblx0ICAgIGlzTmVnYXRpdmUgPSBzdHJpbmdbaW5kZXgrK10gPT09ICctJztcblx0ICB9IC8vIENoZWNrIGlmIHVzZXIgcGFzc2VkIEluZmluaXR5IG9yIE5hTlxuXG5cblx0ICBpZiAoIWlzRGlnaXQoc3RyaW5nW2luZGV4XSkgJiYgc3RyaW5nW2luZGV4XSAhPT0gJy4nKSB7XG5cdCAgICBpZiAoc3RyaW5nW2luZGV4XSA9PT0gJ2knIHx8IHN0cmluZ1tpbmRleF0gPT09ICdJJykge1xuXHQgICAgICByZXR1cm4gbmV3IERlY2ltYWwxMjgoQnVmZmVyJDIuZnJvbShpc05lZ2F0aXZlID8gSU5GX05FR0FUSVZFX0JVRkZFUiA6IElORl9QT1NJVElWRV9CVUZGRVIpKTtcblx0ICAgIH0gZWxzZSBpZiAoc3RyaW5nW2luZGV4XSA9PT0gJ04nKSB7XG5cdCAgICAgIHJldHVybiBuZXcgRGVjaW1hbDEyOChCdWZmZXIkMi5mcm9tKE5BTl9CVUZGRVIpKTtcblx0ICAgIH1cblx0ICB9IC8vIFJlYWQgYWxsIHRoZSBkaWdpdHNcblxuXG5cdCAgd2hpbGUgKGlzRGlnaXQoc3RyaW5nW2luZGV4XSkgfHwgc3RyaW5nW2luZGV4XSA9PT0gJy4nKSB7XG5cdCAgICBpZiAoc3RyaW5nW2luZGV4XSA9PT0gJy4nKSB7XG5cdCAgICAgIGlmIChzYXdSYWRpeCkgaW52YWxpZEVycihzdHJpbmcsICdjb250YWlucyBtdWx0aXBsZSBwZXJpb2RzJyk7XG5cdCAgICAgIHNhd1JhZGl4ID0gdHJ1ZTtcblx0ICAgICAgaW5kZXggPSBpbmRleCArIDE7XG5cdCAgICAgIGNvbnRpbnVlO1xuXHQgICAgfVxuXG5cdCAgICBpZiAobkRpZ2l0c1N0b3JlZCA8IDM0KSB7XG5cdCAgICAgIGlmIChzdHJpbmdbaW5kZXhdICE9PSAnMCcgfHwgZm91bmROb25aZXJvKSB7XG5cdCAgICAgICAgaWYgKCFmb3VuZE5vblplcm8pIHtcblx0ICAgICAgICAgIGZpcnN0Tm9uWmVybyA9IG5EaWdpdHNSZWFkO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGZvdW5kTm9uWmVybyA9IHRydWU7IC8vIE9ubHkgc3RvcmUgMzQgZGlnaXRzXG5cblx0ICAgICAgICBkaWdpdHNbZGlnaXRzSW5zZXJ0KytdID0gcGFyc2VJbnQoc3RyaW5nW2luZGV4XSwgMTApO1xuXHQgICAgICAgIG5EaWdpdHNTdG9yZWQgPSBuRGlnaXRzU3RvcmVkICsgMTtcblx0ICAgICAgfVxuXHQgICAgfVxuXG5cdCAgICBpZiAoZm91bmROb25aZXJvKSBuRGlnaXRzID0gbkRpZ2l0cyArIDE7XG5cdCAgICBpZiAoc2F3UmFkaXgpIHJhZGl4UG9zaXRpb24gPSByYWRpeFBvc2l0aW9uICsgMTtcblx0ICAgIG5EaWdpdHNSZWFkID0gbkRpZ2l0c1JlYWQgKyAxO1xuXHQgICAgaW5kZXggPSBpbmRleCArIDE7XG5cdCAgfVxuXG5cdCAgaWYgKHNhd1JhZGl4ICYmICFuRGlnaXRzUmVhZCkgdGhyb3cgbmV3IFR5cGVFcnJvcignJyArIHN0cmluZyArICcgbm90IGEgdmFsaWQgRGVjaW1hbDEyOCBzdHJpbmcnKTsgLy8gUmVhZCBleHBvbmVudCBpZiBleGlzdHNcblxuXHQgIGlmIChzdHJpbmdbaW5kZXhdID09PSAnZScgfHwgc3RyaW5nW2luZGV4XSA9PT0gJ0UnKSB7XG5cdCAgICAvLyBSZWFkIGV4cG9uZW50IGRpZ2l0c1xuXHQgICAgdmFyIG1hdGNoID0gc3RyaW5nLnN1YnN0cigrK2luZGV4KS5tYXRjaChFWFBPTkVOVF9SRUdFWCk7IC8vIE5vIGRpZ2l0cyByZWFkXG5cblx0ICAgIGlmICghbWF0Y2ggfHwgIW1hdGNoWzJdKSByZXR1cm4gbmV3IERlY2ltYWwxMjgoQnVmZmVyJDIuZnJvbShOQU5fQlVGRkVSKSk7IC8vIEdldCBleHBvbmVudFxuXG5cdCAgICBleHBvbmVudCA9IHBhcnNlSW50KG1hdGNoWzBdLCAxMCk7IC8vIEFkanVzdCB0aGUgaW5kZXhcblxuXHQgICAgaW5kZXggPSBpbmRleCArIG1hdGNoWzBdLmxlbmd0aDtcblx0ICB9IC8vIFJldHVybiBub3QgYSBudW1iZXJcblxuXG5cdCAgaWYgKHN0cmluZ1tpbmRleF0pIHJldHVybiBuZXcgRGVjaW1hbDEyOChCdWZmZXIkMi5mcm9tKE5BTl9CVUZGRVIpKTsgLy8gRG9uZSByZWFkaW5nIGlucHV0XG5cdCAgLy8gRmluZCBmaXJzdCBub24temVybyBkaWdpdCBpbiBkaWdpdHNcblxuXHQgIGZpcnN0RGlnaXQgPSAwO1xuXG5cdCAgaWYgKCFuRGlnaXRzU3RvcmVkKSB7XG5cdCAgICBmaXJzdERpZ2l0ID0gMDtcblx0ICAgIGxhc3REaWdpdCA9IDA7XG5cdCAgICBkaWdpdHNbMF0gPSAwO1xuXHQgICAgbkRpZ2l0cyA9IDE7XG5cdCAgICBuRGlnaXRzU3RvcmVkID0gMTtcblx0ICAgIHNpZ25pZmljYW50RGlnaXRzID0gMDtcblx0ICB9IGVsc2Uge1xuXHQgICAgbGFzdERpZ2l0ID0gbkRpZ2l0c1N0b3JlZCAtIDE7XG5cdCAgICBzaWduaWZpY2FudERpZ2l0cyA9IG5EaWdpdHM7XG5cblx0ICAgIGlmIChzaWduaWZpY2FudERpZ2l0cyAhPT0gMSkge1xuXHQgICAgICB3aGlsZSAoc3RyaW5nW2ZpcnN0Tm9uWmVybyArIHNpZ25pZmljYW50RGlnaXRzIC0gMV0gPT09ICcwJykge1xuXHQgICAgICAgIHNpZ25pZmljYW50RGlnaXRzID0gc2lnbmlmaWNhbnREaWdpdHMgLSAxO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfSAvLyBOb3JtYWxpemF0aW9uIG9mIGV4cG9uZW50XG5cdCAgLy8gQ29ycmVjdCBleHBvbmVudCBiYXNlZCBvbiByYWRpeCBwb3NpdGlvbiwgYW5kIHNoaWZ0IHNpZ25pZmljYW5kIGFzIG5lZWRlZFxuXHQgIC8vIHRvIHJlcHJlc2VudCB1c2VyIGlucHV0XG5cdCAgLy8gT3ZlcmZsb3cgcHJldmVudGlvblxuXG5cblx0ICBpZiAoZXhwb25lbnQgPD0gcmFkaXhQb3NpdGlvbiAmJiByYWRpeFBvc2l0aW9uIC0gZXhwb25lbnQgPiAxIDw8IDE0KSB7XG5cdCAgICBleHBvbmVudCA9IEVYUE9ORU5UX01JTjtcblx0ICB9IGVsc2Uge1xuXHQgICAgZXhwb25lbnQgPSBleHBvbmVudCAtIHJhZGl4UG9zaXRpb247XG5cdCAgfSAvLyBBdHRlbXB0IHRvIG5vcm1hbGl6ZSB0aGUgZXhwb25lbnRcblxuXG5cdCAgd2hpbGUgKGV4cG9uZW50ID4gRVhQT05FTlRfTUFYKSB7XG5cdCAgICAvLyBTaGlmdCBleHBvbmVudCB0byBzaWduaWZpY2FuZCBhbmQgZGVjcmVhc2Vcblx0ICAgIGxhc3REaWdpdCA9IGxhc3REaWdpdCArIDE7XG5cblx0ICAgIGlmIChsYXN0RGlnaXQgLSBmaXJzdERpZ2l0ID4gTUFYX0RJR0lUUykge1xuXHQgICAgICAvLyBDaGVjayBpZiB3ZSBoYXZlIGEgemVybyB0aGVuIGp1c3QgaGFyZCBjbGFtcCwgb3RoZXJ3aXNlIGZhaWxcblx0ICAgICAgdmFyIGRpZ2l0c1N0cmluZyA9IGRpZ2l0cy5qb2luKCcnKTtcblxuXHQgICAgICBpZiAoZGlnaXRzU3RyaW5nLm1hdGNoKC9eMCskLykpIHtcblx0ICAgICAgICBleHBvbmVudCA9IEVYUE9ORU5UX01BWDtcblx0ICAgICAgICBicmVhaztcblx0ICAgICAgfVxuXG5cdCAgICAgIGludmFsaWRFcnIoc3RyaW5nLCAnb3ZlcmZsb3cnKTtcblx0ICAgIH1cblxuXHQgICAgZXhwb25lbnQgPSBleHBvbmVudCAtIDE7XG5cdCAgfVxuXG5cdCAgd2hpbGUgKGV4cG9uZW50IDwgRVhQT05FTlRfTUlOIHx8IG5EaWdpdHNTdG9yZWQgPCBuRGlnaXRzKSB7XG5cdCAgICAvLyBTaGlmdCBsYXN0IGRpZ2l0LiBjYW4gb25seSBkbyB0aGlzIGlmIDwgc2lnbmlmaWNhbnQgZGlnaXRzIHRoYW4gIyBzdG9yZWQuXG5cdCAgICBpZiAobGFzdERpZ2l0ID09PSAwICYmIHNpZ25pZmljYW50RGlnaXRzIDwgbkRpZ2l0c1N0b3JlZCkge1xuXHQgICAgICBleHBvbmVudCA9IEVYUE9ORU5UX01JTjtcblx0ICAgICAgc2lnbmlmaWNhbnREaWdpdHMgPSAwO1xuXHQgICAgICBicmVhaztcblx0ICAgIH1cblxuXHQgICAgaWYgKG5EaWdpdHNTdG9yZWQgPCBuRGlnaXRzKSB7XG5cdCAgICAgIC8vIGFkanVzdCB0byBtYXRjaCBkaWdpdHMgbm90IHN0b3JlZFxuXHQgICAgICBuRGlnaXRzID0gbkRpZ2l0cyAtIDE7XG5cdCAgICB9IGVsc2Uge1xuXHQgICAgICAvLyBhZGp1c3QgdG8gcm91bmRcblx0ICAgICAgbGFzdERpZ2l0ID0gbGFzdERpZ2l0IC0gMTtcblx0ICAgIH1cblxuXHQgICAgaWYgKGV4cG9uZW50IDwgRVhQT05FTlRfTUFYKSB7XG5cdCAgICAgIGV4cG9uZW50ID0gZXhwb25lbnQgKyAxO1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgLy8gQ2hlY2sgaWYgd2UgaGF2ZSBhIHplcm8gdGhlbiBqdXN0IGhhcmQgY2xhbXAsIG90aGVyd2lzZSBmYWlsXG5cdCAgICAgIHZhciBfZGlnaXRzU3RyaW5nID0gZGlnaXRzLmpvaW4oJycpO1xuXG5cdCAgICAgIGlmIChfZGlnaXRzU3RyaW5nLm1hdGNoKC9eMCskLykpIHtcblx0ICAgICAgICBleHBvbmVudCA9IEVYUE9ORU5UX01BWDtcblx0ICAgICAgICBicmVhaztcblx0ICAgICAgfVxuXG5cdCAgICAgIGludmFsaWRFcnIoc3RyaW5nLCAnb3ZlcmZsb3cnKTtcblx0ICAgIH1cblx0ICB9IC8vIFJvdW5kXG5cdCAgLy8gV2UndmUgbm9ybWFsaXplZCB0aGUgZXhwb25lbnQsIGJ1dCBtaWdodCBzdGlsbCBuZWVkIHRvIHJvdW5kLlxuXG5cblx0ICBpZiAobGFzdERpZ2l0IC0gZmlyc3REaWdpdCArIDEgPCBzaWduaWZpY2FudERpZ2l0cykge1xuXHQgICAgdmFyIGVuZE9mU3RyaW5nID0gbkRpZ2l0c1JlYWQ7IC8vIElmIHdlIGhhdmUgc2VlbiBhIHJhZGl4IHBvaW50LCAnc3RyaW5nJyBpcyAxIGxvbmdlciB0aGFuIHdlIGhhdmVcblx0ICAgIC8vIGRvY3VtZW50ZWQgd2l0aCBuZGlnaXRzX3JlYWQsIHNvIGluYyB0aGUgcG9zaXRpb24gb2YgdGhlIGZpcnN0IG5vbnplcm9cblx0ICAgIC8vIGRpZ2l0IGFuZCB0aGUgcG9zaXRpb24gdGhhdCBkaWdpdHMgYXJlIHJlYWQgdG8uXG5cblx0ICAgIGlmIChzYXdSYWRpeCkge1xuXHQgICAgICBmaXJzdE5vblplcm8gPSBmaXJzdE5vblplcm8gKyAxO1xuXHQgICAgICBlbmRPZlN0cmluZyA9IGVuZE9mU3RyaW5nICsgMTtcblx0ICAgIH0gLy8gaWYgbmVnYXRpdmUsIHdlIG5lZWQgdG8gaW5jcmVtZW50IGFnYWluIHRvIGFjY291bnQgZm9yIC0gc2lnbiBhdCBzdGFydC5cblxuXG5cdCAgICBpZiAoaXNOZWdhdGl2ZSkge1xuXHQgICAgICBmaXJzdE5vblplcm8gPSBmaXJzdE5vblplcm8gKyAxO1xuXHQgICAgICBlbmRPZlN0cmluZyA9IGVuZE9mU3RyaW5nICsgMTtcblx0ICAgIH1cblxuXHQgICAgdmFyIHJvdW5kRGlnaXQgPSBwYXJzZUludChzdHJpbmdbZmlyc3ROb25aZXJvICsgbGFzdERpZ2l0ICsgMV0sIDEwKTtcblx0ICAgIHZhciByb3VuZEJpdCA9IDA7XG5cblx0ICAgIGlmIChyb3VuZERpZ2l0ID49IDUpIHtcblx0ICAgICAgcm91bmRCaXQgPSAxO1xuXG5cdCAgICAgIGlmIChyb3VuZERpZ2l0ID09PSA1KSB7XG5cdCAgICAgICAgcm91bmRCaXQgPSBkaWdpdHNbbGFzdERpZ2l0XSAlIDIgPT09IDE7XG5cblx0ICAgICAgICBmb3IgKGkgPSBmaXJzdE5vblplcm8gKyBsYXN0RGlnaXQgKyAyOyBpIDwgZW5kT2ZTdHJpbmc7IGkrKykge1xuXHQgICAgICAgICAgaWYgKHBhcnNlSW50KHN0cmluZ1tpXSwgMTApKSB7XG5cdCAgICAgICAgICAgIHJvdW5kQml0ID0gMTtcblx0ICAgICAgICAgICAgYnJlYWs7XG5cdCAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICB9XG5cblx0ICAgIGlmIChyb3VuZEJpdCkge1xuXHQgICAgICB2YXIgZElkeCA9IGxhc3REaWdpdDtcblxuXHQgICAgICBmb3IgKDsgZElkeCA+PSAwOyBkSWR4LS0pIHtcblx0ICAgICAgICBpZiAoKytkaWdpdHNbZElkeF0gPiA5KSB7XG5cdCAgICAgICAgICBkaWdpdHNbZElkeF0gPSAwOyAvLyBvdmVyZmxvd2VkIG1vc3Qgc2lnbmlmaWNhbnQgZGlnaXRcblxuXHQgICAgICAgICAgaWYgKGRJZHggPT09IDApIHtcblx0ICAgICAgICAgICAgaWYgKGV4cG9uZW50IDwgRVhQT05FTlRfTUFYKSB7XG5cdCAgICAgICAgICAgICAgZXhwb25lbnQgPSBleHBvbmVudCArIDE7XG5cdCAgICAgICAgICAgICAgZGlnaXRzW2RJZHhdID0gMTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICByZXR1cm4gbmV3IERlY2ltYWwxMjgoQnVmZmVyJDIuZnJvbShpc05lZ2F0aXZlID8gSU5GX05FR0FUSVZFX0JVRkZFUiA6IElORl9QT1NJVElWRV9CVUZGRVIpKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0gLy8gRW5jb2RlIHNpZ25pZmljYW5kXG5cdCAgLy8gVGhlIGhpZ2ggMTcgZGlnaXRzIG9mIHRoZSBzaWduaWZpY2FuZFxuXG5cblx0ICBzaWduaWZpY2FuZEhpZ2ggPSBsb25nXzEuZnJvbU51bWJlcigwKTsgLy8gVGhlIGxvdyAxNyBkaWdpdHMgb2YgdGhlIHNpZ25pZmljYW5kXG5cblx0ICBzaWduaWZpY2FuZExvdyA9IGxvbmdfMS5mcm9tTnVtYmVyKDApOyAvLyByZWFkIGEgemVyb1xuXG5cdCAgaWYgKHNpZ25pZmljYW50RGlnaXRzID09PSAwKSB7XG5cdCAgICBzaWduaWZpY2FuZEhpZ2ggPSBsb25nXzEuZnJvbU51bWJlcigwKTtcblx0ICAgIHNpZ25pZmljYW5kTG93ID0gbG9uZ18xLmZyb21OdW1iZXIoMCk7XG5cdCAgfSBlbHNlIGlmIChsYXN0RGlnaXQgLSBmaXJzdERpZ2l0IDwgMTcpIHtcblx0ICAgIHZhciBfZElkeCA9IGZpcnN0RGlnaXQ7XG5cdCAgICBzaWduaWZpY2FuZExvdyA9IGxvbmdfMS5mcm9tTnVtYmVyKGRpZ2l0c1tfZElkeCsrXSk7XG5cdCAgICBzaWduaWZpY2FuZEhpZ2ggPSBuZXcgbG9uZ18xKDAsIDApO1xuXG5cdCAgICBmb3IgKDsgX2RJZHggPD0gbGFzdERpZ2l0OyBfZElkeCsrKSB7XG5cdCAgICAgIHNpZ25pZmljYW5kTG93ID0gc2lnbmlmaWNhbmRMb3cubXVsdGlwbHkobG9uZ18xLmZyb21OdW1iZXIoMTApKTtcblx0ICAgICAgc2lnbmlmaWNhbmRMb3cgPSBzaWduaWZpY2FuZExvdy5hZGQobG9uZ18xLmZyb21OdW1iZXIoZGlnaXRzW19kSWR4XSkpO1xuXHQgICAgfVxuXHQgIH0gZWxzZSB7XG5cdCAgICB2YXIgX2RJZHgyID0gZmlyc3REaWdpdDtcblx0ICAgIHNpZ25pZmljYW5kSGlnaCA9IGxvbmdfMS5mcm9tTnVtYmVyKGRpZ2l0c1tfZElkeDIrK10pO1xuXG5cdCAgICBmb3IgKDsgX2RJZHgyIDw9IGxhc3REaWdpdCAtIDE3OyBfZElkeDIrKykge1xuXHQgICAgICBzaWduaWZpY2FuZEhpZ2ggPSBzaWduaWZpY2FuZEhpZ2gubXVsdGlwbHkobG9uZ18xLmZyb21OdW1iZXIoMTApKTtcblx0ICAgICAgc2lnbmlmaWNhbmRIaWdoID0gc2lnbmlmaWNhbmRIaWdoLmFkZChsb25nXzEuZnJvbU51bWJlcihkaWdpdHNbX2RJZHgyXSkpO1xuXHQgICAgfVxuXG5cdCAgICBzaWduaWZpY2FuZExvdyA9IGxvbmdfMS5mcm9tTnVtYmVyKGRpZ2l0c1tfZElkeDIrK10pO1xuXG5cdCAgICBmb3IgKDsgX2RJZHgyIDw9IGxhc3REaWdpdDsgX2RJZHgyKyspIHtcblx0ICAgICAgc2lnbmlmaWNhbmRMb3cgPSBzaWduaWZpY2FuZExvdy5tdWx0aXBseShsb25nXzEuZnJvbU51bWJlcigxMCkpO1xuXHQgICAgICBzaWduaWZpY2FuZExvdyA9IHNpZ25pZmljYW5kTG93LmFkZChsb25nXzEuZnJvbU51bWJlcihkaWdpdHNbX2RJZHgyXSkpO1xuXHQgICAgfVxuXHQgIH1cblxuXHQgIHZhciBzaWduaWZpY2FuZCA9IG11bHRpcGx5NjR4MihzaWduaWZpY2FuZEhpZ2gsIGxvbmdfMS5mcm9tU3RyaW5nKCcxMDAwMDAwMDAwMDAwMDAwMDAnKSk7XG5cdCAgc2lnbmlmaWNhbmQubG93ID0gc2lnbmlmaWNhbmQubG93LmFkZChzaWduaWZpY2FuZExvdyk7XG5cblx0ICBpZiAobGVzc1RoYW4oc2lnbmlmaWNhbmQubG93LCBzaWduaWZpY2FuZExvdykpIHtcblx0ICAgIHNpZ25pZmljYW5kLmhpZ2ggPSBzaWduaWZpY2FuZC5oaWdoLmFkZChsb25nXzEuZnJvbU51bWJlcigxKSk7XG5cdCAgfSAvLyBCaWFzZWQgZXhwb25lbnRcblxuXG5cdCAgYmlhc2VkRXhwb25lbnQgPSBleHBvbmVudCArIEVYUE9ORU5UX0JJQVM7XG5cdCAgdmFyIGRlYyA9IHtcblx0ICAgIGxvdzogbG9uZ18xLmZyb21OdW1iZXIoMCksXG5cdCAgICBoaWdoOiBsb25nXzEuZnJvbU51bWJlcigwKVxuXHQgIH07IC8vIEVuY29kZSBjb21iaW5hdGlvbiwgZXhwb25lbnQsIGFuZCBzaWduaWZpY2FuZC5cblxuXHQgIGlmIChzaWduaWZpY2FuZC5oaWdoLnNoaWZ0UmlnaHRVbnNpZ25lZCg0OSkuYW5kKGxvbmdfMS5mcm9tTnVtYmVyKDEpKS5lcXVhbHMobG9uZ18xLmZyb21OdW1iZXIoMSkpKSB7XG5cdCAgICAvLyBFbmNvZGUgJzExJyBpbnRvIGJpdHMgMSB0byAzXG5cdCAgICBkZWMuaGlnaCA9IGRlYy5oaWdoLm9yKGxvbmdfMS5mcm9tTnVtYmVyKDB4Mykuc2hpZnRMZWZ0KDYxKSk7XG5cdCAgICBkZWMuaGlnaCA9IGRlYy5oaWdoLm9yKGxvbmdfMS5mcm9tTnVtYmVyKGJpYXNlZEV4cG9uZW50KS5hbmQobG9uZ18xLmZyb21OdW1iZXIoMHgzZmZmKS5zaGlmdExlZnQoNDcpKSk7XG5cdCAgICBkZWMuaGlnaCA9IGRlYy5oaWdoLm9yKHNpZ25pZmljYW5kLmhpZ2guYW5kKGxvbmdfMS5mcm9tTnVtYmVyKDB4N2ZmZmZmZmZmZmZmKSkpO1xuXHQgIH0gZWxzZSB7XG5cdCAgICBkZWMuaGlnaCA9IGRlYy5oaWdoLm9yKGxvbmdfMS5mcm9tTnVtYmVyKGJpYXNlZEV4cG9uZW50ICYgMHgzZmZmKS5zaGlmdExlZnQoNDkpKTtcblx0ICAgIGRlYy5oaWdoID0gZGVjLmhpZ2gub3Ioc2lnbmlmaWNhbmQuaGlnaC5hbmQobG9uZ18xLmZyb21OdW1iZXIoMHgxZmZmZmZmZmZmZmZmKSkpO1xuXHQgIH1cblxuXHQgIGRlYy5sb3cgPSBzaWduaWZpY2FuZC5sb3c7IC8vIEVuY29kZSBzaWduXG5cblx0ICBpZiAoaXNOZWdhdGl2ZSkge1xuXHQgICAgZGVjLmhpZ2ggPSBkZWMuaGlnaC5vcihsb25nXzEuZnJvbVN0cmluZygnOTIyMzM3MjAzNjg1NDc3NTgwOCcpKTtcblx0ICB9IC8vIEVuY29kZSBpbnRvIGEgYnVmZmVyXG5cblxuXHQgIHZhciBidWZmZXIkJDEgPSBCdWZmZXIkMi5hbGxvYygxNik7XG5cdCAgaW5kZXggPSAwOyAvLyBFbmNvZGUgdGhlIGxvdyA2NCBiaXRzIG9mIHRoZSBkZWNpbWFsXG5cdCAgLy8gRW5jb2RlIGxvdyBiaXRzXG5cblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBkZWMubG93LmxvdyAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gZGVjLmxvdy5sb3cgPj4gOCAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gZGVjLmxvdy5sb3cgPj4gMTYgJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGRlYy5sb3cubG93ID4+IDI0ICYgMHhmZjsgLy8gRW5jb2RlIGhpZ2ggYml0c1xuXG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gZGVjLmxvdy5oaWdoICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBkZWMubG93LmhpZ2ggPj4gOCAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gZGVjLmxvdy5oaWdoID4+IDE2ICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBkZWMubG93LmhpZ2ggPj4gMjQgJiAweGZmOyAvLyBFbmNvZGUgdGhlIGhpZ2ggNjQgYml0cyBvZiB0aGUgZGVjaW1hbFxuXHQgIC8vIEVuY29kZSBsb3cgYml0c1xuXG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gZGVjLmhpZ2gubG93ICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBkZWMuaGlnaC5sb3cgPj4gOCAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gZGVjLmhpZ2gubG93ID4+IDE2ICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBkZWMuaGlnaC5sb3cgPj4gMjQgJiAweGZmOyAvLyBFbmNvZGUgaGlnaCBiaXRzXG5cblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBkZWMuaGlnaC5oaWdoICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBkZWMuaGlnaC5oaWdoID4+IDggJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGRlYy5oaWdoLmhpZ2ggPj4gMTYgJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGRlYy5oaWdoLmhpZ2ggPj4gMjQgJiAweGZmOyAvLyBSZXR1cm4gdGhlIG5ldyBEZWNpbWFsMTI4XG5cblx0ICByZXR1cm4gbmV3IERlY2ltYWwxMjgoYnVmZmVyJCQxKTtcblx0fTsgLy8gRXh0cmFjdCBsZWFzdCBzaWduaWZpY2FudCA1IGJpdHNcblxuXG5cdHZhciBDT01CSU5BVElPTl9NQVNLID0gMHgxZjsgLy8gRXh0cmFjdCBsZWFzdCBzaWduaWZpY2FudCAxNCBiaXRzXG5cblx0dmFyIEVYUE9ORU5UX01BU0sgPSAweDNmZmY7IC8vIFZhbHVlIG9mIGNvbWJpbmF0aW9uIGZpZWxkIGZvciBJbmZcblxuXHR2YXIgQ09NQklOQVRJT05fSU5GSU5JVFkgPSAzMDsgLy8gVmFsdWUgb2YgY29tYmluYXRpb24gZmllbGQgZm9yIE5hTlxuXG5cdHZhciBDT01CSU5BVElPTl9OQU4gPSAzMTtcblx0LyoqXG5cdCAqIENyZWF0ZSBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcmF3IERlY2ltYWwxMjggdmFsdWVcblx0ICpcblx0ICogQG1ldGhvZFxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IHJldHVybnMgYSBEZWNpbWFsMTI4IHN0cmluZyByZXByZXNlbnRhdGlvbi5cblx0ICovXG5cblx0RGVjaW1hbDEyOC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG5cdCAgLy8gTm90ZTogYml0cyBpbiB0aGlzIHJvdXRpbmUgYXJlIHJlZmVycmVkIHRvIHN0YXJ0aW5nIGF0IDAsXG5cdCAgLy8gZnJvbSB0aGUgc2lnbiBiaXQsIHRvd2FyZHMgdGhlIGNvZWZmaWNpZW50LlxuXHQgIC8vIGJpdHMgMCAtIDMxXG5cdCAgdmFyIGhpZ2g7IC8vIGJpdHMgMzIgLSA2M1xuXG5cdCAgdmFyIG1pZGg7IC8vIGJpdHMgNjQgLSA5NVxuXG5cdCAgdmFyIG1pZGw7IC8vIGJpdHMgOTYgLSAxMjdcblxuXHQgIHZhciBsb3c7IC8vIGJpdHMgMSAtIDVcblxuXHQgIHZhciBjb21iaW5hdGlvbjsgLy8gZGVjb2RlZCBiaWFzZWQgZXhwb25lbnQgKDE0IGJpdHMpXG5cblx0ICB2YXIgYmlhc2VkX2V4cG9uZW50OyAvLyB0aGUgbnVtYmVyIG9mIHNpZ25pZmljYW5kIGRpZ2l0c1xuXG5cdCAgdmFyIHNpZ25pZmljYW5kX2RpZ2l0cyA9IDA7IC8vIHRoZSBiYXNlLTEwIGRpZ2l0cyBpbiB0aGUgc2lnbmlmaWNhbmRcblxuXHQgIHZhciBzaWduaWZpY2FuZCA9IG5ldyBBcnJheSgzNik7XG5cblx0ICBmb3IgKHZhciBpID0gMDsgaSA8IHNpZ25pZmljYW5kLmxlbmd0aDsgaSsrKSB7XG5cdCAgICBzaWduaWZpY2FuZFtpXSA9IDA7XG5cdCAgfSAvLyByZWFkIHBvaW50ZXIgaW50byBzaWduaWZpY2FuZFxuXG5cblx0ICB2YXIgaW5kZXggPSAwOyAvLyB1bmJpYXNlZCBleHBvbmVudFxuXG5cdCAgdmFyIGV4cG9uZW50OyAvLyB0aGUgZXhwb25lbnQgaWYgc2NpZW50aWZpYyBub3RhdGlvbiBpcyB1c2VkXG5cblx0ICB2YXIgc2NpZW50aWZpY19leHBvbmVudDsgLy8gdHJ1ZSBpZiB0aGUgbnVtYmVyIGlzIHplcm9cblxuXHQgIHZhciBpc196ZXJvID0gZmFsc2U7IC8vIHRoZSBtb3N0IHNpZ25pZmNhbnQgc2lnbmlmaWNhbmQgYml0cyAoNTAtNDYpXG5cblx0ICB2YXIgc2lnbmlmaWNhbmRfbXNiOyAvLyB0ZW1wb3Jhcnkgc3RvcmFnZSBmb3Igc2lnbmlmaWNhbmQgZGVjb2RpbmdcblxuXHQgIHZhciBzaWduaWZpY2FuZDEyOCA9IHtcblx0ICAgIHBhcnRzOiBuZXcgQXJyYXkoNClcblx0ICB9OyAvLyBpbmRleGluZyB2YXJpYWJsZXNcblxuXHQgIHZhciBqLCBrOyAvLyBPdXRwdXQgc3RyaW5nXG5cblx0ICB2YXIgc3RyaW5nID0gW107IC8vIFVucGFjayBpbmRleFxuXG5cdCAgaW5kZXggPSAwOyAvLyBCdWZmZXIgcmVmZXJlbmNlXG5cblx0ICB2YXIgYnVmZmVyJCQxID0gdGhpcy5ieXRlczsgLy8gVW5wYWNrIHRoZSBsb3cgNjRiaXRzIGludG8gYSBsb25nXG5cblx0ICBsb3cgPSBidWZmZXIkJDFbaW5kZXgrK10gfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAyNDtcblx0ICBtaWRsID0gYnVmZmVyJCQxW2luZGV4KytdIHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDggfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMTYgfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMjQ7IC8vIFVucGFjayB0aGUgaGlnaCA2NGJpdHMgaW50byBhIGxvbmdcblxuXHQgIG1pZGggPSBidWZmZXIkJDFbaW5kZXgrK10gfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAyNDtcblx0ICBoaWdoID0gYnVmZmVyJCQxW2luZGV4KytdIHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDggfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMTYgfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMjQ7IC8vIFVucGFjayBpbmRleFxuXG5cdCAgaW5kZXggPSAwOyAvLyBDcmVhdGUgdGhlIHN0YXRlIG9mIHRoZSBkZWNpbWFsXG5cblx0ICB2YXIgZGVjID0ge1xuXHQgICAgbG93OiBuZXcgbG9uZ18xKGxvdywgbWlkbCksXG5cdCAgICBoaWdoOiBuZXcgbG9uZ18xKG1pZGgsIGhpZ2gpXG5cdCAgfTtcblxuXHQgIGlmIChkZWMuaGlnaC5sZXNzVGhhbihsb25nXzEuWkVSTykpIHtcblx0ICAgIHN0cmluZy5wdXNoKCctJyk7XG5cdCAgfSAvLyBEZWNvZGUgY29tYmluYXRpb24gZmllbGQgYW5kIGV4cG9uZW50XG5cblxuXHQgIGNvbWJpbmF0aW9uID0gaGlnaCA+PiAyNiAmIENPTUJJTkFUSU9OX01BU0s7XG5cblx0ICBpZiAoY29tYmluYXRpb24gPj4gMyA9PT0gMykge1xuXHQgICAgLy8gQ2hlY2sgZm9yICdzcGVjaWFsJyB2YWx1ZXNcblx0ICAgIGlmIChjb21iaW5hdGlvbiA9PT0gQ09NQklOQVRJT05fSU5GSU5JVFkpIHtcblx0ICAgICAgcmV0dXJuIHN0cmluZy5qb2luKCcnKSArICdJbmZpbml0eSc7XG5cdCAgICB9IGVsc2UgaWYgKGNvbWJpbmF0aW9uID09PSBDT01CSU5BVElPTl9OQU4pIHtcblx0ICAgICAgcmV0dXJuICdOYU4nO1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgYmlhc2VkX2V4cG9uZW50ID0gaGlnaCA+PiAxNSAmIEVYUE9ORU5UX01BU0s7XG5cdCAgICAgIHNpZ25pZmljYW5kX21zYiA9IDB4MDggKyAoaGlnaCA+PiAxNCAmIDB4MDEpO1xuXHQgICAgfVxuXHQgIH0gZWxzZSB7XG5cdCAgICBzaWduaWZpY2FuZF9tc2IgPSBoaWdoID4+IDE0ICYgMHgwNztcblx0ICAgIGJpYXNlZF9leHBvbmVudCA9IGhpZ2ggPj4gMTcgJiBFWFBPTkVOVF9NQVNLO1xuXHQgIH1cblxuXHQgIGV4cG9uZW50ID0gYmlhc2VkX2V4cG9uZW50IC0gRVhQT05FTlRfQklBUzsgLy8gQ3JlYXRlIHN0cmluZyBvZiBzaWduaWZpY2FuZCBkaWdpdHNcblx0ICAvLyBDb252ZXJ0IHRoZSAxMTQtYml0IGJpbmFyeSBudW1iZXIgcmVwcmVzZW50ZWQgYnlcblx0ICAvLyAoc2lnbmlmaWNhbmRfaGlnaCwgc2lnbmlmaWNhbmRfbG93KSB0byBhdCBtb3N0IDM0IGRlY2ltYWxcblx0ICAvLyBkaWdpdHMgdGhyb3VnaCBtb2R1bG8gYW5kIGRpdmlzaW9uLlxuXG5cdCAgc2lnbmlmaWNhbmQxMjgucGFydHNbMF0gPSAoaGlnaCAmIDB4M2ZmZikgKyAoKHNpZ25pZmljYW5kX21zYiAmIDB4ZikgPDwgMTQpO1xuXHQgIHNpZ25pZmljYW5kMTI4LnBhcnRzWzFdID0gbWlkaDtcblx0ICBzaWduaWZpY2FuZDEyOC5wYXJ0c1syXSA9IG1pZGw7XG5cdCAgc2lnbmlmaWNhbmQxMjgucGFydHNbM10gPSBsb3c7XG5cblx0ICBpZiAoc2lnbmlmaWNhbmQxMjgucGFydHNbMF0gPT09IDAgJiYgc2lnbmlmaWNhbmQxMjgucGFydHNbMV0gPT09IDAgJiYgc2lnbmlmaWNhbmQxMjgucGFydHNbMl0gPT09IDAgJiYgc2lnbmlmaWNhbmQxMjgucGFydHNbM10gPT09IDApIHtcblx0ICAgIGlzX3plcm8gPSB0cnVlO1xuXHQgIH0gZWxzZSB7XG5cdCAgICBmb3IgKGsgPSAzOyBrID49IDA7IGstLSkge1xuXHQgICAgICB2YXIgbGVhc3RfZGlnaXRzID0gMDsgLy8gUGVmb3JtIHRoZSBkaXZpZGVcblxuXHQgICAgICB2YXIgcmVzdWx0ID0gZGl2aWRldTEyOChzaWduaWZpY2FuZDEyOCk7XG5cdCAgICAgIHNpZ25pZmljYW5kMTI4ID0gcmVzdWx0LnF1b3RpZW50O1xuXHQgICAgICBsZWFzdF9kaWdpdHMgPSByZXN1bHQucmVtLmxvdzsgLy8gV2Ugbm93IGhhdmUgdGhlIDkgbGVhc3Qgc2lnbmlmaWNhbnQgZGlnaXRzIChpbiBiYXNlIDIpLlxuXHQgICAgICAvLyBDb252ZXJ0IGFuZCBvdXRwdXQgdG8gc3RyaW5nLlxuXG5cdCAgICAgIGlmICghbGVhc3RfZGlnaXRzKSBjb250aW51ZTtcblxuXHQgICAgICBmb3IgKGogPSA4OyBqID49IDA7IGotLSkge1xuXHQgICAgICAgIC8vIHNpZ25pZmljYW5kW2sgKiA5ICsgal0gPSBNYXRoLnJvdW5kKGxlYXN0X2RpZ2l0cyAlIDEwKTtcblx0ICAgICAgICBzaWduaWZpY2FuZFtrICogOSArIGpdID0gbGVhc3RfZGlnaXRzICUgMTA7IC8vIGxlYXN0X2RpZ2l0cyA9IE1hdGgucm91bmQobGVhc3RfZGlnaXRzIC8gMTApO1xuXG5cdCAgICAgICAgbGVhc3RfZGlnaXRzID0gTWF0aC5mbG9vcihsZWFzdF9kaWdpdHMgLyAxMCk7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9IC8vIE91dHB1dCBmb3JtYXQgb3B0aW9uczpcblx0ICAvLyBTY2llbnRpZmljIC0gWy1dZC5kZGRFKCsvLSlkZCBvciBbLV1kRSgrLy0pZGRcblx0ICAvLyBSZWd1bGFyICAgIC0gZGRkLmRkZFxuXG5cblx0ICBpZiAoaXNfemVybykge1xuXHQgICAgc2lnbmlmaWNhbmRfZGlnaXRzID0gMTtcblx0ICAgIHNpZ25pZmljYW5kW2luZGV4XSA9IDA7XG5cdCAgfSBlbHNlIHtcblx0ICAgIHNpZ25pZmljYW5kX2RpZ2l0cyA9IDM2O1xuXG5cdCAgICB3aGlsZSAoIXNpZ25pZmljYW5kW2luZGV4XSkge1xuXHQgICAgICBzaWduaWZpY2FuZF9kaWdpdHMgPSBzaWduaWZpY2FuZF9kaWdpdHMgLSAxO1xuXHQgICAgICBpbmRleCA9IGluZGV4ICsgMTtcblx0ICAgIH1cblx0ICB9XG5cblx0ICBzY2llbnRpZmljX2V4cG9uZW50ID0gc2lnbmlmaWNhbmRfZGlnaXRzIC0gMSArIGV4cG9uZW50OyAvLyBUaGUgc2NpZW50aWZpYyBleHBvbmVudCBjaGVja3MgYXJlIGRpY3RhdGVkIGJ5IHRoZSBzdHJpbmcgY29udmVyc2lvblxuXHQgIC8vIHNwZWNpZmljYXRpb24gYW5kIGFyZSBzb21ld2hhdCBhcmJpdHJhcnkgY3V0b2Zmcy5cblx0ICAvL1xuXHQgIC8vIFdlIG11c3QgY2hlY2sgZXhwb25lbnQgPiAwLCBiZWNhdXNlIGlmIHRoaXMgaXMgdGhlIGNhc2UsIHRoZSBudW1iZXJcblx0ICAvLyBoYXMgdHJhaWxpbmcgemVyb3MuICBIb3dldmVyLCB3ZSAqY2Fubm90KiBvdXRwdXQgdGhlc2UgdHJhaWxpbmcgemVyb3MsXG5cdCAgLy8gYmVjYXVzZSBkb2luZyBzbyB3b3VsZCBjaGFuZ2UgdGhlIHByZWNpc2lvbiBvZiB0aGUgdmFsdWUsIGFuZCB3b3VsZFxuXHQgIC8vIGNoYW5nZSBzdG9yZWQgZGF0YSBpZiB0aGUgc3RyaW5nIGNvbnZlcnRlZCBudW1iZXIgaXMgcm91bmQgdHJpcHBlZC5cblxuXHQgIGlmIChzY2llbnRpZmljX2V4cG9uZW50ID49IDM0IHx8IHNjaWVudGlmaWNfZXhwb25lbnQgPD0gLTcgfHwgZXhwb25lbnQgPiAwKSB7XG5cdCAgICAvLyBTY2llbnRpZmljIGZvcm1hdFxuXHQgICAgLy8gaWYgdGhlcmUgYXJlIHRvbyBtYW55IHNpZ25pZmljYW50IGRpZ2l0cywgd2Ugc2hvdWxkIGp1c3QgYmUgdHJlYXRpbmcgbnVtYmVyc1xuXHQgICAgLy8gYXMgKyBvciAtIDAgYW5kIHVzaW5nIHRoZSBub24tc2NpZW50aWZpYyBleHBvbmVudCAodGhpcyBpcyBmb3IgdGhlIFwiaW52YWxpZFxuXHQgICAgLy8gcmVwcmVzZW50YXRpb24gc2hvdWxkIGJlIHRyZWF0ZWQgYXMgMC8tMFwiIHNwZWMgY2FzZXMgaW4gZGVjaW1hbDEyOC0xLmpzb24pXG5cdCAgICBpZiAoc2lnbmlmaWNhbmRfZGlnaXRzID4gMzQpIHtcblx0ICAgICAgc3RyaW5nLnB1c2goMCk7XG5cdCAgICAgIGlmIChleHBvbmVudCA+IDApIHN0cmluZy5wdXNoKCdFKycgKyBleHBvbmVudCk7ZWxzZSBpZiAoZXhwb25lbnQgPCAwKSBzdHJpbmcucHVzaCgnRScgKyBleHBvbmVudCk7XG5cdCAgICAgIHJldHVybiBzdHJpbmcuam9pbignJyk7XG5cdCAgICB9XG5cblx0ICAgIHN0cmluZy5wdXNoKHNpZ25pZmljYW5kW2luZGV4KytdKTtcblx0ICAgIHNpZ25pZmljYW5kX2RpZ2l0cyA9IHNpZ25pZmljYW5kX2RpZ2l0cyAtIDE7XG5cblx0ICAgIGlmIChzaWduaWZpY2FuZF9kaWdpdHMpIHtcblx0ICAgICAgc3RyaW5nLnB1c2goJy4nKTtcblx0ICAgIH1cblxuXHQgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IHNpZ25pZmljYW5kX2RpZ2l0czsgX2krKykge1xuXHQgICAgICBzdHJpbmcucHVzaChzaWduaWZpY2FuZFtpbmRleCsrXSk7XG5cdCAgICB9IC8vIEV4cG9uZW50XG5cblxuXHQgICAgc3RyaW5nLnB1c2goJ0UnKTtcblxuXHQgICAgaWYgKHNjaWVudGlmaWNfZXhwb25lbnQgPiAwKSB7XG5cdCAgICAgIHN0cmluZy5wdXNoKCcrJyArIHNjaWVudGlmaWNfZXhwb25lbnQpO1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgc3RyaW5nLnB1c2goc2NpZW50aWZpY19leHBvbmVudCk7XG5cdCAgICB9XG5cdCAgfSBlbHNlIHtcblx0ICAgIC8vIFJlZ3VsYXIgZm9ybWF0IHdpdGggbm8gZGVjaW1hbCBwbGFjZVxuXHQgICAgaWYgKGV4cG9uZW50ID49IDApIHtcblx0ICAgICAgZm9yICh2YXIgX2kyID0gMDsgX2kyIDwgc2lnbmlmaWNhbmRfZGlnaXRzOyBfaTIrKykge1xuXHQgICAgICAgIHN0cmluZy5wdXNoKHNpZ25pZmljYW5kW2luZGV4KytdKTtcblx0ICAgICAgfVxuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgdmFyIHJhZGl4X3Bvc2l0aW9uID0gc2lnbmlmaWNhbmRfZGlnaXRzICsgZXhwb25lbnQ7IC8vIG5vbi16ZXJvIGRpZ2l0cyBiZWZvcmUgcmFkaXhcblxuXHQgICAgICBpZiAocmFkaXhfcG9zaXRpb24gPiAwKSB7XG5cdCAgICAgICAgZm9yICh2YXIgX2kzID0gMDsgX2kzIDwgcmFkaXhfcG9zaXRpb247IF9pMysrKSB7XG5cdCAgICAgICAgICBzdHJpbmcucHVzaChzaWduaWZpY2FuZFtpbmRleCsrXSk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9IGVsc2Uge1xuXHQgICAgICAgIHN0cmluZy5wdXNoKCcwJyk7XG5cdCAgICAgIH1cblxuXHQgICAgICBzdHJpbmcucHVzaCgnLicpOyAvLyBhZGQgbGVhZGluZyB6ZXJvcyBhZnRlciByYWRpeFxuXG5cdCAgICAgIHdoaWxlIChyYWRpeF9wb3NpdGlvbisrIDwgMCkge1xuXHQgICAgICAgIHN0cmluZy5wdXNoKCcwJyk7XG5cdCAgICAgIH1cblxuXHQgICAgICBmb3IgKHZhciBfaTQgPSAwOyBfaTQgPCBzaWduaWZpY2FuZF9kaWdpdHMgLSBNYXRoLm1heChyYWRpeF9wb3NpdGlvbiAtIDEsIDApOyBfaTQrKykge1xuXHQgICAgICAgIHN0cmluZy5wdXNoKHNpZ25pZmljYW5kW2luZGV4KytdKTtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH1cblxuXHQgIHJldHVybiBzdHJpbmcuam9pbignJyk7XG5cdH07XG5cblx0RGVjaW1hbDEyOC5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gKCkge1xuXHQgIHJldHVybiB7XG5cdCAgICAkbnVtYmVyRGVjaW1hbDogdGhpcy50b1N0cmluZygpXG5cdCAgfTtcblx0fTtcblx0LyoqXG5cdCAqIEBpZ25vcmVcblx0ICovXG5cblxuXHREZWNpbWFsMTI4LnByb3RvdHlwZS50b0V4dGVuZGVkSlNPTiA9IGZ1bmN0aW9uICgpIHtcblx0ICByZXR1cm4ge1xuXHQgICAgJG51bWJlckRlY2ltYWw6IHRoaXMudG9TdHJpbmcoKVxuXHQgIH07XG5cdH07XG5cdC8qKlxuXHQgKiBAaWdub3JlXG5cdCAqL1xuXG5cblx0RGVjaW1hbDEyOC5mcm9tRXh0ZW5kZWRKU09OID0gZnVuY3Rpb24gKGRvYykge1xuXHQgIHJldHVybiBEZWNpbWFsMTI4LmZyb21TdHJpbmcoZG9jLiRudW1iZXJEZWNpbWFsKTtcblx0fTtcblxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoRGVjaW1hbDEyOC5wcm90b3R5cGUsICdfYnNvbnR5cGUnLCB7XG5cdCAgdmFsdWU6ICdEZWNpbWFsMTI4J1xuXHR9KTtcblx0dmFyIGRlY2ltYWwxMjggPSBEZWNpbWFsMTI4O1xuXG5cdC8qKlxuXHQgKiBBIGNsYXNzIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBCU09OIE1pbktleSB0eXBlLlxuXHQgKi9cblxuXHRmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2skNyhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cblx0ZnVuY3Rpb24gX2RlZmluZVByb3BlcnRpZXMkNyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9XG5cblx0ZnVuY3Rpb24gX2NyZWF0ZUNsYXNzJDcoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyQ3KENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgX2RlZmluZVByb3BlcnRpZXMkNyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH1cblxuXHR2YXIgTWluS2V5ID1cblx0LyojX19QVVJFX18qL1xuXHRmdW5jdGlvbiAoKSB7XG5cdCAgLyoqXG5cdCAgICogQ3JlYXRlIGEgTWluS2V5IHR5cGVcblx0ICAgKlxuXHQgICAqIEByZXR1cm4ge01pbktleX0gQSBNaW5LZXkgaW5zdGFuY2Vcblx0ICAgKi9cblx0ICBmdW5jdGlvbiBNaW5LZXkoKSB7XG5cdCAgICBfY2xhc3NDYWxsQ2hlY2skNyh0aGlzLCBNaW5LZXkpO1xuXHQgIH1cblx0ICAvKipcblx0ICAgKiBAaWdub3JlXG5cdCAgICovXG5cblxuXHQgIF9jcmVhdGVDbGFzcyQ3KE1pbktleSwgW3tcblx0ICAgIGtleTogXCJ0b0V4dGVuZGVkSlNPTlwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHRvRXh0ZW5kZWRKU09OKCkge1xuXHQgICAgICByZXR1cm4ge1xuXHQgICAgICAgICRtaW5LZXk6IDFcblx0ICAgICAgfTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9XSwgW3tcblx0ICAgIGtleTogXCJmcm9tRXh0ZW5kZWRKU09OXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gZnJvbUV4dGVuZGVkSlNPTigpIHtcblx0ICAgICAgcmV0dXJuIG5ldyBNaW5LZXkoKTtcblx0ICAgIH1cblx0ICB9XSk7XG5cblx0ICByZXR1cm4gTWluS2V5O1xuXHR9KCk7XG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KE1pbktleS5wcm90b3R5cGUsICdfYnNvbnR5cGUnLCB7XG5cdCAgdmFsdWU6ICdNaW5LZXknXG5cdH0pO1xuXHR2YXIgbWluX2tleSA9IE1pbktleTtcblxuXHQvKipcblx0ICogQSBjbGFzcyByZXByZXNlbnRhdGlvbiBvZiB0aGUgQlNPTiBNYXhLZXkgdHlwZS5cblx0ICovXG5cblx0ZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrJDgoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG5cdGZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzJDgodGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfVxuXG5cdGZ1bmN0aW9uIF9jcmVhdGVDbGFzcyQ4KENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgX2RlZmluZVByb3BlcnRpZXMkOChDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzJDgoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9XG5cblx0dmFyIE1heEtleSA9XG5cdC8qI19fUFVSRV9fKi9cblx0ZnVuY3Rpb24gKCkge1xuXHQgIC8qKlxuXHQgICAqIENyZWF0ZSBhIE1heEtleSB0eXBlXG5cdCAgICpcblx0ICAgKiBAcmV0dXJuIHtNYXhLZXl9IEEgTWF4S2V5IGluc3RhbmNlXG5cdCAgICovXG5cdCAgZnVuY3Rpb24gTWF4S2V5KCkge1xuXHQgICAgX2NsYXNzQ2FsbENoZWNrJDgodGhpcywgTWF4S2V5KTtcblx0ICB9XG5cdCAgLyoqXG5cdCAgICogQGlnbm9yZVxuXHQgICAqL1xuXG5cblx0ICBfY3JlYXRlQ2xhc3MkOChNYXhLZXksIFt7XG5cdCAgICBrZXk6IFwidG9FeHRlbmRlZEpTT05cIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB0b0V4dGVuZGVkSlNPTigpIHtcblx0ICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAkbWF4S2V5OiAxXG5cdCAgICAgIH07XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEBpZ25vcmVcblx0ICAgICAqL1xuXG5cdCAgfV0sIFt7XG5cdCAgICBrZXk6IFwiZnJvbUV4dGVuZGVkSlNPTlwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIGZyb21FeHRlbmRlZEpTT04oKSB7XG5cdCAgICAgIHJldHVybiBuZXcgTWF4S2V5KCk7XG5cdCAgICB9XG5cdCAgfV0pO1xuXG5cdCAgcmV0dXJuIE1heEtleTtcblx0fSgpO1xuXG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShNYXhLZXkucHJvdG90eXBlLCAnX2Jzb250eXBlJywge1xuXHQgIHZhbHVlOiAnTWF4S2V5J1xuXHR9KTtcblx0dmFyIG1heF9rZXkgPSBNYXhLZXk7XG5cblx0LyoqXG5cdCAqIEEgY2xhc3MgcmVwcmVzZW50YXRpb24gb2YgdGhlIEJTT04gREJSZWYgdHlwZS5cblx0ICovXG5cblx0ZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrJDkoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG5cdGZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzJDkodGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfVxuXG5cdGZ1bmN0aW9uIF9jcmVhdGVDbGFzcyQ5KENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgX2RlZmluZVByb3BlcnRpZXMkOShDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzJDkoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9XG5cblx0dmFyIERCUmVmID1cblx0LyojX19QVVJFX18qL1xuXHRmdW5jdGlvbiAoKSB7XG5cdCAgLyoqXG5cdCAgICogQ3JlYXRlIGEgREJSZWYgdHlwZVxuXHQgICAqXG5cdCAgICogQHBhcmFtIHtzdHJpbmd9IGNvbGxlY3Rpb24gdGhlIGNvbGxlY3Rpb24gbmFtZS5cblx0ICAgKiBAcGFyYW0ge09iamVjdElkfSBvaWQgdGhlIHJlZmVyZW5jZSBPYmplY3RJZC5cblx0ICAgKiBAcGFyYW0ge3N0cmluZ30gW2RiXSBvcHRpb25hbCBkYiBuYW1lLCBpZiBvbWl0dGVkIHRoZSByZWZlcmVuY2UgaXMgbG9jYWwgdG8gdGhlIGN1cnJlbnQgZGIuXG5cdCAgICogQHJldHVybiB7REJSZWZ9XG5cdCAgICovXG5cdCAgZnVuY3Rpb24gREJSZWYoY29sbGVjdGlvbiwgb2lkLCBkYiwgZmllbGRzKSB7XG5cdCAgICBfY2xhc3NDYWxsQ2hlY2skOSh0aGlzLCBEQlJlZik7XG5cblx0ICAgIC8vIGNoZWNrIGlmIG5hbWVzcGFjZSBoYXMgYmVlbiBwcm92aWRlZFxuXHQgICAgdmFyIHBhcnRzID0gY29sbGVjdGlvbi5zcGxpdCgnLicpO1xuXG5cdCAgICBpZiAocGFydHMubGVuZ3RoID09PSAyKSB7XG5cdCAgICAgIGRiID0gcGFydHMuc2hpZnQoKTtcblx0ICAgICAgY29sbGVjdGlvbiA9IHBhcnRzLnNoaWZ0KCk7XG5cdCAgICB9XG5cblx0ICAgIHRoaXMuY29sbGVjdGlvbiA9IGNvbGxlY3Rpb247XG5cdCAgICB0aGlzLm9pZCA9IG9pZDtcblx0ICAgIHRoaXMuZGIgPSBkYjtcblx0ICAgIHRoaXMuZmllbGRzID0gZmllbGRzIHx8IHt9O1xuXHQgIH1cblx0ICAvKipcblx0ICAgKiBAaWdub3JlXG5cdCAgICogQGFwaSBwcml2YXRlXG5cdCAgICovXG5cblxuXHQgIF9jcmVhdGVDbGFzcyQ5KERCUmVmLCBbe1xuXHQgICAga2V5OiBcInRvSlNPTlwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHRvSlNPTigpIHtcblx0ICAgICAgdmFyIG8gPSBPYmplY3QuYXNzaWduKHtcblx0ICAgICAgICAkcmVmOiB0aGlzLmNvbGxlY3Rpb24sXG5cdCAgICAgICAgJGlkOiB0aGlzLm9pZFxuXHQgICAgICB9LCB0aGlzLmZpZWxkcyk7XG5cdCAgICAgIGlmICh0aGlzLmRiICE9IG51bGwpIG8uJGRiID0gdGhpcy5kYjtcblx0ICAgICAgcmV0dXJuIG87XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEBpZ25vcmVcblx0ICAgICAqL1xuXG5cdCAgfSwge1xuXHQgICAga2V5OiBcInRvRXh0ZW5kZWRKU09OXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gdG9FeHRlbmRlZEpTT04oKSB7XG5cdCAgICAgIHZhciBvID0ge1xuXHQgICAgICAgICRyZWY6IHRoaXMuY29sbGVjdGlvbixcblx0ICAgICAgICAkaWQ6IHRoaXMub2lkXG5cdCAgICAgIH07XG5cdCAgICAgIGlmICh0aGlzLmRiKSBvLiRkYiA9IHRoaXMuZGI7XG5cdCAgICAgIG8gPSBPYmplY3QuYXNzaWduKG8sIHRoaXMuZmllbGRzKTtcblx0ICAgICAgcmV0dXJuIG87XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEBpZ25vcmVcblx0ICAgICAqL1xuXG5cdCAgfV0sIFt7XG5cdCAgICBrZXk6IFwiZnJvbUV4dGVuZGVkSlNPTlwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIGZyb21FeHRlbmRlZEpTT04oZG9jKSB7XG5cdCAgICAgIHZhciBjb3B5ID0gT2JqZWN0LmFzc2lnbih7fSwgZG9jKTtcblx0ICAgICAgWyckcmVmJywgJyRpZCcsICckZGInXS5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7XG5cdCAgICAgICAgcmV0dXJuIGRlbGV0ZSBjb3B5W2tdO1xuXHQgICAgICB9KTtcblx0ICAgICAgcmV0dXJuIG5ldyBEQlJlZihkb2MuJHJlZiwgZG9jLiRpZCwgZG9jLiRkYiwgY29weSk7XG5cdCAgICB9XG5cdCAgfV0pO1xuXG5cdCAgcmV0dXJuIERCUmVmO1xuXHR9KCk7XG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KERCUmVmLnByb3RvdHlwZSwgJ19ic29udHlwZScsIHtcblx0ICB2YWx1ZTogJ0RCUmVmJ1xuXHR9KTsgLy8gdGhlIDEueCBwYXJzZXIgdXNlZCBhIFwibmFtZXNwYWNlXCIgcHJvcGVydHksIHdoaWxlIDQueCB1c2VzIFwiY29sbGVjdGlvblwiLiBUbyBlbnN1cmUgYmFja3dhcmRzXG5cdC8vIGNvbXBhdGliaWxpdHksIGxldCdzIGV4cG9zZSBcIm5hbWVzcGFjZVwiXG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KERCUmVmLnByb3RvdHlwZSwgJ25hbWVzcGFjZScsIHtcblx0ICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcblx0ICAgIHJldHVybiB0aGlzLmNvbGxlY3Rpb247XG5cdCAgfSxcblx0ICBzZXQ6IGZ1bmN0aW9uIHNldCh2YWwpIHtcblx0ICAgIHRoaXMuY29sbGVjdGlvbiA9IHZhbDtcblx0ICB9LFxuXHQgIGNvbmZpZ3VyYWJsZTogZmFsc2Vcblx0fSk7XG5cdHZhciBkYl9yZWYgPSBEQlJlZjtcblxuXHRmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2skYShpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cblx0ZnVuY3Rpb24gX2RlZmluZVByb3BlcnRpZXMkYSh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9XG5cblx0ZnVuY3Rpb24gX2NyZWF0ZUNsYXNzJGEoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyRhKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgX2RlZmluZVByb3BlcnRpZXMkYShDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH1cblxuXHR2YXIgQnVmZmVyJDMgPSBidWZmZXIuQnVmZmVyO1xuXHQvKipcblx0ICogQSBjbGFzcyByZXByZXNlbnRhdGlvbiBvZiB0aGUgQlNPTiBCaW5hcnkgdHlwZS5cblx0ICovXG5cblx0dmFyIEJpbmFyeSA9XG5cdC8qI19fUFVSRV9fKi9cblx0ZnVuY3Rpb24gKCkge1xuXHQgIC8qKlxuXHQgICAqIENyZWF0ZSBhIEJpbmFyeSB0eXBlXG5cdCAgICpcblx0ICAgKiBTdWIgdHlwZXNcblx0ICAgKiAgLSAqKkJTT04uQlNPTl9CSU5BUllfU1VCVFlQRV9ERUZBVUxUKiosIGRlZmF1bHQgQlNPTiB0eXBlLlxuXHQgICAqICAtICoqQlNPTi5CU09OX0JJTkFSWV9TVUJUWVBFX0ZVTkNUSU9OKiosIEJTT04gZnVuY3Rpb24gdHlwZS5cblx0ICAgKiAgLSAqKkJTT04uQlNPTl9CSU5BUllfU1VCVFlQRV9CWVRFX0FSUkFZKiosIEJTT04gYnl0ZSBhcnJheSB0eXBlLlxuXHQgICAqICAtICoqQlNPTi5CU09OX0JJTkFSWV9TVUJUWVBFX1VVSUQqKiwgQlNPTiB1dWlkIHR5cGUuXG5cdCAgICogIC0gKipCU09OLkJTT05fQklOQVJZX1NVQlRZUEVfTUQ1KiosIEJTT04gbWQ1IHR5cGUuXG5cdCAgICogIC0gKipCU09OLkJTT05fQklOQVJZX1NVQlRZUEVfVVNFUl9ERUZJTkVEKiosIEJTT04gdXNlciBkZWZpbmVkIHR5cGUuXG5cdCAgICpcblx0ICAgKiBAcGFyYW0ge0J1ZmZlcn0gYnVmZmVyIGEgYnVmZmVyIG9iamVjdCBjb250YWluaW5nIHRoZSBiaW5hcnkgZGF0YS5cblx0ICAgKiBAcGFyYW0ge051bWJlcn0gW3N1YlR5cGVdIHRoZSBvcHRpb24gYmluYXJ5IHR5cGUuXG5cdCAgICogQHJldHVybiB7QmluYXJ5fVxuXHQgICAqL1xuXHQgIGZ1bmN0aW9uIEJpbmFyeShidWZmZXIkJDEsIHN1YlR5cGUpIHtcblx0ICAgIF9jbGFzc0NhbGxDaGVjayRhKHRoaXMsIEJpbmFyeSk7XG5cblx0ICAgIGlmIChidWZmZXIkJDEgIT0gbnVsbCAmJiAhKHR5cGVvZiBidWZmZXIkJDEgPT09ICdzdHJpbmcnKSAmJiAhQnVmZmVyJDMuaXNCdWZmZXIoYnVmZmVyJCQxKSAmJiAhKGJ1ZmZlciQkMSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpICYmICFBcnJheS5pc0FycmF5KGJ1ZmZlciQkMSkpIHtcblx0ICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb25seSBTdHJpbmcsIEJ1ZmZlciwgVWludDhBcnJheSBvciBBcnJheSBhY2NlcHRlZCcpO1xuXHQgICAgfVxuXG5cdCAgICB0aGlzLnN1Yl90eXBlID0gc3ViVHlwZSA9PSBudWxsID8gQlNPTl9CSU5BUllfU1VCVFlQRV9ERUZBVUxUIDogc3ViVHlwZTtcblx0ICAgIHRoaXMucG9zaXRpb24gPSAwO1xuXG5cdCAgICBpZiAoYnVmZmVyJCQxICE9IG51bGwgJiYgIShidWZmZXIkJDEgaW5zdGFuY2VvZiBOdW1iZXIpKSB7XG5cdCAgICAgIC8vIE9ubHkgYWNjZXB0IEJ1ZmZlciwgVWludDhBcnJheSBvciBBcnJheXNcblx0ICAgICAgaWYgKHR5cGVvZiBidWZmZXIkJDEgPT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgLy8gRGlmZmVyZW50IHdheXMgb2Ygd3JpdGluZyB0aGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgZm9yIHRoZSBkaWZmZXJlbnQgdHlwZXNcblx0ICAgICAgICBpZiAodHlwZW9mIEJ1ZmZlciQzICE9PSAndW5kZWZpbmVkJykge1xuXHQgICAgICAgICAgdGhpcy5idWZmZXIgPSBCdWZmZXIkMy5mcm9tKGJ1ZmZlciQkMSk7XG5cdCAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcgfHwgQXJyYXkuaXNBcnJheShidWZmZXIkJDEpKSB7XG5cdCAgICAgICAgICB0aGlzLmJ1ZmZlciA9IHdyaXRlU3RyaW5nVG9BcnJheShidWZmZXIkJDEpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvbmx5IFN0cmluZywgQnVmZmVyLCBVaW50OEFycmF5IG9yIEFycmF5IGFjY2VwdGVkJyk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9IGVsc2Uge1xuXHQgICAgICAgIHRoaXMuYnVmZmVyID0gYnVmZmVyJCQxO1xuXHQgICAgICB9XG5cblx0ICAgICAgdGhpcy5wb3NpdGlvbiA9IGJ1ZmZlciQkMS5sZW5ndGg7XG5cdCAgICB9IGVsc2Uge1xuXHQgICAgICBpZiAodHlwZW9mIEJ1ZmZlciQzICE9PSAndW5kZWZpbmVkJykge1xuXHQgICAgICAgIHRoaXMuYnVmZmVyID0gQnVmZmVyJDMuYWxsb2MoQmluYXJ5LkJVRkZFUl9TSVpFKTtcblx0ICAgICAgfSBlbHNlIGlmICh0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0ICAgICAgICB0aGlzLmJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KG5ldyBBcnJheUJ1ZmZlcihCaW5hcnkuQlVGRkVSX1NJWkUpKTtcblx0ICAgICAgfSBlbHNlIHtcblx0ICAgICAgICB0aGlzLmJ1ZmZlciA9IG5ldyBBcnJheShCaW5hcnkuQlVGRkVSX1NJWkUpO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfVxuXHQgIC8qKlxuXHQgICAqIFVwZGF0ZXMgdGhpcyBiaW5hcnkgd2l0aCBieXRlX3ZhbHVlLlxuXHQgICAqXG5cdCAgICogQG1ldGhvZFxuXHQgICAqIEBwYXJhbSB7c3RyaW5nfSBieXRlX3ZhbHVlIGEgc2luZ2xlIGJ5dGUgd2Ugd2lzaCB0byB3cml0ZS5cblx0ICAgKi9cblxuXG5cdCAgX2NyZWF0ZUNsYXNzJGEoQmluYXJ5LCBbe1xuXHQgICAga2V5OiBcInB1dFwiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHB1dChieXRlX3ZhbHVlKSB7XG5cdCAgICAgIC8vIElmIGl0J3MgYSBzdHJpbmcgYW5kIGEgaGFzIG1vcmUgdGhhbiBvbmUgY2hhcmFjdGVyIHRocm93IGFuIGVycm9yXG5cdCAgICAgIGlmIChieXRlX3ZhbHVlWydsZW5ndGgnXSAhPSBudWxsICYmIHR5cGVvZiBieXRlX3ZhbHVlICE9PSAnbnVtYmVyJyAmJiBieXRlX3ZhbHVlLmxlbmd0aCAhPT0gMSkgdGhyb3cgbmV3IFR5cGVFcnJvcignb25seSBhY2NlcHRzIHNpbmdsZSBjaGFyYWN0ZXIgU3RyaW5nLCBVaW50OEFycmF5IG9yIEFycmF5Jyk7XG5cdCAgICAgIGlmICh0eXBlb2YgYnl0ZV92YWx1ZSAhPT0gJ251bWJlcicgJiYgYnl0ZV92YWx1ZSA8IDAgfHwgYnl0ZV92YWx1ZSA+IDI1NSkgdGhyb3cgbmV3IFR5cGVFcnJvcignb25seSBhY2NlcHRzIG51bWJlciBpbiBhIHZhbGlkIHVuc2lnbmVkIGJ5dGUgcmFuZ2UgMC0yNTUnKTsgLy8gRGVjb2RlIHRoZSBieXRlIHZhbHVlIG9uY2VcblxuXHQgICAgICB2YXIgZGVjb2RlZF9ieXRlID0gbnVsbDtcblxuXHQgICAgICBpZiAodHlwZW9mIGJ5dGVfdmFsdWUgPT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgZGVjb2RlZF9ieXRlID0gYnl0ZV92YWx1ZS5jaGFyQ29kZUF0KDApO1xuXHQgICAgICB9IGVsc2UgaWYgKGJ5dGVfdmFsdWVbJ2xlbmd0aCddICE9IG51bGwpIHtcblx0ICAgICAgICBkZWNvZGVkX2J5dGUgPSBieXRlX3ZhbHVlWzBdO1xuXHQgICAgICB9IGVsc2Uge1xuXHQgICAgICAgIGRlY29kZWRfYnl0ZSA9IGJ5dGVfdmFsdWU7XG5cdCAgICAgIH1cblxuXHQgICAgICBpZiAodGhpcy5idWZmZXIubGVuZ3RoID4gdGhpcy5wb3NpdGlvbikge1xuXHQgICAgICAgIHRoaXMuYnVmZmVyW3RoaXMucG9zaXRpb24rK10gPSBkZWNvZGVkX2J5dGU7XG5cdCAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgaWYgKHR5cGVvZiBCdWZmZXIkMyAhPT0gJ3VuZGVmaW5lZCcgJiYgQnVmZmVyJDMuaXNCdWZmZXIodGhpcy5idWZmZXIpKSB7XG5cdCAgICAgICAgICAvLyBDcmVhdGUgYWRkaXRpb25hbCBvdmVyZmxvdyBidWZmZXJcblx0ICAgICAgICAgIHZhciBidWZmZXIkJDEgPSBCdWZmZXIkMy5hbGxvYyhCaW5hcnkuQlVGRkVSX1NJWkUgKyB0aGlzLmJ1ZmZlci5sZW5ndGgpOyAvLyBDb21iaW5lIHRoZSB0d28gYnVmZmVycyB0b2dldGhlclxuXG5cdCAgICAgICAgICB0aGlzLmJ1ZmZlci5jb3B5KGJ1ZmZlciQkMSwgMCwgMCwgdGhpcy5idWZmZXIubGVuZ3RoKTtcblx0ICAgICAgICAgIHRoaXMuYnVmZmVyID0gYnVmZmVyJCQxO1xuXHQgICAgICAgICAgdGhpcy5idWZmZXJbdGhpcy5wb3NpdGlvbisrXSA9IGRlY29kZWRfYnl0ZTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgdmFyIF9idWZmZXIgPSBudWxsOyAvLyBDcmVhdGUgYSBuZXcgYnVmZmVyICh0eXBlZCBvciBub3JtYWwgYXJyYXkpXG5cblx0ICAgICAgICAgIGlmIChpc1VpbnQ4QXJyYXkodGhpcy5idWZmZXIpKSB7XG5cdCAgICAgICAgICAgIF9idWZmZXIgPSBuZXcgVWludDhBcnJheShuZXcgQXJyYXlCdWZmZXIoQmluYXJ5LkJVRkZFUl9TSVpFICsgdGhpcy5idWZmZXIubGVuZ3RoKSk7XG5cdCAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICBfYnVmZmVyID0gbmV3IEFycmF5KEJpbmFyeS5CVUZGRVJfU0laRSArIHRoaXMuYnVmZmVyLmxlbmd0aCk7XG5cdCAgICAgICAgICB9IC8vIFdlIG5lZWQgdG8gY29weSBhbGwgdGhlIGNvbnRlbnQgdG8gdGhlIG5ldyBhcnJheVxuXG5cblx0ICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5idWZmZXIubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgICAgX2J1ZmZlcltpXSA9IHRoaXMuYnVmZmVyW2ldO1xuXHQgICAgICAgICAgfSAvLyBSZWFzc2lnbiB0aGUgYnVmZmVyXG5cblxuXHQgICAgICAgICAgdGhpcy5idWZmZXIgPSBfYnVmZmVyOyAvLyBXcml0ZSB0aGUgYnl0ZVxuXG5cdCAgICAgICAgICB0aGlzLmJ1ZmZlclt0aGlzLnBvc2l0aW9uKytdID0gZGVjb2RlZF9ieXRlO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBXcml0ZXMgYSBidWZmZXIgb3Igc3RyaW5nIHRvIHRoZSBiaW5hcnkuXG5cdCAgICAgKlxuXHQgICAgICogQG1ldGhvZFxuXHQgICAgICogQHBhcmFtIHsoQnVmZmVyfHN0cmluZyl9IHN0cmluZyBhIHN0cmluZyBvciBidWZmZXIgdG8gYmUgd3JpdHRlbiB0byB0aGUgQmluYXJ5IEJTT04gb2JqZWN0LlxuXHQgICAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBzcGVjaWZ5IHRoZSBiaW5hcnkgb2Ygd2hlcmUgdG8gd3JpdGUgdGhlIGNvbnRlbnQuXG5cdCAgICAgKiBAcmV0dXJuIHtudWxsfVxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwid3JpdGVcIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB3cml0ZShzdHJpbmcsIG9mZnNldCkge1xuXHQgICAgICBvZmZzZXQgPSB0eXBlb2Ygb2Zmc2V0ID09PSAnbnVtYmVyJyA/IG9mZnNldCA6IHRoaXMucG9zaXRpb247IC8vIElmIHRoZSBidWZmZXIgaXMgdG8gc21hbGwgbGV0J3MgZXh0ZW5kIHRoZSBidWZmZXJcblxuXHQgICAgICBpZiAodGhpcy5idWZmZXIubGVuZ3RoIDwgb2Zmc2V0ICsgc3RyaW5nLmxlbmd0aCkge1xuXHQgICAgICAgIHZhciBidWZmZXIkJDEgPSBudWxsOyAvLyBJZiB3ZSBhcmUgaW4gbm9kZS5qc1xuXG5cdCAgICAgICAgaWYgKHR5cGVvZiBCdWZmZXIkMyAhPT0gJ3VuZGVmaW5lZCcgJiYgQnVmZmVyJDMuaXNCdWZmZXIodGhpcy5idWZmZXIpKSB7XG5cdCAgICAgICAgICBidWZmZXIkJDEgPSBCdWZmZXIkMy5hbGxvYyh0aGlzLmJ1ZmZlci5sZW5ndGggKyBzdHJpbmcubGVuZ3RoKTtcblx0ICAgICAgICAgIHRoaXMuYnVmZmVyLmNvcHkoYnVmZmVyJCQxLCAwLCAwLCB0aGlzLmJ1ZmZlci5sZW5ndGgpO1xuXHQgICAgICAgIH0gZWxzZSBpZiAoaXNVaW50OEFycmF5KHRoaXMuYnVmZmVyKSkge1xuXHQgICAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IGJ1ZmZlclxuXHQgICAgICAgICAgYnVmZmVyJCQxID0gbmV3IFVpbnQ4QXJyYXkobmV3IEFycmF5QnVmZmVyKHRoaXMuYnVmZmVyLmxlbmd0aCArIHN0cmluZy5sZW5ndGgpKTsgLy8gQ29weSB0aGUgY29udGVudFxuXG5cdCAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucG9zaXRpb247IGkrKykge1xuXHQgICAgICAgICAgICBidWZmZXIkJDFbaV0gPSB0aGlzLmJ1ZmZlcltpXTtcblx0ICAgICAgICAgIH1cblx0ICAgICAgICB9IC8vIEFzc2lnbiB0aGUgbmV3IGJ1ZmZlclxuXG5cblx0ICAgICAgICB0aGlzLmJ1ZmZlciA9IGJ1ZmZlciQkMTtcblx0ICAgICAgfVxuXG5cdCAgICAgIGlmICh0eXBlb2YgQnVmZmVyJDMgIT09ICd1bmRlZmluZWQnICYmIEJ1ZmZlciQzLmlzQnVmZmVyKHN0cmluZykgJiYgQnVmZmVyJDMuaXNCdWZmZXIodGhpcy5idWZmZXIpKSB7XG5cdCAgICAgICAgc3RyaW5nLmNvcHkodGhpcy5idWZmZXIsIG9mZnNldCwgMCwgc3RyaW5nLmxlbmd0aCk7XG5cdCAgICAgICAgdGhpcy5wb3NpdGlvbiA9IG9mZnNldCArIHN0cmluZy5sZW5ndGggPiB0aGlzLnBvc2l0aW9uID8gb2Zmc2V0ICsgc3RyaW5nLmxlbmd0aCA6IHRoaXMucG9zaXRpb247IC8vIG9mZnNldCA9IHN0cmluZy5sZW5ndGhcblx0ICAgICAgfSBlbHNlIGlmICh0eXBlb2YgQnVmZmVyJDMgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBzdHJpbmcgPT09ICdzdHJpbmcnICYmIEJ1ZmZlciQzLmlzQnVmZmVyKHRoaXMuYnVmZmVyKSkge1xuXHQgICAgICAgIHRoaXMuYnVmZmVyLndyaXRlKHN0cmluZywgb2Zmc2V0LCAnYmluYXJ5Jyk7XG5cdCAgICAgICAgdGhpcy5wb3NpdGlvbiA9IG9mZnNldCArIHN0cmluZy5sZW5ndGggPiB0aGlzLnBvc2l0aW9uID8gb2Zmc2V0ICsgc3RyaW5nLmxlbmd0aCA6IHRoaXMucG9zaXRpb247IC8vIG9mZnNldCA9IHN0cmluZy5sZW5ndGg7XG5cdCAgICAgIH0gZWxzZSBpZiAoaXNVaW50OEFycmF5KHN0cmluZykgfHwgQXJyYXkuaXNBcnJheShzdHJpbmcpICYmIHR5cGVvZiBzdHJpbmcgIT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IHN0cmluZy5sZW5ndGg7IF9pKyspIHtcblx0ICAgICAgICAgIHRoaXMuYnVmZmVyW29mZnNldCsrXSA9IHN0cmluZ1tfaV07XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgdGhpcy5wb3NpdGlvbiA9IG9mZnNldCA+IHRoaXMucG9zaXRpb24gPyBvZmZzZXQgOiB0aGlzLnBvc2l0aW9uO1xuXHQgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBzdHJpbmcgPT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgZm9yICh2YXIgX2kyID0gMDsgX2kyIDwgc3RyaW5nLmxlbmd0aDsgX2kyKyspIHtcblx0ICAgICAgICAgIHRoaXMuYnVmZmVyW29mZnNldCsrXSA9IHN0cmluZy5jaGFyQ29kZUF0KF9pMik7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgdGhpcy5wb3NpdGlvbiA9IG9mZnNldCA+IHRoaXMucG9zaXRpb24gPyBvZmZzZXQgOiB0aGlzLnBvc2l0aW9uO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJlYWRzICoqbGVuZ3RoKiogYnl0ZXMgc3RhcnRpbmcgYXQgKipwb3NpdGlvbioqLlxuXHQgICAgICpcblx0ICAgICAqIEBtZXRob2Rcblx0ICAgICAqIEBwYXJhbSB7bnVtYmVyfSBwb3NpdGlvbiByZWFkIGZyb20gdGhlIGdpdmVuIHBvc2l0aW9uIGluIHRoZSBCaW5hcnkuXG5cdCAgICAgKiBAcGFyYW0ge251bWJlcn0gbGVuZ3RoIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gcmVhZC5cblx0ICAgICAqIEByZXR1cm4ge0J1ZmZlcn1cblx0ICAgICAqL1xuXG5cdCAgfSwge1xuXHQgICAga2V5OiBcInJlYWRcIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiByZWFkKHBvc2l0aW9uLCBsZW5ndGgpIHtcblx0ICAgICAgbGVuZ3RoID0gbGVuZ3RoICYmIGxlbmd0aCA+IDAgPyBsZW5ndGggOiB0aGlzLnBvc2l0aW9uOyAvLyBMZXQncyByZXR1cm4gdGhlIGRhdGEgYmFzZWQgb24gdGhlIHR5cGUgd2UgaGF2ZVxuXG5cdCAgICAgIGlmICh0aGlzLmJ1ZmZlclsnc2xpY2UnXSkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLmJ1ZmZlci5zbGljZShwb3NpdGlvbiwgcG9zaXRpb24gKyBsZW5ndGgpO1xuXHQgICAgICB9IC8vIENyZWF0ZSBhIGJ1ZmZlciB0byBrZWVwIHRoZSByZXN1bHRcblxuXG5cdCAgICAgIHZhciBidWZmZXIkJDEgPSB0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcgPyBuZXcgVWludDhBcnJheShuZXcgQXJyYXlCdWZmZXIobGVuZ3RoKSkgOiBuZXcgQXJyYXkobGVuZ3RoKTtcblxuXHQgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgYnVmZmVyJCQxW2ldID0gdGhpcy5idWZmZXJbcG9zaXRpb24rK107XG5cdCAgICAgIH0gLy8gUmV0dXJuIHRoZSBidWZmZXJcblxuXG5cdCAgICAgIHJldHVybiBidWZmZXIkJDE7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoaXMgYmluYXJ5IGFzIGEgc3RyaW5nLlxuXHQgICAgICpcblx0ICAgICAqIEBtZXRob2Rcblx0ICAgICAqIEByZXR1cm4ge3N0cmluZ31cblx0ICAgICAqL1xuXG5cdCAgfSwge1xuXHQgICAga2V5OiBcInZhbHVlXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gdmFsdWUoYXNSYXcpIHtcblx0ICAgICAgYXNSYXcgPSBhc1JhdyA9PSBudWxsID8gZmFsc2UgOiBhc1JhdzsgLy8gT3B0aW1pemUgdG8gc2VyaWFsaXplIGZvciB0aGUgc2l0dWF0aW9uIHdoZXJlIHRoZSBkYXRhID09IHNpemUgb2YgYnVmZmVyXG5cblx0ICAgICAgaWYgKGFzUmF3ICYmIHR5cGVvZiBCdWZmZXIkMyAhPT0gJ3VuZGVmaW5lZCcgJiYgQnVmZmVyJDMuaXNCdWZmZXIodGhpcy5idWZmZXIpICYmIHRoaXMuYnVmZmVyLmxlbmd0aCA9PT0gdGhpcy5wb3NpdGlvbikgcmV0dXJuIHRoaXMuYnVmZmVyOyAvLyBJZiBpdCdzIGEgbm9kZS5qcyBidWZmZXIgb2JqZWN0XG5cblx0ICAgICAgaWYgKHR5cGVvZiBCdWZmZXIkMyAhPT0gJ3VuZGVmaW5lZCcgJiYgQnVmZmVyJDMuaXNCdWZmZXIodGhpcy5idWZmZXIpKSB7XG5cdCAgICAgICAgcmV0dXJuIGFzUmF3ID8gdGhpcy5idWZmZXIuc2xpY2UoMCwgdGhpcy5wb3NpdGlvbikgOiB0aGlzLmJ1ZmZlci50b1N0cmluZygnYmluYXJ5JywgMCwgdGhpcy5wb3NpdGlvbik7XG5cdCAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgaWYgKGFzUmF3KSB7XG5cdCAgICAgICAgICAvLyB3ZSBzdXBwb3J0IHRoZSBzbGljZSBjb21tYW5kIHVzZSBpdFxuXHQgICAgICAgICAgaWYgKHRoaXMuYnVmZmVyWydzbGljZSddICE9IG51bGwpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuYnVmZmVyLnNsaWNlKDAsIHRoaXMucG9zaXRpb24pO1xuXHQgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IGJ1ZmZlciB0byBjb3B5IGNvbnRlbnQgdG9cblx0ICAgICAgICAgICAgdmFyIG5ld0J1ZmZlciA9IGlzVWludDhBcnJheSh0aGlzLmJ1ZmZlcikgPyBuZXcgVWludDhBcnJheShuZXcgQXJyYXlCdWZmZXIodGhpcy5wb3NpdGlvbikpIDogbmV3IEFycmF5KHRoaXMucG9zaXRpb24pOyAvLyBDb3B5IGNvbnRlbnRcblxuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucG9zaXRpb247IGkrKykge1xuXHQgICAgICAgICAgICAgIG5ld0J1ZmZlcltpXSA9IHRoaXMuYnVmZmVyW2ldO1xuXHQgICAgICAgICAgICB9IC8vIFJldHVybiB0aGUgYnVmZmVyXG5cblxuXHQgICAgICAgICAgICByZXR1cm4gbmV3QnVmZmVyO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICByZXR1cm4gY29udmVydEFycmF5dG9VdGY4QmluYXJ5U3RyaW5nKHRoaXMuYnVmZmVyLCAwLCB0aGlzLnBvc2l0aW9uKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogTGVuZ3RoLlxuXHQgICAgICpcblx0ICAgICAqIEBtZXRob2Rcblx0ICAgICAqIEByZXR1cm4ge251bWJlcn0gdGhlIGxlbmd0aCBvZiB0aGUgYmluYXJ5LlxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwibGVuZ3RoXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gbGVuZ3RoKCkge1xuXHQgICAgICByZXR1cm4gdGhpcy5wb3NpdGlvbjtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwidG9KU09OXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gdG9KU09OKCkge1xuXHQgICAgICByZXR1cm4gdGhpcy5idWZmZXIgIT0gbnVsbCA/IHRoaXMuYnVmZmVyLnRvU3RyaW5nKCdiYXNlNjQnKSA6ICcnO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBAaWdub3JlXG5cdCAgICAgKi9cblxuXHQgIH0sIHtcblx0ICAgIGtleTogXCJ0b1N0cmluZ1wiLFxuXHQgICAgdmFsdWU6IGZ1bmN0aW9uIHRvU3RyaW5nKGZvcm1hdCkge1xuXHQgICAgICByZXR1cm4gdGhpcy5idWZmZXIgIT0gbnVsbCA/IHRoaXMuYnVmZmVyLnNsaWNlKDAsIHRoaXMucG9zaXRpb24pLnRvU3RyaW5nKGZvcm1hdCkgOiAnJztcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9LCB7XG5cdCAgICBrZXk6IFwidG9FeHRlbmRlZEpTT05cIixcblx0ICAgIHZhbHVlOiBmdW5jdGlvbiB0b0V4dGVuZGVkSlNPTigpIHtcblx0ICAgICAgdmFyIGJhc2U2NFN0cmluZyA9IEJ1ZmZlciQzLmlzQnVmZmVyKHRoaXMuYnVmZmVyKSA/IHRoaXMuYnVmZmVyLnRvU3RyaW5nKCdiYXNlNjQnKSA6IEJ1ZmZlciQzLmZyb20odGhpcy5idWZmZXIpLnRvU3RyaW5nKCdiYXNlNjQnKTtcblx0ICAgICAgdmFyIHN1YlR5cGUgPSBOdW1iZXIodGhpcy5zdWJfdHlwZSkudG9TdHJpbmcoMTYpO1xuXHQgICAgICByZXR1cm4ge1xuXHQgICAgICAgICRiaW5hcnk6IHtcblx0ICAgICAgICAgIGJhc2U2NDogYmFzZTY0U3RyaW5nLFxuXHQgICAgICAgICAgc3ViVHlwZTogc3ViVHlwZS5sZW5ndGggPT09IDEgPyAnMCcgKyBzdWJUeXBlIDogc3ViVHlwZVxuXHQgICAgICAgIH1cblx0ICAgICAgfTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cblx0ICB9XSwgW3tcblx0ICAgIGtleTogXCJmcm9tRXh0ZW5kZWRKU09OXCIsXG5cdCAgICB2YWx1ZTogZnVuY3Rpb24gZnJvbUV4dGVuZGVkSlNPTihkb2MpIHtcblx0ICAgICAgdmFyIHR5cGUgPSBkb2MuJGJpbmFyeS5zdWJUeXBlID8gcGFyc2VJbnQoZG9jLiRiaW5hcnkuc3ViVHlwZSwgMTYpIDogMDtcblx0ICAgICAgdmFyIGRhdGEgPSBCdWZmZXIkMy5mcm9tKGRvYy4kYmluYXJ5LmJhc2U2NCwgJ2Jhc2U2NCcpO1xuXHQgICAgICByZXR1cm4gbmV3IEJpbmFyeShkYXRhLCB0eXBlKTtcblx0ICAgIH1cblx0ICB9XSk7XG5cblx0ICByZXR1cm4gQmluYXJ5O1xuXHR9KCk7XG5cdC8qKlxuXHQgKiBCaW5hcnkgZGVmYXVsdCBzdWJ0eXBlXG5cdCAqIEBpZ25vcmVcblx0ICovXG5cblxuXHR2YXIgQlNPTl9CSU5BUllfU1VCVFlQRV9ERUZBVUxUID0gMDtcblxuXHRmdW5jdGlvbiBpc1VpbnQ4QXJyYXkob2JqKSB7XG5cdCAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopID09PSAnW29iamVjdCBVaW50OEFycmF5XSc7XG5cdH1cblx0LyoqXG5cdCAqIEBpZ25vcmVcblx0ICovXG5cblxuXHRmdW5jdGlvbiB3cml0ZVN0cmluZ1RvQXJyYXkoZGF0YSkge1xuXHQgIC8vIENyZWF0ZSBhIGJ1ZmZlclxuXHQgIHZhciBidWZmZXIkJDEgPSB0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcgPyBuZXcgVWludDhBcnJheShuZXcgQXJyYXlCdWZmZXIoZGF0YS5sZW5ndGgpKSA6IG5ldyBBcnJheShkYXRhLmxlbmd0aCk7IC8vIFdyaXRlIHRoZSBjb250ZW50IHRvIHRoZSBidWZmZXJcblxuXHQgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuXHQgICAgYnVmZmVyJCQxW2ldID0gZGF0YS5jaGFyQ29kZUF0KGkpO1xuXHQgIH0gLy8gV3JpdGUgdGhlIHN0cmluZyB0byB0aGUgYnVmZmVyXG5cblxuXHQgIHJldHVybiBidWZmZXIkJDE7XG5cdH1cblx0LyoqXG5cdCAqIENvbnZlcnQgQXJyYXkgb3QgVWludDhBcnJheSB0byBCaW5hcnkgU3RyaW5nXG5cdCAqXG5cdCAqIEBpZ25vcmVcblx0ICovXG5cblxuXHRmdW5jdGlvbiBjb252ZXJ0QXJyYXl0b1V0ZjhCaW5hcnlTdHJpbmcoYnl0ZUFycmF5LCBzdGFydEluZGV4LCBlbmRJbmRleCkge1xuXHQgIHZhciByZXN1bHQgPSAnJztcblxuXHQgIGZvciAodmFyIGkgPSBzdGFydEluZGV4OyBpIDwgZW5kSW5kZXg7IGkrKykge1xuXHQgICAgcmVzdWx0ID0gcmVzdWx0ICsgU3RyaW5nLmZyb21DaGFyQ29kZShieXRlQXJyYXlbaV0pO1xuXHQgIH1cblxuXHQgIHJldHVybiByZXN1bHQ7XG5cdH1cblxuXHRCaW5hcnkuQlVGRkVSX1NJWkUgPSAyNTY7XG5cdC8qKlxuXHQgKiBEZWZhdWx0IEJTT04gdHlwZVxuXHQgKlxuXHQgKiBAY2xhc3Njb25zdGFudCBTVUJUWVBFX0RFRkFVTFRcblx0ICoqL1xuXG5cdEJpbmFyeS5TVUJUWVBFX0RFRkFVTFQgPSAwO1xuXHQvKipcblx0ICogRnVuY3Rpb24gQlNPTiB0eXBlXG5cdCAqXG5cdCAqIEBjbGFzc2NvbnN0YW50IFNVQlRZUEVfREVGQVVMVFxuXHQgKiovXG5cblx0QmluYXJ5LlNVQlRZUEVfRlVOQ1RJT04gPSAxO1xuXHQvKipcblx0ICogQnl0ZSBBcnJheSBCU09OIHR5cGVcblx0ICpcblx0ICogQGNsYXNzY29uc3RhbnQgU1VCVFlQRV9ERUZBVUxUXG5cdCAqKi9cblxuXHRCaW5hcnkuU1VCVFlQRV9CWVRFX0FSUkFZID0gMjtcblx0LyoqXG5cdCAqIE9MRCBVVUlEIEJTT04gdHlwZVxuXHQgKlxuXHQgKiBAY2xhc3Njb25zdGFudCBTVUJUWVBFX0RFRkFVTFRcblx0ICoqL1xuXG5cdEJpbmFyeS5TVUJUWVBFX1VVSURfT0xEID0gMztcblx0LyoqXG5cdCAqIFVVSUQgQlNPTiB0eXBlXG5cdCAqXG5cdCAqIEBjbGFzc2NvbnN0YW50IFNVQlRZUEVfREVGQVVMVFxuXHQgKiovXG5cblx0QmluYXJ5LlNVQlRZUEVfVVVJRCA9IDQ7XG5cdC8qKlxuXHQgKiBNRDUgQlNPTiB0eXBlXG5cdCAqXG5cdCAqIEBjbGFzc2NvbnN0YW50IFNVQlRZUEVfREVGQVVMVFxuXHQgKiovXG5cblx0QmluYXJ5LlNVQlRZUEVfTUQ1ID0gNTtcblx0LyoqXG5cdCAqIFVzZXIgQlNPTiB0eXBlXG5cdCAqXG5cdCAqIEBjbGFzc2NvbnN0YW50IFNVQlRZUEVfREVGQVVMVFxuXHQgKiovXG5cblx0QmluYXJ5LlNVQlRZUEVfVVNFUl9ERUZJTkVEID0gMTI4O1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoQmluYXJ5LnByb3RvdHlwZSwgJ19ic29udHlwZScsIHtcblx0ICB2YWx1ZTogJ0JpbmFyeSdcblx0fSk7XG5cdHZhciBiaW5hcnkgPSBCaW5hcnk7XG5cblx0dmFyIGNvbnN0YW50cyA9IHtcblx0ICAvLyBCU09OIE1BWCBWQUxVRVNcblx0ICBCU09OX0lOVDMyX01BWDogMHg3ZmZmZmZmZixcblx0ICBCU09OX0lOVDMyX01JTjogLTB4ODAwMDAwMDAsXG5cdCAgQlNPTl9JTlQ2NF9NQVg6IE1hdGgucG93KDIsIDYzKSAtIDEsXG5cdCAgQlNPTl9JTlQ2NF9NSU46IC1NYXRoLnBvdygyLCA2MyksXG5cdCAgLy8gSlMgTUFYIFBSRUNJU0UgVkFMVUVTXG5cdCAgSlNfSU5UX01BWDogMHgyMDAwMDAwMDAwMDAwMCxcblx0ICAvLyBBbnkgaW50ZWdlciB1cCB0byAyXjUzIGNhbiBiZSBwcmVjaXNlbHkgcmVwcmVzZW50ZWQgYnkgYSBkb3VibGUuXG5cdCAgSlNfSU5UX01JTjogLTB4MjAwMDAwMDAwMDAwMDAsXG5cdCAgLy8gQW55IGludGVnZXIgZG93biB0byAtMl41MyBjYW4gYmUgcHJlY2lzZWx5IHJlcHJlc2VudGVkIGJ5IGEgZG91YmxlLlxuXG5cdCAgLyoqXG5cdCAgICogTnVtYmVyIEJTT04gVHlwZVxuXHQgICAqXG5cdCAgICogQGNsYXNzY29uc3RhbnQgQlNPTl9EQVRBX05VTUJFUlxuXHQgICAqKi9cblx0ICBCU09OX0RBVEFfTlVNQkVSOiAxLFxuXG5cdCAgLyoqXG5cdCAgICogU3RyaW5nIEJTT04gVHlwZVxuXHQgICAqXG5cdCAgICogQGNsYXNzY29uc3RhbnQgQlNPTl9EQVRBX1NUUklOR1xuXHQgICAqKi9cblx0ICBCU09OX0RBVEFfU1RSSU5HOiAyLFxuXG5cdCAgLyoqXG5cdCAgICogT2JqZWN0IEJTT04gVHlwZVxuXHQgICAqXG5cdCAgICogQGNsYXNzY29uc3RhbnQgQlNPTl9EQVRBX09CSkVDVFxuXHQgICAqKi9cblx0ICBCU09OX0RBVEFfT0JKRUNUOiAzLFxuXG5cdCAgLyoqXG5cdCAgICogQXJyYXkgQlNPTiBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0RBVEFfQVJSQVlcblx0ICAgKiovXG5cdCAgQlNPTl9EQVRBX0FSUkFZOiA0LFxuXG5cdCAgLyoqXG5cdCAgICogQmluYXJ5IEJTT04gVHlwZVxuXHQgICAqXG5cdCAgICogQGNsYXNzY29uc3RhbnQgQlNPTl9EQVRBX0JJTkFSWVxuXHQgICAqKi9cblx0ICBCU09OX0RBVEFfQklOQVJZOiA1LFxuXG5cdCAgLyoqXG5cdCAgICogQmluYXJ5IEJTT04gVHlwZVxuXHQgICAqXG5cdCAgICogQGNsYXNzY29uc3RhbnQgQlNPTl9EQVRBX1VOREVGSU5FRFxuXHQgICAqKi9cblx0ICBCU09OX0RBVEFfVU5ERUZJTkVEOiA2LFxuXG5cdCAgLyoqXG5cdCAgICogT2JqZWN0SWQgQlNPTiBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0RBVEFfT0lEXG5cdCAgICoqL1xuXHQgIEJTT05fREFUQV9PSUQ6IDcsXG5cblx0ICAvKipcblx0ICAgKiBCb29sZWFuIEJTT04gVHlwZVxuXHQgICAqXG5cdCAgICogQGNsYXNzY29uc3RhbnQgQlNPTl9EQVRBX0JPT0xFQU5cblx0ICAgKiovXG5cdCAgQlNPTl9EQVRBX0JPT0xFQU46IDgsXG5cblx0ICAvKipcblx0ICAgKiBEYXRlIEJTT04gVHlwZVxuXHQgICAqXG5cdCAgICogQGNsYXNzY29uc3RhbnQgQlNPTl9EQVRBX0RBVEVcblx0ICAgKiovXG5cdCAgQlNPTl9EQVRBX0RBVEU6IDksXG5cblx0ICAvKipcblx0ICAgKiBudWxsIEJTT04gVHlwZVxuXHQgICAqXG5cdCAgICogQGNsYXNzY29uc3RhbnQgQlNPTl9EQVRBX05VTExcblx0ICAgKiovXG5cdCAgQlNPTl9EQVRBX05VTEw6IDEwLFxuXG5cdCAgLyoqXG5cdCAgICogUmVnRXhwIEJTT04gVHlwZVxuXHQgICAqXG5cdCAgICogQGNsYXNzY29uc3RhbnQgQlNPTl9EQVRBX1JFR0VYUFxuXHQgICAqKi9cblx0ICBCU09OX0RBVEFfUkVHRVhQOiAxMSxcblxuXHQgIC8qKlxuXHQgICAqIENvZGUgQlNPTiBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0RBVEFfREJQT0lOVEVSXG5cdCAgICoqL1xuXHQgIEJTT05fREFUQV9EQlBPSU5URVI6IDEyLFxuXG5cdCAgLyoqXG5cdCAgICogQ29kZSBCU09OIFR5cGVcblx0ICAgKlxuXHQgICAqIEBjbGFzc2NvbnN0YW50IEJTT05fREFUQV9DT0RFXG5cdCAgICoqL1xuXHQgIEJTT05fREFUQV9DT0RFOiAxMyxcblxuXHQgIC8qKlxuXHQgICAqIFN5bWJvbCBCU09OIFR5cGVcblx0ICAgKlxuXHQgICAqIEBjbGFzc2NvbnN0YW50IEJTT05fREFUQV9TWU1CT0xcblx0ICAgKiovXG5cdCAgQlNPTl9EQVRBX1NZTUJPTDogMTQsXG5cblx0ICAvKipcblx0ICAgKiBDb2RlIHdpdGggU2NvcGUgQlNPTiBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0RBVEFfQ09ERV9XX1NDT1BFXG5cdCAgICoqL1xuXHQgIEJTT05fREFUQV9DT0RFX1dfU0NPUEU6IDE1LFxuXG5cdCAgLyoqXG5cdCAgICogMzIgYml0IEludGVnZXIgQlNPTiBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0RBVEFfSU5UXG5cdCAgICoqL1xuXHQgIEJTT05fREFUQV9JTlQ6IDE2LFxuXG5cdCAgLyoqXG5cdCAgICogVGltZXN0YW1wIEJTT04gVHlwZVxuXHQgICAqXG5cdCAgICogQGNsYXNzY29uc3RhbnQgQlNPTl9EQVRBX1RJTUVTVEFNUFxuXHQgICAqKi9cblx0ICBCU09OX0RBVEFfVElNRVNUQU1QOiAxNyxcblxuXHQgIC8qKlxuXHQgICAqIExvbmcgQlNPTiBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0RBVEFfTE9OR1xuXHQgICAqKi9cblx0ICBCU09OX0RBVEFfTE9ORzogMTgsXG5cblx0ICAvKipcblx0ICAgKiBMb25nIEJTT04gVHlwZVxuXHQgICAqXG5cdCAgICogQGNsYXNzY29uc3RhbnQgQlNPTl9EQVRBX0RFQ0lNQUwxMjhcblx0ICAgKiovXG5cdCAgQlNPTl9EQVRBX0RFQ0lNQUwxMjg6IDE5LFxuXG5cdCAgLyoqXG5cdCAgICogTWluS2V5IEJTT04gVHlwZVxuXHQgICAqXG5cdCAgICogQGNsYXNzY29uc3RhbnQgQlNPTl9EQVRBX01JTl9LRVlcblx0ICAgKiovXG5cdCAgQlNPTl9EQVRBX01JTl9LRVk6IDB4ZmYsXG5cblx0ICAvKipcblx0ICAgKiBNYXhLZXkgQlNPTiBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0RBVEFfTUFYX0tFWVxuXHQgICAqKi9cblx0ICBCU09OX0RBVEFfTUFYX0tFWTogMHg3ZixcblxuXHQgIC8qKlxuXHQgICAqIEJpbmFyeSBEZWZhdWx0IFR5cGVcblx0ICAgKlxuXHQgICAqIEBjbGFzc2NvbnN0YW50IEJTT05fQklOQVJZX1NVQlRZUEVfREVGQVVMVFxuXHQgICAqKi9cblx0ICBCU09OX0JJTkFSWV9TVUJUWVBFX0RFRkFVTFQ6IDAsXG5cblx0ICAvKipcblx0ICAgKiBCaW5hcnkgRnVuY3Rpb24gVHlwZVxuXHQgICAqXG5cdCAgICogQGNsYXNzY29uc3RhbnQgQlNPTl9CSU5BUllfU1VCVFlQRV9GVU5DVElPTlxuXHQgICAqKi9cblx0ICBCU09OX0JJTkFSWV9TVUJUWVBFX0ZVTkNUSU9OOiAxLFxuXG5cdCAgLyoqXG5cdCAgICogQmluYXJ5IEJ5dGUgQXJyYXkgVHlwZVxuXHQgICAqXG5cdCAgICogQGNsYXNzY29uc3RhbnQgQlNPTl9CSU5BUllfU1VCVFlQRV9CWVRFX0FSUkFZXG5cdCAgICoqL1xuXHQgIEJTT05fQklOQVJZX1NVQlRZUEVfQllURV9BUlJBWTogMixcblxuXHQgIC8qKlxuXHQgICAqIEJpbmFyeSBVVUlEIFR5cGVcblx0ICAgKlxuXHQgICAqIEBjbGFzc2NvbnN0YW50IEJTT05fQklOQVJZX1NVQlRZUEVfVVVJRFxuXHQgICAqKi9cblx0ICBCU09OX0JJTkFSWV9TVUJUWVBFX1VVSUQ6IDMsXG5cblx0ICAvKipcblx0ICAgKiBCaW5hcnkgTUQ1IFR5cGVcblx0ICAgKlxuXHQgICAqIEBjbGFzc2NvbnN0YW50IEJTT05fQklOQVJZX1NVQlRZUEVfTUQ1XG5cdCAgICoqL1xuXHQgIEJTT05fQklOQVJZX1NVQlRZUEVfTUQ1OiA0LFxuXG5cdCAgLyoqXG5cdCAgICogQmluYXJ5IFVzZXIgRGVmaW5lZCBUeXBlXG5cdCAgICpcblx0ICAgKiBAY2xhc3Njb25zdGFudCBCU09OX0JJTkFSWV9TVUJUWVBFX1VTRVJfREVGSU5FRFxuXHQgICAqKi9cblx0ICBCU09OX0JJTkFSWV9TVUJUWVBFX1VTRVJfREVGSU5FRDogMTI4XG5cdH07XG5cblx0ZnVuY3Rpb24gX3R5cGVvZiQyKG9iaikgeyBpZiAodHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09IFwic3ltYm9sXCIpIHsgX3R5cGVvZiQyID0gZnVuY3Rpb24gX3R5cGVvZihvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH07IH0gZWxzZSB7IF90eXBlb2YkMiA9IGZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqOyB9OyB9IHJldHVybiBfdHlwZW9mJDIob2JqKTsgfVxuXHQvLyBjb25zdCBNYXAgPSByZXF1aXJlKCcuL21hcCcpO1xuXG5cdC8qKlxuXHQgKiBAbmFtZXNwYWNlIEVKU09OXG5cdCAqL1xuXHQvLyBhbGwgdGhlIHR5cGVzIHdoZXJlIHdlIGRvbid0IG5lZWQgdG8gZG8gYW55IHNwZWNpYWwgcHJvY2Vzc2luZyBhbmQgY2FuIGp1c3QgcGFzcyB0aGUgRUpTT05cblx0Ly9zdHJhaWdodCB0byB0eXBlLmZyb21FeHRlbmRlZEpTT05cblxuXG5cdHZhciBrZXlzVG9Db2RlY3MgPSB7XG5cdCAgJG9pZDogb2JqZWN0aWQsXG5cdCAgJGJpbmFyeTogYmluYXJ5LFxuXHQgICRzeW1ib2w6IHN5bWJvbCxcblx0ICAkbnVtYmVySW50OiBpbnRfMzIsXG5cdCAgJG51bWJlckRlY2ltYWw6IGRlY2ltYWwxMjgsXG5cdCAgJG51bWJlckRvdWJsZTogZG91YmxlXzEsXG5cdCAgJG51bWJlckxvbmc6IGxvbmdfMSxcblx0ICAkbWluS2V5OiBtaW5fa2V5LFxuXHQgICRtYXhLZXk6IG1heF9rZXksXG5cdCAgJHJlZ3VsYXJFeHByZXNzaW9uOiByZWdleHAsXG5cdCAgJHRpbWVzdGFtcDogdGltZXN0YW1wXG5cdH07XG5cblx0ZnVuY3Rpb24gZGVzZXJpYWxpemVWYWx1ZShzZWxmLCBrZXksIHZhbHVlLCBvcHRpb25zKSB7XG5cdCAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcblx0ICAgIGlmIChvcHRpb25zLnJlbGF4ZWQpIHtcblx0ICAgICAgcmV0dXJuIHZhbHVlO1xuXHQgICAgfSAvLyBpZiBpdCdzIGFuIGludGVnZXIsIHNob3VsZCBpbnRlcnByZXQgYXMgc21hbGxlc3QgQlNPTiBpbnRlZ2VyXG5cdCAgICAvLyB0aGF0IGNhbiByZXByZXNlbnQgaXQgZXhhY3RseS4gKGlmIG91dCBvZiByYW5nZSwgaW50ZXJwcmV0IGFzIGRvdWJsZS4pXG5cblxuXHQgICAgaWYgKE1hdGguZmxvb3IodmFsdWUpID09PSB2YWx1ZSkge1xuXHQgICAgICBpZiAodmFsdWUgPj0gQlNPTl9JTlQzMl9NSU4gJiYgdmFsdWUgPD0gQlNPTl9JTlQzMl9NQVgpIHJldHVybiBuZXcgaW50XzMyKHZhbHVlKTtcblx0ICAgICAgaWYgKHZhbHVlID49IEJTT05fSU5UNjRfTUlOICYmIHZhbHVlIDw9IEJTT05fSU5UNjRfTUFYKSByZXR1cm4gbmV3IGxvbmdfMS5mcm9tTnVtYmVyKHZhbHVlKTtcblx0ICAgIH0gLy8gSWYgdGhlIG51bWJlciBpcyBhIG5vbi1pbnRlZ2VyIG9yIG91dCBvZiBpbnRlZ2VyIHJhbmdlLCBzaG91bGQgaW50ZXJwcmV0IGFzIEJTT04gRG91YmxlLlxuXG5cblx0ICAgIHJldHVybiBuZXcgZG91YmxlXzEodmFsdWUpO1xuXHQgIH0gLy8gZnJvbSBoZXJlIG9uIG91dCB3ZSdyZSBsb29raW5nIGZvciBic29uIHR5cGVzLCBzbyBiYWlsIGlmIGl0cyBub3QgYW4gb2JqZWN0XG5cblxuXHQgIGlmICh2YWx1ZSA9PSBudWxsIHx8IF90eXBlb2YkMih2YWx1ZSkgIT09ICdvYmplY3QnKSByZXR1cm4gdmFsdWU7IC8vIHVwZ3JhZGUgZGVwcmVjYXRlZCB1bmRlZmluZWQgdG8gbnVsbFxuXG5cdCAgaWYgKHZhbHVlLiR1bmRlZmluZWQpIHJldHVybiBudWxsO1xuXHQgIHZhciBrZXlzID0gT2JqZWN0LmtleXModmFsdWUpLmZpbHRlcihmdW5jdGlvbiAoaykge1xuXHQgICAgcmV0dXJuIGsuc3RhcnRzV2l0aCgnJCcpICYmIHZhbHVlW2tdICE9IG51bGw7XG5cdCAgfSk7XG5cblx0ICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcblx0ICAgIHZhciBjID0ga2V5c1RvQ29kZWNzW2tleXNbaV1dO1xuXHQgICAgaWYgKGMpIHJldHVybiBjLmZyb21FeHRlbmRlZEpTT04odmFsdWUsIG9wdGlvbnMpO1xuXHQgIH1cblxuXHQgIGlmICh2YWx1ZS4kZGF0ZSAhPSBudWxsKSB7XG5cdCAgICB2YXIgZCA9IHZhbHVlLiRkYXRlO1xuXHQgICAgdmFyIGRhdGUgPSBuZXcgRGF0ZSgpO1xuXHQgICAgaWYgKHR5cGVvZiBkID09PSAnc3RyaW5nJykgZGF0ZS5zZXRUaW1lKERhdGUucGFyc2UoZCkpO2Vsc2UgaWYgKGxvbmdfMS5pc0xvbmcoZCkpIGRhdGUuc2V0VGltZShkLnRvTnVtYmVyKCkpO2Vsc2UgaWYgKHR5cGVvZiBkID09PSAnbnVtYmVyJyAmJiBvcHRpb25zLnJlbGF4ZWQpIGRhdGUuc2V0VGltZShkKTtcblx0ICAgIHJldHVybiBkYXRlO1xuXHQgIH1cblxuXHQgIGlmICh2YWx1ZS4kY29kZSAhPSBudWxsKSB7XG5cdCAgICB2YXIgY29weSA9IE9iamVjdC5hc3NpZ24oe30sIHZhbHVlKTtcblxuXHQgICAgaWYgKHZhbHVlLiRzY29wZSkge1xuXHQgICAgICBjb3B5LiRzY29wZSA9IGRlc2VyaWFsaXplVmFsdWUoc2VsZiwgbnVsbCwgdmFsdWUuJHNjb3BlKTtcblx0ICAgIH1cblxuXHQgICAgcmV0dXJuIGNvZGUuZnJvbUV4dGVuZGVkSlNPTih2YWx1ZSk7XG5cdCAgfVxuXG5cdCAgaWYgKHZhbHVlLiRyZWYgIT0gbnVsbCB8fCB2YWx1ZS4kZGJQb2ludGVyICE9IG51bGwpIHtcblx0ICAgIHZhciB2ID0gdmFsdWUuJHJlZiA/IHZhbHVlIDogdmFsdWUuJGRiUG9pbnRlcjsgLy8gd2UgcnVuIGludG8gdGhpcyBpbiBhIFwiZGVnZW5lcmF0ZSBFSlNPTlwiIGNhc2UgKHdpdGggJGlkIGFuZCAkcmVmIG9yZGVyIGZsaXBwZWQpXG5cdCAgICAvLyBiZWNhdXNlIG9mIHRoZSBvcmRlciBKU09OLnBhcnNlIGdvZXMgdGhyb3VnaCB0aGUgZG9jdW1lbnRcblxuXHQgICAgaWYgKHYgaW5zdGFuY2VvZiBkYl9yZWYpIHJldHVybiB2O1xuXHQgICAgdmFyIGRvbGxhcktleXMgPSBPYmplY3Qua2V5cyh2KS5maWx0ZXIoZnVuY3Rpb24gKGspIHtcblx0ICAgICAgcmV0dXJuIGsuc3RhcnRzV2l0aCgnJCcpO1xuXHQgICAgfSk7XG5cdCAgICB2YXIgdmFsaWQgPSB0cnVlO1xuXHQgICAgZG9sbGFyS2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7XG5cdCAgICAgIGlmIChbJyRyZWYnLCAnJGlkJywgJyRkYiddLmluZGV4T2YoaykgPT09IC0xKSB2YWxpZCA9IGZhbHNlO1xuXHQgICAgfSk7IC8vIG9ubHkgbWFrZSBEQlJlZiBpZiAkIGtleXMgYXJlIGFsbCB2YWxpZFxuXG5cdCAgICBpZiAodmFsaWQpIHJldHVybiBkYl9yZWYuZnJvbUV4dGVuZGVkSlNPTih2KTtcblx0ICB9XG5cblx0ICByZXR1cm4gdmFsdWU7XG5cdH1cblx0LyoqXG5cdCAqIFBhcnNlIGFuIEV4dGVuZGVkIEpTT04gc3RyaW5nLCBjb25zdHJ1Y3RpbmcgdGhlIEphdmFTY3JpcHQgdmFsdWUgb3Igb2JqZWN0IGRlc2NyaWJlZCBieSB0aGF0XG5cdCAqIHN0cmluZy5cblx0ICpcblx0ICogQG1lbWJlcm9mIEVKU09OXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0XG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0aW9uc10gT3B0aW9uYWwgc2V0dGluZ3Ncblx0ICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5yZWxheGVkPXRydWVdIEF0dGVtcHQgdG8gcmV0dXJuIG5hdGl2ZSBKUyB0eXBlcyB3aGVyZSBwb3NzaWJsZSwgcmF0aGVyIHRoYW4gQlNPTiB0eXBlcyAoaWYgdHJ1ZSlcblx0ICogQHJldHVybiB7b2JqZWN0fVxuXHQgKlxuXHQgKiBAZXhhbXBsZVxuXHQgKiBjb25zdCB7IEVKU09OIH0gPSByZXF1aXJlKCdic29uJyk7XG5cdCAqIGNvbnN0IHRleHQgPSAneyBcImludDMyXCI6IHsgXCIkbnVtYmVySW50XCI6IFwiMTBcIiB9IH0nO1xuXHQgKlxuXHQgKiAvLyBwcmludHMgeyBpbnQzMjogeyBbU3RyaW5nOiAnMTAnXSBfYnNvbnR5cGU6ICdJbnQzMicsIHZhbHVlOiAnMTAnIH0gfVxuXHQgKiBjb25zb2xlLmxvZyhFSlNPTi5wYXJzZSh0ZXh0LCB7IHJlbGF4ZWQ6IGZhbHNlIH0pKTtcblx0ICpcblx0ICogLy8gcHJpbnRzIHsgaW50MzI6IDEwIH1cblx0ICogY29uc29sZS5sb2coRUpTT04ucGFyc2UodGV4dCkpO1xuXHQgKi9cblxuXG5cdGZ1bmN0aW9uIHBhcnNlKHRleHQsIG9wdGlvbnMpIHtcblx0ICB2YXIgX3RoaXMgPSB0aGlzO1xuXG5cdCAgb3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oe30sIHtcblx0ICAgIHJlbGF4ZWQ6IHRydWVcblx0ICB9LCBvcHRpb25zKTsgLy8gcmVsYXhlZCBpbXBsaWVzIG5vdCBzdHJpY3RcblxuXHQgIGlmICh0eXBlb2Ygb3B0aW9ucy5yZWxheGVkID09PSAnYm9vbGVhbicpIG9wdGlvbnMuc3RyaWN0ID0gIW9wdGlvbnMucmVsYXhlZDtcblx0ICBpZiAodHlwZW9mIG9wdGlvbnMuc3RyaWN0ID09PSAnYm9vbGVhbicpIG9wdGlvbnMucmVsYXhlZCA9ICFvcHRpb25zLnN0cmljdDtcblx0ICByZXR1cm4gSlNPTi5wYXJzZSh0ZXh0LCBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuXHQgICAgcmV0dXJuIGRlc2VyaWFsaXplVmFsdWUoX3RoaXMsIGtleSwgdmFsdWUsIG9wdGlvbnMpO1xuXHQgIH0pO1xuXHR9IC8vXG5cdC8vIFNlcmlhbGl6ZXJcblx0Ly9cblx0Ly8gTUFYIElOVDMyIGJvdW5kYXJpZXNcblxuXG5cdHZhciBCU09OX0lOVDMyX01BWCA9IDB4N2ZmZmZmZmYsXG5cdCAgICBCU09OX0lOVDMyX01JTiA9IC0weDgwMDAwMDAwLFxuXHQgICAgQlNPTl9JTlQ2NF9NQVggPSAweDdmZmZmZmZmZmZmZmZmZmYsXG5cdCAgICBCU09OX0lOVDY0X01JTiA9IC0weDgwMDAwMDAwMDAwMDAwMDA7XG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBhIEJTT04gZG9jdW1lbnQgdG8gYW4gRXh0ZW5kZWQgSlNPTiBzdHJpbmcsIG9wdGlvbmFsbHkgcmVwbGFjaW5nIHZhbHVlcyBpZiBhIHJlcGxhY2VyXG5cdCAqIGZ1bmN0aW9uIGlzIHNwZWNpZmllZCBvciBvcHRpb25hbGx5IGluY2x1ZGluZyBvbmx5IHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcyBpZiBhIHJlcGxhY2VyIGFycmF5XG5cdCAqIGlzIHNwZWNpZmllZC5cblx0ICpcblx0ICogQG1lbWJlcm9mIEVKU09OXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydCB0byBleHRlbmRlZCBKU09OXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb258YXJyYXl9IFtyZXBsYWNlcl0gQSBmdW5jdGlvbiB0aGF0IGFsdGVycyB0aGUgYmVoYXZpb3Igb2YgdGhlIHN0cmluZ2lmaWNhdGlvbiBwcm9jZXNzLCBvciBhbiBhcnJheSBvZiBTdHJpbmcgYW5kIE51bWJlciBvYmplY3RzIHRoYXQgc2VydmUgYXMgYSB3aGl0ZWxpc3QgZm9yIHNlbGVjdGluZy9maWx0ZXJpbmcgdGhlIHByb3BlcnRpZXMgb2YgdGhlIHZhbHVlIG9iamVjdCB0byBiZSBpbmNsdWRlZCBpbiB0aGUgSlNPTiBzdHJpbmcuIElmIHRoaXMgdmFsdWUgaXMgbnVsbCBvciBub3QgcHJvdmlkZWQsIGFsbCBwcm9wZXJ0aWVzIG9mIHRoZSBvYmplY3QgYXJlIGluY2x1ZGVkIGluIHRoZSByZXN1bHRpbmcgSlNPTiBzdHJpbmdcblx0ICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBbc3BhY2VdIEEgU3RyaW5nIG9yIE51bWJlciBvYmplY3QgdGhhdCdzIHVzZWQgdG8gaW5zZXJ0IHdoaXRlIHNwYWNlIGludG8gdGhlIG91dHB1dCBKU09OIHN0cmluZyBmb3IgcmVhZGFiaWxpdHkgcHVycG9zZXMuXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0aW9uc10gT3B0aW9uYWwgc2V0dGluZ3Ncblx0ICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5yZWxheGVkPXRydWVdIEVuYWJsZWQgRXh0ZW5kZWQgSlNPTidzIGByZWxheGVkYCBtb2RlXG5cdCAqIEByZXR1cm5zIHtzdHJpbmd9XG5cdCAqXG5cdCAqIEBleGFtcGxlXG5cdCAqIGNvbnN0IHsgRUpTT04gfSA9IHJlcXVpcmUoJ2Jzb24nKTtcblx0ICogY29uc3QgSW50MzIgPSByZXF1aXJlKCdtb25nb2RiJykuSW50MzI7XG5cdCAqIGNvbnN0IGRvYyA9IHsgaW50MzI6IG5ldyBJbnQzMigxMCkgfTtcblx0ICpcblx0ICogLy8gcHJpbnRzICd7XCJpbnQzMlwiOntcIiRudW1iZXJJbnRcIjpcIjEwXCJ9fSdcblx0ICogY29uc29sZS5sb2coRUpTT04uc3RyaW5naWZ5KGRvYywgeyByZWxheGVkOiBmYWxzZSB9KSk7XG5cdCAqXG5cdCAqIC8vIHByaW50cyAne1wiaW50MzJcIjoxMH0nXG5cdCAqIGNvbnNvbGUubG9nKEVKU09OLnN0cmluZ2lmeShkb2MpKTtcblx0ICovXG5cblx0ZnVuY3Rpb24gc3RyaW5naWZ5KHZhbHVlLCByZXBsYWNlciwgc3BhY2UsIG9wdGlvbnMpIHtcblx0ICBpZiAoc3BhY2UgIT0gbnVsbCAmJiBfdHlwZW9mJDIoc3BhY2UpID09PSAnb2JqZWN0Jykge1xuXHQgICAgb3B0aW9ucyA9IHNwYWNlO1xuXHQgICAgc3BhY2UgPSAwO1xuXHQgIH1cblxuXHQgIGlmIChyZXBsYWNlciAhPSBudWxsICYmIF90eXBlb2YkMihyZXBsYWNlcikgPT09ICdvYmplY3QnICYmICFBcnJheS5pc0FycmF5KHJlcGxhY2VyKSkge1xuXHQgICAgb3B0aW9ucyA9IHJlcGxhY2VyO1xuXHQgICAgcmVwbGFjZXIgPSBudWxsO1xuXHQgICAgc3BhY2UgPSAwO1xuXHQgIH1cblxuXHQgIG9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCB7XG5cdCAgICByZWxheGVkOiB0cnVlXG5cdCAgfSwgb3B0aW9ucyk7XG5cdCAgdmFyIGRvYyA9IEFycmF5LmlzQXJyYXkodmFsdWUpID8gc2VyaWFsaXplQXJyYXkodmFsdWUsIG9wdGlvbnMpIDogc2VyaWFsaXplRG9jdW1lbnQodmFsdWUsIG9wdGlvbnMpO1xuXHQgIHJldHVybiBKU09OLnN0cmluZ2lmeShkb2MsIHJlcGxhY2VyLCBzcGFjZSk7XG5cdH1cblx0LyoqXG5cdCAqIFNlcmlhbGl6ZXMgYW4gb2JqZWN0IHRvIGFuIEV4dGVuZGVkIEpTT04gc3RyaW5nLCBhbmQgcmVwYXJzZSBpdCBhcyBhIEphdmFTY3JpcHQgb2JqZWN0LlxuXHQgKlxuXHQgKiBAbWVtYmVyb2YgRUpTT05cblx0ICogQHBhcmFtIHtvYmplY3R9IGJzb24gVGhlIG9iamVjdCB0byBzZXJpYWxpemVcblx0ICogQHBhcmFtIHtvYmplY3R9IFtvcHRpb25zXSBPcHRpb25hbCBzZXR0aW5ncyBwYXNzZWQgdG8gdGhlIGBzdHJpbmdpZnlgIGZ1bmN0aW9uXG5cdCAqIEByZXR1cm4ge29iamVjdH1cblx0ICovXG5cblxuXHRmdW5jdGlvbiBzZXJpYWxpemUoYnNvbiwgb3B0aW9ucykge1xuXHQgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXHQgIHJldHVybiBKU09OLnBhcnNlKHN0cmluZ2lmeShic29uLCBvcHRpb25zKSk7XG5cdH1cblx0LyoqXG5cdCAqIERlc2VyaWFsaXplcyBhbiBFeHRlbmRlZCBKU09OIG9iamVjdCBpbnRvIGEgcGxhaW4gSmF2YVNjcmlwdCBvYmplY3Qgd2l0aCBuYXRpdmUvQlNPTiB0eXBlc1xuXHQgKlxuXHQgKiBAbWVtYmVyb2YgRUpTT05cblx0ICogQHBhcmFtIHtvYmplY3R9IGVqc29uIFRoZSBFeHRlbmRlZCBKU09OIG9iamVjdCB0byBkZXNlcmlhbGl6ZVxuXHQgKiBAcGFyYW0ge29iamVjdH0gW29wdGlvbnNdIE9wdGlvbmFsIHNldHRpbmdzIHBhc3NlZCB0byB0aGUgcGFyc2UgbWV0aG9kXG5cdCAqIEByZXR1cm4ge29iamVjdH1cblx0ICovXG5cblxuXHRmdW5jdGlvbiBkZXNlcmlhbGl6ZShlanNvbiwgb3B0aW9ucykge1xuXHQgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXHQgIHJldHVybiBwYXJzZShKU09OLnN0cmluZ2lmeShlanNvbiksIG9wdGlvbnMpO1xuXHR9XG5cblx0ZnVuY3Rpb24gc2VyaWFsaXplQXJyYXkoYXJyYXksIG9wdGlvbnMpIHtcblx0ICByZXR1cm4gYXJyYXkubWFwKGZ1bmN0aW9uICh2KSB7XG5cdCAgICByZXR1cm4gc2VyaWFsaXplVmFsdWUodiwgb3B0aW9ucyk7XG5cdCAgfSk7XG5cdH1cblxuXHRmdW5jdGlvbiBnZXRJU09TdHJpbmcoZGF0ZSkge1xuXHQgIHZhciBpc29TdHIgPSBkYXRlLnRvSVNPU3RyaW5nKCk7IC8vIHdlIHNob3VsZCBvbmx5IHNob3cgbWlsbGlzZWNvbmRzIGluIHRpbWVzdGFtcCBpZiB0aGV5J3JlIG5vbi16ZXJvXG5cblx0ICByZXR1cm4gZGF0ZS5nZXRVVENNaWxsaXNlY29uZHMoKSAhPT0gMCA/IGlzb1N0ciA6IGlzb1N0ci5zbGljZSgwLCAtNSkgKyAnWic7XG5cdH1cblxuXHRmdW5jdGlvbiBzZXJpYWxpemVWYWx1ZSh2YWx1ZSwgb3B0aW9ucykge1xuXHQgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkgcmV0dXJuIHNlcmlhbGl6ZUFycmF5KHZhbHVlLCBvcHRpb25zKTtcblx0ICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkgcmV0dXJuIG51bGw7XG5cblx0ICBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XG5cdCAgICB2YXIgZGF0ZU51bSA9IHZhbHVlLmdldFRpbWUoKSxcblx0ICAgICAgICAvLyBpcyBpdCBpbiB5ZWFyIHJhbmdlIDE5NzAtOTk5OT9cblx0ICAgIGluUmFuZ2UgPSBkYXRlTnVtID4gLTEgJiYgZGF0ZU51bSA8IDI1MzQwMjMxODgwMDAwMDtcblx0ICAgIHJldHVybiBvcHRpb25zLnJlbGF4ZWQgJiYgaW5SYW5nZSA/IHtcblx0ICAgICAgJGRhdGU6IGdldElTT1N0cmluZyh2YWx1ZSlcblx0ICAgIH0gOiB7XG5cdCAgICAgICRkYXRlOiB7XG5cdCAgICAgICAgJG51bWJlckxvbmc6IHZhbHVlLmdldFRpbWUoKS50b1N0cmluZygpXG5cdCAgICAgIH1cblx0ICAgIH07XG5cdCAgfVxuXG5cdCAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgJiYgIW9wdGlvbnMucmVsYXhlZCkge1xuXHQgICAgLy8gaXQncyBhbiBpbnRlZ2VyXG5cdCAgICBpZiAoTWF0aC5mbG9vcih2YWx1ZSkgPT09IHZhbHVlKSB7XG5cdCAgICAgIHZhciBpbnQzMlJhbmdlID0gdmFsdWUgPj0gQlNPTl9JTlQzMl9NSU4gJiYgdmFsdWUgPD0gQlNPTl9JTlQzMl9NQVgsXG5cdCAgICAgICAgICBpbnQ2NFJhbmdlID0gdmFsdWUgPj0gQlNPTl9JTlQ2NF9NSU4gJiYgdmFsdWUgPD0gQlNPTl9JTlQ2NF9NQVg7IC8vIGludGVycHJldCBhcyBiZWluZyBvZiB0aGUgc21hbGxlc3QgQlNPTiBpbnRlZ2VyIHR5cGUgdGhhdCBjYW4gcmVwcmVzZW50IHRoZSBudW1iZXIgZXhhY3RseVxuXG5cdCAgICAgIGlmIChpbnQzMlJhbmdlKSByZXR1cm4ge1xuXHQgICAgICAgICRudW1iZXJJbnQ6IHZhbHVlLnRvU3RyaW5nKClcblx0ICAgICAgfTtcblx0ICAgICAgaWYgKGludDY0UmFuZ2UpIHJldHVybiB7XG5cdCAgICAgICAgJG51bWJlckxvbmc6IHZhbHVlLnRvU3RyaW5nKClcblx0ICAgICAgfTtcblx0ICAgIH1cblxuXHQgICAgcmV0dXJuIHtcblx0ICAgICAgJG51bWJlckRvdWJsZTogdmFsdWUudG9TdHJpbmcoKVxuXHQgICAgfTtcblx0ICB9XG5cblx0ICBpZiAodmFsdWUgaW5zdGFuY2VvZiBSZWdFeHApIHtcblx0ICAgIHZhciBmbGFncyA9IHZhbHVlLmZsYWdzO1xuXG5cdCAgICBpZiAoZmxhZ3MgPT09IHVuZGVmaW5lZCkge1xuXHQgICAgICBmbGFncyA9IHZhbHVlLnRvU3RyaW5nKCkubWF0Y2goL1tnaW11eV0qJC8pWzBdO1xuXHQgICAgfVxuXG5cdCAgICB2YXIgcnggPSBuZXcgcmVnZXhwKHZhbHVlLnNvdXJjZSwgZmxhZ3MpO1xuXHQgICAgcmV0dXJuIHJ4LnRvRXh0ZW5kZWRKU09OKCk7XG5cdCAgfVxuXG5cdCAgaWYgKHZhbHVlICE9IG51bGwgJiYgX3R5cGVvZiQyKHZhbHVlKSA9PT0gJ29iamVjdCcpIHJldHVybiBzZXJpYWxpemVEb2N1bWVudCh2YWx1ZSwgb3B0aW9ucyk7XG5cdCAgcmV0dXJuIHZhbHVlO1xuXHR9XG5cblx0dmFyIEJTT05fVFlQRV9NQVBQSU5HUyA9IHtcblx0ICBCaW5hcnk6IGZ1bmN0aW9uIEJpbmFyeShvKSB7XG5cdCAgICByZXR1cm4gbmV3IGJpbmFyeShvLnZhbHVlKCksIG8uc3VidHlwZSk7XG5cdCAgfSxcblx0ICBDb2RlOiBmdW5jdGlvbiBDb2RlKG8pIHtcblx0ICAgIHJldHVybiBuZXcgY29kZShvLmNvZGUsIG8uc2NvcGUpO1xuXHQgIH0sXG5cdCAgREJSZWY6IGZ1bmN0aW9uIERCUmVmKG8pIHtcblx0ICAgIHJldHVybiBuZXcgZGJfcmVmKG8uY29sbGVjdGlvbiB8fCBvLm5hbWVzcGFjZSwgby5vaWQsIG8uZGIsIG8uZmllbGRzKTtcblx0ICB9LFxuXHQgIC8vIFwibmFtZXNwYWNlXCIgZm9yIDEueCBsaWJyYXJ5IGJhY2t3YXJkcyBjb21wYXRcblx0ICBEZWNpbWFsMTI4OiBmdW5jdGlvbiBEZWNpbWFsMTI4KG8pIHtcblx0ICAgIHJldHVybiBuZXcgZGVjaW1hbDEyOChvLmJ5dGVzKTtcblx0ICB9LFxuXHQgIERvdWJsZTogZnVuY3Rpb24gRG91YmxlKG8pIHtcblx0ICAgIHJldHVybiBuZXcgZG91YmxlXzEoby52YWx1ZSk7XG5cdCAgfSxcblx0ICBJbnQzMjogZnVuY3Rpb24gSW50MzIobykge1xuXHQgICAgcmV0dXJuIG5ldyBpbnRfMzIoby52YWx1ZSk7XG5cdCAgfSxcblx0ICBMb25nOiBmdW5jdGlvbiBMb25nKG8pIHtcblx0ICAgIHJldHVybiBsb25nXzEuZnJvbUJpdHMoIC8vIHVuZGVyc2NvcmUgdmFyaWFudHMgZm9yIDEueCBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxuXHQgICAgby5sb3cgIT0gbnVsbCA/IG8ubG93IDogby5sb3dfLCBvLmxvdyAhPSBudWxsID8gby5oaWdoIDogby5oaWdoXywgby5sb3cgIT0gbnVsbCA/IG8udW5zaWduZWQgOiBvLnVuc2lnbmVkXyk7XG5cdCAgfSxcblx0ICBNYXhLZXk6IGZ1bmN0aW9uIE1heEtleSgpIHtcblx0ICAgIHJldHVybiBuZXcgbWF4X2tleSgpO1xuXHQgIH0sXG5cdCAgTWluS2V5OiBmdW5jdGlvbiBNaW5LZXkoKSB7XG5cdCAgICByZXR1cm4gbmV3IG1pbl9rZXkoKTtcblx0ICB9LFxuXHQgIE9iamVjdElEOiBmdW5jdGlvbiBPYmplY3RJRChvKSB7XG5cdCAgICByZXR1cm4gbmV3IG9iamVjdGlkKG8pO1xuXHQgIH0sXG5cdCAgT2JqZWN0SWQ6IGZ1bmN0aW9uIE9iamVjdElkKG8pIHtcblx0ICAgIHJldHVybiBuZXcgb2JqZWN0aWQobyk7XG5cdCAgfSxcblx0ICAvLyBzdXBwb3J0IDQuMC4wLzQuMC4xIGJlZm9yZSBfYnNvbnR5cGUgd2FzIHJldmVydGVkIGJhY2sgdG8gT2JqZWN0SURcblx0ICBCU09OUmVnRXhwOiBmdW5jdGlvbiBCU09OUmVnRXhwKG8pIHtcblx0ICAgIHJldHVybiBuZXcgcmVnZXhwKG8ucGF0dGVybiwgby5vcHRpb25zKTtcblx0ICB9LFxuXHQgIFN5bWJvbDogZnVuY3Rpb24gU3ltYm9sKG8pIHtcblx0ICAgIHJldHVybiBuZXcgc3ltYm9sKG8udmFsdWUpO1xuXHQgIH0sXG5cdCAgVGltZXN0YW1wOiBmdW5jdGlvbiBUaW1lc3RhbXAobykge1xuXHQgICAgcmV0dXJuIHRpbWVzdGFtcC5mcm9tQml0cyhvLmxvdywgby5oaWdoKTtcblx0ICB9XG5cdH07XG5cblx0ZnVuY3Rpb24gc2VyaWFsaXplRG9jdW1lbnQoZG9jLCBvcHRpb25zKSB7XG5cdCAgaWYgKGRvYyA9PSBudWxsIHx8IF90eXBlb2YkMihkb2MpICE9PSAnb2JqZWN0JykgdGhyb3cgbmV3IEVycm9yKCdub3QgYW4gb2JqZWN0IGluc3RhbmNlJyk7XG5cdCAgdmFyIGJzb250eXBlID0gZG9jLl9ic29udHlwZTtcblxuXHQgIGlmICh0eXBlb2YgYnNvbnR5cGUgPT09ICd1bmRlZmluZWQnKSB7XG5cdCAgICAvLyBJdCdzIGEgcmVndWxhciBvYmplY3QuIFJlY3Vyc2l2ZWx5IHNlcmlhbGl6ZSBpdHMgcHJvcGVydHkgdmFsdWVzLlxuXHQgICAgdmFyIF9kb2MgPSB7fTtcblxuXHQgICAgZm9yICh2YXIgbmFtZSBpbiBkb2MpIHtcblx0ICAgICAgX2RvY1tuYW1lXSA9IHNlcmlhbGl6ZVZhbHVlKGRvY1tuYW1lXSwgb3B0aW9ucyk7XG5cdCAgICB9XG5cblx0ICAgIHJldHVybiBfZG9jO1xuXHQgIH0gZWxzZSBpZiAodHlwZW9mIGJzb250eXBlID09PSAnc3RyaW5nJykge1xuXHQgICAgLy8gdGhlIFwiZG9jdW1lbnRcIiBpcyByZWFsbHkganVzdCBhIEJTT04gdHlwZSBvYmplY3Rcblx0ICAgIHZhciBfZG9jMiA9IGRvYztcblxuXHQgICAgaWYgKHR5cGVvZiBfZG9jMi50b0V4dGVuZGVkSlNPTiAhPT0gJ2Z1bmN0aW9uJykge1xuXHQgICAgICAvLyBUaGVyZSdzIG5vIEVKU09OIHNlcmlhbGl6YXRpb24gZnVuY3Rpb24gb24gdGhlIG9iamVjdC4gSXQncyBwcm9iYWJseSBhblxuXHQgICAgICAvLyBvYmplY3QgY3JlYXRlZCBieSBhIHByZXZpb3VzIHZlcnNpb24gb2YgdGhpcyBsaWJyYXJ5IChvciBhbm90aGVyIGxpYnJhcnkpXG5cdCAgICAgIC8vIHRoYXQncyBkdWNrLXR5cGluZyBvYmplY3RzIHRvIGxvb2sgbGlrZSB0aGV5IHdlcmUgZ2VuZXJhdGVkIGJ5IHRoaXMgbGlicmFyeSkuXG5cdCAgICAgIC8vIENvcHkgdGhlIG9iamVjdCBpbnRvIHRoaXMgbGlicmFyeSdzIHZlcnNpb24gb2YgdGhhdCB0eXBlLlxuXHQgICAgICB2YXIgbWFwcGVyID0gQlNPTl9UWVBFX01BUFBJTkdTW2Jzb250eXBlXTtcblxuXHQgICAgICBpZiAoIW1hcHBlcikge1xuXHQgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1VucmVjb2duaXplZCBvciBpbnZhbGlkIF9ic29udHlwZTogJyArIGJzb250eXBlKTtcblx0ICAgICAgfVxuXG5cdCAgICAgIF9kb2MyID0gbWFwcGVyKF9kb2MyKTtcblx0ICAgIH0gLy8gVHdvIEJTT04gdHlwZXMgbWF5IGhhdmUgbmVzdGVkIG9iamVjdHMgdGhhdCBtYXkgbmVlZCB0byBiZSBzZXJpYWxpemVkIHRvb1xuXG5cblx0ICAgIGlmIChic29udHlwZSA9PT0gJ0NvZGUnICYmIF9kb2MyLnNjb3BlKSB7XG5cdCAgICAgIF9kb2MyID0gbmV3IGNvZGUoX2RvYzIuY29kZSwgc2VyaWFsaXplVmFsdWUoX2RvYzIuc2NvcGUsIG9wdGlvbnMpKTtcblx0ICAgIH0gZWxzZSBpZiAoYnNvbnR5cGUgPT09ICdEQlJlZicgJiYgX2RvYzIub2lkKSB7XG5cdCAgICAgIF9kb2MyID0gbmV3IGRiX3JlZihfZG9jMi5jb2xsZWN0aW9uLCBzZXJpYWxpemVWYWx1ZShfZG9jMi5vaWQsIG9wdGlvbnMpLCBfZG9jMi5kYiwgX2RvYzIuZmllbGRzKTtcblx0ICAgIH1cblxuXHQgICAgcmV0dXJuIF9kb2MyLnRvRXh0ZW5kZWRKU09OKG9wdGlvbnMpO1xuXHQgIH0gZWxzZSB7XG5cdCAgICB0aHJvdyBuZXcgRXJyb3IoJ19ic29udHlwZSBtdXN0IGJlIGEgc3RyaW5nLCBidXQgd2FzOiAnICsgX3R5cGVvZiQyKGJzb250eXBlKSk7XG5cdCAgfVxuXHR9XG5cblx0dmFyIGV4dGVuZGVkX2pzb24gPSB7XG5cdCAgcGFyc2U6IHBhcnNlLFxuXHQgIGRlc2VyaWFsaXplOiBkZXNlcmlhbGl6ZSxcblx0ICBzZXJpYWxpemU6IHNlcmlhbGl6ZSxcblx0ICBzdHJpbmdpZnk6IHN0cmluZ2lmeVxuXHR9O1xuXG5cdHZhciBGSVJTVF9CSVQgPSAweDgwO1xuXHR2YXIgRklSU1RfVFdPX0JJVFMgPSAweGMwO1xuXHR2YXIgRklSU1RfVEhSRUVfQklUUyA9IDB4ZTA7XG5cdHZhciBGSVJTVF9GT1VSX0JJVFMgPSAweGYwO1xuXHR2YXIgRklSU1RfRklWRV9CSVRTID0gMHhmODtcblx0dmFyIFRXT19CSVRfQ0hBUiA9IDB4YzA7XG5cdHZhciBUSFJFRV9CSVRfQ0hBUiA9IDB4ZTA7XG5cdHZhciBGT1VSX0JJVF9DSEFSID0gMHhmMDtcblx0dmFyIENPTlRJTlVJTkdfQ0hBUiA9IDB4ODA7XG5cdC8qKlxuXHQgKiBEZXRlcm1pbmVzIGlmIHRoZSBwYXNzZWQgaW4gYnl0ZXMgYXJlIHZhbGlkIHV0Zjhcblx0ICogQHBhcmFtIHtCdWZmZXJ8VWludDhBcnJheX0gYnl0ZXMgQW4gYXJyYXkgb2YgOC1iaXQgYnl0ZXMuIE11c3QgYmUgaW5kZXhhYmxlIGFuZCBoYXZlIGxlbmd0aCBwcm9wZXJ0eVxuXHQgKiBAcGFyYW0ge051bWJlcn0gc3RhcnQgVGhlIGluZGV4IHRvIHN0YXJ0IHZhbGlkYXRpbmdcblx0ICogQHBhcmFtIHtOdW1iZXJ9IGVuZCBUaGUgaW5kZXggdG8gZW5kIHZhbGlkYXRpbmdcblx0ICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsaWQgdXRmOFxuXHQgKi9cblxuXHRmdW5jdGlvbiB2YWxpZGF0ZVV0ZjgoYnl0ZXMsIHN0YXJ0LCBlbmQpIHtcblx0ICB2YXIgY29udGludWF0aW9uID0gMDtcblxuXHQgIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSArPSAxKSB7XG5cdCAgICB2YXIgYnl0ZSA9IGJ5dGVzW2ldO1xuXG5cdCAgICBpZiAoY29udGludWF0aW9uKSB7XG5cdCAgICAgIGlmICgoYnl0ZSAmIEZJUlNUX1RXT19CSVRTKSAhPT0gQ09OVElOVUlOR19DSEFSKSB7XG5cdCAgICAgICAgcmV0dXJuIGZhbHNlO1xuXHQgICAgICB9XG5cblx0ICAgICAgY29udGludWF0aW9uIC09IDE7XG5cdCAgICB9IGVsc2UgaWYgKGJ5dGUgJiBGSVJTVF9CSVQpIHtcblx0ICAgICAgaWYgKChieXRlICYgRklSU1RfVEhSRUVfQklUUykgPT09IFRXT19CSVRfQ0hBUikge1xuXHQgICAgICAgIGNvbnRpbnVhdGlvbiA9IDE7XG5cdCAgICAgIH0gZWxzZSBpZiAoKGJ5dGUgJiBGSVJTVF9GT1VSX0JJVFMpID09PSBUSFJFRV9CSVRfQ0hBUikge1xuXHQgICAgICAgIGNvbnRpbnVhdGlvbiA9IDI7XG5cdCAgICAgIH0gZWxzZSBpZiAoKGJ5dGUgJiBGSVJTVF9GSVZFX0JJVFMpID09PSBGT1VSX0JJVF9DSEFSKSB7XG5cdCAgICAgICAgY29udGludWF0aW9uID0gMztcblx0ICAgICAgfSBlbHNlIHtcblx0ICAgICAgICByZXR1cm4gZmFsc2U7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9XG5cblx0ICByZXR1cm4gIWNvbnRpbnVhdGlvbjtcblx0fVxuXG5cdHZhciB2YWxpZGF0ZVV0ZjhfMSA9IHZhbGlkYXRlVXRmODtcblx0dmFyIHZhbGlkYXRlX3V0ZjggPSB7XG5cdCAgdmFsaWRhdGVVdGY4OiB2YWxpZGF0ZVV0ZjhfMVxuXHR9O1xuXG5cdHZhciBCdWZmZXIkNCA9IGJ1ZmZlci5CdWZmZXI7XG5cdHZhciB2YWxpZGF0ZVV0ZjgkMSA9IHZhbGlkYXRlX3V0ZjgudmFsaWRhdGVVdGY4OyAvLyBJbnRlcm5hbCBsb25nIHZlcnNpb25zXG5cblx0dmFyIEpTX0lOVF9NQVhfTE9ORyA9IGxvbmdfMS5mcm9tTnVtYmVyKGNvbnN0YW50cy5KU19JTlRfTUFYKTtcblx0dmFyIEpTX0lOVF9NSU5fTE9ORyA9IGxvbmdfMS5mcm9tTnVtYmVyKGNvbnN0YW50cy5KU19JTlRfTUlOKTtcblx0dmFyIGZ1bmN0aW9uQ2FjaGUgPSB7fTtcblxuXHRmdW5jdGlvbiBkZXNlcmlhbGl6ZSQxKGJ1ZmZlciQkMSwgb3B0aW9ucywgaXNBcnJheSkge1xuXHQgIG9wdGlvbnMgPSBvcHRpb25zID09IG51bGwgPyB7fSA6IG9wdGlvbnM7XG5cdCAgdmFyIGluZGV4ID0gb3B0aW9ucyAmJiBvcHRpb25zLmluZGV4ID8gb3B0aW9ucy5pbmRleCA6IDA7IC8vIFJlYWQgdGhlIGRvY3VtZW50IHNpemVcblxuXHQgIHZhciBzaXplID0gYnVmZmVyJCQxW2luZGV4XSB8IGJ1ZmZlciQkMVtpbmRleCArIDFdIDw8IDggfCBidWZmZXIkJDFbaW5kZXggKyAyXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCArIDNdIDw8IDI0O1xuXG5cdCAgaWYgKHNpemUgPCA1KSB7XG5cdCAgICB0aHJvdyBuZXcgRXJyb3IoXCJic29uIHNpemUgbXVzdCBiZSA+PSA1LCBpcyBcIi5jb25jYXQoc2l6ZSkpO1xuXHQgIH1cblxuXHQgIGlmIChvcHRpb25zLmFsbG93T2JqZWN0U21hbGxlclRoYW5CdWZmZXJTaXplICYmIGJ1ZmZlciQkMS5sZW5ndGggPCBzaXplKSB7XG5cdCAgICB0aHJvdyBuZXcgRXJyb3IoXCJidWZmZXIgbGVuZ3RoIFwiLmNvbmNhdChidWZmZXIkJDEubGVuZ3RoLCBcIiBtdXN0IGJlID49IGJzb24gc2l6ZSBcIikuY29uY2F0KHNpemUpKTtcblx0ICB9XG5cblx0ICBpZiAoIW9wdGlvbnMuYWxsb3dPYmplY3RTbWFsbGVyVGhhbkJ1ZmZlclNpemUgJiYgYnVmZmVyJCQxLmxlbmd0aCAhPT0gc2l6ZSkge1xuXHQgICAgdGhyb3cgbmV3IEVycm9yKFwiYnVmZmVyIGxlbmd0aCBcIi5jb25jYXQoYnVmZmVyJCQxLmxlbmd0aCwgXCIgbXVzdCA9PT0gYnNvbiBzaXplIFwiKS5jb25jYXQoc2l6ZSkpO1xuXHQgIH1cblxuXHQgIGlmIChzaXplICsgaW5kZXggPiBidWZmZXIkJDEubGVuZ3RoKSB7XG5cdCAgICB0aHJvdyBuZXcgRXJyb3IoXCIoYnNvbiBzaXplIFwiLmNvbmNhdChzaXplLCBcIiArIG9wdGlvbnMuaW5kZXggXCIpLmNvbmNhdChpbmRleCwgXCIgbXVzdCBiZSA8PSBidWZmZXIgbGVuZ3RoIFwiKS5jb25jYXQoQnVmZmVyJDQuYnl0ZUxlbmd0aChidWZmZXIkJDEpLCBcIilcIikpO1xuXHQgIH0gLy8gSWxsZWdhbCBlbmQgdmFsdWVcblxuXG5cdCAgaWYgKGJ1ZmZlciQkMVtpbmRleCArIHNpemUgLSAxXSAhPT0gMCkge1xuXHQgICAgdGhyb3cgbmV3IEVycm9yKFwiT25lIG9iamVjdCwgc2l6ZWQgY29ycmVjdGx5LCB3aXRoIGEgc3BvdCBmb3IgYW4gRU9PLCBidXQgdGhlIEVPTyBpc24ndCAweDAwXCIpO1xuXHQgIH0gLy8gU3RhcnQgZGVzZXJpYWxpenRpb25cblxuXG5cdCAgcmV0dXJuIGRlc2VyaWFsaXplT2JqZWN0KGJ1ZmZlciQkMSwgaW5kZXgsIG9wdGlvbnMsIGlzQXJyYXkpO1xuXHR9XG5cblx0ZnVuY3Rpb24gZGVzZXJpYWxpemVPYmplY3QoYnVmZmVyJCQxLCBpbmRleCwgb3B0aW9ucywgaXNBcnJheSkge1xuXHQgIHZhciBldmFsRnVuY3Rpb25zID0gb3B0aW9uc1snZXZhbEZ1bmN0aW9ucyddID09IG51bGwgPyBmYWxzZSA6IG9wdGlvbnNbJ2V2YWxGdW5jdGlvbnMnXTtcblx0ICB2YXIgY2FjaGVGdW5jdGlvbnMgPSBvcHRpb25zWydjYWNoZUZ1bmN0aW9ucyddID09IG51bGwgPyBmYWxzZSA6IG9wdGlvbnNbJ2NhY2hlRnVuY3Rpb25zJ107XG5cdCAgdmFyIGNhY2hlRnVuY3Rpb25zQ3JjMzIgPSBvcHRpb25zWydjYWNoZUZ1bmN0aW9uc0NyYzMyJ10gPT0gbnVsbCA/IGZhbHNlIDogb3B0aW9uc1snY2FjaGVGdW5jdGlvbnNDcmMzMiddO1xuXHQgIGlmICghY2FjaGVGdW5jdGlvbnNDcmMzMikgdmFyIGNyYzMyID0gbnVsbDtcblx0ICB2YXIgZmllbGRzQXNSYXcgPSBvcHRpb25zWydmaWVsZHNBc1JhdyddID09IG51bGwgPyBudWxsIDogb3B0aW9uc1snZmllbGRzQXNSYXcnXTsgLy8gUmV0dXJuIHJhdyBic29uIGJ1ZmZlciBpbnN0ZWFkIG9mIHBhcnNpbmcgaXRcblxuXHQgIHZhciByYXcgPSBvcHRpb25zWydyYXcnXSA9PSBudWxsID8gZmFsc2UgOiBvcHRpb25zWydyYXcnXTsgLy8gUmV0dXJuIEJTT05SZWdFeHAgb2JqZWN0cyBpbnN0ZWFkIG9mIG5hdGl2ZSByZWd1bGFyIGV4cHJlc3Npb25zXG5cblx0ICB2YXIgYnNvblJlZ0V4cCA9IHR5cGVvZiBvcHRpb25zWydic29uUmVnRXhwJ10gPT09ICdib29sZWFuJyA/IG9wdGlvbnNbJ2Jzb25SZWdFeHAnXSA6IGZhbHNlOyAvLyBDb250cm9scyB0aGUgcHJvbW90aW9uIG9mIHZhbHVlcyB2cyB3cmFwcGVyIGNsYXNzZXNcblxuXHQgIHZhciBwcm9tb3RlQnVmZmVycyA9IG9wdGlvbnNbJ3Byb21vdGVCdWZmZXJzJ10gPT0gbnVsbCA/IGZhbHNlIDogb3B0aW9uc1sncHJvbW90ZUJ1ZmZlcnMnXTtcblx0ICB2YXIgcHJvbW90ZUxvbmdzID0gb3B0aW9uc1sncHJvbW90ZUxvbmdzJ10gPT0gbnVsbCA/IHRydWUgOiBvcHRpb25zWydwcm9tb3RlTG9uZ3MnXTtcblx0ICB2YXIgcHJvbW90ZVZhbHVlcyA9IG9wdGlvbnNbJ3Byb21vdGVWYWx1ZXMnXSA9PSBudWxsID8gdHJ1ZSA6IG9wdGlvbnNbJ3Byb21vdGVWYWx1ZXMnXTsgLy8gU2V0IHRoZSBzdGFydCBpbmRleFxuXG5cdCAgdmFyIHN0YXJ0SW5kZXggPSBpbmRleDsgLy8gVmFsaWRhdGUgdGhhdCB3ZSBoYXZlIGF0IGxlYXN0IDQgYnl0ZXMgb2YgYnVmZmVyXG5cblx0ICBpZiAoYnVmZmVyJCQxLmxlbmd0aCA8IDUpIHRocm93IG5ldyBFcnJvcignY29ycnVwdCBic29uIG1lc3NhZ2UgPCA1IGJ5dGVzIGxvbmcnKTsgLy8gUmVhZCB0aGUgZG9jdW1lbnQgc2l6ZVxuXG5cdCAgdmFyIHNpemUgPSBidWZmZXIkJDFbaW5kZXgrK10gfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAyNDsgLy8gRW5zdXJlIGJ1ZmZlciBpcyB2YWxpZCBzaXplXG5cblx0ICBpZiAoc2l6ZSA8IDUgfHwgc2l6ZSA+IGJ1ZmZlciQkMS5sZW5ndGgpIHRocm93IG5ldyBFcnJvcignY29ycnVwdCBic29uIG1lc3NhZ2UnKTsgLy8gQ3JlYXRlIGhvbGRpbmcgb2JqZWN0XG5cblx0ICB2YXIgb2JqZWN0ID0gaXNBcnJheSA/IFtdIDoge307IC8vIFVzZWQgZm9yIGFycmF5cyB0byBza2lwIGhhdmluZyB0byBwZXJmb3JtIHV0ZjggZGVjb2RpbmdcblxuXHQgIHZhciBhcnJheUluZGV4ID0gMDtcblx0ICB2YXIgZG9uZSA9IGZhbHNlOyAvLyBXaGlsZSB3ZSBoYXZlIG1vcmUgbGVmdCBkYXRhIGxlZnQga2VlcCBwYXJzaW5nXG5cblx0ICB3aGlsZSAoIWRvbmUpIHtcblx0ICAgIC8vIFJlYWQgdGhlIHR5cGVcblx0ICAgIHZhciBlbGVtZW50VHlwZSA9IGJ1ZmZlciQkMVtpbmRleCsrXTsgLy8gSWYgd2UgZ2V0IGEgemVybyBpdCdzIHRoZSBsYXN0IGJ5dGUsIGV4aXRcblxuXHQgICAgaWYgKGVsZW1lbnRUeXBlID09PSAwKSBicmVhazsgLy8gR2V0IHRoZSBzdGFydCBzZWFyY2ggaW5kZXhcblxuXHQgICAgdmFyIGkgPSBpbmRleDsgLy8gTG9jYXRlIHRoZSBlbmQgb2YgdGhlIGMgc3RyaW5nXG5cblx0ICAgIHdoaWxlIChidWZmZXIkJDFbaV0gIT09IDB4MDAgJiYgaSA8IGJ1ZmZlciQkMS5sZW5ndGgpIHtcblx0ICAgICAgaSsrO1xuXHQgICAgfSAvLyBJZiBhcmUgYXQgdGhlIGVuZCBvZiB0aGUgYnVmZmVyIHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIHRoZSBkb2N1bWVudFxuXG5cblx0ICAgIGlmIChpID49IEJ1ZmZlciQ0LmJ5dGVMZW5ndGgoYnVmZmVyJCQxKSkgdGhyb3cgbmV3IEVycm9yKCdCYWQgQlNPTiBEb2N1bWVudDogaWxsZWdhbCBDU3RyaW5nJyk7XG5cdCAgICB2YXIgbmFtZSA9IGlzQXJyYXkgPyBhcnJheUluZGV4KysgOiBidWZmZXIkJDEudG9TdHJpbmcoJ3V0ZjgnLCBpbmRleCwgaSk7XG5cdCAgICBpbmRleCA9IGkgKyAxO1xuXG5cdCAgICBpZiAoZWxlbWVudFR5cGUgPT09IGNvbnN0YW50cy5CU09OX0RBVEFfU1RSSU5HKSB7XG5cdCAgICAgIHZhciBzdHJpbmdTaXplID0gYnVmZmVyJCQxW2luZGV4KytdIHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDggfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMTYgfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMjQ7XG5cdCAgICAgIGlmIChzdHJpbmdTaXplIDw9IDAgfHwgc3RyaW5nU2l6ZSA+IGJ1ZmZlciQkMS5sZW5ndGggLSBpbmRleCB8fCBidWZmZXIkJDFbaW5kZXggKyBzdHJpbmdTaXplIC0gMV0gIT09IDApIHRocm93IG5ldyBFcnJvcignYmFkIHN0cmluZyBsZW5ndGggaW4gYnNvbicpO1xuXG5cdCAgICAgIGlmICghdmFsaWRhdGVVdGY4JDEoYnVmZmVyJCQxLCBpbmRleCwgaW5kZXggKyBzdHJpbmdTaXplIC0gMSkpIHtcblx0ICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgVVRGLTggc3RyaW5nIGluIEJTT04gZG9jdW1lbnQnKTtcblx0ICAgICAgfVxuXG5cdCAgICAgIHZhciBzID0gYnVmZmVyJCQxLnRvU3RyaW5nKCd1dGY4JywgaW5kZXgsIGluZGV4ICsgc3RyaW5nU2l6ZSAtIDEpO1xuXHQgICAgICBvYmplY3RbbmFtZV0gPSBzO1xuXHQgICAgICBpbmRleCA9IGluZGV4ICsgc3RyaW5nU2l6ZTtcblx0ICAgIH0gZWxzZSBpZiAoZWxlbWVudFR5cGUgPT09IGNvbnN0YW50cy5CU09OX0RBVEFfT0lEKSB7XG5cdCAgICAgIHZhciBvaWQgPSBCdWZmZXIkNC5hbGxvYygxMik7XG5cdCAgICAgIGJ1ZmZlciQkMS5jb3B5KG9pZCwgMCwgaW5kZXgsIGluZGV4ICsgMTIpO1xuXHQgICAgICBvYmplY3RbbmFtZV0gPSBuZXcgb2JqZWN0aWQob2lkKTtcblx0ICAgICAgaW5kZXggPSBpbmRleCArIDEyO1xuXHQgICAgfSBlbHNlIGlmIChlbGVtZW50VHlwZSA9PT0gY29uc3RhbnRzLkJTT05fREFUQV9JTlQgJiYgcHJvbW90ZVZhbHVlcyA9PT0gZmFsc2UpIHtcblx0ICAgICAgb2JqZWN0W25hbWVdID0gbmV3IGludF8zMihidWZmZXIkJDFbaW5kZXgrK10gfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAyNCk7XG5cdCAgICB9IGVsc2UgaWYgKGVsZW1lbnRUeXBlID09PSBjb25zdGFudHMuQlNPTl9EQVRBX0lOVCkge1xuXHQgICAgICBvYmplY3RbbmFtZV0gPSBidWZmZXIkJDFbaW5kZXgrK10gfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAyNDtcblx0ICAgIH0gZWxzZSBpZiAoZWxlbWVudFR5cGUgPT09IGNvbnN0YW50cy5CU09OX0RBVEFfTlVNQkVSICYmIHByb21vdGVWYWx1ZXMgPT09IGZhbHNlKSB7XG5cdCAgICAgIG9iamVjdFtuYW1lXSA9IG5ldyBkb3VibGVfMShidWZmZXIkJDEucmVhZERvdWJsZUxFKGluZGV4KSk7XG5cdCAgICAgIGluZGV4ID0gaW5kZXggKyA4O1xuXHQgICAgfSBlbHNlIGlmIChlbGVtZW50VHlwZSA9PT0gY29uc3RhbnRzLkJTT05fREFUQV9OVU1CRVIpIHtcblx0ICAgICAgb2JqZWN0W25hbWVdID0gYnVmZmVyJCQxLnJlYWREb3VibGVMRShpbmRleCk7XG5cdCAgICAgIGluZGV4ID0gaW5kZXggKyA4O1xuXHQgICAgfSBlbHNlIGlmIChlbGVtZW50VHlwZSA9PT0gY29uc3RhbnRzLkJTT05fREFUQV9EQVRFKSB7XG5cdCAgICAgIHZhciBsb3dCaXRzID0gYnVmZmVyJCQxW2luZGV4KytdIHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDggfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMTYgfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMjQ7XG5cdCAgICAgIHZhciBoaWdoQml0cyA9IGJ1ZmZlciQkMVtpbmRleCsrXSB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCA4IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDE2IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDI0O1xuXHQgICAgICBvYmplY3RbbmFtZV0gPSBuZXcgRGF0ZShuZXcgbG9uZ18xKGxvd0JpdHMsIGhpZ2hCaXRzKS50b051bWJlcigpKTtcblx0ICAgIH0gZWxzZSBpZiAoZWxlbWVudFR5cGUgPT09IGNvbnN0YW50cy5CU09OX0RBVEFfQk9PTEVBTikge1xuXHQgICAgICBpZiAoYnVmZmVyJCQxW2luZGV4XSAhPT0gMCAmJiBidWZmZXIkJDFbaW5kZXhdICE9PSAxKSB0aHJvdyBuZXcgRXJyb3IoJ2lsbGVnYWwgYm9vbGVhbiB0eXBlIHZhbHVlJyk7XG5cdCAgICAgIG9iamVjdFtuYW1lXSA9IGJ1ZmZlciQkMVtpbmRleCsrXSA9PT0gMTtcblx0ICAgIH0gZWxzZSBpZiAoZWxlbWVudFR5cGUgPT09IGNvbnN0YW50cy5CU09OX0RBVEFfT0JKRUNUKSB7XG5cdCAgICAgIHZhciBfaW5kZXggPSBpbmRleDtcblx0ICAgICAgdmFyIG9iamVjdFNpemUgPSBidWZmZXIkJDFbaW5kZXhdIHwgYnVmZmVyJCQxW2luZGV4ICsgMV0gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCArIDJdIDw8IDE2IHwgYnVmZmVyJCQxW2luZGV4ICsgM10gPDwgMjQ7XG5cdCAgICAgIGlmIChvYmplY3RTaXplIDw9IDAgfHwgb2JqZWN0U2l6ZSA+IGJ1ZmZlciQkMS5sZW5ndGggLSBpbmRleCkgdGhyb3cgbmV3IEVycm9yKCdiYWQgZW1iZWRkZWQgZG9jdW1lbnQgbGVuZ3RoIGluIGJzb24nKTsgLy8gV2UgaGF2ZSBhIHJhdyB2YWx1ZVxuXG5cdCAgICAgIGlmIChyYXcpIHtcblx0ICAgICAgICBvYmplY3RbbmFtZV0gPSBidWZmZXIkJDEuc2xpY2UoaW5kZXgsIGluZGV4ICsgb2JqZWN0U2l6ZSk7XG5cdCAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgb2JqZWN0W25hbWVdID0gZGVzZXJpYWxpemVPYmplY3QoYnVmZmVyJCQxLCBfaW5kZXgsIG9wdGlvbnMsIGZhbHNlKTtcblx0ICAgICAgfVxuXG5cdCAgICAgIGluZGV4ID0gaW5kZXggKyBvYmplY3RTaXplO1xuXHQgICAgfSBlbHNlIGlmIChlbGVtZW50VHlwZSA9PT0gY29uc3RhbnRzLkJTT05fREFUQV9BUlJBWSkge1xuXHQgICAgICB2YXIgX2luZGV4MiA9IGluZGV4O1xuXG5cdCAgICAgIHZhciBfb2JqZWN0U2l6ZSA9IGJ1ZmZlciQkMVtpbmRleF0gfCBidWZmZXIkJDFbaW5kZXggKyAxXSA8PCA4IHwgYnVmZmVyJCQxW2luZGV4ICsgMl0gPDwgMTYgfCBidWZmZXIkJDFbaW5kZXggKyAzXSA8PCAyNDtcblxuXHQgICAgICB2YXIgYXJyYXlPcHRpb25zID0gb3B0aW9uczsgLy8gU3RvcCBpbmRleFxuXG5cdCAgICAgIHZhciBzdG9wSW5kZXggPSBpbmRleCArIF9vYmplY3RTaXplOyAvLyBBbGwgZWxlbWVudHMgb2YgYXJyYXkgdG8gYmUgcmV0dXJuZWQgYXMgcmF3IGJzb25cblxuXHQgICAgICBpZiAoZmllbGRzQXNSYXcgJiYgZmllbGRzQXNSYXdbbmFtZV0pIHtcblx0ICAgICAgICBhcnJheU9wdGlvbnMgPSB7fTtcblxuXHQgICAgICAgIGZvciAodmFyIG4gaW4gb3B0aW9ucykge1xuXHQgICAgICAgICAgYXJyYXlPcHRpb25zW25dID0gb3B0aW9uc1tuXTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBhcnJheU9wdGlvbnNbJ3JhdyddID0gdHJ1ZTtcblx0ICAgICAgfVxuXG5cdCAgICAgIG9iamVjdFtuYW1lXSA9IGRlc2VyaWFsaXplT2JqZWN0KGJ1ZmZlciQkMSwgX2luZGV4MiwgYXJyYXlPcHRpb25zLCB0cnVlKTtcblx0ICAgICAgaW5kZXggPSBpbmRleCArIF9vYmplY3RTaXplO1xuXHQgICAgICBpZiAoYnVmZmVyJCQxW2luZGV4IC0gMV0gIT09IDApIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBhcnJheSB0ZXJtaW5hdG9yIGJ5dGUnKTtcblx0ICAgICAgaWYgKGluZGV4ICE9PSBzdG9wSW5kZXgpIHRocm93IG5ldyBFcnJvcignY29ycnVwdGVkIGFycmF5IGJzb24nKTtcblx0ICAgIH0gZWxzZSBpZiAoZWxlbWVudFR5cGUgPT09IGNvbnN0YW50cy5CU09OX0RBVEFfVU5ERUZJTkVEKSB7XG5cdCAgICAgIG9iamVjdFtuYW1lXSA9IHVuZGVmaW5lZDtcblx0ICAgIH0gZWxzZSBpZiAoZWxlbWVudFR5cGUgPT09IGNvbnN0YW50cy5CU09OX0RBVEFfTlVMTCkge1xuXHQgICAgICBvYmplY3RbbmFtZV0gPSBudWxsO1xuXHQgICAgfSBlbHNlIGlmIChlbGVtZW50VHlwZSA9PT0gY29uc3RhbnRzLkJTT05fREFUQV9MT05HKSB7XG5cdCAgICAgIC8vIFVucGFjayB0aGUgbG93IGFuZCBoaWdoIGJpdHNcblx0ICAgICAgdmFyIF9sb3dCaXRzID0gYnVmZmVyJCQxW2luZGV4KytdIHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDggfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMTYgfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMjQ7XG5cblx0ICAgICAgdmFyIF9oaWdoQml0cyA9IGJ1ZmZlciQkMVtpbmRleCsrXSB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCA4IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDE2IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDI0O1xuXG5cdCAgICAgIHZhciBsb25nJCQxID0gbmV3IGxvbmdfMShfbG93Qml0cywgX2hpZ2hCaXRzKTsgLy8gUHJvbW90ZSB0aGUgbG9uZyBpZiBwb3NzaWJsZVxuXG5cdCAgICAgIGlmIChwcm9tb3RlTG9uZ3MgJiYgcHJvbW90ZVZhbHVlcyA9PT0gdHJ1ZSkge1xuXHQgICAgICAgIG9iamVjdFtuYW1lXSA9IGxvbmckJDEubGVzc1RoYW5PckVxdWFsKEpTX0lOVF9NQVhfTE9ORykgJiYgbG9uZyQkMS5ncmVhdGVyVGhhbk9yRXF1YWwoSlNfSU5UX01JTl9MT05HKSA/IGxvbmckJDEudG9OdW1iZXIoKSA6IGxvbmckJDE7XG5cdCAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgb2JqZWN0W25hbWVdID0gbG9uZyQkMTtcblx0ICAgICAgfVxuXHQgICAgfSBlbHNlIGlmIChlbGVtZW50VHlwZSA9PT0gY29uc3RhbnRzLkJTT05fREFUQV9ERUNJTUFMMTI4KSB7XG5cdCAgICAgIC8vIEJ1ZmZlciB0byBjb250YWluIHRoZSBkZWNpbWFsIGJ5dGVzXG5cdCAgICAgIHZhciBieXRlcyA9IEJ1ZmZlciQ0LmFsbG9jKDE2KTsgLy8gQ29weSB0aGUgbmV4dCAxNiBieXRlcyBpbnRvIHRoZSBieXRlcyBidWZmZXJcblxuXHQgICAgICBidWZmZXIkJDEuY29weShieXRlcywgMCwgaW5kZXgsIGluZGV4ICsgMTYpOyAvLyBVcGRhdGUgaW5kZXhcblxuXHQgICAgICBpbmRleCA9IGluZGV4ICsgMTY7IC8vIEFzc2lnbiB0aGUgbmV3IERlY2ltYWwxMjggdmFsdWVcblxuXHQgICAgICB2YXIgZGVjaW1hbDEyOCQkMSA9IG5ldyBkZWNpbWFsMTI4KGJ5dGVzKTsgLy8gSWYgd2UgaGF2ZSBhbiBhbHRlcm5hdGl2ZSBtYXBwZXIgdXNlIHRoYXRcblxuXHQgICAgICBvYmplY3RbbmFtZV0gPSBkZWNpbWFsMTI4JCQxLnRvT2JqZWN0ID8gZGVjaW1hbDEyOCQkMS50b09iamVjdCgpIDogZGVjaW1hbDEyOCQkMTtcblx0ICAgIH0gZWxzZSBpZiAoZWxlbWVudFR5cGUgPT09IGNvbnN0YW50cy5CU09OX0RBVEFfQklOQVJZKSB7XG5cdCAgICAgIHZhciBiaW5hcnlTaXplID0gYnVmZmVyJCQxW2luZGV4KytdIHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDggfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMTYgfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMjQ7XG5cdCAgICAgIHZhciB0b3RhbEJpbmFyeVNpemUgPSBiaW5hcnlTaXplO1xuXHQgICAgICB2YXIgc3ViVHlwZSA9IGJ1ZmZlciQkMVtpbmRleCsrXTsgLy8gRGlkIHdlIGhhdmUgYSBuZWdhdGl2ZSBiaW5hcnkgc2l6ZSwgdGhyb3dcblxuXHQgICAgICBpZiAoYmluYXJ5U2l6ZSA8IDApIHRocm93IG5ldyBFcnJvcignTmVnYXRpdmUgYmluYXJ5IHR5cGUgZWxlbWVudCBzaXplIGZvdW5kJyk7IC8vIElzIHRoZSBsZW5ndGggbG9uZ2VyIHRoYW4gdGhlIGRvY3VtZW50XG5cblx0ICAgICAgaWYgKGJpbmFyeVNpemUgPiBCdWZmZXIkNC5ieXRlTGVuZ3RoKGJ1ZmZlciQkMSkpIHRocm93IG5ldyBFcnJvcignQmluYXJ5IHR5cGUgc2l6ZSBsYXJnZXIgdGhhbiBkb2N1bWVudCBzaXplJyk7IC8vIERlY29kZSBhcyByYXcgQnVmZmVyIG9iamVjdCBpZiBvcHRpb25zIHNwZWNpZmllcyBpdFxuXG5cdCAgICAgIGlmIChidWZmZXIkJDFbJ3NsaWNlJ10gIT0gbnVsbCkge1xuXHQgICAgICAgIC8vIElmIHdlIGhhdmUgc3VidHlwZSAyIHNraXAgdGhlIDQgYnl0ZXMgZm9yIHRoZSBzaXplXG5cdCAgICAgICAgaWYgKHN1YlR5cGUgPT09IGJpbmFyeS5TVUJUWVBFX0JZVEVfQVJSQVkpIHtcblx0ICAgICAgICAgIGJpbmFyeVNpemUgPSBidWZmZXIkJDFbaW5kZXgrK10gfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAyNDtcblx0ICAgICAgICAgIGlmIChiaW5hcnlTaXplIDwgMCkgdGhyb3cgbmV3IEVycm9yKCdOZWdhdGl2ZSBiaW5hcnkgdHlwZSBlbGVtZW50IHNpemUgZm91bmQgZm9yIHN1YnR5cGUgMHgwMicpO1xuXHQgICAgICAgICAgaWYgKGJpbmFyeVNpemUgPiB0b3RhbEJpbmFyeVNpemUgLSA0KSB0aHJvdyBuZXcgRXJyb3IoJ0JpbmFyeSB0eXBlIHdpdGggc3VidHlwZSAweDAyIGNvbnRhaW5zIHRvIGxvbmcgYmluYXJ5IHNpemUnKTtcblx0ICAgICAgICAgIGlmIChiaW5hcnlTaXplIDwgdG90YWxCaW5hcnlTaXplIC0gNCkgdGhyb3cgbmV3IEVycm9yKCdCaW5hcnkgdHlwZSB3aXRoIHN1YnR5cGUgMHgwMiBjb250YWlucyB0byBzaG9ydCBiaW5hcnkgc2l6ZScpO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmIChwcm9tb3RlQnVmZmVycyAmJiBwcm9tb3RlVmFsdWVzKSB7XG5cdCAgICAgICAgICBvYmplY3RbbmFtZV0gPSBidWZmZXIkJDEuc2xpY2UoaW5kZXgsIGluZGV4ICsgYmluYXJ5U2l6ZSk7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIG9iamVjdFtuYW1lXSA9IG5ldyBiaW5hcnkoYnVmZmVyJCQxLnNsaWNlKGluZGV4LCBpbmRleCArIGJpbmFyeVNpemUpLCBzdWJUeXBlKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgdmFyIF9idWZmZXIgPSB0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcgPyBuZXcgVWludDhBcnJheShuZXcgQXJyYXlCdWZmZXIoYmluYXJ5U2l6ZSkpIDogbmV3IEFycmF5KGJpbmFyeVNpemUpOyAvLyBJZiB3ZSBoYXZlIHN1YnR5cGUgMiBza2lwIHRoZSA0IGJ5dGVzIGZvciB0aGUgc2l6ZVxuXG5cblx0ICAgICAgICBpZiAoc3ViVHlwZSA9PT0gYmluYXJ5LlNVQlRZUEVfQllURV9BUlJBWSkge1xuXHQgICAgICAgICAgYmluYXJ5U2l6ZSA9IGJ1ZmZlciQkMVtpbmRleCsrXSB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCA4IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDE2IHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDI0O1xuXHQgICAgICAgICAgaWYgKGJpbmFyeVNpemUgPCAwKSB0aHJvdyBuZXcgRXJyb3IoJ05lZ2F0aXZlIGJpbmFyeSB0eXBlIGVsZW1lbnQgc2l6ZSBmb3VuZCBmb3Igc3VidHlwZSAweDAyJyk7XG5cdCAgICAgICAgICBpZiAoYmluYXJ5U2l6ZSA+IHRvdGFsQmluYXJ5U2l6ZSAtIDQpIHRocm93IG5ldyBFcnJvcignQmluYXJ5IHR5cGUgd2l0aCBzdWJ0eXBlIDB4MDIgY29udGFpbnMgdG8gbG9uZyBiaW5hcnkgc2l6ZScpO1xuXHQgICAgICAgICAgaWYgKGJpbmFyeVNpemUgPCB0b3RhbEJpbmFyeVNpemUgLSA0KSB0aHJvdyBuZXcgRXJyb3IoJ0JpbmFyeSB0eXBlIHdpdGggc3VidHlwZSAweDAyIGNvbnRhaW5zIHRvIHNob3J0IGJpbmFyeSBzaXplJyk7XG5cdCAgICAgICAgfSAvLyBDb3B5IHRoZSBkYXRhXG5cblxuXHQgICAgICAgIGZvciAoaSA9IDA7IGkgPCBiaW5hcnlTaXplOyBpKyspIHtcblx0ICAgICAgICAgIF9idWZmZXJbaV0gPSBidWZmZXIkJDFbaW5kZXggKyBpXTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBpZiAocHJvbW90ZUJ1ZmZlcnMgJiYgcHJvbW90ZVZhbHVlcykge1xuXHQgICAgICAgICAgb2JqZWN0W25hbWVdID0gX2J1ZmZlcjtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgb2JqZWN0W25hbWVdID0gbmV3IGJpbmFyeShfYnVmZmVyLCBzdWJUeXBlKTtcblx0ICAgICAgICB9XG5cdCAgICAgIH0gLy8gVXBkYXRlIHRoZSBpbmRleFxuXG5cblx0ICAgICAgaW5kZXggPSBpbmRleCArIGJpbmFyeVNpemU7XG5cdCAgICB9IGVsc2UgaWYgKGVsZW1lbnRUeXBlID09PSBjb25zdGFudHMuQlNPTl9EQVRBX1JFR0VYUCAmJiBic29uUmVnRXhwID09PSBmYWxzZSkge1xuXHQgICAgICAvLyBHZXQgdGhlIHN0YXJ0IHNlYXJjaCBpbmRleFxuXHQgICAgICBpID0gaW5kZXg7IC8vIExvY2F0ZSB0aGUgZW5kIG9mIHRoZSBjIHN0cmluZ1xuXG5cdCAgICAgIHdoaWxlIChidWZmZXIkJDFbaV0gIT09IDB4MDAgJiYgaSA8IGJ1ZmZlciQkMS5sZW5ndGgpIHtcblx0ICAgICAgICBpKys7XG5cdCAgICAgIH0gLy8gSWYgYXJlIGF0IHRoZSBlbmQgb2YgdGhlIGJ1ZmZlciB0aGVyZSBpcyBhIHByb2JsZW0gd2l0aCB0aGUgZG9jdW1lbnRcblxuXG5cdCAgICAgIGlmIChpID49IGJ1ZmZlciQkMS5sZW5ndGgpIHRocm93IG5ldyBFcnJvcignQmFkIEJTT04gRG9jdW1lbnQ6IGlsbGVnYWwgQ1N0cmluZycpOyAvLyBSZXR1cm4gdGhlIEMgc3RyaW5nXG5cblx0ICAgICAgdmFyIHNvdXJjZSA9IGJ1ZmZlciQkMS50b1N0cmluZygndXRmOCcsIGluZGV4LCBpKTsgLy8gQ3JlYXRlIHRoZSByZWdleHBcblxuXHQgICAgICBpbmRleCA9IGkgKyAxOyAvLyBHZXQgdGhlIHN0YXJ0IHNlYXJjaCBpbmRleFxuXG5cdCAgICAgIGkgPSBpbmRleDsgLy8gTG9jYXRlIHRoZSBlbmQgb2YgdGhlIGMgc3RyaW5nXG5cblx0ICAgICAgd2hpbGUgKGJ1ZmZlciQkMVtpXSAhPT0gMHgwMCAmJiBpIDwgYnVmZmVyJCQxLmxlbmd0aCkge1xuXHQgICAgICAgIGkrKztcblx0ICAgICAgfSAvLyBJZiBhcmUgYXQgdGhlIGVuZCBvZiB0aGUgYnVmZmVyIHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIHRoZSBkb2N1bWVudFxuXG5cblx0ICAgICAgaWYgKGkgPj0gYnVmZmVyJCQxLmxlbmd0aCkgdGhyb3cgbmV3IEVycm9yKCdCYWQgQlNPTiBEb2N1bWVudDogaWxsZWdhbCBDU3RyaW5nJyk7IC8vIFJldHVybiB0aGUgQyBzdHJpbmdcblxuXHQgICAgICB2YXIgcmVnRXhwT3B0aW9ucyA9IGJ1ZmZlciQkMS50b1N0cmluZygndXRmOCcsIGluZGV4LCBpKTtcblx0ICAgICAgaW5kZXggPSBpICsgMTsgLy8gRm9yIGVhY2ggb3B0aW9uIGFkZCB0aGUgY29ycmVzcG9uZGluZyBvbmUgZm9yIGphdmFzY3JpcHRcblxuXHQgICAgICB2YXIgb3B0aW9uc0FycmF5ID0gbmV3IEFycmF5KHJlZ0V4cE9wdGlvbnMubGVuZ3RoKTsgLy8gUGFyc2Ugb3B0aW9uc1xuXG5cdCAgICAgIGZvciAoaSA9IDA7IGkgPCByZWdFeHBPcHRpb25zLmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgc3dpdGNoIChyZWdFeHBPcHRpb25zW2ldKSB7XG5cdCAgICAgICAgICBjYXNlICdtJzpcblx0ICAgICAgICAgICAgb3B0aW9uc0FycmF5W2ldID0gJ20nO1xuXHQgICAgICAgICAgICBicmVhaztcblxuXHQgICAgICAgICAgY2FzZSAncyc6XG5cdCAgICAgICAgICAgIG9wdGlvbnNBcnJheVtpXSA9ICdnJztcblx0ICAgICAgICAgICAgYnJlYWs7XG5cblx0ICAgICAgICAgIGNhc2UgJ2knOlxuXHQgICAgICAgICAgICBvcHRpb25zQXJyYXlbaV0gPSAnaSc7XG5cdCAgICAgICAgICAgIGJyZWFrO1xuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXG5cdCAgICAgIG9iamVjdFtuYW1lXSA9IG5ldyBSZWdFeHAoc291cmNlLCBvcHRpb25zQXJyYXkuam9pbignJykpO1xuXHQgICAgfSBlbHNlIGlmIChlbGVtZW50VHlwZSA9PT0gY29uc3RhbnRzLkJTT05fREFUQV9SRUdFWFAgJiYgYnNvblJlZ0V4cCA9PT0gdHJ1ZSkge1xuXHQgICAgICAvLyBHZXQgdGhlIHN0YXJ0IHNlYXJjaCBpbmRleFxuXHQgICAgICBpID0gaW5kZXg7IC8vIExvY2F0ZSB0aGUgZW5kIG9mIHRoZSBjIHN0cmluZ1xuXG5cdCAgICAgIHdoaWxlIChidWZmZXIkJDFbaV0gIT09IDB4MDAgJiYgaSA8IGJ1ZmZlciQkMS5sZW5ndGgpIHtcblx0ICAgICAgICBpKys7XG5cdCAgICAgIH0gLy8gSWYgYXJlIGF0IHRoZSBlbmQgb2YgdGhlIGJ1ZmZlciB0aGVyZSBpcyBhIHByb2JsZW0gd2l0aCB0aGUgZG9jdW1lbnRcblxuXG5cdCAgICAgIGlmIChpID49IGJ1ZmZlciQkMS5sZW5ndGgpIHRocm93IG5ldyBFcnJvcignQmFkIEJTT04gRG9jdW1lbnQ6IGlsbGVnYWwgQ1N0cmluZycpOyAvLyBSZXR1cm4gdGhlIEMgc3RyaW5nXG5cblx0ICAgICAgdmFyIF9zb3VyY2UgPSBidWZmZXIkJDEudG9TdHJpbmcoJ3V0ZjgnLCBpbmRleCwgaSk7XG5cblx0ICAgICAgaW5kZXggPSBpICsgMTsgLy8gR2V0IHRoZSBzdGFydCBzZWFyY2ggaW5kZXhcblxuXHQgICAgICBpID0gaW5kZXg7IC8vIExvY2F0ZSB0aGUgZW5kIG9mIHRoZSBjIHN0cmluZ1xuXG5cdCAgICAgIHdoaWxlIChidWZmZXIkJDFbaV0gIT09IDB4MDAgJiYgaSA8IGJ1ZmZlciQkMS5sZW5ndGgpIHtcblx0ICAgICAgICBpKys7XG5cdCAgICAgIH0gLy8gSWYgYXJlIGF0IHRoZSBlbmQgb2YgdGhlIGJ1ZmZlciB0aGVyZSBpcyBhIHByb2JsZW0gd2l0aCB0aGUgZG9jdW1lbnRcblxuXG5cdCAgICAgIGlmIChpID49IGJ1ZmZlciQkMS5sZW5ndGgpIHRocm93IG5ldyBFcnJvcignQmFkIEJTT04gRG9jdW1lbnQ6IGlsbGVnYWwgQ1N0cmluZycpOyAvLyBSZXR1cm4gdGhlIEMgc3RyaW5nXG5cblx0ICAgICAgdmFyIF9yZWdFeHBPcHRpb25zID0gYnVmZmVyJCQxLnRvU3RyaW5nKCd1dGY4JywgaW5kZXgsIGkpO1xuXG5cdCAgICAgIGluZGV4ID0gaSArIDE7IC8vIFNldCB0aGUgb2JqZWN0XG5cblx0ICAgICAgb2JqZWN0W25hbWVdID0gbmV3IHJlZ2V4cChfc291cmNlLCBfcmVnRXhwT3B0aW9ucyk7XG5cdCAgICB9IGVsc2UgaWYgKGVsZW1lbnRUeXBlID09PSBjb25zdGFudHMuQlNPTl9EQVRBX1NZTUJPTCkge1xuXHQgICAgICB2YXIgX3N0cmluZ1NpemUgPSBidWZmZXIkJDFbaW5kZXgrK10gfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAyNDtcblxuXHQgICAgICBpZiAoX3N0cmluZ1NpemUgPD0gMCB8fCBfc3RyaW5nU2l6ZSA+IGJ1ZmZlciQkMS5sZW5ndGggLSBpbmRleCB8fCBidWZmZXIkJDFbaW5kZXggKyBfc3RyaW5nU2l6ZSAtIDFdICE9PSAwKSB0aHJvdyBuZXcgRXJyb3IoJ2JhZCBzdHJpbmcgbGVuZ3RoIGluIGJzb24nKTsgLy8gc3ltYm9sIGlzIGRlcHJlY2F0ZWQgLSB1cGdyYWRlIHRvIHN0cmluZy5cblxuXHQgICAgICBvYmplY3RbbmFtZV0gPSBidWZmZXIkJDEudG9TdHJpbmcoJ3V0ZjgnLCBpbmRleCwgaW5kZXggKyBfc3RyaW5nU2l6ZSAtIDEpO1xuXHQgICAgICBpbmRleCA9IGluZGV4ICsgX3N0cmluZ1NpemU7XG5cdCAgICB9IGVsc2UgaWYgKGVsZW1lbnRUeXBlID09PSBjb25zdGFudHMuQlNPTl9EQVRBX1RJTUVTVEFNUCkge1xuXHQgICAgICB2YXIgX2xvd0JpdHMyID0gYnVmZmVyJCQxW2luZGV4KytdIHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDggfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMTYgfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMjQ7XG5cblx0ICAgICAgdmFyIF9oaWdoQml0czIgPSBidWZmZXIkJDFbaW5kZXgrK10gfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAyNDtcblxuXHQgICAgICBvYmplY3RbbmFtZV0gPSBuZXcgdGltZXN0YW1wKF9sb3dCaXRzMiwgX2hpZ2hCaXRzMik7XG5cdCAgICB9IGVsc2UgaWYgKGVsZW1lbnRUeXBlID09PSBjb25zdGFudHMuQlNPTl9EQVRBX01JTl9LRVkpIHtcblx0ICAgICAgb2JqZWN0W25hbWVdID0gbmV3IG1pbl9rZXkoKTtcblx0ICAgIH0gZWxzZSBpZiAoZWxlbWVudFR5cGUgPT09IGNvbnN0YW50cy5CU09OX0RBVEFfTUFYX0tFWSkge1xuXHQgICAgICBvYmplY3RbbmFtZV0gPSBuZXcgbWF4X2tleSgpO1xuXHQgICAgfSBlbHNlIGlmIChlbGVtZW50VHlwZSA9PT0gY29uc3RhbnRzLkJTT05fREFUQV9DT0RFKSB7XG5cdCAgICAgIHZhciBfc3RyaW5nU2l6ZTIgPSBidWZmZXIkJDFbaW5kZXgrK10gfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAyNDtcblxuXHQgICAgICBpZiAoX3N0cmluZ1NpemUyIDw9IDAgfHwgX3N0cmluZ1NpemUyID4gYnVmZmVyJCQxLmxlbmd0aCAtIGluZGV4IHx8IGJ1ZmZlciQkMVtpbmRleCArIF9zdHJpbmdTaXplMiAtIDFdICE9PSAwKSB0aHJvdyBuZXcgRXJyb3IoJ2JhZCBzdHJpbmcgbGVuZ3RoIGluIGJzb24nKTtcblx0ICAgICAgdmFyIGZ1bmN0aW9uU3RyaW5nID0gYnVmZmVyJCQxLnRvU3RyaW5nKCd1dGY4JywgaW5kZXgsIGluZGV4ICsgX3N0cmluZ1NpemUyIC0gMSk7IC8vIElmIHdlIGFyZSBldmFsdWF0aW5nIHRoZSBmdW5jdGlvbnNcblxuXHQgICAgICBpZiAoZXZhbEZ1bmN0aW9ucykge1xuXHQgICAgICAgIC8vIElmIHdlIGhhdmUgY2FjaGUgZW5hYmxlZCBsZXQncyBsb29rIGZvciB0aGUgbWQ1IG9mIHRoZSBmdW5jdGlvbiBpbiB0aGUgY2FjaGVcblx0ICAgICAgICBpZiAoY2FjaGVGdW5jdGlvbnMpIHtcblx0ICAgICAgICAgIHZhciBoYXNoID0gY2FjaGVGdW5jdGlvbnNDcmMzMiA/IGNyYzMyKGZ1bmN0aW9uU3RyaW5nKSA6IGZ1bmN0aW9uU3RyaW5nOyAvLyBHb3QgdG8gZG8gdGhpcyB0byBhdm9pZCBWOCBkZW9wdGltaXppbmcgdGhlIGNhbGwgZHVlIHRvIGZpbmRpbmcgZXZhbFxuXG5cdCAgICAgICAgICBvYmplY3RbbmFtZV0gPSBpc29sYXRlRXZhbFdpdGhIYXNoKGZ1bmN0aW9uQ2FjaGUsIGhhc2gsIGZ1bmN0aW9uU3RyaW5nLCBvYmplY3QpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICBvYmplY3RbbmFtZV0gPSBpc29sYXRlRXZhbChmdW5jdGlvblN0cmluZyk7XG5cdCAgICAgICAgfVxuXHQgICAgICB9IGVsc2Uge1xuXHQgICAgICAgIG9iamVjdFtuYW1lXSA9IG5ldyBjb2RlKGZ1bmN0aW9uU3RyaW5nKTtcblx0ICAgICAgfSAvLyBVcGRhdGUgcGFyc2UgaW5kZXggcG9zaXRpb25cblxuXG5cdCAgICAgIGluZGV4ID0gaW5kZXggKyBfc3RyaW5nU2l6ZTI7XG5cdCAgICB9IGVsc2UgaWYgKGVsZW1lbnRUeXBlID09PSBjb25zdGFudHMuQlNPTl9EQVRBX0NPREVfV19TQ09QRSkge1xuXHQgICAgICB2YXIgdG90YWxTaXplID0gYnVmZmVyJCQxW2luZGV4KytdIHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDggfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMTYgfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMjQ7IC8vIEVsZW1lbnQgY2Fubm90IGJlIHNob3J0ZXIgdGhhbiB0b3RhbFNpemUgKyBzdHJpbmdTaXplICsgZG9jdW1lbnRTaXplICsgdGVybWluYXRvclxuXG5cdCAgICAgIGlmICh0b3RhbFNpemUgPCA0ICsgNCArIDQgKyAxKSB7XG5cdCAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdjb2RlX3dfc2NvcGUgdG90YWwgc2l6ZSBzaG9ydGVyIG1pbmltdW0gZXhwZWN0ZWQgbGVuZ3RoJyk7XG5cdCAgICAgIH0gLy8gR2V0IHRoZSBjb2RlIHN0cmluZyBzaXplXG5cblxuXHQgICAgICB2YXIgX3N0cmluZ1NpemUzID0gYnVmZmVyJCQxW2luZGV4KytdIHwgYnVmZmVyJCQxW2luZGV4KytdIDw8IDggfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMTYgfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgMjQ7IC8vIENoZWNrIGlmIHdlIGhhdmUgYSB2YWxpZCBzdHJpbmdcblxuXG5cdCAgICAgIGlmIChfc3RyaW5nU2l6ZTMgPD0gMCB8fCBfc3RyaW5nU2l6ZTMgPiBidWZmZXIkJDEubGVuZ3RoIC0gaW5kZXggfHwgYnVmZmVyJCQxW2luZGV4ICsgX3N0cmluZ1NpemUzIC0gMV0gIT09IDApIHRocm93IG5ldyBFcnJvcignYmFkIHN0cmluZyBsZW5ndGggaW4gYnNvbicpOyAvLyBKYXZhc2NyaXB0IGZ1bmN0aW9uXG5cblx0ICAgICAgdmFyIF9mdW5jdGlvblN0cmluZyA9IGJ1ZmZlciQkMS50b1N0cmluZygndXRmOCcsIGluZGV4LCBpbmRleCArIF9zdHJpbmdTaXplMyAtIDEpOyAvLyBVcGRhdGUgcGFyc2UgaW5kZXggcG9zaXRpb25cblxuXG5cdCAgICAgIGluZGV4ID0gaW5kZXggKyBfc3RyaW5nU2l6ZTM7IC8vIFBhcnNlIHRoZSBlbGVtZW50XG5cblx0ICAgICAgdmFyIF9pbmRleDMgPSBpbmRleDsgLy8gRGVjb2RlIHRoZSBzaXplIG9mIHRoZSBvYmplY3QgZG9jdW1lbnRcblxuXHQgICAgICB2YXIgX29iamVjdFNpemUyID0gYnVmZmVyJCQxW2luZGV4XSB8IGJ1ZmZlciQkMVtpbmRleCArIDFdIDw8IDggfCBidWZmZXIkJDFbaW5kZXggKyAyXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCArIDNdIDw8IDI0OyAvLyBEZWNvZGUgdGhlIHNjb3BlIG9iamVjdFxuXG5cblx0ICAgICAgdmFyIHNjb3BlT2JqZWN0ID0gZGVzZXJpYWxpemVPYmplY3QoYnVmZmVyJCQxLCBfaW5kZXgzLCBvcHRpb25zLCBmYWxzZSk7IC8vIEFkanVzdCB0aGUgaW5kZXhcblxuXHQgICAgICBpbmRleCA9IGluZGV4ICsgX29iamVjdFNpemUyOyAvLyBDaGVjayBpZiBmaWVsZCBsZW5ndGggaXMgdG8gc2hvcnRcblxuXHQgICAgICBpZiAodG90YWxTaXplIDwgNCArIDQgKyBfb2JqZWN0U2l6ZTIgKyBfc3RyaW5nU2l6ZTMpIHtcblx0ICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvZGVfd19zY29wZSB0b3RhbCBzaXplIGlzIHRvIHNob3J0LCB0cnVuY2F0aW5nIHNjb3BlJyk7XG5cdCAgICAgIH0gLy8gQ2hlY2sgaWYgdG90YWxTaXplIGZpZWxkIGlzIHRvIGxvbmdcblxuXG5cdCAgICAgIGlmICh0b3RhbFNpemUgPiA0ICsgNCArIF9vYmplY3RTaXplMiArIF9zdHJpbmdTaXplMykge1xuXHQgICAgICAgIHRocm93IG5ldyBFcnJvcignY29kZV93X3Njb3BlIHRvdGFsIHNpemUgaXMgdG8gbG9uZywgY2xpcHMgb3V0ZXIgZG9jdW1lbnQnKTtcblx0ICAgICAgfSAvLyBJZiB3ZSBhcmUgZXZhbHVhdGluZyB0aGUgZnVuY3Rpb25zXG5cblxuXHQgICAgICBpZiAoZXZhbEZ1bmN0aW9ucykge1xuXHQgICAgICAgIC8vIElmIHdlIGhhdmUgY2FjaGUgZW5hYmxlZCBsZXQncyBsb29rIGZvciB0aGUgbWQ1IG9mIHRoZSBmdW5jdGlvbiBpbiB0aGUgY2FjaGVcblx0ICAgICAgICBpZiAoY2FjaGVGdW5jdGlvbnMpIHtcblx0ICAgICAgICAgIHZhciBfaGFzaCA9IGNhY2hlRnVuY3Rpb25zQ3JjMzIgPyBjcmMzMihfZnVuY3Rpb25TdHJpbmcpIDogX2Z1bmN0aW9uU3RyaW5nOyAvLyBHb3QgdG8gZG8gdGhpcyB0byBhdm9pZCBWOCBkZW9wdGltaXppbmcgdGhlIGNhbGwgZHVlIHRvIGZpbmRpbmcgZXZhbFxuXG5cblx0ICAgICAgICAgIG9iamVjdFtuYW1lXSA9IGlzb2xhdGVFdmFsV2l0aEhhc2goZnVuY3Rpb25DYWNoZSwgX2hhc2gsIF9mdW5jdGlvblN0cmluZywgb2JqZWN0KTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgb2JqZWN0W25hbWVdID0gaXNvbGF0ZUV2YWwoX2Z1bmN0aW9uU3RyaW5nKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBvYmplY3RbbmFtZV0uc2NvcGUgPSBzY29wZU9iamVjdDtcblx0ICAgICAgfSBlbHNlIHtcblx0ICAgICAgICBvYmplY3RbbmFtZV0gPSBuZXcgY29kZShfZnVuY3Rpb25TdHJpbmcsIHNjb3BlT2JqZWN0KTtcblx0ICAgICAgfVxuXHQgICAgfSBlbHNlIGlmIChlbGVtZW50VHlwZSA9PT0gY29uc3RhbnRzLkJTT05fREFUQV9EQlBPSU5URVIpIHtcblx0ICAgICAgLy8gR2V0IHRoZSBjb2RlIHN0cmluZyBzaXplXG5cdCAgICAgIHZhciBfc3RyaW5nU2l6ZTQgPSBidWZmZXIkJDFbaW5kZXgrK10gfCBidWZmZXIkJDFbaW5kZXgrK10gPDwgOCB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAxNiB8IGJ1ZmZlciQkMVtpbmRleCsrXSA8PCAyNDsgLy8gQ2hlY2sgaWYgd2UgaGF2ZSBhIHZhbGlkIHN0cmluZ1xuXG5cblx0ICAgICAgaWYgKF9zdHJpbmdTaXplNCA8PSAwIHx8IF9zdHJpbmdTaXplNCA+IGJ1ZmZlciQkMS5sZW5ndGggLSBpbmRleCB8fCBidWZmZXIkJDFbaW5kZXggKyBfc3RyaW5nU2l6ZTQgLSAxXSAhPT0gMCkgdGhyb3cgbmV3IEVycm9yKCdiYWQgc3RyaW5nIGxlbmd0aCBpbiBic29uJyk7IC8vIE5hbWVzcGFjZVxuXG5cdCAgICAgIGlmICghdmFsaWRhdGVVdGY4JDEoYnVmZmVyJCQxLCBpbmRleCwgaW5kZXggKyBfc3RyaW5nU2l6ZTQgLSAxKSkge1xuXHQgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBVVEYtOCBzdHJpbmcgaW4gQlNPTiBkb2N1bWVudCcpO1xuXHQgICAgICB9XG5cblx0ICAgICAgdmFyIG5hbWVzcGFjZSA9IGJ1ZmZlciQkMS50b1N0cmluZygndXRmOCcsIGluZGV4LCBpbmRleCArIF9zdHJpbmdTaXplNCAtIDEpOyAvLyBVcGRhdGUgcGFyc2UgaW5kZXggcG9zaXRpb25cblxuXHQgICAgICBpbmRleCA9IGluZGV4ICsgX3N0cmluZ1NpemU0OyAvLyBSZWFkIHRoZSBvaWRcblxuXHQgICAgICB2YXIgb2lkQnVmZmVyID0gQnVmZmVyJDQuYWxsb2MoMTIpO1xuXHQgICAgICBidWZmZXIkJDEuY29weShvaWRCdWZmZXIsIDAsIGluZGV4LCBpbmRleCArIDEyKTtcblxuXHQgICAgICB2YXIgX29pZCA9IG5ldyBvYmplY3RpZChvaWRCdWZmZXIpOyAvLyBVcGRhdGUgdGhlIGluZGV4XG5cblxuXHQgICAgICBpbmRleCA9IGluZGV4ICsgMTI7IC8vIFVwZ3JhZGUgdG8gREJSZWYgdHlwZVxuXG5cdCAgICAgIG9iamVjdFtuYW1lXSA9IG5ldyBkYl9yZWYobmFtZXNwYWNlLCBfb2lkKTtcblx0ICAgIH0gZWxzZSB7XG5cdCAgICAgIHRocm93IG5ldyBFcnJvcignRGV0ZWN0ZWQgdW5rbm93biBCU09OIHR5cGUgJyArIGVsZW1lbnRUeXBlLnRvU3RyaW5nKDE2KSArICcgZm9yIGZpZWxkbmFtZSBcIicgKyBuYW1lICsgJ1wiLCBhcmUgeW91IHVzaW5nIHRoZSBsYXRlc3QgQlNPTiBwYXJzZXI/Jyk7XG5cdCAgICB9XG5cdCAgfSAvLyBDaGVjayBpZiB0aGUgZGVzZXJpYWxpemF0aW9uIHdhcyBhZ2FpbnN0IGEgdmFsaWQgYXJyYXkvb2JqZWN0XG5cblxuXHQgIGlmIChzaXplICE9PSBpbmRleCAtIHN0YXJ0SW5kZXgpIHtcblx0ICAgIGlmIChpc0FycmF5KSB0aHJvdyBuZXcgRXJyb3IoJ2NvcnJ1cHQgYXJyYXkgYnNvbicpO1xuXHQgICAgdGhyb3cgbmV3IEVycm9yKCdjb3JydXB0IG9iamVjdCBic29uJyk7XG5cdCAgfSAvLyBjaGVjayBpZiBvYmplY3QncyAkIGtleXMgYXJlIHRob3NlIG9mIGEgREJSZWZcblxuXG5cdCAgdmFyIGRvbGxhcktleXMgPSBPYmplY3Qua2V5cyhvYmplY3QpLmZpbHRlcihmdW5jdGlvbiAoaykge1xuXHQgICAgcmV0dXJuIGsuc3RhcnRzV2l0aCgnJCcpO1xuXHQgIH0pO1xuXHQgIHZhciB2YWxpZCA9IHRydWU7XG5cdCAgZG9sbGFyS2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7XG5cdCAgICBpZiAoWyckcmVmJywgJyRpZCcsICckZGInXS5pbmRleE9mKGspID09PSAtMSkgdmFsaWQgPSBmYWxzZTtcblx0ICB9KTsgLy8gaWYgYSAka2V5IG5vdCBpbiBcIiRyZWZcIiwgXCIkaWRcIiwgXCIkZGJcIiwgZG9uJ3QgbWFrZSBhIERCUmVmXG5cblx0ICBpZiAoIXZhbGlkKSByZXR1cm4gb2JqZWN0O1xuXG5cdCAgaWYgKG9iamVjdFsnJGlkJ10gIT0gbnVsbCAmJiBvYmplY3RbJyRyZWYnXSAhPSBudWxsKSB7XG5cdCAgICB2YXIgY29weSA9IE9iamVjdC5hc3NpZ24oe30sIG9iamVjdCk7XG5cdCAgICBkZWxldGUgY29weS4kcmVmO1xuXHQgICAgZGVsZXRlIGNvcHkuJGlkO1xuXHQgICAgZGVsZXRlIGNvcHkuJGRiO1xuXHQgICAgcmV0dXJuIG5ldyBkYl9yZWYob2JqZWN0LiRyZWYsIG9iamVjdC4kaWQsIG9iamVjdC4kZGIgfHwgbnVsbCwgY29weSk7XG5cdCAgfVxuXG5cdCAgcmV0dXJuIG9iamVjdDtcblx0fVxuXHQvKipcblx0ICogRW5zdXJlIGV2YWwgaXMgaXNvbGF0ZWQuXG5cdCAqXG5cdCAqIEBpZ25vcmVcblx0ICogQGFwaSBwcml2YXRlXG5cdCAqL1xuXG5cblx0ZnVuY3Rpb24gaXNvbGF0ZUV2YWxXaXRoSGFzaChmdW5jdGlvbkNhY2hlLCBoYXNoLCBmdW5jdGlvblN0cmluZywgb2JqZWN0KSB7XG5cdCAgLy8gQ29udGFpbnMgdGhlIHZhbHVlIHdlIGFyZSBnb2luZyB0byBzZXRcblx0ICB2YXIgdmFsdWUgPSBudWxsOyAvLyBDaGVjayBmb3IgY2FjaGUgaGl0LCBldmFsIGlmIG1pc3NpbmcgYW5kIHJldHVybiBjYWNoZWQgZnVuY3Rpb25cblxuXHQgIGlmIChmdW5jdGlvbkNhY2hlW2hhc2hdID09IG51bGwpIHtcblx0ICAgIGV2YWwoJ3ZhbHVlID0gJyArIGZ1bmN0aW9uU3RyaW5nKTtcblx0ICAgIGZ1bmN0aW9uQ2FjaGVbaGFzaF0gPSB2YWx1ZTtcblx0ICB9IC8vIFNldCB0aGUgb2JqZWN0XG5cblxuXHQgIHJldHVybiBmdW5jdGlvbkNhY2hlW2hhc2hdLmJpbmQob2JqZWN0KTtcblx0fVxuXHQvKipcblx0ICogRW5zdXJlIGV2YWwgaXMgaXNvbGF0ZWQuXG5cdCAqXG5cdCAqIEBpZ25vcmVcblx0ICogQGFwaSBwcml2YXRlXG5cdCAqL1xuXG5cblx0ZnVuY3Rpb24gaXNvbGF0ZUV2YWwoZnVuY3Rpb25TdHJpbmcpIHtcblx0ICAvLyBDb250YWlucyB0aGUgdmFsdWUgd2UgYXJlIGdvaW5nIHRvIHNldFxuXHQgIHZhciB2YWx1ZSA9IG51bGw7IC8vIEV2YWwgdGhlIGZ1bmN0aW9uXG5cblx0ICBldmFsKCd2YWx1ZSA9ICcgKyBmdW5jdGlvblN0cmluZyk7XG5cdCAgcmV0dXJuIHZhbHVlO1xuXHR9XG5cblx0dmFyIGRlc2VyaWFsaXplciA9IGRlc2VyaWFsaXplJDE7XG5cblx0Ly8gQWxsIHJpZ2h0cyByZXNlcnZlZC5cblx0Ly9cblx0Ly8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG5cdC8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuXHQvL1xuXHQvLyAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG5cdC8vICAgIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG5cdC8vXG5cdC8vICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcblx0Ly8gICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvblxuXHQvLyAgICBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cblx0Ly9cblx0Ly8gICogTmVpdGhlciB0aGUgbmFtZSBvZiBGYWlyIE9ha3MgTGFicywgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcblx0Ly8gICAgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG5cdC8vICAgIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuXHQvL1xuXHQvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuXHQvLyBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG5cdC8vIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG5cdC8vIEFSRSBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBPV05FUiBPUiBDT05UUklCVVRPUlMgQkVcblx0Ly8gTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuXHQvLyBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuXHQvLyBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1Ncblx0Ly8gSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cblx0Ly8gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcblx0Ly8gQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcblx0Ly8gUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG5cdC8vXG5cdC8vXG5cdC8vIE1vZGlmaWNhdGlvbnMgdG8gd3JpdGVJRUVFNzU0IHRvIHN1cHBvcnQgbmVnYXRpdmUgemVyb2VzIG1hZGUgYnkgQnJpYW4gV2hpdGVcblxuXHRmdW5jdGlvbiByZWFkSUVFRTc1NChidWZmZXIkJDEsIG9mZnNldCwgZW5kaWFuLCBtTGVuLCBuQnl0ZXMpIHtcblx0ICB2YXIgZSxcblx0ICAgICAgbSxcblx0ICAgICAgYkJFID0gZW5kaWFuID09PSAnYmlnJyxcblx0ICAgICAgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMSxcblx0ICAgICAgZU1heCA9ICgxIDw8IGVMZW4pIC0gMSxcblx0ICAgICAgZUJpYXMgPSBlTWF4ID4+IDEsXG5cdCAgICAgIG5CaXRzID0gLTcsXG5cdCAgICAgIGkgPSBiQkUgPyAwIDogbkJ5dGVzIC0gMSxcblx0ICAgICAgZCA9IGJCRSA/IDEgOiAtMSxcblx0ICAgICAgcyA9IGJ1ZmZlciQkMVtvZmZzZXQgKyBpXTtcblx0ICBpICs9IGQ7XG5cdCAgZSA9IHMgJiAoMSA8PCAtbkJpdHMpIC0gMTtcblx0ICBzID4+PSAtbkJpdHM7XG5cdCAgbkJpdHMgKz0gZUxlbjtcblxuXHQgIGZvciAoOyBuQml0cyA+IDA7IGUgPSBlICogMjU2ICsgYnVmZmVyJCQxW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHtcblx0ICB9XG5cblx0ICBtID0gZSAmICgxIDw8IC1uQml0cykgLSAxO1xuXHQgIGUgPj49IC1uQml0cztcblx0ICBuQml0cyArPSBtTGVuO1xuXG5cdCAgZm9yICg7IG5CaXRzID4gMDsgbSA9IG0gKiAyNTYgKyBidWZmZXIkJDFbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge1xuXHQgIH1cblxuXHQgIGlmIChlID09PSAwKSB7XG5cdCAgICBlID0gMSAtIGVCaWFzO1xuXHQgIH0gZWxzZSBpZiAoZSA9PT0gZU1heCkge1xuXHQgICAgcmV0dXJuIG0gPyBOYU4gOiAocyA/IC0xIDogMSkgKiBJbmZpbml0eTtcblx0ICB9IGVsc2Uge1xuXHQgICAgbSA9IG0gKyBNYXRoLnBvdygyLCBtTGVuKTtcblx0ICAgIGUgPSBlIC0gZUJpYXM7XG5cdCAgfVxuXG5cdCAgcmV0dXJuIChzID8gLTEgOiAxKSAqIG0gKiBNYXRoLnBvdygyLCBlIC0gbUxlbik7XG5cdH1cblxuXHRmdW5jdGlvbiB3cml0ZUlFRUU3NTQoYnVmZmVyJCQxLCB2YWx1ZSwgb2Zmc2V0LCBlbmRpYW4sIG1MZW4sIG5CeXRlcykge1xuXHQgIHZhciBlLFxuXHQgICAgICBtLFxuXHQgICAgICBjLFxuXHQgICAgICBiQkUgPSBlbmRpYW4gPT09ICdiaWcnLFxuXHQgICAgICBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxLFxuXHQgICAgICBlTWF4ID0gKDEgPDwgZUxlbikgLSAxLFxuXHQgICAgICBlQmlhcyA9IGVNYXggPj4gMSxcblx0ICAgICAgcnQgPSBtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMCxcblx0ICAgICAgaSA9IGJCRSA/IG5CeXRlcyAtIDEgOiAwLFxuXHQgICAgICBkID0gYkJFID8gLTEgOiAxLFxuXHQgICAgICBzID0gdmFsdWUgPCAwIHx8IHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDAgPyAxIDogMDtcblx0ICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKTtcblxuXHQgIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG5cdCAgICBtID0gaXNOYU4odmFsdWUpID8gMSA6IDA7XG5cdCAgICBlID0gZU1heDtcblx0ICB9IGVsc2Uge1xuXHQgICAgZSA9IE1hdGguZmxvb3IoTWF0aC5sb2codmFsdWUpIC8gTWF0aC5MTjIpO1xuXG5cdCAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG5cdCAgICAgIGUtLTtcblx0ICAgICAgYyAqPSAyO1xuXHQgICAgfVxuXG5cdCAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcblx0ICAgICAgdmFsdWUgKz0gcnQgLyBjO1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgdmFsdWUgKz0gcnQgKiBNYXRoLnBvdygyLCAxIC0gZUJpYXMpO1xuXHQgICAgfVxuXG5cdCAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcblx0ICAgICAgZSsrO1xuXHQgICAgICBjIC89IDI7XG5cdCAgICB9XG5cblx0ICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuXHQgICAgICBtID0gMDtcblx0ICAgICAgZSA9IGVNYXg7XG5cdCAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG5cdCAgICAgIG0gPSAodmFsdWUgKiBjIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKTtcblx0ICAgICAgZSA9IGUgKyBlQmlhcztcblx0ICAgIH0gZWxzZSB7XG5cdCAgICAgIG0gPSB2YWx1ZSAqIE1hdGgucG93KDIsIGVCaWFzIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKTtcblx0ICAgICAgZSA9IDA7XG5cdCAgICB9XG5cdCAgfVxuXG5cdCAgaWYgKGlzTmFOKHZhbHVlKSkgbSA9IDA7XG5cblx0ICB3aGlsZSAobUxlbiA+PSA4KSB7XG5cdCAgICBidWZmZXIkJDFbb2Zmc2V0ICsgaV0gPSBtICYgMHhmZjtcblx0ICAgIGkgKz0gZDtcblx0ICAgIG0gLz0gMjU2O1xuXHQgICAgbUxlbiAtPSA4O1xuXHQgIH1cblxuXHQgIGUgPSBlIDw8IG1MZW4gfCBtO1xuXHQgIGlmIChpc05hTih2YWx1ZSkpIGUgKz0gODtcblx0ICBlTGVuICs9IG1MZW47XG5cblx0ICB3aGlsZSAoZUxlbiA+IDApIHtcblx0ICAgIGJ1ZmZlciQkMVtvZmZzZXQgKyBpXSA9IGUgJiAweGZmO1xuXHQgICAgaSArPSBkO1xuXHQgICAgZSAvPSAyNTY7XG5cdCAgICBlTGVuIC09IDg7XG5cdCAgfVxuXG5cdCAgYnVmZmVyJCQxW29mZnNldCArIGkgLSBkXSB8PSBzICogMTI4O1xuXHR9XG5cblx0dmFyIGZsb2F0X3BhcnNlciA9IHtcblx0ICByZWFkSUVFRTc1NDogcmVhZElFRUU3NTQsXG5cdCAgd3JpdGVJRUVFNzU0OiB3cml0ZUlFRUU3NTRcblx0fTtcblxuXHRmdW5jdGlvbiBfdHlwZW9mJDMob2JqKSB7IGlmICh0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIikgeyBfdHlwZW9mJDMgPSBmdW5jdGlvbiBfdHlwZW9mKG9iaikgeyByZXR1cm4gdHlwZW9mIG9iajsgfTsgfSBlbHNlIHsgX3R5cGVvZiQzID0gZnVuY3Rpb24gX3R5cGVvZihvYmopIHsgcmV0dXJuIG9iaiAmJiB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7IH07IH0gcmV0dXJuIF90eXBlb2YkMyhvYmopOyB9XG5cblx0dmFyIEJ1ZmZlciQ1ID0gYnVmZmVyLkJ1ZmZlcjtcblx0dmFyIHdyaXRlSUVFRTc1NCQxID0gZmxvYXRfcGFyc2VyLndyaXRlSUVFRTc1NDtcblx0dmFyIG5vcm1hbGl6ZWRGdW5jdGlvblN0cmluZyQxID0gdXRpbHMubm9ybWFsaXplZEZ1bmN0aW9uU3RyaW5nO1xuXHR2YXIgcmVnZXhwJDEgPSAvXFx4MDAvOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWNvbnRyb2wtcmVnZXhcblxuXHR2YXIgaWdub3JlS2V5cyA9IG5ldyBTZXQoWyckZGInLCAnJHJlZicsICckaWQnLCAnJGNsdXN0ZXJUaW1lJ10pOyAvLyBUbyBlbnN1cmUgdGhhdCAwLjQgb2Ygbm9kZSB3b3JrcyBjb3JyZWN0bHlcblxuXHR2YXIgaXNEYXRlJDEgPSBmdW5jdGlvbiBpc0RhdGUoZCkge1xuXHQgIHJldHVybiBfdHlwZW9mJDMoZCkgPT09ICdvYmplY3QnICYmIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChkKSA9PT0gJ1tvYmplY3QgRGF0ZV0nO1xuXHR9O1xuXG5cdHZhciBpc1JlZ0V4cCQxID0gZnVuY3Rpb24gaXNSZWdFeHAoZCkge1xuXHQgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZCkgPT09ICdbb2JqZWN0IFJlZ0V4cF0nO1xuXHR9O1xuXG5cdGZ1bmN0aW9uIHNlcmlhbGl6ZVN0cmluZyhidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCBpc0FycmF5KSB7XG5cdCAgLy8gRW5jb2RlIFN0cmluZyB0eXBlXG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gY29uc3RhbnRzLkJTT05fREFUQV9TVFJJTkc7IC8vIE51bWJlciBvZiB3cml0dGVuIGJ5dGVzXG5cblx0ICB2YXIgbnVtYmVyT2ZXcml0dGVuQnl0ZXMgPSAhaXNBcnJheSA/IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAndXRmOCcpIDogYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICdhc2NpaScpOyAvLyBFbmNvZGUgdGhlIG5hbWVcblxuXHQgIGluZGV4ID0gaW5kZXggKyBudW1iZXJPZldyaXR0ZW5CeXRlcyArIDE7XG5cdCAgYnVmZmVyJCQxW2luZGV4IC0gMV0gPSAwOyAvLyBXcml0ZSB0aGUgc3RyaW5nXG5cblx0ICB2YXIgc2l6ZSA9IGJ1ZmZlciQkMS53cml0ZSh2YWx1ZSwgaW5kZXggKyA0LCAndXRmOCcpOyAvLyBXcml0ZSB0aGUgc2l6ZSBvZiB0aGUgc3RyaW5nIHRvIGJ1ZmZlclxuXG5cdCAgYnVmZmVyJCQxW2luZGV4ICsgM10gPSBzaXplICsgMSA+PiAyNCAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4ICsgMl0gPSBzaXplICsgMSA+PiAxNiAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4ICsgMV0gPSBzaXplICsgMSA+PiA4ICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXhdID0gc2l6ZSArIDEgJiAweGZmOyAvLyBVcGRhdGUgaW5kZXhcblxuXHQgIGluZGV4ID0gaW5kZXggKyA0ICsgc2l6ZTsgLy8gV3JpdGUgemVyb1xuXG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gMDtcblx0ICByZXR1cm4gaW5kZXg7XG5cdH1cblxuXHRmdW5jdGlvbiBzZXJpYWxpemVOdW1iZXIoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgaXNBcnJheSkge1xuXHQgIC8vIFdlIGhhdmUgYW4gaW50ZWdlciB2YWx1ZVxuXHQgIGlmIChNYXRoLmZsb29yKHZhbHVlKSA9PT0gdmFsdWUgJiYgdmFsdWUgPj0gY29uc3RhbnRzLkpTX0lOVF9NSU4gJiYgdmFsdWUgPD0gY29uc3RhbnRzLkpTX0lOVF9NQVgpIHtcblx0ICAgIC8vIElmIHRoZSB2YWx1ZSBmaXRzIGluIDMyIGJpdHMgZW5jb2RlIGFzIGludCwgaWYgaXQgZml0cyBpbiBhIGRvdWJsZVxuXHQgICAgLy8gZW5jb2RlIGl0IGFzIGEgZG91YmxlLCBvdGhlcndpc2UgbG9uZ1xuXHQgICAgaWYgKHZhbHVlID49IGNvbnN0YW50cy5CU09OX0lOVDMyX01JTiAmJiB2YWx1ZSA8PSBjb25zdGFudHMuQlNPTl9JTlQzMl9NQVgpIHtcblx0ICAgICAgLy8gU2V0IGludCB0eXBlIDMyIGJpdHMgb3IgbGVzc1xuXHQgICAgICBidWZmZXIkJDFbaW5kZXgrK10gPSBjb25zdGFudHMuQlNPTl9EQVRBX0lOVDsgLy8gTnVtYmVyIG9mIHdyaXR0ZW4gYnl0ZXNcblxuXHQgICAgICB2YXIgbnVtYmVyT2ZXcml0dGVuQnl0ZXMgPSAhaXNBcnJheSA/IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAndXRmOCcpIDogYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICdhc2NpaScpOyAvLyBFbmNvZGUgdGhlIG5hbWVcblxuXHQgICAgICBpbmRleCA9IGluZGV4ICsgbnVtYmVyT2ZXcml0dGVuQnl0ZXM7XG5cdCAgICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDA7IC8vIFdyaXRlIHRoZSBpbnQgdmFsdWVcblxuXHQgICAgICBidWZmZXIkJDFbaW5kZXgrK10gPSB2YWx1ZSAmIDB4ZmY7XG5cdCAgICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHZhbHVlID4+IDggJiAweGZmO1xuXHQgICAgICBidWZmZXIkJDFbaW5kZXgrK10gPSB2YWx1ZSA+PiAxNiAmIDB4ZmY7XG5cdCAgICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHZhbHVlID4+IDI0ICYgMHhmZjtcblx0ICAgIH0gZWxzZSBpZiAodmFsdWUgPj0gY29uc3RhbnRzLkpTX0lOVF9NSU4gJiYgdmFsdWUgPD0gY29uc3RhbnRzLkpTX0lOVF9NQVgpIHtcblx0ICAgICAgLy8gRW5jb2RlIGFzIGRvdWJsZVxuXHQgICAgICBidWZmZXIkJDFbaW5kZXgrK10gPSBjb25zdGFudHMuQlNPTl9EQVRBX05VTUJFUjsgLy8gTnVtYmVyIG9mIHdyaXR0ZW4gYnl0ZXNcblxuXHQgICAgICB2YXIgX251bWJlck9mV3JpdHRlbkJ5dGVzID0gIWlzQXJyYXkgPyBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ3V0ZjgnKSA6IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAnYXNjaWknKTsgLy8gRW5jb2RlIHRoZSBuYW1lXG5cblxuXHQgICAgICBpbmRleCA9IGluZGV4ICsgX251bWJlck9mV3JpdHRlbkJ5dGVzO1xuXHQgICAgICBidWZmZXIkJDFbaW5kZXgrK10gPSAwOyAvLyBXcml0ZSBmbG9hdFxuXG5cdCAgICAgIHdyaXRlSUVFRTc1NCQxKGJ1ZmZlciQkMSwgdmFsdWUsIGluZGV4LCAnbGl0dGxlJywgNTIsIDgpOyAvLyBBanVzdCBpbmRleFxuXG5cdCAgICAgIGluZGV4ID0gaW5kZXggKyA4O1xuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgLy8gU2V0IGxvbmcgdHlwZVxuXHQgICAgICBidWZmZXIkJDFbaW5kZXgrK10gPSBjb25zdGFudHMuQlNPTl9EQVRBX0xPTkc7IC8vIE51bWJlciBvZiB3cml0dGVuIGJ5dGVzXG5cblx0ICAgICAgdmFyIF9udW1iZXJPZldyaXR0ZW5CeXRlczIgPSAhaXNBcnJheSA/IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAndXRmOCcpIDogYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICdhc2NpaScpOyAvLyBFbmNvZGUgdGhlIG5hbWVcblxuXG5cdCAgICAgIGluZGV4ID0gaW5kZXggKyBfbnVtYmVyT2ZXcml0dGVuQnl0ZXMyO1xuXHQgICAgICBidWZmZXIkJDFbaW5kZXgrK10gPSAwO1xuXHQgICAgICB2YXIgbG9uZ1ZhbCA9IGxvbmdfMS5mcm9tTnVtYmVyKHZhbHVlKTtcblx0ICAgICAgdmFyIGxvd0JpdHMgPSBsb25nVmFsLmdldExvd0JpdHMoKTtcblx0ICAgICAgdmFyIGhpZ2hCaXRzID0gbG9uZ1ZhbC5nZXRIaWdoQml0cygpOyAvLyBFbmNvZGUgbG93IGJpdHNcblxuXHQgICAgICBidWZmZXIkJDFbaW5kZXgrK10gPSBsb3dCaXRzICYgMHhmZjtcblx0ICAgICAgYnVmZmVyJCQxW2luZGV4KytdID0gbG93Qml0cyA+PiA4ICYgMHhmZjtcblx0ICAgICAgYnVmZmVyJCQxW2luZGV4KytdID0gbG93Qml0cyA+PiAxNiAmIDB4ZmY7XG5cdCAgICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGxvd0JpdHMgPj4gMjQgJiAweGZmOyAvLyBFbmNvZGUgaGlnaCBiaXRzXG5cblx0ICAgICAgYnVmZmVyJCQxW2luZGV4KytdID0gaGlnaEJpdHMgJiAweGZmO1xuXHQgICAgICBidWZmZXIkJDFbaW5kZXgrK10gPSBoaWdoQml0cyA+PiA4ICYgMHhmZjtcblx0ICAgICAgYnVmZmVyJCQxW2luZGV4KytdID0gaGlnaEJpdHMgPj4gMTYgJiAweGZmO1xuXHQgICAgICBidWZmZXIkJDFbaW5kZXgrK10gPSBoaWdoQml0cyA+PiAyNCAmIDB4ZmY7XG5cdCAgICB9XG5cdCAgfSBlbHNlIHtcblx0ICAgIC8vIEVuY29kZSBhcyBkb3VibGVcblx0ICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGNvbnN0YW50cy5CU09OX0RBVEFfTlVNQkVSOyAvLyBOdW1iZXIgb2Ygd3JpdHRlbiBieXRlc1xuXG5cdCAgICB2YXIgX251bWJlck9mV3JpdHRlbkJ5dGVzMyA9ICFpc0FycmF5ID8gYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICd1dGY4JykgOiBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ2FzY2lpJyk7IC8vIEVuY29kZSB0aGUgbmFtZVxuXG5cblx0ICAgIGluZGV4ID0gaW5kZXggKyBfbnVtYmVyT2ZXcml0dGVuQnl0ZXMzO1xuXHQgICAgYnVmZmVyJCQxW2luZGV4KytdID0gMDsgLy8gV3JpdGUgZmxvYXRcblxuXHQgICAgd3JpdGVJRUVFNzU0JDEoYnVmZmVyJCQxLCB2YWx1ZSwgaW5kZXgsICdsaXR0bGUnLCA1MiwgOCk7IC8vIEFqdXN0IGluZGV4XG5cblx0ICAgIGluZGV4ID0gaW5kZXggKyA4O1xuXHQgIH1cblxuXHQgIHJldHVybiBpbmRleDtcblx0fVxuXG5cdGZ1bmN0aW9uIHNlcmlhbGl6ZU51bGwoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgaXNBcnJheSkge1xuXHQgIC8vIFNldCBsb25nIHR5cGVcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBjb25zdGFudHMuQlNPTl9EQVRBX05VTEw7IC8vIE51bWJlciBvZiB3cml0dGVuIGJ5dGVzXG5cblx0ICB2YXIgbnVtYmVyT2ZXcml0dGVuQnl0ZXMgPSAhaXNBcnJheSA/IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAndXRmOCcpIDogYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICdhc2NpaScpOyAvLyBFbmNvZGUgdGhlIG5hbWVcblxuXHQgIGluZGV4ID0gaW5kZXggKyBudW1iZXJPZldyaXR0ZW5CeXRlcztcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSAwO1xuXHQgIHJldHVybiBpbmRleDtcblx0fVxuXG5cdGZ1bmN0aW9uIHNlcmlhbGl6ZUJvb2xlYW4oYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgaXNBcnJheSkge1xuXHQgIC8vIFdyaXRlIHRoZSB0eXBlXG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gY29uc3RhbnRzLkJTT05fREFUQV9CT09MRUFOOyAvLyBOdW1iZXIgb2Ygd3JpdHRlbiBieXRlc1xuXG5cdCAgdmFyIG51bWJlck9mV3JpdHRlbkJ5dGVzID0gIWlzQXJyYXkgPyBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ3V0ZjgnKSA6IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAnYXNjaWknKTsgLy8gRW5jb2RlIHRoZSBuYW1lXG5cblx0ICBpbmRleCA9IGluZGV4ICsgbnVtYmVyT2ZXcml0dGVuQnl0ZXM7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gMDsgLy8gRW5jb2RlIHRoZSBib29sZWFuIHZhbHVlXG5cblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSB2YWx1ZSA/IDEgOiAwO1xuXHQgIHJldHVybiBpbmRleDtcblx0fVxuXG5cdGZ1bmN0aW9uIHNlcmlhbGl6ZURhdGUoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgaXNBcnJheSkge1xuXHQgIC8vIFdyaXRlIHRoZSB0eXBlXG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gY29uc3RhbnRzLkJTT05fREFUQV9EQVRFOyAvLyBOdW1iZXIgb2Ygd3JpdHRlbiBieXRlc1xuXG5cdCAgdmFyIG51bWJlck9mV3JpdHRlbkJ5dGVzID0gIWlzQXJyYXkgPyBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ3V0ZjgnKSA6IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAnYXNjaWknKTsgLy8gRW5jb2RlIHRoZSBuYW1lXG5cblx0ICBpbmRleCA9IGluZGV4ICsgbnVtYmVyT2ZXcml0dGVuQnl0ZXM7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gMDsgLy8gV3JpdGUgdGhlIGRhdGVcblxuXHQgIHZhciBkYXRlSW5NaWxpcyA9IGxvbmdfMS5mcm9tTnVtYmVyKHZhbHVlLmdldFRpbWUoKSk7XG5cdCAgdmFyIGxvd0JpdHMgPSBkYXRlSW5NaWxpcy5nZXRMb3dCaXRzKCk7XG5cdCAgdmFyIGhpZ2hCaXRzID0gZGF0ZUluTWlsaXMuZ2V0SGlnaEJpdHMoKTsgLy8gRW5jb2RlIGxvdyBiaXRzXG5cblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBsb3dCaXRzICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBsb3dCaXRzID4+IDggJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGxvd0JpdHMgPj4gMTYgJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGxvd0JpdHMgPj4gMjQgJiAweGZmOyAvLyBFbmNvZGUgaGlnaCBiaXRzXG5cblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBoaWdoQml0cyAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gaGlnaEJpdHMgPj4gOCAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gaGlnaEJpdHMgPj4gMTYgJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGhpZ2hCaXRzID4+IDI0ICYgMHhmZjtcblx0ICByZXR1cm4gaW5kZXg7XG5cdH1cblxuXHRmdW5jdGlvbiBzZXJpYWxpemVSZWdFeHAoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgaXNBcnJheSkge1xuXHQgIC8vIFdyaXRlIHRoZSB0eXBlXG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gY29uc3RhbnRzLkJTT05fREFUQV9SRUdFWFA7IC8vIE51bWJlciBvZiB3cml0dGVuIGJ5dGVzXG5cblx0ICB2YXIgbnVtYmVyT2ZXcml0dGVuQnl0ZXMgPSAhaXNBcnJheSA/IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAndXRmOCcpIDogYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICdhc2NpaScpOyAvLyBFbmNvZGUgdGhlIG5hbWVcblxuXHQgIGluZGV4ID0gaW5kZXggKyBudW1iZXJPZldyaXR0ZW5CeXRlcztcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSAwO1xuXG5cdCAgaWYgKHZhbHVlLnNvdXJjZSAmJiB2YWx1ZS5zb3VyY2UubWF0Y2gocmVnZXhwJDEpICE9IG51bGwpIHtcblx0ICAgIHRocm93IEVycm9yKCd2YWx1ZSAnICsgdmFsdWUuc291cmNlICsgJyBtdXN0IG5vdCBjb250YWluIG51bGwgYnl0ZXMnKTtcblx0ICB9IC8vIEFkanVzdCB0aGUgaW5kZXhcblxuXG5cdCAgaW5kZXggPSBpbmRleCArIGJ1ZmZlciQkMS53cml0ZSh2YWx1ZS5zb3VyY2UsIGluZGV4LCAndXRmOCcpOyAvLyBXcml0ZSB6ZXJvXG5cblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSAweDAwOyAvLyBXcml0ZSB0aGUgcGFyYW1ldGVyc1xuXG5cdCAgaWYgKHZhbHVlLmlnbm9yZUNhc2UpIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDB4Njk7IC8vIGlcblxuXHQgIGlmICh2YWx1ZS5nbG9iYWwpIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDB4NzM7IC8vIHNcblxuXHQgIGlmICh2YWx1ZS5tdWx0aWxpbmUpIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDB4NmQ7IC8vIG1cblx0ICAvLyBBZGQgZW5kaW5nIHplcm9cblxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDB4MDA7XG5cdCAgcmV0dXJuIGluZGV4O1xuXHR9XG5cblx0ZnVuY3Rpb24gc2VyaWFsaXplQlNPTlJlZ0V4cChidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCBpc0FycmF5KSB7XG5cdCAgLy8gV3JpdGUgdGhlIHR5cGVcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBjb25zdGFudHMuQlNPTl9EQVRBX1JFR0VYUDsgLy8gTnVtYmVyIG9mIHdyaXR0ZW4gYnl0ZXNcblxuXHQgIHZhciBudW1iZXJPZldyaXR0ZW5CeXRlcyA9ICFpc0FycmF5ID8gYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICd1dGY4JykgOiBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ2FzY2lpJyk7IC8vIEVuY29kZSB0aGUgbmFtZVxuXG5cdCAgaW5kZXggPSBpbmRleCArIG51bWJlck9mV3JpdHRlbkJ5dGVzO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDA7IC8vIENoZWNrIHRoZSBwYXR0ZXJuIGZvciAwIGJ5dGVzXG5cblx0ICBpZiAodmFsdWUucGF0dGVybi5tYXRjaChyZWdleHAkMSkgIT0gbnVsbCkge1xuXHQgICAgLy8gVGhlIEJTT04gc3BlYyBkb2Vzbid0IGFsbG93IGtleXMgd2l0aCBudWxsIGJ5dGVzIGJlY2F1c2Uga2V5cyBhcmVcblx0ICAgIC8vIG51bGwtdGVybWluYXRlZC5cblx0ICAgIHRocm93IEVycm9yKCdwYXR0ZXJuICcgKyB2YWx1ZS5wYXR0ZXJuICsgJyBtdXN0IG5vdCBjb250YWluIG51bGwgYnl0ZXMnKTtcblx0ICB9IC8vIEFkanVzdCB0aGUgaW5kZXhcblxuXG5cdCAgaW5kZXggPSBpbmRleCArIGJ1ZmZlciQkMS53cml0ZSh2YWx1ZS5wYXR0ZXJuLCBpbmRleCwgJ3V0ZjgnKTsgLy8gV3JpdGUgemVyb1xuXG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gMHgwMDsgLy8gV3JpdGUgdGhlIG9wdGlvbnNcblxuXHQgIGluZGV4ID0gaW5kZXggKyBidWZmZXIkJDEud3JpdGUodmFsdWUub3B0aW9ucy5zcGxpdCgnJykuc29ydCgpLmpvaW4oJycpLCBpbmRleCwgJ3V0ZjgnKTsgLy8gQWRkIGVuZGluZyB6ZXJvXG5cblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSAweDAwO1xuXHQgIHJldHVybiBpbmRleDtcblx0fVxuXG5cdGZ1bmN0aW9uIHNlcmlhbGl6ZU1pbk1heChidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCBpc0FycmF5KSB7XG5cdCAgLy8gV3JpdGUgdGhlIHR5cGUgb2YgZWl0aGVyIG1pbiBvciBtYXgga2V5XG5cdCAgaWYgKHZhbHVlID09PSBudWxsKSB7XG5cdCAgICBidWZmZXIkJDFbaW5kZXgrK10gPSBjb25zdGFudHMuQlNPTl9EQVRBX05VTEw7XG5cdCAgfSBlbHNlIGlmICh2YWx1ZS5fYnNvbnR5cGUgPT09ICdNaW5LZXknKSB7XG5cdCAgICBidWZmZXIkJDFbaW5kZXgrK10gPSBjb25zdGFudHMuQlNPTl9EQVRBX01JTl9LRVk7XG5cdCAgfSBlbHNlIHtcblx0ICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGNvbnN0YW50cy5CU09OX0RBVEFfTUFYX0tFWTtcblx0ICB9IC8vIE51bWJlciBvZiB3cml0dGVuIGJ5dGVzXG5cblxuXHQgIHZhciBudW1iZXJPZldyaXR0ZW5CeXRlcyA9ICFpc0FycmF5ID8gYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICd1dGY4JykgOiBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ2FzY2lpJyk7IC8vIEVuY29kZSB0aGUgbmFtZVxuXG5cdCAgaW5kZXggPSBpbmRleCArIG51bWJlck9mV3JpdHRlbkJ5dGVzO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDA7XG5cdCAgcmV0dXJuIGluZGV4O1xuXHR9XG5cblx0ZnVuY3Rpb24gc2VyaWFsaXplT2JqZWN0SWQoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgaXNBcnJheSkge1xuXHQgIC8vIFdyaXRlIHRoZSB0eXBlXG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gY29uc3RhbnRzLkJTT05fREFUQV9PSUQ7IC8vIE51bWJlciBvZiB3cml0dGVuIGJ5dGVzXG5cblx0ICB2YXIgbnVtYmVyT2ZXcml0dGVuQnl0ZXMgPSAhaXNBcnJheSA/IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAndXRmOCcpIDogYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICdhc2NpaScpOyAvLyBFbmNvZGUgdGhlIG5hbWVcblxuXHQgIGluZGV4ID0gaW5kZXggKyBudW1iZXJPZldyaXR0ZW5CeXRlcztcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSAwOyAvLyBXcml0ZSB0aGUgb2JqZWN0SWQgaW50byB0aGUgc2hhcmVkIGJ1ZmZlclxuXG5cdCAgaWYgKHR5cGVvZiB2YWx1ZS5pZCA9PT0gJ3N0cmluZycpIHtcblx0ICAgIGJ1ZmZlciQkMS53cml0ZSh2YWx1ZS5pZCwgaW5kZXgsICdiaW5hcnknKTtcblx0ICB9IGVsc2UgaWYgKHZhbHVlLmlkICYmIHZhbHVlLmlkLmNvcHkpIHtcblx0ICAgIHZhbHVlLmlkLmNvcHkoYnVmZmVyJCQxLCBpbmRleCwgMCwgMTIpO1xuXHQgIH0gZWxzZSB7XG5cdCAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvYmplY3QgWycgKyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkgKyAnXSBpcyBub3QgYSB2YWxpZCBPYmplY3RJZCcpO1xuXHQgIH0gLy8gQWp1c3QgaW5kZXhcblxuXG5cdCAgcmV0dXJuIGluZGV4ICsgMTI7XG5cdH1cblxuXHRmdW5jdGlvbiBzZXJpYWxpemVCdWZmZXIoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgaXNBcnJheSkge1xuXHQgIC8vIFdyaXRlIHRoZSB0eXBlXG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gY29uc3RhbnRzLkJTT05fREFUQV9CSU5BUlk7IC8vIE51bWJlciBvZiB3cml0dGVuIGJ5dGVzXG5cblx0ICB2YXIgbnVtYmVyT2ZXcml0dGVuQnl0ZXMgPSAhaXNBcnJheSA/IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAndXRmOCcpIDogYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICdhc2NpaScpOyAvLyBFbmNvZGUgdGhlIG5hbWVcblxuXHQgIGluZGV4ID0gaW5kZXggKyBudW1iZXJPZldyaXR0ZW5CeXRlcztcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSAwOyAvLyBHZXQgc2l6ZSBvZiB0aGUgYnVmZmVyIChjdXJyZW50IHdyaXRlIHBvaW50KVxuXG5cdCAgdmFyIHNpemUgPSB2YWx1ZS5sZW5ndGg7IC8vIFdyaXRlIHRoZSBzaXplIG9mIHRoZSBzdHJpbmcgdG8gYnVmZmVyXG5cblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBzaXplICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBzaXplID4+IDggJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHNpemUgPj4gMTYgJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHNpemUgPj4gMjQgJiAweGZmOyAvLyBXcml0ZSB0aGUgZGVmYXVsdCBzdWJ0eXBlXG5cblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBjb25zdGFudHMuQlNPTl9CSU5BUllfU1VCVFlQRV9ERUZBVUxUOyAvLyBDb3B5IHRoZSBjb250ZW50IGZvcm0gdGhlIGJpbmFyeSBmaWVsZCB0byB0aGUgYnVmZmVyXG5cblx0ICB2YWx1ZS5jb3B5KGJ1ZmZlciQkMSwgaW5kZXgsIDAsIHNpemUpOyAvLyBBZGp1c3QgdGhlIGluZGV4XG5cblx0ICBpbmRleCA9IGluZGV4ICsgc2l6ZTtcblx0ICByZXR1cm4gaW5kZXg7XG5cdH1cblxuXHRmdW5jdGlvbiBzZXJpYWxpemVPYmplY3QoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgY2hlY2tLZXlzLCBkZXB0aCwgc2VyaWFsaXplRnVuY3Rpb25zLCBpZ25vcmVVbmRlZmluZWQsIGlzQXJyYXksIHBhdGgpIHtcblx0ICBmb3IgKHZhciBpID0gMDsgaSA8IHBhdGgubGVuZ3RoOyBpKyspIHtcblx0ICAgIGlmIChwYXRoW2ldID09PSB2YWx1ZSkgdGhyb3cgbmV3IEVycm9yKCdjeWNsaWMgZGVwZW5kZW5jeSBkZXRlY3RlZCcpO1xuXHQgIH0gLy8gUHVzaCB2YWx1ZSB0byBzdGFja1xuXG5cblx0ICBwYXRoLnB1c2godmFsdWUpOyAvLyBXcml0ZSB0aGUgdHlwZVxuXG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyBjb25zdGFudHMuQlNPTl9EQVRBX0FSUkFZIDogY29uc3RhbnRzLkJTT05fREFUQV9PQkpFQ1Q7IC8vIE51bWJlciBvZiB3cml0dGVuIGJ5dGVzXG5cblx0ICB2YXIgbnVtYmVyT2ZXcml0dGVuQnl0ZXMgPSAhaXNBcnJheSA/IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAndXRmOCcpIDogYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICdhc2NpaScpOyAvLyBFbmNvZGUgdGhlIG5hbWVcblxuXHQgIGluZGV4ID0gaW5kZXggKyBudW1iZXJPZldyaXR0ZW5CeXRlcztcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSAwO1xuXHQgIHZhciBlbmRJbmRleCA9IHNlcmlhbGl6ZUludG8oYnVmZmVyJCQxLCB2YWx1ZSwgY2hlY2tLZXlzLCBpbmRleCwgZGVwdGggKyAxLCBzZXJpYWxpemVGdW5jdGlvbnMsIGlnbm9yZVVuZGVmaW5lZCwgcGF0aCk7IC8vIFBvcCBzdGFja1xuXG5cdCAgcGF0aC5wb3AoKTtcblx0ICByZXR1cm4gZW5kSW5kZXg7XG5cdH1cblxuXHRmdW5jdGlvbiBzZXJpYWxpemVEZWNpbWFsMTI4KGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIGlzQXJyYXkpIHtcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBjb25zdGFudHMuQlNPTl9EQVRBX0RFQ0lNQUwxMjg7IC8vIE51bWJlciBvZiB3cml0dGVuIGJ5dGVzXG5cblx0ICB2YXIgbnVtYmVyT2ZXcml0dGVuQnl0ZXMgPSAhaXNBcnJheSA/IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAndXRmOCcpIDogYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICdhc2NpaScpOyAvLyBFbmNvZGUgdGhlIG5hbWVcblxuXHQgIGluZGV4ID0gaW5kZXggKyBudW1iZXJPZldyaXR0ZW5CeXRlcztcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSAwOyAvLyBXcml0ZSB0aGUgZGF0YSBmcm9tIHRoZSB2YWx1ZVxuXG5cdCAgdmFsdWUuYnl0ZXMuY29weShidWZmZXIkJDEsIGluZGV4LCAwLCAxNik7XG5cdCAgcmV0dXJuIGluZGV4ICsgMTY7XG5cdH1cblxuXHRmdW5jdGlvbiBzZXJpYWxpemVMb25nKGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIGlzQXJyYXkpIHtcblx0ICAvLyBXcml0ZSB0aGUgdHlwZVxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHZhbHVlLl9ic29udHlwZSA9PT0gJ0xvbmcnID8gY29uc3RhbnRzLkJTT05fREFUQV9MT05HIDogY29uc3RhbnRzLkJTT05fREFUQV9USU1FU1RBTVA7IC8vIE51bWJlciBvZiB3cml0dGVuIGJ5dGVzXG5cblx0ICB2YXIgbnVtYmVyT2ZXcml0dGVuQnl0ZXMgPSAhaXNBcnJheSA/IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAndXRmOCcpIDogYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICdhc2NpaScpOyAvLyBFbmNvZGUgdGhlIG5hbWVcblxuXHQgIGluZGV4ID0gaW5kZXggKyBudW1iZXJPZldyaXR0ZW5CeXRlcztcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSAwOyAvLyBXcml0ZSB0aGUgZGF0ZVxuXG5cdCAgdmFyIGxvd0JpdHMgPSB2YWx1ZS5nZXRMb3dCaXRzKCk7XG5cdCAgdmFyIGhpZ2hCaXRzID0gdmFsdWUuZ2V0SGlnaEJpdHMoKTsgLy8gRW5jb2RlIGxvdyBiaXRzXG5cblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBsb3dCaXRzICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBsb3dCaXRzID4+IDggJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGxvd0JpdHMgPj4gMTYgJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGxvd0JpdHMgPj4gMjQgJiAweGZmOyAvLyBFbmNvZGUgaGlnaCBiaXRzXG5cblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBoaWdoQml0cyAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gaGlnaEJpdHMgPj4gOCAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gaGlnaEJpdHMgPj4gMTYgJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGhpZ2hCaXRzID4+IDI0ICYgMHhmZjtcblx0ICByZXR1cm4gaW5kZXg7XG5cdH1cblxuXHRmdW5jdGlvbiBzZXJpYWxpemVJbnQzMihidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCBpc0FycmF5KSB7XG5cdCAgLy8gU2V0IGludCB0eXBlIDMyIGJpdHMgb3IgbGVzc1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGNvbnN0YW50cy5CU09OX0RBVEFfSU5UOyAvLyBOdW1iZXIgb2Ygd3JpdHRlbiBieXRlc1xuXG5cdCAgdmFyIG51bWJlck9mV3JpdHRlbkJ5dGVzID0gIWlzQXJyYXkgPyBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ3V0ZjgnKSA6IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAnYXNjaWknKTsgLy8gRW5jb2RlIHRoZSBuYW1lXG5cblx0ICBpbmRleCA9IGluZGV4ICsgbnVtYmVyT2ZXcml0dGVuQnl0ZXM7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gMDsgLy8gV3JpdGUgdGhlIGludCB2YWx1ZVxuXG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gdmFsdWUgJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHZhbHVlID4+IDggJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHZhbHVlID4+IDE2ICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSB2YWx1ZSA+PiAyNCAmIDB4ZmY7XG5cdCAgcmV0dXJuIGluZGV4O1xuXHR9XG5cblx0ZnVuY3Rpb24gc2VyaWFsaXplRG91YmxlKGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIGlzQXJyYXkpIHtcblx0ICAvLyBFbmNvZGUgYXMgZG91YmxlXG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gY29uc3RhbnRzLkJTT05fREFUQV9OVU1CRVI7IC8vIE51bWJlciBvZiB3cml0dGVuIGJ5dGVzXG5cblx0ICB2YXIgbnVtYmVyT2ZXcml0dGVuQnl0ZXMgPSAhaXNBcnJheSA/IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAndXRmOCcpIDogYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICdhc2NpaScpOyAvLyBFbmNvZGUgdGhlIG5hbWVcblxuXHQgIGluZGV4ID0gaW5kZXggKyBudW1iZXJPZldyaXR0ZW5CeXRlcztcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSAwOyAvLyBXcml0ZSBmbG9hdFxuXG5cdCAgd3JpdGVJRUVFNzU0JDEoYnVmZmVyJCQxLCB2YWx1ZS52YWx1ZSwgaW5kZXgsICdsaXR0bGUnLCA1MiwgOCk7IC8vIEFkanVzdCBpbmRleFxuXG5cdCAgaW5kZXggPSBpbmRleCArIDg7XG5cdCAgcmV0dXJuIGluZGV4O1xuXHR9XG5cblx0ZnVuY3Rpb24gc2VyaWFsaXplRnVuY3Rpb24oYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgY2hlY2tLZXlzLCBkZXB0aCwgaXNBcnJheSkge1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGNvbnN0YW50cy5CU09OX0RBVEFfQ09ERTsgLy8gTnVtYmVyIG9mIHdyaXR0ZW4gYnl0ZXNcblxuXHQgIHZhciBudW1iZXJPZldyaXR0ZW5CeXRlcyA9ICFpc0FycmF5ID8gYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICd1dGY4JykgOiBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ2FzY2lpJyk7IC8vIEVuY29kZSB0aGUgbmFtZVxuXG5cdCAgaW5kZXggPSBpbmRleCArIG51bWJlck9mV3JpdHRlbkJ5dGVzO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDA7IC8vIEZ1bmN0aW9uIHN0cmluZ1xuXG5cdCAgdmFyIGZ1bmN0aW9uU3RyaW5nID0gbm9ybWFsaXplZEZ1bmN0aW9uU3RyaW5nJDEodmFsdWUpOyAvLyBXcml0ZSB0aGUgc3RyaW5nXG5cblx0ICB2YXIgc2l6ZSA9IGJ1ZmZlciQkMS53cml0ZShmdW5jdGlvblN0cmluZywgaW5kZXggKyA0LCAndXRmOCcpICsgMTsgLy8gV3JpdGUgdGhlIHNpemUgb2YgdGhlIHN0cmluZyB0byBidWZmZXJcblxuXHQgIGJ1ZmZlciQkMVtpbmRleF0gPSBzaXplICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXggKyAxXSA9IHNpemUgPj4gOCAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4ICsgMl0gPSBzaXplID4+IDE2ICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXggKyAzXSA9IHNpemUgPj4gMjQgJiAweGZmOyAvLyBVcGRhdGUgaW5kZXhcblxuXHQgIGluZGV4ID0gaW5kZXggKyA0ICsgc2l6ZSAtIDE7IC8vIFdyaXRlIHplcm9cblxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDA7XG5cdCAgcmV0dXJuIGluZGV4O1xuXHR9XG5cblx0ZnVuY3Rpb24gc2VyaWFsaXplQ29kZShidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCBjaGVja0tleXMsIGRlcHRoLCBzZXJpYWxpemVGdW5jdGlvbnMsIGlnbm9yZVVuZGVmaW5lZCwgaXNBcnJheSkge1xuXHQgIGlmICh2YWx1ZS5zY29wZSAmJiBfdHlwZW9mJDModmFsdWUuc2NvcGUpID09PSAnb2JqZWN0Jykge1xuXHQgICAgLy8gV3JpdGUgdGhlIHR5cGVcblx0ICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGNvbnN0YW50cy5CU09OX0RBVEFfQ09ERV9XX1NDT1BFOyAvLyBOdW1iZXIgb2Ygd3JpdHRlbiBieXRlc1xuXG5cdCAgICB2YXIgbnVtYmVyT2ZXcml0dGVuQnl0ZXMgPSAhaXNBcnJheSA/IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAndXRmOCcpIDogYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICdhc2NpaScpOyAvLyBFbmNvZGUgdGhlIG5hbWVcblxuXHQgICAgaW5kZXggPSBpbmRleCArIG51bWJlck9mV3JpdHRlbkJ5dGVzO1xuXHQgICAgYnVmZmVyJCQxW2luZGV4KytdID0gMDsgLy8gU3RhcnRpbmcgaW5kZXhcblxuXHQgICAgdmFyIHN0YXJ0SW5kZXggPSBpbmRleDsgLy8gU2VyaWFsaXplIHRoZSBmdW5jdGlvblxuXHQgICAgLy8gR2V0IHRoZSBmdW5jdGlvbiBzdHJpbmdcblxuXHQgICAgdmFyIGZ1bmN0aW9uU3RyaW5nID0gdHlwZW9mIHZhbHVlLmNvZGUgPT09ICdzdHJpbmcnID8gdmFsdWUuY29kZSA6IHZhbHVlLmNvZGUudG9TdHJpbmcoKTsgLy8gSW5kZXggYWRqdXN0bWVudFxuXG5cdCAgICBpbmRleCA9IGluZGV4ICsgNDsgLy8gV3JpdGUgc3RyaW5nIGludG8gYnVmZmVyXG5cblx0ICAgIHZhciBjb2RlU2l6ZSA9IGJ1ZmZlciQkMS53cml0ZShmdW5jdGlvblN0cmluZywgaW5kZXggKyA0LCAndXRmOCcpICsgMTsgLy8gV3JpdGUgdGhlIHNpemUgb2YgdGhlIHN0cmluZyB0byBidWZmZXJcblxuXHQgICAgYnVmZmVyJCQxW2luZGV4XSA9IGNvZGVTaXplICYgMHhmZjtcblx0ICAgIGJ1ZmZlciQkMVtpbmRleCArIDFdID0gY29kZVNpemUgPj4gOCAmIDB4ZmY7XG5cdCAgICBidWZmZXIkJDFbaW5kZXggKyAyXSA9IGNvZGVTaXplID4+IDE2ICYgMHhmZjtcblx0ICAgIGJ1ZmZlciQkMVtpbmRleCArIDNdID0gY29kZVNpemUgPj4gMjQgJiAweGZmOyAvLyBXcml0ZSBlbmQgMFxuXG5cdCAgICBidWZmZXIkJDFbaW5kZXggKyA0ICsgY29kZVNpemUgLSAxXSA9IDA7IC8vIFdyaXRlIHRoZVxuXG5cdCAgICBpbmRleCA9IGluZGV4ICsgY29kZVNpemUgKyA0OyAvL1xuXHQgICAgLy8gU2VyaWFsaXplIHRoZSBzY29wZSB2YWx1ZVxuXG5cdCAgICB2YXIgZW5kSW5kZXggPSBzZXJpYWxpemVJbnRvKGJ1ZmZlciQkMSwgdmFsdWUuc2NvcGUsIGNoZWNrS2V5cywgaW5kZXgsIGRlcHRoICsgMSwgc2VyaWFsaXplRnVuY3Rpb25zLCBpZ25vcmVVbmRlZmluZWQpO1xuXHQgICAgaW5kZXggPSBlbmRJbmRleCAtIDE7IC8vIFdyaXQgdGhlIHRvdGFsXG5cblx0ICAgIHZhciB0b3RhbFNpemUgPSBlbmRJbmRleCAtIHN0YXJ0SW5kZXg7IC8vIFdyaXRlIHRoZSB0b3RhbCBzaXplIG9mIHRoZSBvYmplY3RcblxuXHQgICAgYnVmZmVyJCQxW3N0YXJ0SW5kZXgrK10gPSB0b3RhbFNpemUgJiAweGZmO1xuXHQgICAgYnVmZmVyJCQxW3N0YXJ0SW5kZXgrK10gPSB0b3RhbFNpemUgPj4gOCAmIDB4ZmY7XG5cdCAgICBidWZmZXIkJDFbc3RhcnRJbmRleCsrXSA9IHRvdGFsU2l6ZSA+PiAxNiAmIDB4ZmY7XG5cdCAgICBidWZmZXIkJDFbc3RhcnRJbmRleCsrXSA9IHRvdGFsU2l6ZSA+PiAyNCAmIDB4ZmY7IC8vIFdyaXRlIHRyYWlsaW5nIHplcm9cblxuXHQgICAgYnVmZmVyJCQxW2luZGV4KytdID0gMDtcblx0ICB9IGVsc2Uge1xuXHQgICAgYnVmZmVyJCQxW2luZGV4KytdID0gY29uc3RhbnRzLkJTT05fREFUQV9DT0RFOyAvLyBOdW1iZXIgb2Ygd3JpdHRlbiBieXRlc1xuXG5cdCAgICB2YXIgX251bWJlck9mV3JpdHRlbkJ5dGVzNCA9ICFpc0FycmF5ID8gYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICd1dGY4JykgOiBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ2FzY2lpJyk7IC8vIEVuY29kZSB0aGUgbmFtZVxuXG5cblx0ICAgIGluZGV4ID0gaW5kZXggKyBfbnVtYmVyT2ZXcml0dGVuQnl0ZXM0O1xuXHQgICAgYnVmZmVyJCQxW2luZGV4KytdID0gMDsgLy8gRnVuY3Rpb24gc3RyaW5nXG5cblx0ICAgIHZhciBfZnVuY3Rpb25TdHJpbmcgPSB2YWx1ZS5jb2RlLnRvU3RyaW5nKCk7IC8vIFdyaXRlIHRoZSBzdHJpbmdcblxuXG5cdCAgICB2YXIgc2l6ZSA9IGJ1ZmZlciQkMS53cml0ZShfZnVuY3Rpb25TdHJpbmcsIGluZGV4ICsgNCwgJ3V0ZjgnKSArIDE7IC8vIFdyaXRlIHRoZSBzaXplIG9mIHRoZSBzdHJpbmcgdG8gYnVmZmVyXG5cblx0ICAgIGJ1ZmZlciQkMVtpbmRleF0gPSBzaXplICYgMHhmZjtcblx0ICAgIGJ1ZmZlciQkMVtpbmRleCArIDFdID0gc2l6ZSA+PiA4ICYgMHhmZjtcblx0ICAgIGJ1ZmZlciQkMVtpbmRleCArIDJdID0gc2l6ZSA+PiAxNiAmIDB4ZmY7XG5cdCAgICBidWZmZXIkJDFbaW5kZXggKyAzXSA9IHNpemUgPj4gMjQgJiAweGZmOyAvLyBVcGRhdGUgaW5kZXhcblxuXHQgICAgaW5kZXggPSBpbmRleCArIDQgKyBzaXplIC0gMTsgLy8gV3JpdGUgemVyb1xuXG5cdCAgICBidWZmZXIkJDFbaW5kZXgrK10gPSAwO1xuXHQgIH1cblxuXHQgIHJldHVybiBpbmRleDtcblx0fVxuXG5cdGZ1bmN0aW9uIHNlcmlhbGl6ZUJpbmFyeShidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCBpc0FycmF5KSB7XG5cdCAgLy8gV3JpdGUgdGhlIHR5cGVcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBjb25zdGFudHMuQlNPTl9EQVRBX0JJTkFSWTsgLy8gTnVtYmVyIG9mIHdyaXR0ZW4gYnl0ZXNcblxuXHQgIHZhciBudW1iZXJPZldyaXR0ZW5CeXRlcyA9ICFpc0FycmF5ID8gYnVmZmVyJCQxLndyaXRlKGtleSwgaW5kZXgsICd1dGY4JykgOiBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ2FzY2lpJyk7IC8vIEVuY29kZSB0aGUgbmFtZVxuXG5cdCAgaW5kZXggPSBpbmRleCArIG51bWJlck9mV3JpdHRlbkJ5dGVzO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IDA7IC8vIEV4dHJhY3QgdGhlIGJ1ZmZlclxuXG5cdCAgdmFyIGRhdGEgPSB2YWx1ZS52YWx1ZSh0cnVlKTsgLy8gQ2FsY3VsYXRlIHNpemVcblxuXHQgIHZhciBzaXplID0gdmFsdWUucG9zaXRpb247IC8vIEFkZCB0aGUgZGVwcmVjYXRlZCAwMiB0eXBlIDQgYnl0ZXMgb2Ygc2l6ZSB0byB0b3RhbFxuXG5cdCAgaWYgKHZhbHVlLnN1Yl90eXBlID09PSBiaW5hcnkuU1VCVFlQRV9CWVRFX0FSUkFZKSBzaXplID0gc2l6ZSArIDQ7IC8vIFdyaXRlIHRoZSBzaXplIG9mIHRoZSBzdHJpbmcgdG8gYnVmZmVyXG5cblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBzaXplICYgMHhmZjtcblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSBzaXplID4+IDggJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHNpemUgPj4gMTYgJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHNpemUgPj4gMjQgJiAweGZmOyAvLyBXcml0ZSB0aGUgc3VidHlwZSB0byB0aGUgYnVmZmVyXG5cblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSB2YWx1ZS5zdWJfdHlwZTsgLy8gSWYgd2UgaGF2ZSBiaW5hcnkgdHlwZSAyIHRoZSA0IGZpcnN0IGJ5dGVzIGFyZSB0aGUgc2l6ZVxuXG5cdCAgaWYgKHZhbHVlLnN1Yl90eXBlID09PSBiaW5hcnkuU1VCVFlQRV9CWVRFX0FSUkFZKSB7XG5cdCAgICBzaXplID0gc2l6ZSAtIDQ7XG5cdCAgICBidWZmZXIkJDFbaW5kZXgrK10gPSBzaXplICYgMHhmZjtcblx0ICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHNpemUgPj4gOCAmIDB4ZmY7XG5cdCAgICBidWZmZXIkJDFbaW5kZXgrK10gPSBzaXplID4+IDE2ICYgMHhmZjtcblx0ICAgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IHNpemUgPj4gMjQgJiAweGZmO1xuXHQgIH0gLy8gV3JpdGUgdGhlIGRhdGEgdG8gdGhlIG9iamVjdFxuXG5cblx0ICBkYXRhLmNvcHkoYnVmZmVyJCQxLCBpbmRleCwgMCwgdmFsdWUucG9zaXRpb24pOyAvLyBBZGp1c3QgdGhlIGluZGV4XG5cblx0ICBpbmRleCA9IGluZGV4ICsgdmFsdWUucG9zaXRpb247XG5cdCAgcmV0dXJuIGluZGV4O1xuXHR9XG5cblx0ZnVuY3Rpb24gc2VyaWFsaXplU3ltYm9sKGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIGlzQXJyYXkpIHtcblx0ICAvLyBXcml0ZSB0aGUgdHlwZVxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGNvbnN0YW50cy5CU09OX0RBVEFfU1lNQk9MOyAvLyBOdW1iZXIgb2Ygd3JpdHRlbiBieXRlc1xuXG5cdCAgdmFyIG51bWJlck9mV3JpdHRlbkJ5dGVzID0gIWlzQXJyYXkgPyBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ3V0ZjgnKSA6IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAnYXNjaWknKTsgLy8gRW5jb2RlIHRoZSBuYW1lXG5cblx0ICBpbmRleCA9IGluZGV4ICsgbnVtYmVyT2ZXcml0dGVuQnl0ZXM7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gMDsgLy8gV3JpdGUgdGhlIHN0cmluZ1xuXG5cdCAgdmFyIHNpemUgPSBidWZmZXIkJDEud3JpdGUodmFsdWUudmFsdWUsIGluZGV4ICsgNCwgJ3V0ZjgnKSArIDE7IC8vIFdyaXRlIHRoZSBzaXplIG9mIHRoZSBzdHJpbmcgdG8gYnVmZmVyXG5cblx0ICBidWZmZXIkJDFbaW5kZXhdID0gc2l6ZSAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4ICsgMV0gPSBzaXplID4+IDggJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtpbmRleCArIDJdID0gc2l6ZSA+PiAxNiAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW2luZGV4ICsgM10gPSBzaXplID4+IDI0ICYgMHhmZjsgLy8gVXBkYXRlIGluZGV4XG5cblx0ICBpbmRleCA9IGluZGV4ICsgNCArIHNpemUgLSAxOyAvLyBXcml0ZSB6ZXJvXG5cblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSAweDAwO1xuXHQgIHJldHVybiBpbmRleDtcblx0fVxuXG5cdGZ1bmN0aW9uIHNlcmlhbGl6ZURCUmVmKGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIGRlcHRoLCBzZXJpYWxpemVGdW5jdGlvbnMsIGlzQXJyYXkpIHtcblx0ICAvLyBXcml0ZSB0aGUgdHlwZVxuXHQgIGJ1ZmZlciQkMVtpbmRleCsrXSA9IGNvbnN0YW50cy5CU09OX0RBVEFfT0JKRUNUOyAvLyBOdW1iZXIgb2Ygd3JpdHRlbiBieXRlc1xuXG5cdCAgdmFyIG51bWJlck9mV3JpdHRlbkJ5dGVzID0gIWlzQXJyYXkgPyBidWZmZXIkJDEud3JpdGUoa2V5LCBpbmRleCwgJ3V0ZjgnKSA6IGJ1ZmZlciQkMS53cml0ZShrZXksIGluZGV4LCAnYXNjaWknKTsgLy8gRW5jb2RlIHRoZSBuYW1lXG5cblx0ICBpbmRleCA9IGluZGV4ICsgbnVtYmVyT2ZXcml0dGVuQnl0ZXM7XG5cdCAgYnVmZmVyJCQxW2luZGV4KytdID0gMDtcblx0ICB2YXIgc3RhcnRJbmRleCA9IGluZGV4O1xuXHQgIHZhciBlbmRJbmRleDtcblx0ICB2YXIgb3V0cHV0ID0ge1xuXHQgICAgJHJlZjogdmFsdWUuY29sbGVjdGlvbiB8fCB2YWx1ZS5uYW1lc3BhY2UsXG5cdCAgICAvLyBcIm5hbWVzcGFjZVwiIHdhcyB3aGF0IGxpYnJhcnkgMS54IGNhbGxlZCBcImNvbGxlY3Rpb25cIlxuXHQgICAgJGlkOiB2YWx1ZS5vaWRcblx0ICB9O1xuXHQgIGlmICh2YWx1ZS5kYiAhPSBudWxsKSBvdXRwdXQuJGRiID0gdmFsdWUuZGI7XG5cdCAgb3V0cHV0ID0gT2JqZWN0LmFzc2lnbihvdXRwdXQsIHZhbHVlLmZpZWxkcyk7XG5cdCAgZW5kSW5kZXggPSBzZXJpYWxpemVJbnRvKGJ1ZmZlciQkMSwgb3V0cHV0LCBmYWxzZSwgaW5kZXgsIGRlcHRoICsgMSwgc2VyaWFsaXplRnVuY3Rpb25zKTsgLy8gQ2FsY3VsYXRlIG9iamVjdCBzaXplXG5cblx0ICB2YXIgc2l6ZSA9IGVuZEluZGV4IC0gc3RhcnRJbmRleDsgLy8gV3JpdGUgdGhlIHNpemVcblxuXHQgIGJ1ZmZlciQkMVtzdGFydEluZGV4KytdID0gc2l6ZSAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW3N0YXJ0SW5kZXgrK10gPSBzaXplID4+IDggJiAweGZmO1xuXHQgIGJ1ZmZlciQkMVtzdGFydEluZGV4KytdID0gc2l6ZSA+PiAxNiAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW3N0YXJ0SW5kZXgrK10gPSBzaXplID4+IDI0ICYgMHhmZjsgLy8gU2V0IGluZGV4XG5cblx0ICByZXR1cm4gZW5kSW5kZXg7XG5cdH1cblxuXHRmdW5jdGlvbiBzZXJpYWxpemVJbnRvKGJ1ZmZlciQkMSwgb2JqZWN0LCBjaGVja0tleXMsIHN0YXJ0aW5nSW5kZXgsIGRlcHRoLCBzZXJpYWxpemVGdW5jdGlvbnMsIGlnbm9yZVVuZGVmaW5lZCwgcGF0aCkge1xuXHQgIHN0YXJ0aW5nSW5kZXggPSBzdGFydGluZ0luZGV4IHx8IDA7XG5cdCAgcGF0aCA9IHBhdGggfHwgW107IC8vIFB1c2ggdGhlIG9iamVjdCB0byB0aGUgcGF0aFxuXG5cdCAgcGF0aC5wdXNoKG9iamVjdCk7IC8vIFN0YXJ0IHBsYWNlIHRvIHNlcmlhbGl6ZSBpbnRvXG5cblx0ICB2YXIgaW5kZXggPSBzdGFydGluZ0luZGV4ICsgNDsgLy8gU3BlY2lhbCBjYXNlIGlzQXJyYXlcblxuXHQgIGlmIChBcnJheS5pc0FycmF5KG9iamVjdCkpIHtcblx0ICAgIC8vIEdldCBvYmplY3Qga2V5c1xuXHQgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QubGVuZ3RoOyBpKyspIHtcblx0ICAgICAgdmFyIGtleSA9ICcnICsgaTtcblx0ICAgICAgdmFyIHZhbHVlID0gb2JqZWN0W2ldOyAvLyBJcyB0aGVyZSBhbiBvdmVycmlkZSB2YWx1ZVxuXG5cdCAgICAgIGlmICh2YWx1ZSAmJiB2YWx1ZS50b0JTT04pIHtcblx0ICAgICAgICBpZiAodHlwZW9mIHZhbHVlLnRvQlNPTiAhPT0gJ2Z1bmN0aW9uJykgdGhyb3cgbmV3IFR5cGVFcnJvcigndG9CU09OIGlzIG5vdCBhIGZ1bmN0aW9uJyk7XG5cdCAgICAgICAgdmFsdWUgPSB2YWx1ZS50b0JTT04oKTtcblx0ICAgICAgfVxuXG5cdCAgICAgIHZhciB0eXBlID0gX3R5cGVvZiQzKHZhbHVlKTtcblxuXHQgICAgICBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZVN0cmluZyhidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCB0cnVlKTtcblx0ICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplTnVtYmVyKGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIHRydWUpO1xuXHQgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdib29sZWFuJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplQm9vbGVhbihidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCB0cnVlKTtcblx0ICAgICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUgfHwgaXNEYXRlJDEodmFsdWUpKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVEYXRlKGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIHRydWUpO1xuXHQgICAgICB9IGVsc2UgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZU51bGwoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgdHJ1ZSk7XG5cdCAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT09IG51bGwpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZU51bGwoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgdHJ1ZSk7XG5cdCAgICAgIH0gZWxzZSBpZiAodmFsdWVbJ19ic29udHlwZSddID09PSAnT2JqZWN0SWQnIHx8IHZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ09iamVjdElEJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplT2JqZWN0SWQoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgdHJ1ZSk7XG5cdCAgICAgIH0gZWxzZSBpZiAoQnVmZmVyJDUuaXNCdWZmZXIodmFsdWUpKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVCdWZmZXIoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgdHJ1ZSk7XG5cdCAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBSZWdFeHAgfHwgaXNSZWdFeHAkMSh2YWx1ZSkpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZVJlZ0V4cChidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCB0cnVlKTtcblx0ICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnb2JqZWN0JyAmJiB2YWx1ZVsnX2Jzb250eXBlJ10gPT0gbnVsbCkge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplT2JqZWN0KGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIGNoZWNrS2V5cywgZGVwdGgsIHNlcmlhbGl6ZUZ1bmN0aW9ucywgaWdub3JlVW5kZWZpbmVkLCB0cnVlLCBwYXRoKTtcblx0ICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnb2JqZWN0JyAmJiB2YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdEZWNpbWFsMTI4Jykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplRGVjaW1hbDEyOChidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCB0cnVlKTtcblx0ICAgICAgfSBlbHNlIGlmICh2YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdMb25nJyB8fCB2YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdUaW1lc3RhbXAnKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVMb25nKGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIHRydWUpO1xuXHQgICAgICB9IGVsc2UgaWYgKHZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ0RvdWJsZScpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZURvdWJsZShidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCB0cnVlKTtcblx0ICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgJiYgc2VyaWFsaXplRnVuY3Rpb25zKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVGdW5jdGlvbihidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCBjaGVja0tleXMsIGRlcHRoLCBzZXJpYWxpemVGdW5jdGlvbnMsIHRydWUpO1xuXHQgICAgICB9IGVsc2UgaWYgKHZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ0NvZGUnKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVDb2RlKGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIGNoZWNrS2V5cywgZGVwdGgsIHNlcmlhbGl6ZUZ1bmN0aW9ucywgaWdub3JlVW5kZWZpbmVkLCB0cnVlKTtcblx0ICAgICAgfSBlbHNlIGlmICh2YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdCaW5hcnknKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVCaW5hcnkoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgdHJ1ZSk7XG5cdCAgICAgIH0gZWxzZSBpZiAodmFsdWVbJ19ic29udHlwZSddID09PSAnU3ltYm9sJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplU3ltYm9sKGJ1ZmZlciQkMSwga2V5LCB2YWx1ZSwgaW5kZXgsIHRydWUpO1xuXHQgICAgICB9IGVsc2UgaWYgKHZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ0RCUmVmJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplREJSZWYoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgZGVwdGgsIHNlcmlhbGl6ZUZ1bmN0aW9ucywgdHJ1ZSk7XG5cdCAgICAgIH0gZWxzZSBpZiAodmFsdWVbJ19ic29udHlwZSddID09PSAnQlNPTlJlZ0V4cCcpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZUJTT05SZWdFeHAoYnVmZmVyJCQxLCBrZXksIHZhbHVlLCBpbmRleCwgdHJ1ZSk7XG5cdCAgICAgIH0gZWxzZSBpZiAodmFsdWVbJ19ic29udHlwZSddID09PSAnSW50MzInKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVJbnQzMihidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCB0cnVlKTtcblx0ICAgICAgfSBlbHNlIGlmICh2YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdNaW5LZXknIHx8IHZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ01heEtleScpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZU1pbk1heChidWZmZXIkJDEsIGtleSwgdmFsdWUsIGluZGV4LCB0cnVlKTtcblx0ICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWVbJ19ic29udHlwZSddICE9PSAndW5kZWZpbmVkJykge1xuXHQgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1VucmVjb2duaXplZCBvciBpbnZhbGlkIF9ic29udHlwZTogJyArIHZhbHVlWydfYnNvbnR5cGUnXSk7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9IGVsc2UgaWYgKG9iamVjdCBpbnN0YW5jZW9mIG1hcCkge1xuXHQgICAgdmFyIGl0ZXJhdG9yID0gb2JqZWN0LmVudHJpZXMoKTtcblx0ICAgIHZhciBkb25lID0gZmFsc2U7XG5cblx0ICAgIHdoaWxlICghZG9uZSkge1xuXHQgICAgICAvLyBVbnBhY2sgdGhlIG5leHQgZW50cnlcblx0ICAgICAgdmFyIGVudHJ5ID0gaXRlcmF0b3IubmV4dCgpO1xuXHQgICAgICBkb25lID0gZW50cnkuZG9uZTsgLy8gQXJlIHdlIGRvbmUsIHRoZW4gc2tpcCBhbmQgdGVybWluYXRlXG5cblx0ICAgICAgaWYgKGRvbmUpIGNvbnRpbnVlOyAvLyBHZXQgdGhlIGVudHJ5IHZhbHVlc1xuXG5cdCAgICAgIHZhciBfa2V5ID0gZW50cnkudmFsdWVbMF07XG5cdCAgICAgIHZhciBfdmFsdWUgPSBlbnRyeS52YWx1ZVsxXTsgLy8gQ2hlY2sgdGhlIHR5cGUgb2YgdGhlIHZhbHVlXG5cblx0ICAgICAgdmFyIF90eXBlID0gX3R5cGVvZiQzKF92YWx1ZSk7IC8vIENoZWNrIHRoZSBrZXkgYW5kIHRocm93IGVycm9yIGlmIGl0J3MgaWxsZWdhbFxuXG5cblx0ICAgICAgaWYgKHR5cGVvZiBfa2V5ID09PSAnc3RyaW5nJyAmJiAhaWdub3JlS2V5cy5oYXMoX2tleSkpIHtcblx0ICAgICAgICBpZiAoX2tleS5tYXRjaChyZWdleHAkMSkgIT0gbnVsbCkge1xuXHQgICAgICAgICAgLy8gVGhlIEJTT04gc3BlYyBkb2Vzbid0IGFsbG93IGtleXMgd2l0aCBudWxsIGJ5dGVzIGJlY2F1c2Uga2V5cyBhcmVcblx0ICAgICAgICAgIC8vIG51bGwtdGVybWluYXRlZC5cblx0ICAgICAgICAgIHRocm93IEVycm9yKCdrZXkgJyArIF9rZXkgKyAnIG11c3Qgbm90IGNvbnRhaW4gbnVsbCBieXRlcycpO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmIChjaGVja0tleXMpIHtcblx0ICAgICAgICAgIGlmICgnJCcgPT09IF9rZXlbMF0pIHtcblx0ICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ2tleSAnICsgX2tleSArIFwiIG11c3Qgbm90IHN0YXJ0IHdpdGggJyQnXCIpO1xuXHQgICAgICAgICAgfSBlbHNlIGlmICh+X2tleS5pbmRleE9mKCcuJykpIHtcblx0ICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ2tleSAnICsgX2tleSArIFwiIG11c3Qgbm90IGNvbnRhaW4gJy4nXCIpO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgfVxuXG5cdCAgICAgIGlmIChfdHlwZSA9PT0gJ3N0cmluZycpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZVN0cmluZyhidWZmZXIkJDEsIF9rZXksIF92YWx1ZSwgaW5kZXgpO1xuXHQgICAgICB9IGVsc2UgaWYgKF90eXBlID09PSAnbnVtYmVyJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplTnVtYmVyKGJ1ZmZlciQkMSwgX2tleSwgX3ZhbHVlLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3R5cGUgPT09ICdib29sZWFuJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplQm9vbGVhbihidWZmZXIkJDEsIF9rZXksIF92YWx1ZSwgaW5kZXgpO1xuXHQgICAgICB9IGVsc2UgaWYgKF92YWx1ZSBpbnN0YW5jZW9mIERhdGUgfHwgaXNEYXRlJDEoX3ZhbHVlKSkge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplRGF0ZShidWZmZXIkJDEsIF9rZXksIF92YWx1ZSwgaW5kZXgpO1xuXHQgICAgICB9IGVsc2UgaWYgKF92YWx1ZSA9PT0gbnVsbCB8fCBfdmFsdWUgPT09IHVuZGVmaW5lZCAmJiBpZ25vcmVVbmRlZmluZWQgPT09IGZhbHNlKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVOdWxsKGJ1ZmZlciQkMSwgX2tleSwgX3ZhbHVlLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3ZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ09iamVjdElkJyB8fCBfdmFsdWVbJ19ic29udHlwZSddID09PSAnT2JqZWN0SUQnKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVPYmplY3RJZChidWZmZXIkJDEsIF9rZXksIF92YWx1ZSwgaW5kZXgpO1xuXHQgICAgICB9IGVsc2UgaWYgKEJ1ZmZlciQ1LmlzQnVmZmVyKF92YWx1ZSkpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZUJ1ZmZlcihidWZmZXIkJDEsIF9rZXksIF92YWx1ZSwgaW5kZXgpO1xuXHQgICAgICB9IGVsc2UgaWYgKF92YWx1ZSBpbnN0YW5jZW9mIFJlZ0V4cCB8fCBpc1JlZ0V4cCQxKF92YWx1ZSkpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZVJlZ0V4cChidWZmZXIkJDEsIF9rZXksIF92YWx1ZSwgaW5kZXgpO1xuXHQgICAgICB9IGVsc2UgaWYgKF90eXBlID09PSAnb2JqZWN0JyAmJiBfdmFsdWVbJ19ic29udHlwZSddID09IG51bGwpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZU9iamVjdChidWZmZXIkJDEsIF9rZXksIF92YWx1ZSwgaW5kZXgsIGNoZWNrS2V5cywgZGVwdGgsIHNlcmlhbGl6ZUZ1bmN0aW9ucywgaWdub3JlVW5kZWZpbmVkLCBmYWxzZSwgcGF0aCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3R5cGUgPT09ICdvYmplY3QnICYmIF92YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdEZWNpbWFsMTI4Jykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplRGVjaW1hbDEyOChidWZmZXIkJDEsIF9rZXksIF92YWx1ZSwgaW5kZXgpO1xuXHQgICAgICB9IGVsc2UgaWYgKF92YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdMb25nJyB8fCBfdmFsdWVbJ19ic29udHlwZSddID09PSAnVGltZXN0YW1wJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplTG9uZyhidWZmZXIkJDEsIF9rZXksIF92YWx1ZSwgaW5kZXgpO1xuXHQgICAgICB9IGVsc2UgaWYgKF92YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdEb3VibGUnKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVEb3VibGUoYnVmZmVyJCQxLCBfa2V5LCBfdmFsdWUsIGluZGV4KTtcblx0ICAgICAgfSBlbHNlIGlmIChfdmFsdWVbJ19ic29udHlwZSddID09PSAnQ29kZScpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZUNvZGUoYnVmZmVyJCQxLCBfa2V5LCBfdmFsdWUsIGluZGV4LCBjaGVja0tleXMsIGRlcHRoLCBzZXJpYWxpemVGdW5jdGlvbnMsIGlnbm9yZVVuZGVmaW5lZCk7XG5cdCAgICAgIH0gZWxzZSBpZiAodHlwZW9mIF92YWx1ZSA9PT0gJ2Z1bmN0aW9uJyAmJiBzZXJpYWxpemVGdW5jdGlvbnMpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZUZ1bmN0aW9uKGJ1ZmZlciQkMSwgX2tleSwgX3ZhbHVlLCBpbmRleCwgY2hlY2tLZXlzLCBkZXB0aCwgc2VyaWFsaXplRnVuY3Rpb25zKTtcblx0ICAgICAgfSBlbHNlIGlmIChfdmFsdWVbJ19ic29udHlwZSddID09PSAnQmluYXJ5Jykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplQmluYXJ5KGJ1ZmZlciQkMSwgX2tleSwgX3ZhbHVlLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3ZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ1N5bWJvbCcpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZVN5bWJvbChidWZmZXIkJDEsIF9rZXksIF92YWx1ZSwgaW5kZXgpO1xuXHQgICAgICB9IGVsc2UgaWYgKF92YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdEQlJlZicpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZURCUmVmKGJ1ZmZlciQkMSwgX2tleSwgX3ZhbHVlLCBpbmRleCwgZGVwdGgsIHNlcmlhbGl6ZUZ1bmN0aW9ucyk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3ZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ0JTT05SZWdFeHAnKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVCU09OUmVnRXhwKGJ1ZmZlciQkMSwgX2tleSwgX3ZhbHVlLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3ZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ0ludDMyJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplSW50MzIoYnVmZmVyJCQxLCBfa2V5LCBfdmFsdWUsIGluZGV4KTtcblx0ICAgICAgfSBlbHNlIGlmIChfdmFsdWVbJ19ic29udHlwZSddID09PSAnTWluS2V5JyB8fCBfdmFsdWVbJ19ic29udHlwZSddID09PSAnTWF4S2V5Jykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplTWluTWF4KGJ1ZmZlciQkMSwgX2tleSwgX3ZhbHVlLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAodHlwZW9mIF92YWx1ZVsnX2Jzb250eXBlJ10gIT09ICd1bmRlZmluZWQnKSB7XG5cdCAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5yZWNvZ25pemVkIG9yIGludmFsaWQgX2Jzb250eXBlOiAnICsgX3ZhbHVlWydfYnNvbnR5cGUnXSk7XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9IGVsc2Uge1xuXHQgICAgLy8gRGlkIHdlIHByb3ZpZGUgYSBjdXN0b20gc2VyaWFsaXphdGlvbiBtZXRob2Rcblx0ICAgIGlmIChvYmplY3QudG9CU09OKSB7XG5cdCAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnRvQlNPTiAhPT0gJ2Z1bmN0aW9uJykgdGhyb3cgbmV3IFR5cGVFcnJvcigndG9CU09OIGlzIG5vdCBhIGZ1bmN0aW9uJyk7XG5cdCAgICAgIG9iamVjdCA9IG9iamVjdC50b0JTT04oKTtcblx0ICAgICAgaWYgKG9iamVjdCAhPSBudWxsICYmIF90eXBlb2YkMyhvYmplY3QpICE9PSAnb2JqZWN0JykgdGhyb3cgbmV3IFR5cGVFcnJvcigndG9CU09OIGZ1bmN0aW9uIGRpZCBub3QgcmV0dXJuIGFuIG9iamVjdCcpO1xuXHQgICAgfSAvLyBJdGVyYXRlIG92ZXIgYWxsIHRoZSBrZXlzXG5cblxuXHQgICAgZm9yICh2YXIgX2tleTIgaW4gb2JqZWN0KSB7XG5cdCAgICAgIHZhciBfdmFsdWUyID0gb2JqZWN0W19rZXkyXTsgLy8gSXMgdGhlcmUgYW4gb3ZlcnJpZGUgdmFsdWVcblxuXHQgICAgICBpZiAoX3ZhbHVlMiAmJiBfdmFsdWUyLnRvQlNPTikge1xuXHQgICAgICAgIGlmICh0eXBlb2YgX3ZhbHVlMi50b0JTT04gIT09ICdmdW5jdGlvbicpIHRocm93IG5ldyBUeXBlRXJyb3IoJ3RvQlNPTiBpcyBub3QgYSBmdW5jdGlvbicpO1xuXHQgICAgICAgIF92YWx1ZTIgPSBfdmFsdWUyLnRvQlNPTigpO1xuXHQgICAgICB9IC8vIENoZWNrIHRoZSB0eXBlIG9mIHRoZSB2YWx1ZVxuXG5cblx0ICAgICAgdmFyIF90eXBlMiA9IF90eXBlb2YkMyhfdmFsdWUyKTsgLy8gQ2hlY2sgdGhlIGtleSBhbmQgdGhyb3cgZXJyb3IgaWYgaXQncyBpbGxlZ2FsXG5cblxuXHQgICAgICBpZiAodHlwZW9mIF9rZXkyID09PSAnc3RyaW5nJyAmJiAhaWdub3JlS2V5cy5oYXMoX2tleTIpKSB7XG5cdCAgICAgICAgaWYgKF9rZXkyLm1hdGNoKHJlZ2V4cCQxKSAhPSBudWxsKSB7XG5cdCAgICAgICAgICAvLyBUaGUgQlNPTiBzcGVjIGRvZXNuJ3QgYWxsb3cga2V5cyB3aXRoIG51bGwgYnl0ZXMgYmVjYXVzZSBrZXlzIGFyZVxuXHQgICAgICAgICAgLy8gbnVsbC10ZXJtaW5hdGVkLlxuXHQgICAgICAgICAgdGhyb3cgRXJyb3IoJ2tleSAnICsgX2tleTIgKyAnIG11c3Qgbm90IGNvbnRhaW4gbnVsbCBieXRlcycpO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmIChjaGVja0tleXMpIHtcblx0ICAgICAgICAgIGlmICgnJCcgPT09IF9rZXkyWzBdKSB7XG5cdCAgICAgICAgICAgIHRocm93IEVycm9yKCdrZXkgJyArIF9rZXkyICsgXCIgbXVzdCBub3Qgc3RhcnQgd2l0aCAnJCdcIik7XG5cdCAgICAgICAgICB9IGVsc2UgaWYgKH5fa2V5Mi5pbmRleE9mKCcuJykpIHtcblx0ICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ2tleSAnICsgX2tleTIgKyBcIiBtdXN0IG5vdCBjb250YWluICcuJ1wiKTtcblx0ICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgIH1cblxuXHQgICAgICBpZiAoX3R5cGUyID09PSAnc3RyaW5nJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplU3RyaW5nKGJ1ZmZlciQkMSwgX2tleTIsIF92YWx1ZTIsIGluZGV4KTtcblx0ICAgICAgfSBlbHNlIGlmIChfdHlwZTIgPT09ICdudW1iZXInKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVOdW1iZXIoYnVmZmVyJCQxLCBfa2V5MiwgX3ZhbHVlMiwgaW5kZXgpO1xuXHQgICAgICB9IGVsc2UgaWYgKF90eXBlMiA9PT0gJ2Jvb2xlYW4nKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVCb29sZWFuKGJ1ZmZlciQkMSwgX2tleTIsIF92YWx1ZTIsIGluZGV4KTtcblx0ICAgICAgfSBlbHNlIGlmIChfdmFsdWUyIGluc3RhbmNlb2YgRGF0ZSB8fCBpc0RhdGUkMShfdmFsdWUyKSkge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplRGF0ZShidWZmZXIkJDEsIF9rZXkyLCBfdmFsdWUyLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3ZhbHVlMiA9PT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgICAgaWYgKGlnbm9yZVVuZGVmaW5lZCA9PT0gZmFsc2UpIGluZGV4ID0gc2VyaWFsaXplTnVsbChidWZmZXIkJDEsIF9rZXkyLCBfdmFsdWUyLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3ZhbHVlMiA9PT0gbnVsbCkge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplTnVsbChidWZmZXIkJDEsIF9rZXkyLCBfdmFsdWUyLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3ZhbHVlMlsnX2Jzb250eXBlJ10gPT09ICdPYmplY3RJZCcgfHwgX3ZhbHVlMlsnX2Jzb250eXBlJ10gPT09ICdPYmplY3RJRCcpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZU9iamVjdElkKGJ1ZmZlciQkMSwgX2tleTIsIF92YWx1ZTIsIGluZGV4KTtcblx0ICAgICAgfSBlbHNlIGlmIChCdWZmZXIkNS5pc0J1ZmZlcihfdmFsdWUyKSkge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplQnVmZmVyKGJ1ZmZlciQkMSwgX2tleTIsIF92YWx1ZTIsIGluZGV4KTtcblx0ICAgICAgfSBlbHNlIGlmIChfdmFsdWUyIGluc3RhbmNlb2YgUmVnRXhwIHx8IGlzUmVnRXhwJDEoX3ZhbHVlMikpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZVJlZ0V4cChidWZmZXIkJDEsIF9rZXkyLCBfdmFsdWUyLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3R5cGUyID09PSAnb2JqZWN0JyAmJiBfdmFsdWUyWydfYnNvbnR5cGUnXSA9PSBudWxsKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVPYmplY3QoYnVmZmVyJCQxLCBfa2V5MiwgX3ZhbHVlMiwgaW5kZXgsIGNoZWNrS2V5cywgZGVwdGgsIHNlcmlhbGl6ZUZ1bmN0aW9ucywgaWdub3JlVW5kZWZpbmVkLCBmYWxzZSwgcGF0aCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3R5cGUyID09PSAnb2JqZWN0JyAmJiBfdmFsdWUyWydfYnNvbnR5cGUnXSA9PT0gJ0RlY2ltYWwxMjgnKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVEZWNpbWFsMTI4KGJ1ZmZlciQkMSwgX2tleTIsIF92YWx1ZTIsIGluZGV4KTtcblx0ICAgICAgfSBlbHNlIGlmIChfdmFsdWUyWydfYnNvbnR5cGUnXSA9PT0gJ0xvbmcnIHx8IF92YWx1ZTJbJ19ic29udHlwZSddID09PSAnVGltZXN0YW1wJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplTG9uZyhidWZmZXIkJDEsIF9rZXkyLCBfdmFsdWUyLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3ZhbHVlMlsnX2Jzb250eXBlJ10gPT09ICdEb3VibGUnKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVEb3VibGUoYnVmZmVyJCQxLCBfa2V5MiwgX3ZhbHVlMiwgaW5kZXgpO1xuXHQgICAgICB9IGVsc2UgaWYgKF92YWx1ZTJbJ19ic29udHlwZSddID09PSAnQ29kZScpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZUNvZGUoYnVmZmVyJCQxLCBfa2V5MiwgX3ZhbHVlMiwgaW5kZXgsIGNoZWNrS2V5cywgZGVwdGgsIHNlcmlhbGl6ZUZ1bmN0aW9ucywgaWdub3JlVW5kZWZpbmVkKTtcblx0ICAgICAgfSBlbHNlIGlmICh0eXBlb2YgX3ZhbHVlMiA9PT0gJ2Z1bmN0aW9uJyAmJiBzZXJpYWxpemVGdW5jdGlvbnMpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZUZ1bmN0aW9uKGJ1ZmZlciQkMSwgX2tleTIsIF92YWx1ZTIsIGluZGV4LCBjaGVja0tleXMsIGRlcHRoLCBzZXJpYWxpemVGdW5jdGlvbnMpO1xuXHQgICAgICB9IGVsc2UgaWYgKF92YWx1ZTJbJ19ic29udHlwZSddID09PSAnQmluYXJ5Jykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplQmluYXJ5KGJ1ZmZlciQkMSwgX2tleTIsIF92YWx1ZTIsIGluZGV4KTtcblx0ICAgICAgfSBlbHNlIGlmIChfdmFsdWUyWydfYnNvbnR5cGUnXSA9PT0gJ1N5bWJvbCcpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZVN5bWJvbChidWZmZXIkJDEsIF9rZXkyLCBfdmFsdWUyLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAoX3ZhbHVlMlsnX2Jzb250eXBlJ10gPT09ICdEQlJlZicpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZURCUmVmKGJ1ZmZlciQkMSwgX2tleTIsIF92YWx1ZTIsIGluZGV4LCBkZXB0aCwgc2VyaWFsaXplRnVuY3Rpb25zKTtcblx0ICAgICAgfSBlbHNlIGlmIChfdmFsdWUyWydfYnNvbnR5cGUnXSA9PT0gJ0JTT05SZWdFeHAnKSB7XG5cdCAgICAgICAgaW5kZXggPSBzZXJpYWxpemVCU09OUmVnRXhwKGJ1ZmZlciQkMSwgX2tleTIsIF92YWx1ZTIsIGluZGV4KTtcblx0ICAgICAgfSBlbHNlIGlmIChfdmFsdWUyWydfYnNvbnR5cGUnXSA9PT0gJ0ludDMyJykge1xuXHQgICAgICAgIGluZGV4ID0gc2VyaWFsaXplSW50MzIoYnVmZmVyJCQxLCBfa2V5MiwgX3ZhbHVlMiwgaW5kZXgpO1xuXHQgICAgICB9IGVsc2UgaWYgKF92YWx1ZTJbJ19ic29udHlwZSddID09PSAnTWluS2V5JyB8fCBfdmFsdWUyWydfYnNvbnR5cGUnXSA9PT0gJ01heEtleScpIHtcblx0ICAgICAgICBpbmRleCA9IHNlcmlhbGl6ZU1pbk1heChidWZmZXIkJDEsIF9rZXkyLCBfdmFsdWUyLCBpbmRleCk7XG5cdCAgICAgIH0gZWxzZSBpZiAodHlwZW9mIF92YWx1ZTJbJ19ic29udHlwZSddICE9PSAndW5kZWZpbmVkJykge1xuXHQgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1VucmVjb2duaXplZCBvciBpbnZhbGlkIF9ic29udHlwZTogJyArIF92YWx1ZTJbJ19ic29udHlwZSddKTtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH0gLy8gUmVtb3ZlIHRoZSBwYXRoXG5cblxuXHQgIHBhdGgucG9wKCk7IC8vIEZpbmFsIHBhZGRpbmcgYnl0ZSBmb3Igb2JqZWN0XG5cblx0ICBidWZmZXIkJDFbaW5kZXgrK10gPSAweDAwOyAvLyBGaW5hbCBzaXplXG5cblx0ICB2YXIgc2l6ZSA9IGluZGV4IC0gc3RhcnRpbmdJbmRleDsgLy8gV3JpdGUgdGhlIHNpemUgb2YgdGhlIG9iamVjdFxuXG5cdCAgYnVmZmVyJCQxW3N0YXJ0aW5nSW5kZXgrK10gPSBzaXplICYgMHhmZjtcblx0ICBidWZmZXIkJDFbc3RhcnRpbmdJbmRleCsrXSA9IHNpemUgPj4gOCAmIDB4ZmY7XG5cdCAgYnVmZmVyJCQxW3N0YXJ0aW5nSW5kZXgrK10gPSBzaXplID4+IDE2ICYgMHhmZjtcblx0ICBidWZmZXIkJDFbc3RhcnRpbmdJbmRleCsrXSA9IHNpemUgPj4gMjQgJiAweGZmO1xuXHQgIHJldHVybiBpbmRleDtcblx0fVxuXG5cdHZhciBzZXJpYWxpemVyID0gc2VyaWFsaXplSW50bztcblxuXHRmdW5jdGlvbiBfdHlwZW9mJDQob2JqKSB7IGlmICh0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIikgeyBfdHlwZW9mJDQgPSBmdW5jdGlvbiBfdHlwZW9mKG9iaikgeyByZXR1cm4gdHlwZW9mIG9iajsgfTsgfSBlbHNlIHsgX3R5cGVvZiQ0ID0gZnVuY3Rpb24gX3R5cGVvZihvYmopIHsgcmV0dXJuIG9iaiAmJiB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7IH07IH0gcmV0dXJuIF90eXBlb2YkNChvYmopOyB9XG5cblx0dmFyIEJ1ZmZlciQ2ID0gYnVmZmVyLkJ1ZmZlcjtcblx0dmFyIG5vcm1hbGl6ZWRGdW5jdGlvblN0cmluZyQyID0gdXRpbHMubm9ybWFsaXplZEZ1bmN0aW9uU3RyaW5nOyAvLyBUbyBlbnN1cmUgdGhhdCAwLjQgb2Ygbm9kZSB3b3JrcyBjb3JyZWN0bHlcblxuXHRmdW5jdGlvbiBpc0RhdGUkMihkKSB7XG5cdCAgcmV0dXJuIF90eXBlb2YkNChkKSA9PT0gJ29iamVjdCcgJiYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGQpID09PSAnW29iamVjdCBEYXRlXSc7XG5cdH1cblxuXHRmdW5jdGlvbiBjYWxjdWxhdGVPYmplY3RTaXplKG9iamVjdCwgc2VyaWFsaXplRnVuY3Rpb25zLCBpZ25vcmVVbmRlZmluZWQpIHtcblx0ICB2YXIgdG90YWxMZW5ndGggPSA0ICsgMTtcblxuXHQgIGlmIChBcnJheS5pc0FycmF5KG9iamVjdCkpIHtcblx0ICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0Lmxlbmd0aDsgaSsrKSB7XG5cdCAgICAgIHRvdGFsTGVuZ3RoICs9IGNhbGN1bGF0ZUVsZW1lbnQoaS50b1N0cmluZygpLCBvYmplY3RbaV0sIHNlcmlhbGl6ZUZ1bmN0aW9ucywgdHJ1ZSwgaWdub3JlVW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICB9IGVsc2Uge1xuXHQgICAgLy8gSWYgd2UgaGF2ZSB0b0JTT04gZGVmaW5lZCwgb3ZlcnJpZGUgdGhlIGN1cnJlbnQgb2JqZWN0XG5cdCAgICBpZiAob2JqZWN0LnRvQlNPTikge1xuXHQgICAgICBvYmplY3QgPSBvYmplY3QudG9CU09OKCk7XG5cdCAgICB9IC8vIENhbGN1bGF0ZSBzaXplXG5cblxuXHQgICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuXHQgICAgICB0b3RhbExlbmd0aCArPSBjYWxjdWxhdGVFbGVtZW50KGtleSwgb2JqZWN0W2tleV0sIHNlcmlhbGl6ZUZ1bmN0aW9ucywgZmFsc2UsIGlnbm9yZVVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgfVxuXG5cdCAgcmV0dXJuIHRvdGFsTGVuZ3RoO1xuXHR9XG5cdC8qKlxuXHQgKiBAaWdub3JlXG5cdCAqIEBhcGkgcHJpdmF0ZVxuXHQgKi9cblxuXG5cdGZ1bmN0aW9uIGNhbGN1bGF0ZUVsZW1lbnQobmFtZSwgdmFsdWUsIHNlcmlhbGl6ZUZ1bmN0aW9ucywgaXNBcnJheSwgaWdub3JlVW5kZWZpbmVkKSB7XG5cdCAgLy8gSWYgd2UgaGF2ZSB0b0JTT04gZGVmaW5lZCwgb3ZlcnJpZGUgdGhlIGN1cnJlbnQgb2JqZWN0XG5cdCAgaWYgKHZhbHVlICYmIHZhbHVlLnRvQlNPTikge1xuXHQgICAgdmFsdWUgPSB2YWx1ZS50b0JTT04oKTtcblx0ICB9XG5cblx0ICBzd2l0Y2ggKF90eXBlb2YkNCh2YWx1ZSkpIHtcblx0ICAgIGNhc2UgJ3N0cmluZyc6XG5cdCAgICAgIHJldHVybiAxICsgQnVmZmVyJDYuYnl0ZUxlbmd0aChuYW1lLCAndXRmOCcpICsgMSArIDQgKyBCdWZmZXIkNi5ieXRlTGVuZ3RoKHZhbHVlLCAndXRmOCcpICsgMTtcblxuXHQgICAgY2FzZSAnbnVtYmVyJzpcblx0ICAgICAgaWYgKE1hdGguZmxvb3IodmFsdWUpID09PSB2YWx1ZSAmJiB2YWx1ZSA+PSBjb25zdGFudHMuSlNfSU5UX01JTiAmJiB2YWx1ZSA8PSBjb25zdGFudHMuSlNfSU5UX01BWCkge1xuXHQgICAgICAgIGlmICh2YWx1ZSA+PSBjb25zdGFudHMuQlNPTl9JTlQzMl9NSU4gJiYgdmFsdWUgPD0gY29uc3RhbnRzLkJTT05fSU5UMzJfTUFYKSB7XG5cdCAgICAgICAgICAvLyAzMiBiaXRcblx0ICAgICAgICAgIHJldHVybiAobmFtZSAhPSBudWxsID8gQnVmZmVyJDYuYnl0ZUxlbmd0aChuYW1lLCAndXRmOCcpICsgMSA6IDApICsgKDQgKyAxKTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgcmV0dXJuIChuYW1lICE9IG51bGwgPyBCdWZmZXIkNi5ieXRlTGVuZ3RoKG5hbWUsICd1dGY4JykgKyAxIDogMCkgKyAoOCArIDEpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAvLyA2NCBiaXRcblx0ICAgICAgICByZXR1cm4gKG5hbWUgIT0gbnVsbCA/IEJ1ZmZlciQ2LmJ5dGVMZW5ndGgobmFtZSwgJ3V0ZjgnKSArIDEgOiAwKSArICg4ICsgMSk7XG5cdCAgICAgIH1cblxuXHQgICAgY2FzZSAndW5kZWZpbmVkJzpcblx0ICAgICAgaWYgKGlzQXJyYXkgfHwgIWlnbm9yZVVuZGVmaW5lZCkgcmV0dXJuIChuYW1lICE9IG51bGwgPyBCdWZmZXIkNi5ieXRlTGVuZ3RoKG5hbWUsICd1dGY4JykgKyAxIDogMCkgKyAxO1xuXHQgICAgICByZXR1cm4gMDtcblxuXHQgICAgY2FzZSAnYm9vbGVhbic6XG5cdCAgICAgIHJldHVybiAobmFtZSAhPSBudWxsID8gQnVmZmVyJDYuYnl0ZUxlbmd0aChuYW1lLCAndXRmOCcpICsgMSA6IDApICsgKDEgKyAxKTtcblxuXHQgICAgY2FzZSAnb2JqZWN0Jzpcblx0ICAgICAgaWYgKHZhbHVlID09IG51bGwgfHwgdmFsdWVbJ19ic29udHlwZSddID09PSAnTWluS2V5JyB8fCB2YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdNYXhLZXknKSB7XG5cdCAgICAgICAgcmV0dXJuIChuYW1lICE9IG51bGwgPyBCdWZmZXIkNi5ieXRlTGVuZ3RoKG5hbWUsICd1dGY4JykgKyAxIDogMCkgKyAxO1xuXHQgICAgICB9IGVsc2UgaWYgKHZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ09iamVjdElkJyB8fCB2YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdPYmplY3RJRCcpIHtcblx0ICAgICAgICByZXR1cm4gKG5hbWUgIT0gbnVsbCA/IEJ1ZmZlciQ2LmJ5dGVMZW5ndGgobmFtZSwgJ3V0ZjgnKSArIDEgOiAwKSArICgxMiArIDEpO1xuXHQgICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSB8fCBpc0RhdGUkMih2YWx1ZSkpIHtcblx0ICAgICAgICByZXR1cm4gKG5hbWUgIT0gbnVsbCA/IEJ1ZmZlciQ2LmJ5dGVMZW5ndGgobmFtZSwgJ3V0ZjgnKSArIDEgOiAwKSArICg4ICsgMSk7XG5cdCAgICAgIH0gZWxzZSBpZiAodHlwZW9mIEJ1ZmZlciQ2ICE9PSAndW5kZWZpbmVkJyAmJiBCdWZmZXIkNi5pc0J1ZmZlcih2YWx1ZSkpIHtcblx0ICAgICAgICByZXR1cm4gKG5hbWUgIT0gbnVsbCA/IEJ1ZmZlciQ2LmJ5dGVMZW5ndGgobmFtZSwgJ3V0ZjgnKSArIDEgOiAwKSArICgxICsgNCArIDEpICsgdmFsdWUubGVuZ3RoO1xuXHQgICAgICB9IGVsc2UgaWYgKHZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ0xvbmcnIHx8IHZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ0RvdWJsZScgfHwgdmFsdWVbJ19ic29udHlwZSddID09PSAnVGltZXN0YW1wJykge1xuXHQgICAgICAgIHJldHVybiAobmFtZSAhPSBudWxsID8gQnVmZmVyJDYuYnl0ZUxlbmd0aChuYW1lLCAndXRmOCcpICsgMSA6IDApICsgKDggKyAxKTtcblx0ICAgICAgfSBlbHNlIGlmICh2YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdEZWNpbWFsMTI4Jykge1xuXHQgICAgICAgIHJldHVybiAobmFtZSAhPSBudWxsID8gQnVmZmVyJDYuYnl0ZUxlbmd0aChuYW1lLCAndXRmOCcpICsgMSA6IDApICsgKDE2ICsgMSk7XG5cdCAgICAgIH0gZWxzZSBpZiAodmFsdWVbJ19ic29udHlwZSddID09PSAnQ29kZScpIHtcblx0ICAgICAgICAvLyBDYWxjdWxhdGUgc2l6ZSBkZXBlbmRpbmcgb24gdGhlIGF2YWlsYWJpbGl0eSBvZiBhIHNjb3BlXG5cdCAgICAgICAgaWYgKHZhbHVlLnNjb3BlICE9IG51bGwgJiYgT2JqZWN0LmtleXModmFsdWUuc2NvcGUpLmxlbmd0aCA+IDApIHtcblx0ICAgICAgICAgIHJldHVybiAobmFtZSAhPSBudWxsID8gQnVmZmVyJDYuYnl0ZUxlbmd0aChuYW1lLCAndXRmOCcpICsgMSA6IDApICsgMSArIDQgKyA0ICsgQnVmZmVyJDYuYnl0ZUxlbmd0aCh2YWx1ZS5jb2RlLnRvU3RyaW5nKCksICd1dGY4JykgKyAxICsgY2FsY3VsYXRlT2JqZWN0U2l6ZSh2YWx1ZS5zY29wZSwgc2VyaWFsaXplRnVuY3Rpb25zLCBpZ25vcmVVbmRlZmluZWQpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICByZXR1cm4gKG5hbWUgIT0gbnVsbCA/IEJ1ZmZlciQ2LmJ5dGVMZW5ndGgobmFtZSwgJ3V0ZjgnKSArIDEgOiAwKSArIDEgKyA0ICsgQnVmZmVyJDYuYnl0ZUxlbmd0aCh2YWx1ZS5jb2RlLnRvU3RyaW5nKCksICd1dGY4JykgKyAxO1xuXHQgICAgICAgIH1cblx0ICAgICAgfSBlbHNlIGlmICh2YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdCaW5hcnknKSB7XG5cdCAgICAgICAgLy8gQ2hlY2sgd2hhdCBraW5kIG9mIHN1YnR5cGUgd2UgaGF2ZVxuXHQgICAgICAgIGlmICh2YWx1ZS5zdWJfdHlwZSA9PT0gYmluYXJ5LlNVQlRZUEVfQllURV9BUlJBWSkge1xuXHQgICAgICAgICAgcmV0dXJuIChuYW1lICE9IG51bGwgPyBCdWZmZXIkNi5ieXRlTGVuZ3RoKG5hbWUsICd1dGY4JykgKyAxIDogMCkgKyAodmFsdWUucG9zaXRpb24gKyAxICsgNCArIDEgKyA0KTtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgcmV0dXJuIChuYW1lICE9IG51bGwgPyBCdWZmZXIkNi5ieXRlTGVuZ3RoKG5hbWUsICd1dGY4JykgKyAxIDogMCkgKyAodmFsdWUucG9zaXRpb24gKyAxICsgNCArIDEpO1xuXHQgICAgICAgIH1cblx0ICAgICAgfSBlbHNlIGlmICh2YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdTeW1ib2wnKSB7XG5cdCAgICAgICAgcmV0dXJuIChuYW1lICE9IG51bGwgPyBCdWZmZXIkNi5ieXRlTGVuZ3RoKG5hbWUsICd1dGY4JykgKyAxIDogMCkgKyBCdWZmZXIkNi5ieXRlTGVuZ3RoKHZhbHVlLnZhbHVlLCAndXRmOCcpICsgNCArIDEgKyAxO1xuXHQgICAgICB9IGVsc2UgaWYgKHZhbHVlWydfYnNvbnR5cGUnXSA9PT0gJ0RCUmVmJykge1xuXHQgICAgICAgIC8vIFNldCB1cCBjb3JyZWN0IG9iamVjdCBmb3Igc2VyaWFsaXphdGlvblxuXHQgICAgICAgIHZhciBvcmRlcmVkX3ZhbHVlcyA9IE9iamVjdC5hc3NpZ24oe1xuXHQgICAgICAgICAgJHJlZjogdmFsdWUuY29sbGVjdGlvbixcblx0ICAgICAgICAgICRpZDogdmFsdWUub2lkXG5cdCAgICAgICAgfSwgdmFsdWUuZmllbGRzKTsgLy8gQWRkIGRiIHJlZmVyZW5jZSBpZiBpdCBleGlzdHNcblxuXHQgICAgICAgIGlmICh2YWx1ZS5kYiAhPSBudWxsKSB7XG5cdCAgICAgICAgICBvcmRlcmVkX3ZhbHVlc1snJGRiJ10gPSB2YWx1ZS5kYjtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICByZXR1cm4gKG5hbWUgIT0gbnVsbCA/IEJ1ZmZlciQ2LmJ5dGVMZW5ndGgobmFtZSwgJ3V0ZjgnKSArIDEgOiAwKSArIDEgKyBjYWxjdWxhdGVPYmplY3RTaXplKG9yZGVyZWRfdmFsdWVzLCBzZXJpYWxpemVGdW5jdGlvbnMsIGlnbm9yZVVuZGVmaW5lZCk7XG5cdCAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBSZWdFeHAgfHwgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXScpIHtcblx0ICAgICAgICByZXR1cm4gKG5hbWUgIT0gbnVsbCA/IEJ1ZmZlciQ2LmJ5dGVMZW5ndGgobmFtZSwgJ3V0ZjgnKSArIDEgOiAwKSArIDEgKyBCdWZmZXIkNi5ieXRlTGVuZ3RoKHZhbHVlLnNvdXJjZSwgJ3V0ZjgnKSArIDEgKyAodmFsdWUuZ2xvYmFsID8gMSA6IDApICsgKHZhbHVlLmlnbm9yZUNhc2UgPyAxIDogMCkgKyAodmFsdWUubXVsdGlsaW5lID8gMSA6IDApICsgMTtcblx0ICAgICAgfSBlbHNlIGlmICh2YWx1ZVsnX2Jzb250eXBlJ10gPT09ICdCU09OUmVnRXhwJykge1xuXHQgICAgICAgIHJldHVybiAobmFtZSAhPSBudWxsID8gQnVmZmVyJDYuYnl0ZUxlbmd0aChuYW1lLCAndXRmOCcpICsgMSA6IDApICsgMSArIEJ1ZmZlciQ2LmJ5dGVMZW5ndGgodmFsdWUucGF0dGVybiwgJ3V0ZjgnKSArIDEgKyBCdWZmZXIkNi5ieXRlTGVuZ3RoKHZhbHVlLm9wdGlvbnMsICd1dGY4JykgKyAxO1xuXHQgICAgICB9IGVsc2Uge1xuXHQgICAgICAgIHJldHVybiAobmFtZSAhPSBudWxsID8gQnVmZmVyJDYuYnl0ZUxlbmd0aChuYW1lLCAndXRmOCcpICsgMSA6IDApICsgY2FsY3VsYXRlT2JqZWN0U2l6ZSh2YWx1ZSwgc2VyaWFsaXplRnVuY3Rpb25zLCBpZ25vcmVVbmRlZmluZWQpICsgMTtcblx0ICAgICAgfVxuXG5cdCAgICBjYXNlICdmdW5jdGlvbic6XG5cdCAgICAgIC8vIFdURiBmb3IgMC40Llggd2hlcmUgdHlwZW9mIC9zb21lcmVnZXhwLyA9PT0gJ2Z1bmN0aW9uJ1xuXHQgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBSZWdFeHAgfHwgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXScgfHwgU3RyaW5nLmNhbGwodmFsdWUpID09PSAnW29iamVjdCBSZWdFeHBdJykge1xuXHQgICAgICAgIHJldHVybiAobmFtZSAhPSBudWxsID8gQnVmZmVyJDYuYnl0ZUxlbmd0aChuYW1lLCAndXRmOCcpICsgMSA6IDApICsgMSArIEJ1ZmZlciQ2LmJ5dGVMZW5ndGgodmFsdWUuc291cmNlLCAndXRmOCcpICsgMSArICh2YWx1ZS5nbG9iYWwgPyAxIDogMCkgKyAodmFsdWUuaWdub3JlQ2FzZSA/IDEgOiAwKSArICh2YWx1ZS5tdWx0aWxpbmUgPyAxIDogMCkgKyAxO1xuXHQgICAgICB9IGVsc2Uge1xuXHQgICAgICAgIGlmIChzZXJpYWxpemVGdW5jdGlvbnMgJiYgdmFsdWUuc2NvcGUgIT0gbnVsbCAmJiBPYmplY3Qua2V5cyh2YWx1ZS5zY29wZSkubGVuZ3RoID4gMCkge1xuXHQgICAgICAgICAgcmV0dXJuIChuYW1lICE9IG51bGwgPyBCdWZmZXIkNi5ieXRlTGVuZ3RoKG5hbWUsICd1dGY4JykgKyAxIDogMCkgKyAxICsgNCArIDQgKyBCdWZmZXIkNi5ieXRlTGVuZ3RoKG5vcm1hbGl6ZWRGdW5jdGlvblN0cmluZyQyKHZhbHVlKSwgJ3V0ZjgnKSArIDEgKyBjYWxjdWxhdGVPYmplY3RTaXplKHZhbHVlLnNjb3BlLCBzZXJpYWxpemVGdW5jdGlvbnMsIGlnbm9yZVVuZGVmaW5lZCk7XG5cdCAgICAgICAgfSBlbHNlIGlmIChzZXJpYWxpemVGdW5jdGlvbnMpIHtcblx0ICAgICAgICAgIHJldHVybiAobmFtZSAhPSBudWxsID8gQnVmZmVyJDYuYnl0ZUxlbmd0aChuYW1lLCAndXRmOCcpICsgMSA6IDApICsgMSArIDQgKyBCdWZmZXIkNi5ieXRlTGVuZ3RoKG5vcm1hbGl6ZWRGdW5jdGlvblN0cmluZyQyKHZhbHVlKSwgJ3V0ZjgnKSArIDE7XG5cdCAgICAgICAgfVxuXHQgICAgICB9XG5cblx0ICB9XG5cblx0ICByZXR1cm4gMDtcblx0fVxuXG5cdHZhciBjYWxjdWxhdGVfc2l6ZSA9IGNhbGN1bGF0ZU9iamVjdFNpemU7XG5cblx0dmFyIEJ1ZmZlciQ3ID0gYnVmZmVyLkJ1ZmZlcjtcblx0LyoqXG5cdCAqIE1ha2VzIHN1cmUgdGhhdCwgaWYgYSBVaW50OEFycmF5IGlzIHBhc3NlZCBpbiwgaXQgaXMgd3JhcHBlZCBpbiBhIEJ1ZmZlci5cblx0ICpcblx0ICogQHBhcmFtIHtCdWZmZXJ8VWludDhBcnJheX0gcG90ZW50aWFsQnVmZmVyIFRoZSBwb3RlbnRpYWwgYnVmZmVyXG5cdCAqIEByZXR1cm5zIHtCdWZmZXJ9IHRoZSBpbnB1dCBpZiBwb3RlbnRpYWxCdWZmZXIgaXMgYSBidWZmZXIsIG9yIGEgYnVmZmVyIHRoYXRcblx0ICogd3JhcHMgYSBwYXNzZWQgaW4gVWludDhBcnJheVxuXHQgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGFueXRoaW5nIG90aGVyIHRoYW4gYSBCdWZmZXIgb3IgVWludDhBcnJheSBpcyBwYXNzZWQgaW5cblx0ICovXG5cblx0dmFyIGVuc3VyZV9idWZmZXIgPSBmdW5jdGlvbiBlbnN1cmVCdWZmZXIocG90ZW50aWFsQnVmZmVyKSB7XG5cdCAgaWYgKHBvdGVudGlhbEJ1ZmZlciBpbnN0YW5jZW9mIEJ1ZmZlciQ3KSB7XG5cdCAgICByZXR1cm4gcG90ZW50aWFsQnVmZmVyO1xuXHQgIH1cblxuXHQgIGlmIChwb3RlbnRpYWxCdWZmZXIgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG5cdCAgICByZXR1cm4gQnVmZmVyJDcuZnJvbShwb3RlbnRpYWxCdWZmZXIuYnVmZmVyKTtcblx0ICB9XG5cblx0ICB0aHJvdyBuZXcgVHlwZUVycm9yKCdNdXN0IHVzZSBlaXRoZXIgQnVmZmVyIG9yIFVpbnQ4QXJyYXknKTtcblx0fTtcblxuXHR2YXIgQnVmZmVyJDggPSBidWZmZXIuQnVmZmVyOyAvLyBQYXJ0cyBvZiB0aGUgcGFyc2VyXG5cblx0LyoqXG5cdCAqIEBpZ25vcmVcblx0ICovXG5cdC8vIERlZmF1bHQgTWF4IFNpemVcblxuXHR2YXIgTUFYU0laRSA9IDEwMjQgKiAxMDI0ICogMTc7IC8vIEN1cnJlbnQgSW50ZXJuYWwgVGVtcG9yYXJ5IFNlcmlhbGl6YXRpb24gQnVmZmVyXG5cblx0dmFyIGJ1ZmZlciQxID0gQnVmZmVyJDguYWxsb2MoTUFYU0laRSk7XG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBzaXplIG9mIHRoZSBpbnRlcm5hbCBzZXJpYWxpemF0aW9uIGJ1ZmZlci5cblx0ICpcblx0ICogQG1ldGhvZFxuXHQgKiBAcGFyYW0ge251bWJlcn0gc2l6ZSBUaGUgZGVzaXJlZCBzaXplIGZvciB0aGUgaW50ZXJuYWwgc2VyaWFsaXphdGlvbiBidWZmZXJcblx0ICovXG5cblx0ZnVuY3Rpb24gc2V0SW50ZXJuYWxCdWZmZXJTaXplKHNpemUpIHtcblx0ICAvLyBSZXNpemUgdGhlIGludGVybmFsIHNlcmlhbGl6YXRpb24gYnVmZmVyIGlmIG5lZWRlZFxuXHQgIGlmIChidWZmZXIkMS5sZW5ndGggPCBzaXplKSB7XG5cdCAgICBidWZmZXIkMSA9IEJ1ZmZlciQ4LmFsbG9jKHNpemUpO1xuXHQgIH1cblx0fVxuXHQvKipcblx0ICogU2VyaWFsaXplIGEgSmF2YXNjcmlwdCBvYmplY3QuXG5cdCAqXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgdGhlIEphdmFzY3JpcHQgb2JqZWN0IHRvIHNlcmlhbGl6ZS5cblx0ICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5jaGVja0tleXNdIHRoZSBzZXJpYWxpemVyIHdpbGwgY2hlY2sgaWYga2V5cyBhcmUgdmFsaWQuXG5cdCAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdGlvbnMuc2VyaWFsaXplRnVuY3Rpb25zPWZhbHNlXSBzZXJpYWxpemUgdGhlIGphdmFzY3JpcHQgZnVuY3Rpb25zICoqKGRlZmF1bHQ6ZmFsc2UpKiouXG5cdCAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdGlvbnMuaWdub3JlVW5kZWZpbmVkPXRydWVdIGlnbm9yZSB1bmRlZmluZWQgZmllbGRzICoqKGRlZmF1bHQ6dHJ1ZSkqKi5cblx0ICogQHJldHVybiB7QnVmZmVyfSByZXR1cm5zIHRoZSBCdWZmZXIgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIHNlcmlhbGl6ZWQgb2JqZWN0LlxuXHQgKi9cblxuXG5cdGZ1bmN0aW9uIHNlcmlhbGl6ZSQxKG9iamVjdCwgb3B0aW9ucykge1xuXHQgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OyAvLyBVbnBhY2sgdGhlIG9wdGlvbnNcblxuXHQgIHZhciBjaGVja0tleXMgPSB0eXBlb2Ygb3B0aW9ucy5jaGVja0tleXMgPT09ICdib29sZWFuJyA/IG9wdGlvbnMuY2hlY2tLZXlzIDogZmFsc2U7XG5cdCAgdmFyIHNlcmlhbGl6ZUZ1bmN0aW9ucyA9IHR5cGVvZiBvcHRpb25zLnNlcmlhbGl6ZUZ1bmN0aW9ucyA9PT0gJ2Jvb2xlYW4nID8gb3B0aW9ucy5zZXJpYWxpemVGdW5jdGlvbnMgOiBmYWxzZTtcblx0ICB2YXIgaWdub3JlVW5kZWZpbmVkID0gdHlwZW9mIG9wdGlvbnMuaWdub3JlVW5kZWZpbmVkID09PSAnYm9vbGVhbicgPyBvcHRpb25zLmlnbm9yZVVuZGVmaW5lZCA6IHRydWU7XG5cdCAgdmFyIG1pbkludGVybmFsQnVmZmVyU2l6ZSA9IHR5cGVvZiBvcHRpb25zLm1pbkludGVybmFsQnVmZmVyU2l6ZSA9PT0gJ251bWJlcicgPyBvcHRpb25zLm1pbkludGVybmFsQnVmZmVyU2l6ZSA6IE1BWFNJWkU7IC8vIFJlc2l6ZSB0aGUgaW50ZXJuYWwgc2VyaWFsaXphdGlvbiBidWZmZXIgaWYgbmVlZGVkXG5cblx0ICBpZiAoYnVmZmVyJDEubGVuZ3RoIDwgbWluSW50ZXJuYWxCdWZmZXJTaXplKSB7XG5cdCAgICBidWZmZXIkMSA9IEJ1ZmZlciQ4LmFsbG9jKG1pbkludGVybmFsQnVmZmVyU2l6ZSk7XG5cdCAgfSAvLyBBdHRlbXB0IHRvIHNlcmlhbGl6ZVxuXG5cblx0ICB2YXIgc2VyaWFsaXphdGlvbkluZGV4ID0gc2VyaWFsaXplcihidWZmZXIkMSwgb2JqZWN0LCBjaGVja0tleXMsIDAsIDAsIHNlcmlhbGl6ZUZ1bmN0aW9ucywgaWdub3JlVW5kZWZpbmVkLCBbXSk7IC8vIENyZWF0ZSB0aGUgZmluYWwgYnVmZmVyXG5cblx0ICB2YXIgZmluaXNoZWRCdWZmZXIgPSBCdWZmZXIkOC5hbGxvYyhzZXJpYWxpemF0aW9uSW5kZXgpOyAvLyBDb3B5IGludG8gdGhlIGZpbmlzaGVkIGJ1ZmZlclxuXG5cdCAgYnVmZmVyJDEuY29weShmaW5pc2hlZEJ1ZmZlciwgMCwgMCwgZmluaXNoZWRCdWZmZXIubGVuZ3RoKTsgLy8gUmV0dXJuIHRoZSBidWZmZXJcblxuXHQgIHJldHVybiBmaW5pc2hlZEJ1ZmZlcjtcblx0fVxuXHQvKipcblx0ICogU2VyaWFsaXplIGEgSmF2YXNjcmlwdCBvYmplY3QgdXNpbmcgYSBwcmVkZWZpbmVkIEJ1ZmZlciBhbmQgaW5kZXggaW50byB0aGUgYnVmZmVyLCB1c2VmdWwgd2hlbiBwcmUtYWxsb2NhdGluZyB0aGUgc3BhY2UgZm9yIHNlcmlhbGl6YXRpb24uXG5cdCAqXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgdGhlIEphdmFzY3JpcHQgb2JqZWN0IHRvIHNlcmlhbGl6ZS5cblx0ICogQHBhcmFtIHtCdWZmZXJ9IGJ1ZmZlciB0aGUgQnVmZmVyIHlvdSBwcmUtYWxsb2NhdGVkIHRvIHN0b3JlIHRoZSBzZXJpYWxpemVkIEJTT04gb2JqZWN0LlxuXHQgKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLmNoZWNrS2V5c10gdGhlIHNlcmlhbGl6ZXIgd2lsbCBjaGVjayBpZiBrZXlzIGFyZSB2YWxpZC5cblx0ICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5zZXJpYWxpemVGdW5jdGlvbnM9ZmFsc2VdIHNlcmlhbGl6ZSB0aGUgamF2YXNjcmlwdCBmdW5jdGlvbnMgKiooZGVmYXVsdDpmYWxzZSkqKi5cblx0ICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5pZ25vcmVVbmRlZmluZWQ9dHJ1ZV0gaWdub3JlIHVuZGVmaW5lZCBmaWVsZHMgKiooZGVmYXVsdDp0cnVlKSoqLlxuXHQgKiBAcGFyYW0ge051bWJlcn0gW29wdGlvbnMuaW5kZXhdIHRoZSBpbmRleCBpbiB0aGUgYnVmZmVyIHdoZXJlIHdlIHdpc2ggdG8gc3RhcnQgc2VyaWFsaXppbmcgaW50by5cblx0ICogQHJldHVybiB7TnVtYmVyfSByZXR1cm5zIHRoZSBpbmRleCBwb2ludGluZyB0byB0aGUgbGFzdCB3cml0dGVuIGJ5dGUgaW4gdGhlIGJ1ZmZlci5cblx0ICovXG5cblxuXHRmdW5jdGlvbiBzZXJpYWxpemVXaXRoQnVmZmVyQW5kSW5kZXgob2JqZWN0LCBmaW5hbEJ1ZmZlciwgb3B0aW9ucykge1xuXHQgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OyAvLyBVbnBhY2sgdGhlIG9wdGlvbnNcblxuXHQgIHZhciBjaGVja0tleXMgPSB0eXBlb2Ygb3B0aW9ucy5jaGVja0tleXMgPT09ICdib29sZWFuJyA/IG9wdGlvbnMuY2hlY2tLZXlzIDogZmFsc2U7XG5cdCAgdmFyIHNlcmlhbGl6ZUZ1bmN0aW9ucyA9IHR5cGVvZiBvcHRpb25zLnNlcmlhbGl6ZUZ1bmN0aW9ucyA9PT0gJ2Jvb2xlYW4nID8gb3B0aW9ucy5zZXJpYWxpemVGdW5jdGlvbnMgOiBmYWxzZTtcblx0ICB2YXIgaWdub3JlVW5kZWZpbmVkID0gdHlwZW9mIG9wdGlvbnMuaWdub3JlVW5kZWZpbmVkID09PSAnYm9vbGVhbicgPyBvcHRpb25zLmlnbm9yZVVuZGVmaW5lZCA6IHRydWU7XG5cdCAgdmFyIHN0YXJ0SW5kZXggPSB0eXBlb2Ygb3B0aW9ucy5pbmRleCA9PT0gJ251bWJlcicgPyBvcHRpb25zLmluZGV4IDogMDsgLy8gQXR0ZW1wdCB0byBzZXJpYWxpemVcblxuXHQgIHZhciBzZXJpYWxpemF0aW9uSW5kZXggPSBzZXJpYWxpemVyKGJ1ZmZlciQxLCBvYmplY3QsIGNoZWNrS2V5cywgMCwgMCwgc2VyaWFsaXplRnVuY3Rpb25zLCBpZ25vcmVVbmRlZmluZWQpO1xuXHQgIGJ1ZmZlciQxLmNvcHkoZmluYWxCdWZmZXIsIHN0YXJ0SW5kZXgsIDAsIHNlcmlhbGl6YXRpb25JbmRleCk7IC8vIFJldHVybiB0aGUgaW5kZXhcblxuXHQgIHJldHVybiBzdGFydEluZGV4ICsgc2VyaWFsaXphdGlvbkluZGV4IC0gMTtcblx0fVxuXHQvKipcblx0ICogRGVzZXJpYWxpemUgZGF0YSBhcyBCU09OLlxuXHQgKlxuXHQgKiBAcGFyYW0ge0J1ZmZlcn0gYnVmZmVyIHRoZSBidWZmZXIgY29udGFpbmluZyB0aGUgc2VyaWFsaXplZCBzZXQgb2YgQlNPTiBkb2N1bWVudHMuXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5ldmFsRnVuY3Rpb25zPWZhbHNlXSBldmFsdWF0ZSBmdW5jdGlvbnMgaW4gdGhlIEJTT04gZG9jdW1lbnQgc2NvcGVkIHRvIHRoZSBvYmplY3QgZGVzZXJpYWxpemVkLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMuY2FjaGVGdW5jdGlvbnM9ZmFsc2VdIGNhY2hlIGV2YWx1YXRlZCBmdW5jdGlvbnMgZm9yIHJldXNlLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMuY2FjaGVGdW5jdGlvbnNDcmMzMj1mYWxzZV0gdXNlIGEgY3JjMzIgY29kZSBmb3IgY2FjaGluZywgb3RoZXJ3aXNlIHVzZSB0aGUgc3RyaW5nIG9mIHRoZSBmdW5jdGlvbi5cblx0ICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLnByb21vdGVMb25ncz10cnVlXSB3aGVuIGRlc2VyaWFsaXppbmcgYSBMb25nIHdpbGwgZml0IGl0IGludG8gYSBOdW1iZXIgaWYgaXQncyBzbWFsbGVyIHRoYW4gNTMgYml0c1xuXHQgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMucHJvbW90ZUJ1ZmZlcnM9ZmFsc2VdIHdoZW4gZGVzZXJpYWxpemluZyBhIEJpbmFyeSB3aWxsIHJldHVybiBpdCBhcyBhIG5vZGUuanMgQnVmZmVyIGluc3RhbmNlLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMucHJvbW90ZVZhbHVlcz1mYWxzZV0gd2hlbiBkZXNlcmlhbGl6aW5nIHdpbGwgcHJvbW90ZSBCU09OIHZhbHVlcyB0byB0aGVpciBOb2RlLmpzIGNsb3Nlc3QgZXF1aXZhbGVudCB0eXBlcy5cblx0ICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLmZpZWxkc0FzUmF3PW51bGxdIGFsbG93IHRvIHNwZWNpZnkgaWYgdGhlcmUgd2hhdCBmaWVsZHMgd2Ugd2lzaCB0byByZXR1cm4gYXMgdW5zZXJpYWxpemVkIHJhdyBidWZmZXIuXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5ic29uUmVnRXhwPWZhbHNlXSByZXR1cm4gQlNPTiByZWd1bGFyIGV4cHJlc3Npb25zIGFzIEJTT05SZWdFeHAgaW5zdGFuY2VzLlxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmFsbG93T2JqZWN0U21hbGxlclRoYW5CdWZmZXJTaXplPWZhbHNlXSBhbGxvd3MgdGhlIGJ1ZmZlciB0byBiZSBsYXJnZXIgdGhhbiB0aGUgcGFyc2VkIEJTT04gb2JqZWN0XG5cdCAqIEByZXR1cm4ge09iamVjdH0gcmV0dXJucyB0aGUgZGVzZXJpYWxpemVkIEphdmFzY3JpcHQgT2JqZWN0LlxuXHQgKi9cblxuXG5cdGZ1bmN0aW9uIGRlc2VyaWFsaXplJDIoYnVmZmVyJCQxLCBvcHRpb25zKSB7XG5cdCAgYnVmZmVyJCQxID0gZW5zdXJlX2J1ZmZlcihidWZmZXIkJDEpO1xuXHQgIHJldHVybiBkZXNlcmlhbGl6ZXIoYnVmZmVyJCQxLCBvcHRpb25zKTtcblx0fVxuXHQvKipcblx0ICogQ2FsY3VsYXRlIHRoZSBic29uIHNpemUgZm9yIGEgcGFzc2VkIGluIEphdmFzY3JpcHQgb2JqZWN0LlxuXHQgKlxuXHQgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IHRoZSBKYXZhc2NyaXB0IG9iamVjdCB0byBjYWxjdWxhdGUgdGhlIEJTT04gYnl0ZSBzaXplIGZvci5cblx0ICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5zZXJpYWxpemVGdW5jdGlvbnM9ZmFsc2VdIHNlcmlhbGl6ZSB0aGUgamF2YXNjcmlwdCBmdW5jdGlvbnMgKiooZGVmYXVsdDpmYWxzZSkqKi5cblx0ICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5pZ25vcmVVbmRlZmluZWQ9dHJ1ZV0gaWdub3JlIHVuZGVmaW5lZCBmaWVsZHMgKiooZGVmYXVsdDp0cnVlKSoqLlxuXHQgKiBAcmV0dXJuIHtOdW1iZXJ9IHJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyB0aGUgQlNPTiBvYmplY3Qgd2lsbCB0YWtlIHVwLlxuXHQgKi9cblxuXG5cdGZ1bmN0aW9uIGNhbGN1bGF0ZU9iamVjdFNpemUkMShvYmplY3QsIG9wdGlvbnMpIHtcblx0ICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblx0ICB2YXIgc2VyaWFsaXplRnVuY3Rpb25zID0gdHlwZW9mIG9wdGlvbnMuc2VyaWFsaXplRnVuY3Rpb25zID09PSAnYm9vbGVhbicgPyBvcHRpb25zLnNlcmlhbGl6ZUZ1bmN0aW9ucyA6IGZhbHNlO1xuXHQgIHZhciBpZ25vcmVVbmRlZmluZWQgPSB0eXBlb2Ygb3B0aW9ucy5pZ25vcmVVbmRlZmluZWQgPT09ICdib29sZWFuJyA/IG9wdGlvbnMuaWdub3JlVW5kZWZpbmVkIDogdHJ1ZTtcblx0ICByZXR1cm4gY2FsY3VsYXRlX3NpemUob2JqZWN0LCBzZXJpYWxpemVGdW5jdGlvbnMsIGlnbm9yZVVuZGVmaW5lZCk7XG5cdH1cblx0LyoqXG5cdCAqIERlc2VyaWFsaXplIHN0cmVhbSBkYXRhIGFzIEJTT04gZG9jdW1lbnRzLlxuXHQgKlxuXHQgKiBAcGFyYW0ge0J1ZmZlcn0gZGF0YSB0aGUgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIHNlcmlhbGl6ZWQgc2V0IG9mIEJTT04gZG9jdW1lbnRzLlxuXHQgKiBAcGFyYW0ge051bWJlcn0gc3RhcnRJbmRleCB0aGUgc3RhcnQgaW5kZXggaW4gdGhlIGRhdGEgQnVmZmVyIHdoZXJlIHRoZSBkZXNlcmlhbGl6YXRpb24gaXMgdG8gc3RhcnQuXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBudW1iZXJPZkRvY3VtZW50cyBudW1iZXIgb2YgZG9jdW1lbnRzIHRvIGRlc2VyaWFsaXplLlxuXHQgKiBAcGFyYW0ge0FycmF5fSBkb2N1bWVudHMgYW4gYXJyYXkgd2hlcmUgdG8gc3RvcmUgdGhlIGRlc2VyaWFsaXplZCBkb2N1bWVudHMuXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBkb2NTdGFydEluZGV4IHRoZSBpbmRleCBpbiB0aGUgZG9jdW1lbnRzIGFycmF5IGZyb20gd2hlcmUgdG8gc3RhcnQgaW5zZXJ0aW5nIGRvY3VtZW50cy5cblx0ICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSBhZGRpdGlvbmFsIG9wdGlvbnMgdXNlZCBmb3IgdGhlIGRlc2VyaWFsaXphdGlvbi5cblx0ICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLmV2YWxGdW5jdGlvbnM9ZmFsc2VdIGV2YWx1YXRlIGZ1bmN0aW9ucyBpbiB0aGUgQlNPTiBkb2N1bWVudCBzY29wZWQgdG8gdGhlIG9iamVjdCBkZXNlcmlhbGl6ZWQuXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5jYWNoZUZ1bmN0aW9ucz1mYWxzZV0gY2FjaGUgZXZhbHVhdGVkIGZ1bmN0aW9ucyBmb3IgcmV1c2UuXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5jYWNoZUZ1bmN0aW9uc0NyYzMyPWZhbHNlXSB1c2UgYSBjcmMzMiBjb2RlIGZvciBjYWNoaW5nLCBvdGhlcndpc2UgdXNlIHRoZSBzdHJpbmcgb2YgdGhlIGZ1bmN0aW9uLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMucHJvbW90ZUxvbmdzPXRydWVdIHdoZW4gZGVzZXJpYWxpemluZyBhIExvbmcgd2lsbCBmaXQgaXQgaW50byBhIE51bWJlciBpZiBpdCdzIHNtYWxsZXIgdGhhbiA1MyBiaXRzXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5wcm9tb3RlQnVmZmVycz1mYWxzZV0gd2hlbiBkZXNlcmlhbGl6aW5nIGEgQmluYXJ5IHdpbGwgcmV0dXJuIGl0IGFzIGEgbm9kZS5qcyBCdWZmZXIgaW5zdGFuY2UuXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5wcm9tb3RlVmFsdWVzPWZhbHNlXSB3aGVuIGRlc2VyaWFsaXppbmcgd2lsbCBwcm9tb3RlIEJTT04gdmFsdWVzIHRvIHRoZWlyIE5vZGUuanMgY2xvc2VzdCBlcXVpdmFsZW50IHR5cGVzLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMuZmllbGRzQXNSYXc9bnVsbF0gYWxsb3cgdG8gc3BlY2lmeSBpZiB0aGVyZSB3aGF0IGZpZWxkcyB3ZSB3aXNoIHRvIHJldHVybiBhcyB1bnNlcmlhbGl6ZWQgcmF3IGJ1ZmZlci5cblx0ICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLmJzb25SZWdFeHA9ZmFsc2VdIHJldHVybiBCU09OIHJlZ3VsYXIgZXhwcmVzc2lvbnMgYXMgQlNPTlJlZ0V4cCBpbnN0YW5jZXMuXG5cdCAqIEByZXR1cm4ge051bWJlcn0gcmV0dXJucyB0aGUgbmV4dCBpbmRleCBpbiB0aGUgYnVmZmVyIGFmdGVyIGRlc2VyaWFsaXphdGlvbiAqKngqKiBudW1iZXJzIG9mIGRvY3VtZW50cy5cblx0ICovXG5cblxuXHRmdW5jdGlvbiBkZXNlcmlhbGl6ZVN0cmVhbShkYXRhLCBzdGFydEluZGV4LCBudW1iZXJPZkRvY3VtZW50cywgZG9jdW1lbnRzLCBkb2NTdGFydEluZGV4LCBvcHRpb25zKSB7XG5cdCAgb3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oe1xuXHQgICAgYWxsb3dPYmplY3RTbWFsbGVyVGhhbkJ1ZmZlclNpemU6IHRydWVcblx0ICB9LCBvcHRpb25zKTtcblx0ICBkYXRhID0gZW5zdXJlX2J1ZmZlcihkYXRhKTtcblx0ICB2YXIgaW5kZXggPSBzdGFydEluZGV4OyAvLyBMb29wIG92ZXIgYWxsIGRvY3VtZW50c1xuXG5cdCAgZm9yICh2YXIgaSA9IDA7IGkgPCBudW1iZXJPZkRvY3VtZW50czsgaSsrKSB7XG5cdCAgICAvLyBGaW5kIHNpemUgb2YgdGhlIGRvY3VtZW50XG5cdCAgICB2YXIgc2l6ZSA9IGRhdGFbaW5kZXhdIHwgZGF0YVtpbmRleCArIDFdIDw8IDggfCBkYXRhW2luZGV4ICsgMl0gPDwgMTYgfCBkYXRhW2luZGV4ICsgM10gPDwgMjQ7IC8vIFVwZGF0ZSBvcHRpb25zIHdpdGggaW5kZXhcblxuXHQgICAgb3B0aW9ucy5pbmRleCA9IGluZGV4OyAvLyBQYXJzZSB0aGUgZG9jdW1lbnQgYXQgdGhpcyBwb2ludFxuXG5cdCAgICBkb2N1bWVudHNbZG9jU3RhcnRJbmRleCArIGldID0gZGVzZXJpYWxpemVyKGRhdGEsIG9wdGlvbnMpOyAvLyBBZGp1c3QgaW5kZXggYnkgdGhlIGRvY3VtZW50IHNpemVcblxuXHQgICAgaW5kZXggPSBpbmRleCArIHNpemU7XG5cdCAgfSAvLyBSZXR1cm4gb2JqZWN0IGNvbnRhaW5pbmcgZW5kIGluZGV4IG9mIHBhcnNpbmcgYW5kIGxpc3Qgb2YgZG9jdW1lbnRzXG5cblxuXHQgIHJldHVybiBpbmRleDtcblx0fVxuXG5cdHZhciBic29uID0ge1xuXHQgIC8vIGNvbnN0YW50c1xuXHQgIC8vIE5PVEU6IHRoaXMgaXMgZG9uZSB0aGlzIHdheSBiZWNhdXNlIHJvbGx1cCBjYW4ndCByZXNvbHZlIGFuIGBPYmplY3QuYXNzaWduYGVkIGV4cG9ydFxuXHQgIEJTT05fSU5UMzJfTUFYOiBjb25zdGFudHMuQlNPTl9JTlQzMl9NQVgsXG5cdCAgQlNPTl9JTlQzMl9NSU46IGNvbnN0YW50cy5CU09OX0lOVDMyX01JTixcblx0ICBCU09OX0lOVDY0X01BWDogY29uc3RhbnRzLkJTT05fSU5UNjRfTUFYLFxuXHQgIEJTT05fSU5UNjRfTUlOOiBjb25zdGFudHMuQlNPTl9JTlQ2NF9NSU4sXG5cdCAgSlNfSU5UX01BWDogY29uc3RhbnRzLkpTX0lOVF9NQVgsXG5cdCAgSlNfSU5UX01JTjogY29uc3RhbnRzLkpTX0lOVF9NSU4sXG5cdCAgQlNPTl9EQVRBX05VTUJFUjogY29uc3RhbnRzLkJTT05fREFUQV9OVU1CRVIsXG5cdCAgQlNPTl9EQVRBX1NUUklORzogY29uc3RhbnRzLkJTT05fREFUQV9TVFJJTkcsXG5cdCAgQlNPTl9EQVRBX09CSkVDVDogY29uc3RhbnRzLkJTT05fREFUQV9PQkpFQ1QsXG5cdCAgQlNPTl9EQVRBX0FSUkFZOiBjb25zdGFudHMuQlNPTl9EQVRBX0FSUkFZLFxuXHQgIEJTT05fREFUQV9CSU5BUlk6IGNvbnN0YW50cy5CU09OX0RBVEFfQklOQVJZLFxuXHQgIEJTT05fREFUQV9VTkRFRklORUQ6IGNvbnN0YW50cy5CU09OX0RBVEFfVU5ERUZJTkVELFxuXHQgIEJTT05fREFUQV9PSUQ6IGNvbnN0YW50cy5CU09OX0RBVEFfT0lELFxuXHQgIEJTT05fREFUQV9CT09MRUFOOiBjb25zdGFudHMuQlNPTl9EQVRBX0JPT0xFQU4sXG5cdCAgQlNPTl9EQVRBX0RBVEU6IGNvbnN0YW50cy5CU09OX0RBVEFfREFURSxcblx0ICBCU09OX0RBVEFfTlVMTDogY29uc3RhbnRzLkJTT05fREFUQV9OVUxMLFxuXHQgIEJTT05fREFUQV9SRUdFWFA6IGNvbnN0YW50cy5CU09OX0RBVEFfUkVHRVhQLFxuXHQgIEJTT05fREFUQV9EQlBPSU5URVI6IGNvbnN0YW50cy5CU09OX0RBVEFfREJQT0lOVEVSLFxuXHQgIEJTT05fREFUQV9DT0RFOiBjb25zdGFudHMuQlNPTl9EQVRBX0NPREUsXG5cdCAgQlNPTl9EQVRBX1NZTUJPTDogY29uc3RhbnRzLkJTT05fREFUQV9TWU1CT0wsXG5cdCAgQlNPTl9EQVRBX0NPREVfV19TQ09QRTogY29uc3RhbnRzLkJTT05fREFUQV9DT0RFX1dfU0NPUEUsXG5cdCAgQlNPTl9EQVRBX0lOVDogY29uc3RhbnRzLkJTT05fREFUQV9JTlQsXG5cdCAgQlNPTl9EQVRBX1RJTUVTVEFNUDogY29uc3RhbnRzLkJTT05fREFUQV9USU1FU1RBTVAsXG5cdCAgQlNPTl9EQVRBX0xPTkc6IGNvbnN0YW50cy5CU09OX0RBVEFfTE9ORyxcblx0ICBCU09OX0RBVEFfREVDSU1BTDEyODogY29uc3RhbnRzLkJTT05fREFUQV9ERUNJTUFMMTI4LFxuXHQgIEJTT05fREFUQV9NSU5fS0VZOiBjb25zdGFudHMuQlNPTl9EQVRBX01JTl9LRVksXG5cdCAgQlNPTl9EQVRBX01BWF9LRVk6IGNvbnN0YW50cy5CU09OX0RBVEFfTUFYX0tFWSxcblx0ICBCU09OX0JJTkFSWV9TVUJUWVBFX0RFRkFVTFQ6IGNvbnN0YW50cy5CU09OX0JJTkFSWV9TVUJUWVBFX0RFRkFVTFQsXG5cdCAgQlNPTl9CSU5BUllfU1VCVFlQRV9GVU5DVElPTjogY29uc3RhbnRzLkJTT05fQklOQVJZX1NVQlRZUEVfRlVOQ1RJT04sXG5cdCAgQlNPTl9CSU5BUllfU1VCVFlQRV9CWVRFX0FSUkFZOiBjb25zdGFudHMuQlNPTl9CSU5BUllfU1VCVFlQRV9CWVRFX0FSUkFZLFxuXHQgIEJTT05fQklOQVJZX1NVQlRZUEVfVVVJRDogY29uc3RhbnRzLkJTT05fQklOQVJZX1NVQlRZUEVfVVVJRCxcblx0ICBCU09OX0JJTkFSWV9TVUJUWVBFX01ENTogY29uc3RhbnRzLkJTT05fQklOQVJZX1NVQlRZUEVfTUQ1LFxuXHQgIEJTT05fQklOQVJZX1NVQlRZUEVfVVNFUl9ERUZJTkVEOiBjb25zdGFudHMuQlNPTl9CSU5BUllfU1VCVFlQRV9VU0VSX0RFRklORUQsXG5cdCAgLy8gd3JhcHBlZCB0eXBlc1xuXHQgIENvZGU6IGNvZGUsXG5cdCAgTWFwOiBtYXAsXG5cdCAgQlNPTlN5bWJvbDogc3ltYm9sLFxuXHQgIERCUmVmOiBkYl9yZWYsXG5cdCAgQmluYXJ5OiBiaW5hcnksXG5cdCAgT2JqZWN0SWQ6IG9iamVjdGlkLFxuXHQgIExvbmc6IGxvbmdfMSxcblx0ICBUaW1lc3RhbXA6IHRpbWVzdGFtcCxcblx0ICBEb3VibGU6IGRvdWJsZV8xLFxuXHQgIEludDMyOiBpbnRfMzIsXG5cdCAgTWluS2V5OiBtaW5fa2V5LFxuXHQgIE1heEtleTogbWF4X2tleSxcblx0ICBCU09OUmVnRXhwOiByZWdleHAsXG5cdCAgRGVjaW1hbDEyODogZGVjaW1hbDEyOCxcblx0ICAvLyBtZXRob2RzXG5cdCAgc2VyaWFsaXplOiBzZXJpYWxpemUkMSxcblx0ICBzZXJpYWxpemVXaXRoQnVmZmVyQW5kSW5kZXg6IHNlcmlhbGl6ZVdpdGhCdWZmZXJBbmRJbmRleCxcblx0ICBkZXNlcmlhbGl6ZTogZGVzZXJpYWxpemUkMixcblx0ICBjYWxjdWxhdGVPYmplY3RTaXplOiBjYWxjdWxhdGVPYmplY3RTaXplJDEsXG5cdCAgZGVzZXJpYWxpemVTdHJlYW06IGRlc2VyaWFsaXplU3RyZWFtLFxuXHQgIHNldEludGVybmFsQnVmZmVyU2l6ZTogc2V0SW50ZXJuYWxCdWZmZXJTaXplLFxuXHQgIC8vIGxlZ2FjeSBzdXBwb3J0XG5cdCAgT2JqZWN0SUQ6IG9iamVjdGlkLFxuXHQgIC8vIEV4dGVuZGVkIEpTT05cblx0ICBFSlNPTjogZXh0ZW5kZWRfanNvblxuXHR9O1xuXHR2YXIgYnNvbl8xID0gYnNvbi5CU09OX0lOVDMyX01BWDtcblx0dmFyIGJzb25fMiA9IGJzb24uQlNPTl9JTlQzMl9NSU47XG5cdHZhciBic29uXzMgPSBic29uLkJTT05fSU5UNjRfTUFYO1xuXHR2YXIgYnNvbl80ID0gYnNvbi5CU09OX0lOVDY0X01JTjtcblx0dmFyIGJzb25fNSA9IGJzb24uSlNfSU5UX01BWDtcblx0dmFyIGJzb25fNiA9IGJzb24uSlNfSU5UX01JTjtcblx0dmFyIGJzb25fNyA9IGJzb24uQlNPTl9EQVRBX05VTUJFUjtcblx0dmFyIGJzb25fOCA9IGJzb24uQlNPTl9EQVRBX1NUUklORztcblx0dmFyIGJzb25fOSA9IGJzb24uQlNPTl9EQVRBX09CSkVDVDtcblx0dmFyIGJzb25fMTAgPSBic29uLkJTT05fREFUQV9BUlJBWTtcblx0dmFyIGJzb25fMTEgPSBic29uLkJTT05fREFUQV9CSU5BUlk7XG5cdHZhciBic29uXzEyID0gYnNvbi5CU09OX0RBVEFfVU5ERUZJTkVEO1xuXHR2YXIgYnNvbl8xMyA9IGJzb24uQlNPTl9EQVRBX09JRDtcblx0dmFyIGJzb25fMTQgPSBic29uLkJTT05fREFUQV9CT09MRUFOO1xuXHR2YXIgYnNvbl8xNSA9IGJzb24uQlNPTl9EQVRBX0RBVEU7XG5cdHZhciBic29uXzE2ID0gYnNvbi5CU09OX0RBVEFfTlVMTDtcblx0dmFyIGJzb25fMTcgPSBic29uLkJTT05fREFUQV9SRUdFWFA7XG5cdHZhciBic29uXzE4ID0gYnNvbi5CU09OX0RBVEFfREJQT0lOVEVSO1xuXHR2YXIgYnNvbl8xOSA9IGJzb24uQlNPTl9EQVRBX0NPREU7XG5cdHZhciBic29uXzIwID0gYnNvbi5CU09OX0RBVEFfU1lNQk9MO1xuXHR2YXIgYnNvbl8yMSA9IGJzb24uQlNPTl9EQVRBX0NPREVfV19TQ09QRTtcblx0dmFyIGJzb25fMjIgPSBic29uLkJTT05fREFUQV9JTlQ7XG5cdHZhciBic29uXzIzID0gYnNvbi5CU09OX0RBVEFfVElNRVNUQU1QO1xuXHR2YXIgYnNvbl8yNCA9IGJzb24uQlNPTl9EQVRBX0xPTkc7XG5cdHZhciBic29uXzI1ID0gYnNvbi5CU09OX0RBVEFfREVDSU1BTDEyODtcblx0dmFyIGJzb25fMjYgPSBic29uLkJTT05fREFUQV9NSU5fS0VZO1xuXHR2YXIgYnNvbl8yNyA9IGJzb24uQlNPTl9EQVRBX01BWF9LRVk7XG5cdHZhciBic29uXzI4ID0gYnNvbi5CU09OX0JJTkFSWV9TVUJUWVBFX0RFRkFVTFQ7XG5cdHZhciBic29uXzI5ID0gYnNvbi5CU09OX0JJTkFSWV9TVUJUWVBFX0ZVTkNUSU9OO1xuXHR2YXIgYnNvbl8zMCA9IGJzb24uQlNPTl9CSU5BUllfU1VCVFlQRV9CWVRFX0FSUkFZO1xuXHR2YXIgYnNvbl8zMSA9IGJzb24uQlNPTl9CSU5BUllfU1VCVFlQRV9VVUlEO1xuXHR2YXIgYnNvbl8zMiA9IGJzb24uQlNPTl9CSU5BUllfU1VCVFlQRV9NRDU7XG5cdHZhciBic29uXzMzID0gYnNvbi5CU09OX0JJTkFSWV9TVUJUWVBFX1VTRVJfREVGSU5FRDtcblx0dmFyIGJzb25fMzQgPSBic29uLkNvZGU7XG5cdHZhciBic29uXzM1ID0gYnNvbi5CU09OU3ltYm9sO1xuXHR2YXIgYnNvbl8zNiA9IGJzb24uREJSZWY7XG5cdHZhciBic29uXzM3ID0gYnNvbi5CaW5hcnk7XG5cdHZhciBic29uXzM4ID0gYnNvbi5PYmplY3RJZDtcblx0dmFyIGJzb25fMzkgPSBic29uLkxvbmc7XG5cdHZhciBic29uXzQwID0gYnNvbi5UaW1lc3RhbXA7XG5cdHZhciBic29uXzQxID0gYnNvbi5Eb3VibGU7XG5cdHZhciBic29uXzQyID0gYnNvbi5JbnQzMjtcblx0dmFyIGJzb25fNDMgPSBic29uLk1pbktleTtcblx0dmFyIGJzb25fNDQgPSBic29uLk1heEtleTtcblx0dmFyIGJzb25fNDUgPSBic29uLkJTT05SZWdFeHA7XG5cdHZhciBic29uXzQ2ID0gYnNvbi5EZWNpbWFsMTI4O1xuXHR2YXIgYnNvbl80NyA9IGJzb24uc2VyaWFsaXplO1xuXHR2YXIgYnNvbl80OCA9IGJzb24uc2VyaWFsaXplV2l0aEJ1ZmZlckFuZEluZGV4O1xuXHR2YXIgYnNvbl80OSA9IGJzb24uZGVzZXJpYWxpemU7XG5cdHZhciBic29uXzUwID0gYnNvbi5jYWxjdWxhdGVPYmplY3RTaXplO1xuXHR2YXIgYnNvbl81MSA9IGJzb24uZGVzZXJpYWxpemVTdHJlYW07XG5cdHZhciBic29uXzUyID0gYnNvbi5zZXRJbnRlcm5hbEJ1ZmZlclNpemU7XG5cdHZhciBic29uXzUzID0gYnNvbi5PYmplY3RJRDtcblx0dmFyIGJzb25fNTQgPSBic29uLkVKU09OO1xuXG5cdGV4cG9ydHMuZGVmYXVsdCA9IGJzb247XG5cdGV4cG9ydHMuQlNPTl9JTlQzMl9NQVggPSBic29uXzE7XG5cdGV4cG9ydHMuQlNPTl9JTlQzMl9NSU4gPSBic29uXzI7XG5cdGV4cG9ydHMuQlNPTl9JTlQ2NF9NQVggPSBic29uXzM7XG5cdGV4cG9ydHMuQlNPTl9JTlQ2NF9NSU4gPSBic29uXzQ7XG5cdGV4cG9ydHMuSlNfSU5UX01BWCA9IGJzb25fNTtcblx0ZXhwb3J0cy5KU19JTlRfTUlOID0gYnNvbl82O1xuXHRleHBvcnRzLkJTT05fREFUQV9OVU1CRVIgPSBic29uXzc7XG5cdGV4cG9ydHMuQlNPTl9EQVRBX1NUUklORyA9IGJzb25fODtcblx0ZXhwb3J0cy5CU09OX0RBVEFfT0JKRUNUID0gYnNvbl85O1xuXHRleHBvcnRzLkJTT05fREFUQV9BUlJBWSA9IGJzb25fMTA7XG5cdGV4cG9ydHMuQlNPTl9EQVRBX0JJTkFSWSA9IGJzb25fMTE7XG5cdGV4cG9ydHMuQlNPTl9EQVRBX1VOREVGSU5FRCA9IGJzb25fMTI7XG5cdGV4cG9ydHMuQlNPTl9EQVRBX09JRCA9IGJzb25fMTM7XG5cdGV4cG9ydHMuQlNPTl9EQVRBX0JPT0xFQU4gPSBic29uXzE0O1xuXHRleHBvcnRzLkJTT05fREFUQV9EQVRFID0gYnNvbl8xNTtcblx0ZXhwb3J0cy5CU09OX0RBVEFfTlVMTCA9IGJzb25fMTY7XG5cdGV4cG9ydHMuQlNPTl9EQVRBX1JFR0VYUCA9IGJzb25fMTc7XG5cdGV4cG9ydHMuQlNPTl9EQVRBX0RCUE9JTlRFUiA9IGJzb25fMTg7XG5cdGV4cG9ydHMuQlNPTl9EQVRBX0NPREUgPSBic29uXzE5O1xuXHRleHBvcnRzLkJTT05fREFUQV9TWU1CT0wgPSBic29uXzIwO1xuXHRleHBvcnRzLkJTT05fREFUQV9DT0RFX1dfU0NPUEUgPSBic29uXzIxO1xuXHRleHBvcnRzLkJTT05fREFUQV9JTlQgPSBic29uXzIyO1xuXHRleHBvcnRzLkJTT05fREFUQV9USU1FU1RBTVAgPSBic29uXzIzO1xuXHRleHBvcnRzLkJTT05fREFUQV9MT05HID0gYnNvbl8yNDtcblx0ZXhwb3J0cy5CU09OX0RBVEFfREVDSU1BTDEyOCA9IGJzb25fMjU7XG5cdGV4cG9ydHMuQlNPTl9EQVRBX01JTl9LRVkgPSBic29uXzI2O1xuXHRleHBvcnRzLkJTT05fREFUQV9NQVhfS0VZID0gYnNvbl8yNztcblx0ZXhwb3J0cy5CU09OX0JJTkFSWV9TVUJUWVBFX0RFRkFVTFQgPSBic29uXzI4O1xuXHRleHBvcnRzLkJTT05fQklOQVJZX1NVQlRZUEVfRlVOQ1RJT04gPSBic29uXzI5O1xuXHRleHBvcnRzLkJTT05fQklOQVJZX1NVQlRZUEVfQllURV9BUlJBWSA9IGJzb25fMzA7XG5cdGV4cG9ydHMuQlNPTl9CSU5BUllfU1VCVFlQRV9VVUlEID0gYnNvbl8zMTtcblx0ZXhwb3J0cy5CU09OX0JJTkFSWV9TVUJUWVBFX01ENSA9IGJzb25fMzI7XG5cdGV4cG9ydHMuQlNPTl9CSU5BUllfU1VCVFlQRV9VU0VSX0RFRklORUQgPSBic29uXzMzO1xuXHRleHBvcnRzLkNvZGUgPSBic29uXzM0O1xuXHRleHBvcnRzLkJTT05TeW1ib2wgPSBic29uXzM1O1xuXHRleHBvcnRzLkRCUmVmID0gYnNvbl8zNjtcblx0ZXhwb3J0cy5CaW5hcnkgPSBic29uXzM3O1xuXHRleHBvcnRzLk9iamVjdElkID0gYnNvbl8zODtcblx0ZXhwb3J0cy5Mb25nID0gYnNvbl8zOTtcblx0ZXhwb3J0cy5UaW1lc3RhbXAgPSBic29uXzQwO1xuXHRleHBvcnRzLkRvdWJsZSA9IGJzb25fNDE7XG5cdGV4cG9ydHMuSW50MzIgPSBic29uXzQyO1xuXHRleHBvcnRzLk1pbktleSA9IGJzb25fNDM7XG5cdGV4cG9ydHMuTWF4S2V5ID0gYnNvbl80NDtcblx0ZXhwb3J0cy5CU09OUmVnRXhwID0gYnNvbl80NTtcblx0ZXhwb3J0cy5EZWNpbWFsMTI4ID0gYnNvbl80Njtcblx0ZXhwb3J0cy5zZXJpYWxpemUgPSBic29uXzQ3O1xuXHRleHBvcnRzLnNlcmlhbGl6ZVdpdGhCdWZmZXJBbmRJbmRleCA9IGJzb25fNDg7XG5cdGV4cG9ydHMuZGVzZXJpYWxpemUgPSBic29uXzQ5O1xuXHRleHBvcnRzLmNhbGN1bGF0ZU9iamVjdFNpemUgPSBic29uXzUwO1xuXHRleHBvcnRzLmRlc2VyaWFsaXplU3RyZWFtID0gYnNvbl81MTtcblx0ZXhwb3J0cy5zZXRJbnRlcm5hbEJ1ZmZlclNpemUgPSBic29uXzUyO1xuXHRleHBvcnRzLk9iamVjdElEID0gYnNvbl81Mztcblx0ZXhwb3J0cy5FSlNPTiA9IGJzb25fNTQ7XG5cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcblxufSkpKTtcblxuLyogV0VCUEFDSyBWQVIgSU5KRUNUSU9OICovfS5jYWxsKGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18oMCksIF9fd2VicGFja19yZXF1aXJlX18oMSkuQnVmZmVyKSlcblxuLyoqKi8gfSksXG4vKiAzICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblwidXNlIHN0cmljdFwiO1xuXG5cbmV4cG9ydHMuYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGhcbmV4cG9ydHMudG9CeXRlQXJyYXkgPSB0b0J5dGVBcnJheVxuZXhwb3J0cy5mcm9tQnl0ZUFycmF5ID0gZnJvbUJ5dGVBcnJheVxuXG52YXIgbG9va3VwID0gW11cbnZhciByZXZMb29rdXAgPSBbXVxudmFyIEFyciA9IHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJyA/IFVpbnQ4QXJyYXkgOiBBcnJheVxuXG52YXIgY29kZSA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJ1xuZm9yICh2YXIgaSA9IDAsIGxlbiA9IGNvZGUubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgbG9va3VwW2ldID0gY29kZVtpXVxuICByZXZMb29rdXBbY29kZS5jaGFyQ29kZUF0KGkpXSA9IGlcbn1cblxuLy8gU3VwcG9ydCBkZWNvZGluZyBVUkwtc2FmZSBiYXNlNjQgc3RyaW5ncywgYXMgTm9kZS5qcyBkb2VzLlxuLy8gU2VlOiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9CYXNlNjQjVVJMX2FwcGxpY2F0aW9uc1xucmV2TG9va3VwWyctJy5jaGFyQ29kZUF0KDApXSA9IDYyXG5yZXZMb29rdXBbJ18nLmNoYXJDb2RlQXQoMCldID0gNjNcblxuZnVuY3Rpb24gZ2V0TGVucyAoYjY0KSB7XG4gIHZhciBsZW4gPSBiNjQubGVuZ3RoXG5cbiAgaWYgKGxlbiAlIDQgPiAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHN0cmluZy4gTGVuZ3RoIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA0JylcbiAgfVxuXG4gIC8vIFRyaW0gb2ZmIGV4dHJhIGJ5dGVzIGFmdGVyIHBsYWNlaG9sZGVyIGJ5dGVzIGFyZSBmb3VuZFxuICAvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9iZWF0Z2FtbWl0L2Jhc2U2NC1qcy9pc3N1ZXMvNDJcbiAgdmFyIHZhbGlkTGVuID0gYjY0LmluZGV4T2YoJz0nKVxuICBpZiAodmFsaWRMZW4gPT09IC0xKSB2YWxpZExlbiA9IGxlblxuXG4gIHZhciBwbGFjZUhvbGRlcnNMZW4gPSB2YWxpZExlbiA9PT0gbGVuXG4gICAgPyAwXG4gICAgOiA0IC0gKHZhbGlkTGVuICUgNClcblxuICByZXR1cm4gW3ZhbGlkTGVuLCBwbGFjZUhvbGRlcnNMZW5dXG59XG5cbi8vIGJhc2U2NCBpcyA0LzMgKyB1cCB0byB0d28gY2hhcmFjdGVycyBvZiB0aGUgb3JpZ2luYWwgZGF0YVxuZnVuY3Rpb24gYnl0ZUxlbmd0aCAoYjY0KSB7XG4gIHZhciBsZW5zID0gZ2V0TGVucyhiNjQpXG4gIHZhciB2YWxpZExlbiA9IGxlbnNbMF1cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IGxlbnNbMV1cbiAgcmV0dXJuICgodmFsaWRMZW4gKyBwbGFjZUhvbGRlcnNMZW4pICogMyAvIDQpIC0gcGxhY2VIb2xkZXJzTGVuXG59XG5cbmZ1bmN0aW9uIF9ieXRlTGVuZ3RoIChiNjQsIHZhbGlkTGVuLCBwbGFjZUhvbGRlcnNMZW4pIHtcbiAgcmV0dXJuICgodmFsaWRMZW4gKyBwbGFjZUhvbGRlcnNMZW4pICogMyAvIDQpIC0gcGxhY2VIb2xkZXJzTGVuXG59XG5cbmZ1bmN0aW9uIHRvQnl0ZUFycmF5IChiNjQpIHtcbiAgdmFyIHRtcFxuICB2YXIgbGVucyA9IGdldExlbnMoYjY0KVxuICB2YXIgdmFsaWRMZW4gPSBsZW5zWzBdXG4gIHZhciBwbGFjZUhvbGRlcnNMZW4gPSBsZW5zWzFdXG5cbiAgdmFyIGFyciA9IG5ldyBBcnIoX2J5dGVMZW5ndGgoYjY0LCB2YWxpZExlbiwgcGxhY2VIb2xkZXJzTGVuKSlcblxuICB2YXIgY3VyQnl0ZSA9IDBcblxuICAvLyBpZiB0aGVyZSBhcmUgcGxhY2Vob2xkZXJzLCBvbmx5IGdldCB1cCB0byB0aGUgbGFzdCBjb21wbGV0ZSA0IGNoYXJzXG4gIHZhciBsZW4gPSBwbGFjZUhvbGRlcnNMZW4gPiAwXG4gICAgPyB2YWxpZExlbiAtIDRcbiAgICA6IHZhbGlkTGVuXG5cbiAgdmFyIGlcbiAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDE4KSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPDwgMTIpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA8PCA2KSB8XG4gICAgICByZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDMpXVxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiAxNikgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDgpICYgMHhGRlxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgaWYgKHBsYWNlSG9sZGVyc0xlbiA9PT0gMikge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAyKSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPj4gNClcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIGlmIChwbGFjZUhvbGRlcnNMZW4gPT09IDEpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTApIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCA0KSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAyKV0gPj4gMilcbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gOCkgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICByZXR1cm4gYXJyXG59XG5cbmZ1bmN0aW9uIHRyaXBsZXRUb0Jhc2U2NCAobnVtKSB7XG4gIHJldHVybiBsb29rdXBbbnVtID4+IDE4ICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gPj4gMTIgJiAweDNGXSArXG4gICAgbG9va3VwW251bSA+PiA2ICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gJiAweDNGXVxufVxuXG5mdW5jdGlvbiBlbmNvZGVDaHVuayAodWludDgsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHRtcFxuICB2YXIgb3V0cHV0ID0gW11cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpICs9IDMpIHtcbiAgICB0bXAgPVxuICAgICAgKCh1aW50OFtpXSA8PCAxNikgJiAweEZGMDAwMCkgK1xuICAgICAgKCh1aW50OFtpICsgMV0gPDwgOCkgJiAweEZGMDApICtcbiAgICAgICh1aW50OFtpICsgMl0gJiAweEZGKVxuICAgIG91dHB1dC5wdXNoKHRyaXBsZXRUb0Jhc2U2NCh0bXApKVxuICB9XG4gIHJldHVybiBvdXRwdXQuam9pbignJylcbn1cblxuZnVuY3Rpb24gZnJvbUJ5dGVBcnJheSAodWludDgpIHtcbiAgdmFyIHRtcFxuICB2YXIgbGVuID0gdWludDgubGVuZ3RoXG4gIHZhciBleHRyYUJ5dGVzID0gbGVuICUgMyAvLyBpZiB3ZSBoYXZlIDEgYnl0ZSBsZWZ0LCBwYWQgMiBieXRlc1xuICB2YXIgcGFydHMgPSBbXVxuICB2YXIgbWF4Q2h1bmtMZW5ndGggPSAxNjM4MyAvLyBtdXN0IGJlIG11bHRpcGxlIG9mIDNcblxuICAvLyBnbyB0aHJvdWdoIHRoZSBhcnJheSBldmVyeSB0aHJlZSBieXRlcywgd2UnbGwgZGVhbCB3aXRoIHRyYWlsaW5nIHN0dWZmIGxhdGVyXG4gIGZvciAodmFyIGkgPSAwLCBsZW4yID0gbGVuIC0gZXh0cmFCeXRlczsgaSA8IGxlbjI7IGkgKz0gbWF4Q2h1bmtMZW5ndGgpIHtcbiAgICBwYXJ0cy5wdXNoKGVuY29kZUNodW5rKFxuICAgICAgdWludDgsIGksIChpICsgbWF4Q2h1bmtMZW5ndGgpID4gbGVuMiA/IGxlbjIgOiAoaSArIG1heENodW5rTGVuZ3RoKVxuICAgICkpXG4gIH1cblxuICAvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG4gIGlmIChleHRyYUJ5dGVzID09PSAxKSB7XG4gICAgdG1wID0gdWludDhbbGVuIC0gMV1cbiAgICBwYXJ0cy5wdXNoKFxuICAgICAgbG9va3VwW3RtcCA+PiAyXSArXG4gICAgICBsb29rdXBbKHRtcCA8PCA0KSAmIDB4M0ZdICtcbiAgICAgICc9PSdcbiAgICApXG4gIH0gZWxzZSBpZiAoZXh0cmFCeXRlcyA9PT0gMikge1xuICAgIHRtcCA9ICh1aW50OFtsZW4gLSAyXSA8PCA4KSArIHVpbnQ4W2xlbiAtIDFdXG4gICAgcGFydHMucHVzaChcbiAgICAgIGxvb2t1cFt0bXAgPj4gMTBdICtcbiAgICAgIGxvb2t1cFsodG1wID4+IDQpICYgMHgzRl0gK1xuICAgICAgbG9va3VwWyh0bXAgPDwgMikgJiAweDNGXSArXG4gICAgICAnPSdcbiAgICApXG4gIH1cblxuICByZXR1cm4gcGFydHMuam9pbignJylcbn1cblxuXG4vKioqLyB9KSxcbi8qIDQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuZXhwb3J0cy5yZWFkID0gZnVuY3Rpb24gKGJ1ZmZlciwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG1cbiAgdmFyIGVMZW4gPSAobkJ5dGVzICogOCkgLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIG5CaXRzID0gLTdcbiAgdmFyIGkgPSBpc0xFID8gKG5CeXRlcyAtIDEpIDogMFxuICB2YXIgZCA9IGlzTEUgPyAtMSA6IDFcbiAgdmFyIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV1cblxuICBpICs9IGRcblxuICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBzID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBlTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IGUgPSAoZSAqIDI1NikgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBtID0gZSAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBlID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBtTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IG0gPSAobSAqIDI1NikgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBpZiAoZSA9PT0gMCkge1xuICAgIGUgPSAxIC0gZUJpYXNcbiAgfSBlbHNlIGlmIChlID09PSBlTWF4KSB7XG4gICAgcmV0dXJuIG0gPyBOYU4gOiAoKHMgPyAtMSA6IDEpICogSW5maW5pdHkpXG4gIH0gZWxzZSB7XG4gICAgbSA9IG0gKyBNYXRoLnBvdygyLCBtTGVuKVxuICAgIGUgPSBlIC0gZUJpYXNcbiAgfVxuICByZXR1cm4gKHMgPyAtMSA6IDEpICogbSAqIE1hdGgucG93KDIsIGUgLSBtTGVuKVxufVxuXG5leHBvcnRzLndyaXRlID0gZnVuY3Rpb24gKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtLCBjXG4gIHZhciBlTGVuID0gKG5CeXRlcyAqIDgpIC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBydCA9IChtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMClcbiAgdmFyIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKVxuICB2YXIgZCA9IGlzTEUgPyAxIDogLTFcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgKHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDApID8gMSA6IDBcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKVxuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwXG4gICAgZSA9IGVNYXhcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMilcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS1cbiAgICAgIGMgKj0gMlxuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gY1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcylcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKytcbiAgICAgIGMgLz0gMlxuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDBcbiAgICAgIGUgPSBlTWF4XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICgodmFsdWUgKiBjKSAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSBlICsgZUJpYXNcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gMFxuICAgIH1cbiAgfVxuXG4gIGZvciAoOyBtTGVuID49IDg7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IG0gJiAweGZmLCBpICs9IGQsIG0gLz0gMjU2LCBtTGVuIC09IDgpIHt9XG5cbiAgZSA9IChlIDw8IG1MZW4pIHwgbVxuICBlTGVuICs9IG1MZW5cbiAgZm9yICg7IGVMZW4gPiAwOyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBlICYgMHhmZiwgaSArPSBkLCBlIC89IDI1NiwgZUxlbiAtPSA4KSB7fVxuXG4gIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyOFxufVxuXG5cbi8qKiovIH0pLFxuLyogNSAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG52YXIgdG9TdHJpbmcgPSB7fS50b1N0cmluZztcblxubW9kdWxlLmV4cG9ydHMgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uIChhcnIpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwoYXJyKSA9PSAnW29iamVjdCBBcnJheV0nO1xufTtcblxuXG4vKioqLyB9KSxcbi8qIDYgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxubW9kdWxlLmV4cG9ydHMgPSBMb25nO1xyXG5cclxuLyoqXHJcbiAqIHdhc20gb3B0aW1pemF0aW9ucywgdG8gZG8gbmF0aXZlIGk2NCBtdWx0aXBsaWNhdGlvbiBhbmQgZGl2aWRlXHJcbiAqL1xyXG52YXIgd2FzbSA9IG51bGw7XHJcblxyXG50cnkge1xyXG4gIHdhc20gPSBuZXcgV2ViQXNzZW1ibHkuSW5zdGFuY2UobmV3IFdlYkFzc2VtYmx5Lk1vZHVsZShuZXcgVWludDhBcnJheShbXHJcbiAgICAwLCA5NywgMTE1LCAxMDksIDEsIDAsIDAsIDAsIDEsIDEzLCAyLCA5NiwgMCwgMSwgMTI3LCA5NiwgNCwgMTI3LCAxMjcsIDEyNywgMTI3LCAxLCAxMjcsIDMsIDcsIDYsIDAsIDEsIDEsIDEsIDEsIDEsIDYsIDYsIDEsIDEyNywgMSwgNjUsIDAsIDExLCA3LCA1MCwgNiwgMywgMTA5LCAxMTcsIDEwOCwgMCwgMSwgNSwgMTAwLCAxMDUsIDExOCwgOTUsIDExNSwgMCwgMiwgNSwgMTAwLCAxMDUsIDExOCwgOTUsIDExNywgMCwgMywgNSwgMTE0LCAxMDEsIDEwOSwgOTUsIDExNSwgMCwgNCwgNSwgMTE0LCAxMDEsIDEwOSwgOTUsIDExNywgMCwgNSwgOCwgMTAzLCAxMDEsIDExNiwgOTUsIDEwNCwgMTA1LCAxMDMsIDEwNCwgMCwgMCwgMTAsIDE5MSwgMSwgNiwgNCwgMCwgMzUsIDAsIDExLCAzNiwgMSwgMSwgMTI2LCAzMiwgMCwgMTczLCAzMiwgMSwgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAzMiwgMiwgMTczLCAzMiwgMywgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAxMjYsIDM0LCA0LCA2NiwgMzIsIDEzNSwgMTY3LCAzNiwgMCwgMzIsIDQsIDE2NywgMTEsIDM2LCAxLCAxLCAxMjYsIDMyLCAwLCAxNzMsIDMyLCAxLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDMyLCAyLCAxNzMsIDMyLCAzLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDEyNywgMzQsIDQsIDY2LCAzMiwgMTM1LCAxNjcsIDM2LCAwLCAzMiwgNCwgMTY3LCAxMSwgMzYsIDEsIDEsIDEyNiwgMzIsIDAsIDE3MywgMzIsIDEsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMzIsIDIsIDE3MywgMzIsIDMsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMTI4LCAzNCwgNCwgNjYsIDMyLCAxMzUsIDE2NywgMzYsIDAsIDMyLCA0LCAxNjcsIDExLCAzNiwgMSwgMSwgMTI2LCAzMiwgMCwgMTczLCAzMiwgMSwgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAzMiwgMiwgMTczLCAzMiwgMywgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAxMjksIDM0LCA0LCA2NiwgMzIsIDEzNSwgMTY3LCAzNiwgMCwgMzIsIDQsIDE2NywgMTEsIDM2LCAxLCAxLCAxMjYsIDMyLCAwLCAxNzMsIDMyLCAxLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDMyLCAyLCAxNzMsIDMyLCAzLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDEzMCwgMzQsIDQsIDY2LCAzMiwgMTM1LCAxNjcsIDM2LCAwLCAzMiwgNCwgMTY3LCAxMVxyXG4gIF0pKSwge30pLmV4cG9ydHM7XHJcbn0gY2F0Y2ggKGUpIHtcclxuICAvLyBubyB3YXNtIHN1cHBvcnQgOihcclxufVxyXG5cclxuLyoqXHJcbiAqIENvbnN0cnVjdHMgYSA2NCBiaXQgdHdvJ3MtY29tcGxlbWVudCBpbnRlZ2VyLCBnaXZlbiBpdHMgbG93IGFuZCBoaWdoIDMyIGJpdCB2YWx1ZXMgYXMgKnNpZ25lZCogaW50ZWdlcnMuXHJcbiAqICBTZWUgdGhlIGZyb20qIGZ1bmN0aW9ucyBiZWxvdyBmb3IgbW9yZSBjb252ZW5pZW50IHdheXMgb2YgY29uc3RydWN0aW5nIExvbmdzLlxyXG4gKiBAZXhwb3J0cyBMb25nXHJcbiAqIEBjbGFzcyBBIExvbmcgY2xhc3MgZm9yIHJlcHJlc2VudGluZyBhIDY0IGJpdCB0d28ncy1jb21wbGVtZW50IGludGVnZXIgdmFsdWUuXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBsb3cgVGhlIGxvdyAoc2lnbmVkKSAzMiBiaXRzIG9mIHRoZSBsb25nXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBoaWdoIFRoZSBoaWdoIChzaWduZWQpIDMyIGJpdHMgb2YgdGhlIGxvbmdcclxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxyXG4gKiBAY29uc3RydWN0b3JcclxuICovXHJcbmZ1bmN0aW9uIExvbmcobG93LCBoaWdoLCB1bnNpZ25lZCkge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGxvdyAzMiBiaXRzIGFzIGEgc2lnbmVkIHZhbHVlLlxyXG4gICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAqL1xyXG4gICAgdGhpcy5sb3cgPSBsb3cgfCAwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGhpZ2ggMzIgYml0cyBhcyBhIHNpZ25lZCB2YWx1ZS5cclxuICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHRoaXMuaGlnaCA9IGhpZ2ggfCAwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV2hldGhlciB1bnNpZ25lZCBvciBub3QuXHJcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgdGhpcy51bnNpZ25lZCA9ICEhdW5zaWduZWQ7XHJcbn1cclxuXHJcbi8vIFRoZSBpbnRlcm5hbCByZXByZXNlbnRhdGlvbiBvZiBhIGxvbmcgaXMgdGhlIHR3byBnaXZlbiBzaWduZWQsIDMyLWJpdCB2YWx1ZXMuXHJcbi8vIFdlIHVzZSAzMi1iaXQgcGllY2VzIGJlY2F1c2UgdGhlc2UgYXJlIHRoZSBzaXplIG9mIGludGVnZXJzIG9uIHdoaWNoXHJcbi8vIEphdmFzY3JpcHQgcGVyZm9ybXMgYml0LW9wZXJhdGlvbnMuICBGb3Igb3BlcmF0aW9ucyBsaWtlIGFkZGl0aW9uIGFuZFxyXG4vLyBtdWx0aXBsaWNhdGlvbiwgd2Ugc3BsaXQgZWFjaCBudW1iZXIgaW50byAxNiBiaXQgcGllY2VzLCB3aGljaCBjYW4gZWFzaWx5IGJlXHJcbi8vIG11bHRpcGxpZWQgd2l0aGluIEphdmFzY3JpcHQncyBmbG9hdGluZy1wb2ludCByZXByZXNlbnRhdGlvbiB3aXRob3V0IG92ZXJmbG93XHJcbi8vIG9yIGNoYW5nZSBpbiBzaWduLlxyXG4vL1xyXG4vLyBJbiB0aGUgYWxnb3JpdGhtcyBiZWxvdywgd2UgZnJlcXVlbnRseSByZWR1Y2UgdGhlIG5lZ2F0aXZlIGNhc2UgdG8gdGhlXHJcbi8vIHBvc2l0aXZlIGNhc2UgYnkgbmVnYXRpbmcgdGhlIGlucHV0KHMpIGFuZCB0aGVuIHBvc3QtcHJvY2Vzc2luZyB0aGUgcmVzdWx0LlxyXG4vLyBOb3RlIHRoYXQgd2UgbXVzdCBBTFdBWVMgY2hlY2sgc3BlY2lhbGx5IHdoZXRoZXIgdGhvc2UgdmFsdWVzIGFyZSBNSU5fVkFMVUVcclxuLy8gKC0yXjYzKSBiZWNhdXNlIC1NSU5fVkFMVUUgPT0gTUlOX1ZBTFVFIChzaW5jZSAyXjYzIGNhbm5vdCBiZSByZXByZXNlbnRlZCBhc1xyXG4vLyBhIHBvc2l0aXZlIG51bWJlciwgaXQgb3ZlcmZsb3dzIGJhY2sgaW50byBhIG5lZ2F0aXZlKS4gIE5vdCBoYW5kbGluZyB0aGlzXHJcbi8vIGNhc2Ugd291bGQgb2Z0ZW4gcmVzdWx0IGluIGluZmluaXRlIHJlY3Vyc2lvbi5cclxuLy9cclxuLy8gQ29tbW9uIGNvbnN0YW50IHZhbHVlcyBaRVJPLCBPTkUsIE5FR19PTkUsIGV0Yy4gYXJlIGRlZmluZWQgYmVsb3cgdGhlIGZyb20qXHJcbi8vIG1ldGhvZHMgb24gd2hpY2ggdGhleSBkZXBlbmQuXHJcblxyXG4vKipcclxuICogQW4gaW5kaWNhdG9yIHVzZWQgdG8gcmVsaWFibHkgZGV0ZXJtaW5lIGlmIGFuIG9iamVjdCBpcyBhIExvbmcgb3Igbm90LlxyXG4gKiBAdHlwZSB7Ym9vbGVhbn1cclxuICogQGNvbnN0XHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5Mb25nLnByb3RvdHlwZS5fX2lzTG9uZ19fO1xyXG5cclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KExvbmcucHJvdG90eXBlLCBcIl9faXNMb25nX19cIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxuXHJcbi8qKlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHsqfSBvYmogT2JqZWN0XHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKiBAaW5uZXJcclxuICovXHJcbmZ1bmN0aW9uIGlzTG9uZyhvYmopIHtcclxuICAgIHJldHVybiAob2JqICYmIG9ialtcIl9faXNMb25nX19cIl0pID09PSB0cnVlO1xyXG59XHJcblxyXG4vKipcclxuICogVGVzdHMgaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgYSBMb25nLlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHsqfSBvYmogT2JqZWN0XHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKi9cclxuTG9uZy5pc0xvbmcgPSBpc0xvbmc7XHJcblxyXG4vKipcclxuICogQSBjYWNoZSBvZiB0aGUgTG9uZyByZXByZXNlbnRhdGlvbnMgb2Ygc21hbGwgaW50ZWdlciB2YWx1ZXMuXHJcbiAqIEB0eXBlIHshT2JqZWN0fVxyXG4gKiBAaW5uZXJcclxuICovXHJcbnZhciBJTlRfQ0FDSEUgPSB7fTtcclxuXHJcbi8qKlxyXG4gKiBBIGNhY2hlIG9mIHRoZSBMb25nIHJlcHJlc2VudGF0aW9ucyBvZiBzbWFsbCB1bnNpZ25lZCBpbnRlZ2VyIHZhbHVlcy5cclxuICogQHR5cGUgeyFPYmplY3R9XHJcbiAqIEBpbm5lclxyXG4gKi9cclxudmFyIFVJTlRfQ0FDSEUgPSB7fTtcclxuXHJcbi8qKlxyXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcclxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWRcclxuICogQHJldHVybnMgeyFMb25nfVxyXG4gKiBAaW5uZXJcclxuICovXHJcbmZ1bmN0aW9uIGZyb21JbnQodmFsdWUsIHVuc2lnbmVkKSB7XHJcbiAgICB2YXIgb2JqLCBjYWNoZWRPYmosIGNhY2hlO1xyXG4gICAgaWYgKHVuc2lnbmVkKSB7XHJcbiAgICAgICAgdmFsdWUgPj4+PSAwO1xyXG4gICAgICAgIGlmIChjYWNoZSA9ICgwIDw9IHZhbHVlICYmIHZhbHVlIDwgMjU2KSkge1xyXG4gICAgICAgICAgICBjYWNoZWRPYmogPSBVSU5UX0NBQ0hFW3ZhbHVlXTtcclxuICAgICAgICAgICAgaWYgKGNhY2hlZE9iailcclxuICAgICAgICAgICAgICAgIHJldHVybiBjYWNoZWRPYmo7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIG9iaiA9IGZyb21CaXRzKHZhbHVlLCAodmFsdWUgfCAwKSA8IDAgPyAtMSA6IDAsIHRydWUpO1xyXG4gICAgICAgIGlmIChjYWNoZSlcclxuICAgICAgICAgICAgVUlOVF9DQUNIRVt2YWx1ZV0gPSBvYmo7XHJcbiAgICAgICAgcmV0dXJuIG9iajtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdmFsdWUgfD0gMDtcclxuICAgICAgICBpZiAoY2FjaGUgPSAoLTEyOCA8PSB2YWx1ZSAmJiB2YWx1ZSA8IDEyOCkpIHtcclxuICAgICAgICAgICAgY2FjaGVkT2JqID0gSU5UX0NBQ0hFW3ZhbHVlXTtcclxuICAgICAgICAgICAgaWYgKGNhY2hlZE9iailcclxuICAgICAgICAgICAgICAgIHJldHVybiBjYWNoZWRPYmo7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIG9iaiA9IGZyb21CaXRzKHZhbHVlLCB2YWx1ZSA8IDAgPyAtMSA6IDAsIGZhbHNlKTtcclxuICAgICAgICBpZiAoY2FjaGUpXHJcbiAgICAgICAgICAgIElOVF9DQUNIRVt2YWx1ZV0gPSBvYmo7XHJcbiAgICAgICAgcmV0dXJuIG9iajtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgYSBMb25nIHJlcHJlc2VudGluZyB0aGUgZ2l2ZW4gMzIgYml0IGludGVnZXIgdmFsdWUuXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVGhlIDMyIGJpdCBpbnRlZ2VyIGluIHF1ZXN0aW9uXHJcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcclxuICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXHJcbiAqL1xyXG5Mb25nLmZyb21JbnQgPSBmcm9tSW50O1xyXG5cclxuLyoqXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxyXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZFxyXG4gKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAqIEBpbm5lclxyXG4gKi9cclxuZnVuY3Rpb24gZnJvbU51bWJlcih2YWx1ZSwgdW5zaWduZWQpIHtcclxuICAgIGlmIChpc05hTih2YWx1ZSkpXHJcbiAgICAgICAgcmV0dXJuIHVuc2lnbmVkID8gVVpFUk8gOiBaRVJPO1xyXG4gICAgaWYgKHVuc2lnbmVkKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlIDwgMClcclxuICAgICAgICAgICAgcmV0dXJuIFVaRVJPO1xyXG4gICAgICAgIGlmICh2YWx1ZSA+PSBUV09fUFdSXzY0X0RCTClcclxuICAgICAgICAgICAgcmV0dXJuIE1BWF9VTlNJR05FRF9WQUxVRTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgaWYgKHZhbHVlIDw9IC1UV09fUFdSXzYzX0RCTClcclxuICAgICAgICAgICAgcmV0dXJuIE1JTl9WQUxVRTtcclxuICAgICAgICBpZiAodmFsdWUgKyAxID49IFRXT19QV1JfNjNfREJMKVxyXG4gICAgICAgICAgICByZXR1cm4gTUFYX1ZBTFVFO1xyXG4gICAgfVxyXG4gICAgaWYgKHZhbHVlIDwgMClcclxuICAgICAgICByZXR1cm4gZnJvbU51bWJlcigtdmFsdWUsIHVuc2lnbmVkKS5uZWcoKTtcclxuICAgIHJldHVybiBmcm9tQml0cygodmFsdWUgJSBUV09fUFdSXzMyX0RCTCkgfCAwLCAodmFsdWUgLyBUV09fUFdSXzMyX0RCTCkgfCAwLCB1bnNpZ25lZCk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIGEgTG9uZyByZXByZXNlbnRpbmcgdGhlIGdpdmVuIHZhbHVlLCBwcm92aWRlZCB0aGF0IGl0IGlzIGEgZmluaXRlIG51bWJlci4gT3RoZXJ3aXNlLCB6ZXJvIGlzIHJldHVybmVkLlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFRoZSBudW1iZXIgaW4gcXVlc3Rpb25cclxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcclxuICovXHJcbkxvbmcuZnJvbU51bWJlciA9IGZyb21OdW1iZXI7XHJcblxyXG4vKipcclxuICogQHBhcmFtIHtudW1iZXJ9IGxvd0JpdHNcclxuICogQHBhcmFtIHtudW1iZXJ9IGhpZ2hCaXRzXHJcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkXHJcbiAqIEByZXR1cm5zIHshTG9uZ31cclxuICogQGlubmVyXHJcbiAqL1xyXG5mdW5jdGlvbiBmcm9tQml0cyhsb3dCaXRzLCBoaWdoQml0cywgdW5zaWduZWQpIHtcclxuICAgIHJldHVybiBuZXcgTG9uZyhsb3dCaXRzLCBoaWdoQml0cywgdW5zaWduZWQpO1xyXG59XHJcblxyXG4vKipcclxuICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50aW5nIHRoZSA2NCBiaXQgaW50ZWdlciB0aGF0IGNvbWVzIGJ5IGNvbmNhdGVuYXRpbmcgdGhlIGdpdmVuIGxvdyBhbmQgaGlnaCBiaXRzLiBFYWNoIGlzXHJcbiAqICBhc3N1bWVkIHRvIHVzZSAzMiBiaXRzLlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtudW1iZXJ9IGxvd0JpdHMgVGhlIGxvdyAzMiBiaXRzXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBoaWdoQml0cyBUaGUgaGlnaCAzMiBiaXRzXHJcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcclxuICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXHJcbiAqL1xyXG5Mb25nLmZyb21CaXRzID0gZnJvbUJpdHM7XHJcblxyXG4vKipcclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBiYXNlXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBleHBvbmVudFxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gKiBAaW5uZXJcclxuICovXHJcbnZhciBwb3dfZGJsID0gTWF0aC5wb3c7IC8vIFVzZWQgNCB0aW1lcyAoNCo4IHRvIDE1KzQpXHJcblxyXG4vKipcclxuICogQHBhcmFtIHtzdHJpbmd9IHN0clxyXG4gKiBAcGFyYW0geyhib29sZWFufG51bWJlcik9fSB1bnNpZ25lZFxyXG4gKiBAcGFyYW0ge251bWJlcj19IHJhZGl4XHJcbiAqIEByZXR1cm5zIHshTG9uZ31cclxuICogQGlubmVyXHJcbiAqL1xyXG5mdW5jdGlvbiBmcm9tU3RyaW5nKHN0ciwgdW5zaWduZWQsIHJhZGl4KSB7XHJcbiAgICBpZiAoc3RyLmxlbmd0aCA9PT0gMClcclxuICAgICAgICB0aHJvdyBFcnJvcignZW1wdHkgc3RyaW5nJyk7XHJcbiAgICBpZiAoc3RyID09PSBcIk5hTlwiIHx8IHN0ciA9PT0gXCJJbmZpbml0eVwiIHx8IHN0ciA9PT0gXCIrSW5maW5pdHlcIiB8fCBzdHIgPT09IFwiLUluZmluaXR5XCIpXHJcbiAgICAgICAgcmV0dXJuIFpFUk87XHJcbiAgICBpZiAodHlwZW9mIHVuc2lnbmVkID09PSAnbnVtYmVyJykge1xyXG4gICAgICAgIC8vIEZvciBnb29nLm1hdGgubG9uZyBjb21wYXRpYmlsaXR5XHJcbiAgICAgICAgcmFkaXggPSB1bnNpZ25lZCxcclxuICAgICAgICB1bnNpZ25lZCA9IGZhbHNlO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICB1bnNpZ25lZCA9ICEhIHVuc2lnbmVkO1xyXG4gICAgfVxyXG4gICAgcmFkaXggPSByYWRpeCB8fCAxMDtcclxuICAgIGlmIChyYWRpeCA8IDIgfHwgMzYgPCByYWRpeClcclxuICAgICAgICB0aHJvdyBSYW5nZUVycm9yKCdyYWRpeCcpO1xyXG5cclxuICAgIHZhciBwO1xyXG4gICAgaWYgKChwID0gc3RyLmluZGV4T2YoJy0nKSkgPiAwKVxyXG4gICAgICAgIHRocm93IEVycm9yKCdpbnRlcmlvciBoeXBoZW4nKTtcclxuICAgIGVsc2UgaWYgKHAgPT09IDApIHtcclxuICAgICAgICByZXR1cm4gZnJvbVN0cmluZyhzdHIuc3Vic3RyaW5nKDEpLCB1bnNpZ25lZCwgcmFkaXgpLm5lZygpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIERvIHNldmVyYWwgKDgpIGRpZ2l0cyBlYWNoIHRpbWUgdGhyb3VnaCB0aGUgbG9vcCwgc28gYXMgdG9cclxuICAgIC8vIG1pbmltaXplIHRoZSBjYWxscyB0byB0aGUgdmVyeSBleHBlbnNpdmUgZW11bGF0ZWQgZGl2LlxyXG4gICAgdmFyIHJhZGl4VG9Qb3dlciA9IGZyb21OdW1iZXIocG93X2RibChyYWRpeCwgOCkpO1xyXG5cclxuICAgIHZhciByZXN1bHQgPSBaRVJPO1xyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpICs9IDgpIHtcclxuICAgICAgICB2YXIgc2l6ZSA9IE1hdGgubWluKDgsIHN0ci5sZW5ndGggLSBpKSxcclxuICAgICAgICAgICAgdmFsdWUgPSBwYXJzZUludChzdHIuc3Vic3RyaW5nKGksIGkgKyBzaXplKSwgcmFkaXgpO1xyXG4gICAgICAgIGlmIChzaXplIDwgOCkge1xyXG4gICAgICAgICAgICB2YXIgcG93ZXIgPSBmcm9tTnVtYmVyKHBvd19kYmwocmFkaXgsIHNpemUpKTtcclxuICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0Lm11bChwb3dlcikuYWRkKGZyb21OdW1iZXIodmFsdWUpKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXN1bHQgPSByZXN1bHQubXVsKHJhZGl4VG9Qb3dlcik7XHJcbiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5hZGQoZnJvbU51bWJlcih2YWx1ZSkpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJlc3VsdC51bnNpZ25lZCA9IHVuc2lnbmVkO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgYSBMb25nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiBzdHJpbmcsIHdyaXR0ZW4gdXNpbmcgdGhlIHNwZWNpZmllZCByYWRpeC5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgVGhlIHRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIExvbmdcclxuICogQHBhcmFtIHsoYm9vbGVhbnxudW1iZXIpPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxyXG4gKiBAcGFyYW0ge251bWJlcj19IHJhZGl4IFRoZSByYWRpeCBpbiB3aGljaCB0aGUgdGV4dCBpcyB3cml0dGVuICgyLTM2KSwgZGVmYXVsdHMgdG8gMTBcclxuICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXHJcbiAqL1xyXG5Mb25nLmZyb21TdHJpbmcgPSBmcm9tU3RyaW5nO1xyXG5cclxuLyoqXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd8IXtsb3c6IG51bWJlciwgaGlnaDogbnVtYmVyLCB1bnNpZ25lZDogYm9vbGVhbn19IHZhbFxyXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZFxyXG4gKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAqIEBpbm5lclxyXG4gKi9cclxuZnVuY3Rpb24gZnJvbVZhbHVlKHZhbCwgdW5zaWduZWQpIHtcclxuICAgIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJylcclxuICAgICAgICByZXR1cm4gZnJvbU51bWJlcih2YWwsIHVuc2lnbmVkKTtcclxuICAgIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJylcclxuICAgICAgICByZXR1cm4gZnJvbVN0cmluZyh2YWwsIHVuc2lnbmVkKTtcclxuICAgIC8vIFRocm93cyBmb3Igbm9uLW9iamVjdHMsIGNvbnZlcnRzIG5vbi1pbnN0YW5jZW9mIExvbmc6XHJcbiAgICByZXR1cm4gZnJvbUJpdHModmFsLmxvdywgdmFsLmhpZ2gsIHR5cGVvZiB1bnNpZ25lZCA9PT0gJ2Jvb2xlYW4nID8gdW5zaWduZWQgOiB2YWwudW5zaWduZWQpO1xyXG59XHJcblxyXG4vKipcclxuICogQ29udmVydHMgdGhlIHNwZWNpZmllZCB2YWx1ZSB0byBhIExvbmcgdXNpbmcgdGhlIGFwcHJvcHJpYXRlIGZyb20qIGZ1bmN0aW9uIGZvciBpdHMgdHlwZS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ3whe2xvdzogbnVtYmVyLCBoaWdoOiBudW1iZXIsIHVuc2lnbmVkOiBib29sZWFufX0gdmFsIFZhbHVlXHJcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcclxuICogQHJldHVybnMgeyFMb25nfVxyXG4gKi9cclxuTG9uZy5mcm9tVmFsdWUgPSBmcm9tVmFsdWU7XHJcblxyXG4vLyBOT1RFOiB0aGUgY29tcGlsZXIgc2hvdWxkIGlubGluZSB0aGVzZSBjb25zdGFudCB2YWx1ZXMgYmVsb3cgYW5kIHRoZW4gcmVtb3ZlIHRoZXNlIHZhcmlhYmxlcywgc28gdGhlcmUgc2hvdWxkIGJlXHJcbi8vIG5vIHJ1bnRpbWUgcGVuYWx0eSBmb3IgdGhlc2UuXHJcblxyXG4vKipcclxuICogQHR5cGUge251bWJlcn1cclxuICogQGNvbnN0XHJcbiAqIEBpbm5lclxyXG4gKi9cclxudmFyIFRXT19QV1JfMTZfREJMID0gMSA8PCAxNjtcclxuXHJcbi8qKlxyXG4gKiBAdHlwZSB7bnVtYmVyfVxyXG4gKiBAY29uc3RcclxuICogQGlubmVyXHJcbiAqL1xyXG52YXIgVFdPX1BXUl8yNF9EQkwgPSAxIDw8IDI0O1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlIHtudW1iZXJ9XHJcbiAqIEBjb25zdFxyXG4gKiBAaW5uZXJcclxuICovXHJcbnZhciBUV09fUFdSXzMyX0RCTCA9IFRXT19QV1JfMTZfREJMICogVFdPX1BXUl8xNl9EQkw7XHJcblxyXG4vKipcclxuICogQHR5cGUge251bWJlcn1cclxuICogQGNvbnN0XHJcbiAqIEBpbm5lclxyXG4gKi9cclxudmFyIFRXT19QV1JfNjRfREJMID0gVFdPX1BXUl8zMl9EQkwgKiBUV09fUFdSXzMyX0RCTDtcclxuXHJcbi8qKlxyXG4gKiBAdHlwZSB7bnVtYmVyfVxyXG4gKiBAY29uc3RcclxuICogQGlubmVyXHJcbiAqL1xyXG52YXIgVFdPX1BXUl82M19EQkwgPSBUV09fUFdSXzY0X0RCTCAvIDI7XHJcblxyXG4vKipcclxuICogQHR5cGUgeyFMb25nfVxyXG4gKiBAY29uc3RcclxuICogQGlubmVyXHJcbiAqL1xyXG52YXIgVFdPX1BXUl8yNCA9IGZyb21JbnQoVFdPX1BXUl8yNF9EQkwpO1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlIHshTG9uZ31cclxuICogQGlubmVyXHJcbiAqL1xyXG52YXIgWkVSTyA9IGZyb21JbnQoMCk7XHJcblxyXG4vKipcclxuICogU2lnbmVkIHplcm8uXHJcbiAqIEB0eXBlIHshTG9uZ31cclxuICovXHJcbkxvbmcuWkVSTyA9IFpFUk87XHJcblxyXG4vKipcclxuICogQHR5cGUgeyFMb25nfVxyXG4gKiBAaW5uZXJcclxuICovXHJcbnZhciBVWkVSTyA9IGZyb21JbnQoMCwgdHJ1ZSk7XHJcblxyXG4vKipcclxuICogVW5zaWduZWQgemVyby5cclxuICogQHR5cGUgeyFMb25nfVxyXG4gKi9cclxuTG9uZy5VWkVSTyA9IFVaRVJPO1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlIHshTG9uZ31cclxuICogQGlubmVyXHJcbiAqL1xyXG52YXIgT05FID0gZnJvbUludCgxKTtcclxuXHJcbi8qKlxyXG4gKiBTaWduZWQgb25lLlxyXG4gKiBAdHlwZSB7IUxvbmd9XHJcbiAqL1xyXG5Mb25nLk9ORSA9IE9ORTtcclxuXHJcbi8qKlxyXG4gKiBAdHlwZSB7IUxvbmd9XHJcbiAqIEBpbm5lclxyXG4gKi9cclxudmFyIFVPTkUgPSBmcm9tSW50KDEsIHRydWUpO1xyXG5cclxuLyoqXHJcbiAqIFVuc2lnbmVkIG9uZS5cclxuICogQHR5cGUgeyFMb25nfVxyXG4gKi9cclxuTG9uZy5VT05FID0gVU9ORTtcclxuXHJcbi8qKlxyXG4gKiBAdHlwZSB7IUxvbmd9XHJcbiAqIEBpbm5lclxyXG4gKi9cclxudmFyIE5FR19PTkUgPSBmcm9tSW50KC0xKTtcclxuXHJcbi8qKlxyXG4gKiBTaWduZWQgbmVnYXRpdmUgb25lLlxyXG4gKiBAdHlwZSB7IUxvbmd9XHJcbiAqL1xyXG5Mb25nLk5FR19PTkUgPSBORUdfT05FO1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlIHshTG9uZ31cclxuICogQGlubmVyXHJcbiAqL1xyXG52YXIgTUFYX1ZBTFVFID0gZnJvbUJpdHMoMHhGRkZGRkZGRnwwLCAweDdGRkZGRkZGfDAsIGZhbHNlKTtcclxuXHJcbi8qKlxyXG4gKiBNYXhpbXVtIHNpZ25lZCB2YWx1ZS5cclxuICogQHR5cGUgeyFMb25nfVxyXG4gKi9cclxuTG9uZy5NQVhfVkFMVUUgPSBNQVhfVkFMVUU7XHJcblxyXG4vKipcclxuICogQHR5cGUgeyFMb25nfVxyXG4gKiBAaW5uZXJcclxuICovXHJcbnZhciBNQVhfVU5TSUdORURfVkFMVUUgPSBmcm9tQml0cygweEZGRkZGRkZGfDAsIDB4RkZGRkZGRkZ8MCwgdHJ1ZSk7XHJcblxyXG4vKipcclxuICogTWF4aW11bSB1bnNpZ25lZCB2YWx1ZS5cclxuICogQHR5cGUgeyFMb25nfVxyXG4gKi9cclxuTG9uZy5NQVhfVU5TSUdORURfVkFMVUUgPSBNQVhfVU5TSUdORURfVkFMVUU7XHJcblxyXG4vKipcclxuICogQHR5cGUgeyFMb25nfVxyXG4gKiBAaW5uZXJcclxuICovXHJcbnZhciBNSU5fVkFMVUUgPSBmcm9tQml0cygwLCAweDgwMDAwMDAwfDAsIGZhbHNlKTtcclxuXHJcbi8qKlxyXG4gKiBNaW5pbXVtIHNpZ25lZCB2YWx1ZS5cclxuICogQHR5cGUgeyFMb25nfVxyXG4gKi9cclxuTG9uZy5NSU5fVkFMVUUgPSBNSU5fVkFMVUU7XHJcblxyXG4vKipcclxuICogQGFsaWFzIExvbmcucHJvdG90eXBlXHJcbiAqIEBpbm5lclxyXG4gKi9cclxudmFyIExvbmdQcm90b3R5cGUgPSBMb25nLnByb3RvdHlwZTtcclxuXHJcbi8qKlxyXG4gKiBDb252ZXJ0cyB0aGUgTG9uZyB0byBhIDMyIGJpdCBpbnRlZ2VyLCBhc3N1bWluZyBpdCBpcyBhIDMyIGJpdCBpbnRlZ2VyLlxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS50b0ludCA9IGZ1bmN0aW9uIHRvSW50KCkge1xyXG4gICAgcmV0dXJuIHRoaXMudW5zaWduZWQgPyB0aGlzLmxvdyA+Pj4gMCA6IHRoaXMubG93O1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIENvbnZlcnRzIHRoZSBMb25nIHRvIGEgdGhlIG5lYXJlc3QgZmxvYXRpbmctcG9pbnQgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB2YWx1ZSAoZG91YmxlLCA1MyBiaXQgbWFudGlzc2EpLlxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS50b051bWJlciA9IGZ1bmN0aW9uIHRvTnVtYmVyKCkge1xyXG4gICAgaWYgKHRoaXMudW5zaWduZWQpXHJcbiAgICAgICAgcmV0dXJuICgodGhpcy5oaWdoID4+PiAwKSAqIFRXT19QV1JfMzJfREJMKSArICh0aGlzLmxvdyA+Pj4gMCk7XHJcbiAgICByZXR1cm4gdGhpcy5oaWdoICogVFdPX1BXUl8zMl9EQkwgKyAodGhpcy5sb3cgPj4+IDApO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIENvbnZlcnRzIHRoZSBMb25nIHRvIGEgc3RyaW5nIHdyaXR0ZW4gaW4gdGhlIHNwZWNpZmllZCByYWRpeC5cclxuICogQHBhcmFtIHtudW1iZXI9fSByYWRpeCBSYWRpeCAoMi0zNiksIGRlZmF1bHRzIHRvIDEwXHJcbiAqIEByZXR1cm5zIHtzdHJpbmd9XHJcbiAqIEBvdmVycmlkZVxyXG4gKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgcmFkaXhgIGlzIG91dCBvZiByYW5nZVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKHJhZGl4KSB7XHJcbiAgICByYWRpeCA9IHJhZGl4IHx8IDEwO1xyXG4gICAgaWYgKHJhZGl4IDwgMiB8fCAzNiA8IHJhZGl4KVxyXG4gICAgICAgIHRocm93IFJhbmdlRXJyb3IoJ3JhZGl4Jyk7XHJcbiAgICBpZiAodGhpcy5pc1plcm8oKSlcclxuICAgICAgICByZXR1cm4gJzAnO1xyXG4gICAgaWYgKHRoaXMuaXNOZWdhdGl2ZSgpKSB7IC8vIFVuc2lnbmVkIExvbmdzIGFyZSBuZXZlciBuZWdhdGl2ZVxyXG4gICAgICAgIGlmICh0aGlzLmVxKE1JTl9WQUxVRSkpIHtcclxuICAgICAgICAgICAgLy8gV2UgbmVlZCB0byBjaGFuZ2UgdGhlIExvbmcgdmFsdWUgYmVmb3JlIGl0IGNhbiBiZSBuZWdhdGVkLCBzbyB3ZSByZW1vdmVcclxuICAgICAgICAgICAgLy8gdGhlIGJvdHRvbS1tb3N0IGRpZ2l0IGluIHRoaXMgYmFzZSBhbmQgdGhlbiByZWN1cnNlIHRvIGRvIHRoZSByZXN0LlxyXG4gICAgICAgICAgICB2YXIgcmFkaXhMb25nID0gZnJvbU51bWJlcihyYWRpeCksXHJcbiAgICAgICAgICAgICAgICBkaXYgPSB0aGlzLmRpdihyYWRpeExvbmcpLFxyXG4gICAgICAgICAgICAgICAgcmVtMSA9IGRpdi5tdWwocmFkaXhMb25nKS5zdWIodGhpcyk7XHJcbiAgICAgICAgICAgIHJldHVybiBkaXYudG9TdHJpbmcocmFkaXgpICsgcmVtMS50b0ludCgpLnRvU3RyaW5nKHJhZGl4KTtcclxuICAgICAgICB9IGVsc2VcclxuICAgICAgICAgICAgcmV0dXJuICctJyArIHRoaXMubmVnKCkudG9TdHJpbmcocmFkaXgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIERvIHNldmVyYWwgKDYpIGRpZ2l0cyBlYWNoIHRpbWUgdGhyb3VnaCB0aGUgbG9vcCwgc28gYXMgdG9cclxuICAgIC8vIG1pbmltaXplIHRoZSBjYWxscyB0byB0aGUgdmVyeSBleHBlbnNpdmUgZW11bGF0ZWQgZGl2LlxyXG4gICAgdmFyIHJhZGl4VG9Qb3dlciA9IGZyb21OdW1iZXIocG93X2RibChyYWRpeCwgNiksIHRoaXMudW5zaWduZWQpLFxyXG4gICAgICAgIHJlbSA9IHRoaXM7XHJcbiAgICB2YXIgcmVzdWx0ID0gJyc7XHJcbiAgICB3aGlsZSAodHJ1ZSkge1xyXG4gICAgICAgIHZhciByZW1EaXYgPSByZW0uZGl2KHJhZGl4VG9Qb3dlciksXHJcbiAgICAgICAgICAgIGludHZhbCA9IHJlbS5zdWIocmVtRGl2Lm11bChyYWRpeFRvUG93ZXIpKS50b0ludCgpID4+PiAwLFxyXG4gICAgICAgICAgICBkaWdpdHMgPSBpbnR2YWwudG9TdHJpbmcocmFkaXgpO1xyXG4gICAgICAgIHJlbSA9IHJlbURpdjtcclxuICAgICAgICBpZiAocmVtLmlzWmVybygpKVxyXG4gICAgICAgICAgICByZXR1cm4gZGlnaXRzICsgcmVzdWx0O1xyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB3aGlsZSAoZGlnaXRzLmxlbmd0aCA8IDYpXHJcbiAgICAgICAgICAgICAgICBkaWdpdHMgPSAnMCcgKyBkaWdpdHM7XHJcbiAgICAgICAgICAgIHJlc3VsdCA9ICcnICsgZGlnaXRzICsgcmVzdWx0O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufTtcclxuXHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBoaWdoIDMyIGJpdHMgYXMgYSBzaWduZWQgaW50ZWdlci5cclxuICogQHJldHVybnMge251bWJlcn0gU2lnbmVkIGhpZ2ggYml0c1xyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5nZXRIaWdoQml0cyA9IGZ1bmN0aW9uIGdldEhpZ2hCaXRzKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuaGlnaDtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBoaWdoIDMyIGJpdHMgYXMgYW4gdW5zaWduZWQgaW50ZWdlci5cclxuICogQHJldHVybnMge251bWJlcn0gVW5zaWduZWQgaGlnaCBiaXRzXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmdldEhpZ2hCaXRzVW5zaWduZWQgPSBmdW5jdGlvbiBnZXRIaWdoQml0c1Vuc2lnbmVkKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuaGlnaCA+Pj4gMDtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBsb3cgMzIgYml0cyBhcyBhIHNpZ25lZCBpbnRlZ2VyLlxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBTaWduZWQgbG93IGJpdHNcclxuICovXHJcbkxvbmdQcm90b3R5cGUuZ2V0TG93Qml0cyA9IGZ1bmN0aW9uIGdldExvd0JpdHMoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5sb3c7XHJcbn07XHJcblxyXG4vKipcclxuICogR2V0cyB0aGUgbG93IDMyIGJpdHMgYXMgYW4gdW5zaWduZWQgaW50ZWdlci5cclxuICogQHJldHVybnMge251bWJlcn0gVW5zaWduZWQgbG93IGJpdHNcclxuICovXHJcbkxvbmdQcm90b3R5cGUuZ2V0TG93Qml0c1Vuc2lnbmVkID0gZnVuY3Rpb24gZ2V0TG93Qml0c1Vuc2lnbmVkKCkge1xyXG4gICAgcmV0dXJuIHRoaXMubG93ID4+PiAwO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEdldHMgdGhlIG51bWJlciBvZiBiaXRzIG5lZWRlZCB0byByZXByZXNlbnQgdGhlIGFic29sdXRlIHZhbHVlIG9mIHRoaXMgTG9uZy5cclxuICogQHJldHVybnMge251bWJlcn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUuZ2V0TnVtQml0c0FicyA9IGZ1bmN0aW9uIGdldE51bUJpdHNBYnMoKSB7XHJcbiAgICBpZiAodGhpcy5pc05lZ2F0aXZlKCkpIC8vIFVuc2lnbmVkIExvbmdzIGFyZSBuZXZlciBuZWdhdGl2ZVxyXG4gICAgICAgIHJldHVybiB0aGlzLmVxKE1JTl9WQUxVRSkgPyA2NCA6IHRoaXMubmVnKCkuZ2V0TnVtQml0c0FicygpO1xyXG4gICAgdmFyIHZhbCA9IHRoaXMuaGlnaCAhPSAwID8gdGhpcy5oaWdoIDogdGhpcy5sb3c7XHJcbiAgICBmb3IgKHZhciBiaXQgPSAzMTsgYml0ID4gMDsgYml0LS0pXHJcbiAgICAgICAgaWYgKCh2YWwgJiAoMSA8PCBiaXQpKSAhPSAwKVxyXG4gICAgICAgICAgICBicmVhaztcclxuICAgIHJldHVybiB0aGlzLmhpZ2ggIT0gMCA/IGJpdCArIDMzIDogYml0ICsgMTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBlcXVhbHMgemVyby5cclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmlzWmVybyA9IGZ1bmN0aW9uIGlzWmVybygpIHtcclxuICAgIHJldHVybiB0aGlzLmhpZ2ggPT09IDAgJiYgdGhpcy5sb3cgPT09IDA7XHJcbn07XHJcblxyXG4vKipcclxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZXF1YWxzIHplcm8uIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjaXNaZXJvfS5cclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmVxeiA9IExvbmdQcm90b3R5cGUuaXNaZXJvO1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIG5lZ2F0aXZlLlxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUuaXNOZWdhdGl2ZSA9IGZ1bmN0aW9uIGlzTmVnYXRpdmUoKSB7XHJcbiAgICByZXR1cm4gIXRoaXMudW5zaWduZWQgJiYgdGhpcy5oaWdoIDwgMDtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBwb3NpdGl2ZS5cclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmlzUG9zaXRpdmUgPSBmdW5jdGlvbiBpc1Bvc2l0aXZlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMudW5zaWduZWQgfHwgdGhpcy5oaWdoID49IDA7XHJcbn07XHJcblxyXG4vKipcclxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgb2RkLlxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUuaXNPZGQgPSBmdW5jdGlvbiBpc09kZCgpIHtcclxuICAgIHJldHVybiAodGhpcy5sb3cgJiAxKSA9PT0gMTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBldmVuLlxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUuaXNFdmVuID0gZnVuY3Rpb24gaXNFdmVuKCkge1xyXG4gICAgcmV0dXJuICh0aGlzLmxvdyAmIDEpID09PSAwO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGVxdWFscyB0aGUgc3BlY2lmaWVkJ3MuXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIGVxdWFscyhvdGhlcikge1xyXG4gICAgaWYgKCFpc0xvbmcob3RoZXIpKVxyXG4gICAgICAgIG90aGVyID0gZnJvbVZhbHVlKG90aGVyKTtcclxuICAgIGlmICh0aGlzLnVuc2lnbmVkICE9PSBvdGhlci51bnNpZ25lZCAmJiAodGhpcy5oaWdoID4+PiAzMSkgPT09IDEgJiYgKG90aGVyLmhpZ2ggPj4+IDMxKSA9PT0gMSlcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICByZXR1cm4gdGhpcy5oaWdoID09PSBvdGhlci5oaWdoICYmIHRoaXMubG93ID09PSBvdGhlci5sb3c7XHJcbn07XHJcblxyXG4vKipcclxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZXF1YWxzIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNlcXVhbHN9LlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUuZXEgPSBMb25nUHJvdG90eXBlLmVxdWFscztcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBkaWZmZXJzIGZyb20gdGhlIHNwZWNpZmllZCdzLlxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5ub3RFcXVhbHMgPSBmdW5jdGlvbiBub3RFcXVhbHMob3RoZXIpIHtcclxuICAgIHJldHVybiAhdGhpcy5lcSgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGRpZmZlcnMgZnJvbSB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbm90RXF1YWxzfS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLm5lcSA9IExvbmdQcm90b3R5cGUubm90RXF1YWxzO1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGRpZmZlcnMgZnJvbSB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbm90RXF1YWxzfS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLm5lID0gTG9uZ1Byb3RvdHlwZS5ub3RFcXVhbHM7XHJcblxyXG4vKipcclxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbGVzcyB0aGFuIHRoZSBzcGVjaWZpZWQncy5cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUubGVzc1RoYW4gPSBmdW5jdGlvbiBsZXNzVGhhbihvdGhlcikge1xyXG4gICAgcmV0dXJuIHRoaXMuY29tcCgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpIDwgMDtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2xlc3NUaGFufS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmx0ID0gTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbjtcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdGhlIHNwZWNpZmllZCdzLlxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbk9yRXF1YWwgPSBmdW5jdGlvbiBsZXNzVGhhbk9yRXF1YWwob3RoZXIpIHtcclxuICAgIHJldHVybiB0aGlzLmNvbXAoLyogdmFsaWRhdGVzICovIG90aGVyKSA8PSAwO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbGVzc1RoYW5PckVxdWFsfS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmx0ZSA9IExvbmdQcm90b3R5cGUubGVzc1RoYW5PckVxdWFsO1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbGVzc1RoYW5PckVxdWFsfS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmxlID0gTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbk9yRXF1YWw7XHJcblxyXG4vKipcclxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIHRoZSBzcGVjaWZpZWQncy5cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW4gPSBmdW5jdGlvbiBncmVhdGVyVGhhbihvdGhlcikge1xyXG4gICAgcmV0dXJuIHRoaXMuY29tcCgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpID4gMDtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2dyZWF0ZXJUaGFufS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmd0ID0gTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbjtcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdGhlIHNwZWNpZmllZCdzLlxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbk9yRXF1YWwgPSBmdW5jdGlvbiBncmVhdGVyVGhhbk9yRXF1YWwob3RoZXIpIHtcclxuICAgIHJldHVybiB0aGlzLmNvbXAoLyogdmFsaWRhdGVzICovIG90aGVyKSA+PSAwO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjZ3JlYXRlclRoYW5PckVxdWFsfS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmd0ZSA9IExvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW5PckVxdWFsO1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjZ3JlYXRlclRoYW5PckVxdWFsfS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmdlID0gTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbk9yRXF1YWw7XHJcblxyXG4vKipcclxuICogQ29tcGFyZXMgdGhpcyBMb25nJ3MgdmFsdWUgd2l0aCB0aGUgc3BlY2lmaWVkJ3MuXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge251bWJlcn0gMCBpZiB0aGV5IGFyZSB0aGUgc2FtZSwgMSBpZiB0aGUgdGhpcyBpcyBncmVhdGVyIGFuZCAtMVxyXG4gKiAgaWYgdGhlIGdpdmVuIG9uZSBpcyBncmVhdGVyXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlKG90aGVyKSB7XHJcbiAgICBpZiAoIWlzTG9uZyhvdGhlcikpXHJcbiAgICAgICAgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xyXG4gICAgaWYgKHRoaXMuZXEob3RoZXIpKVxyXG4gICAgICAgIHJldHVybiAwO1xyXG4gICAgdmFyIHRoaXNOZWcgPSB0aGlzLmlzTmVnYXRpdmUoKSxcclxuICAgICAgICBvdGhlck5lZyA9IG90aGVyLmlzTmVnYXRpdmUoKTtcclxuICAgIGlmICh0aGlzTmVnICYmICFvdGhlck5lZylcclxuICAgICAgICByZXR1cm4gLTE7XHJcbiAgICBpZiAoIXRoaXNOZWcgJiYgb3RoZXJOZWcpXHJcbiAgICAgICAgcmV0dXJuIDE7XHJcbiAgICAvLyBBdCB0aGlzIHBvaW50IHRoZSBzaWduIGJpdHMgYXJlIHRoZSBzYW1lXHJcbiAgICBpZiAoIXRoaXMudW5zaWduZWQpXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc3ViKG90aGVyKS5pc05lZ2F0aXZlKCkgPyAtMSA6IDE7XHJcbiAgICAvLyBCb3RoIGFyZSBwb3NpdGl2ZSBpZiBhdCBsZWFzdCBvbmUgaXMgdW5zaWduZWRcclxuICAgIHJldHVybiAob3RoZXIuaGlnaCA+Pj4gMCkgPiAodGhpcy5oaWdoID4+PiAwKSB8fCAob3RoZXIuaGlnaCA9PT0gdGhpcy5oaWdoICYmIChvdGhlci5sb3cgPj4+IDApID4gKHRoaXMubG93ID4+PiAwKSkgPyAtMSA6IDE7XHJcbn07XHJcblxyXG4vKipcclxuICogQ29tcGFyZXMgdGhpcyBMb25nJ3MgdmFsdWUgd2l0aCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjY29tcGFyZX0uXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IDAgaWYgdGhleSBhcmUgdGhlIHNhbWUsIDEgaWYgdGhlIHRoaXMgaXMgZ3JlYXRlciBhbmQgLTFcclxuICogIGlmIHRoZSBnaXZlbiBvbmUgaXMgZ3JlYXRlclxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5jb21wID0gTG9uZ1Byb3RvdHlwZS5jb21wYXJlO1xyXG5cclxuLyoqXHJcbiAqIE5lZ2F0ZXMgdGhpcyBMb25nJ3MgdmFsdWUuXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gTmVnYXRlZCBMb25nXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLm5lZ2F0ZSA9IGZ1bmN0aW9uIG5lZ2F0ZSgpIHtcclxuICAgIGlmICghdGhpcy51bnNpZ25lZCAmJiB0aGlzLmVxKE1JTl9WQUxVRSkpXHJcbiAgICAgICAgcmV0dXJuIE1JTl9WQUxVRTtcclxuICAgIHJldHVybiB0aGlzLm5vdCgpLmFkZChPTkUpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIE5lZ2F0ZXMgdGhpcyBMb25nJ3MgdmFsdWUuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbmVnYXRlfS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gTmVnYXRlZCBMb25nXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLm5lZyA9IExvbmdQcm90b3R5cGUubmVnYXRlO1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhlIHN1bSBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gYWRkZW5kIEFkZGVuZFxyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFN1bVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiBhZGQoYWRkZW5kKSB7XHJcbiAgICBpZiAoIWlzTG9uZyhhZGRlbmQpKVxyXG4gICAgICAgIGFkZGVuZCA9IGZyb21WYWx1ZShhZGRlbmQpO1xyXG5cclxuICAgIC8vIERpdmlkZSBlYWNoIG51bWJlciBpbnRvIDQgY2h1bmtzIG9mIDE2IGJpdHMsIGFuZCB0aGVuIHN1bSB0aGUgY2h1bmtzLlxyXG5cclxuICAgIHZhciBhNDggPSB0aGlzLmhpZ2ggPj4+IDE2O1xyXG4gICAgdmFyIGEzMiA9IHRoaXMuaGlnaCAmIDB4RkZGRjtcclxuICAgIHZhciBhMTYgPSB0aGlzLmxvdyA+Pj4gMTY7XHJcbiAgICB2YXIgYTAwID0gdGhpcy5sb3cgJiAweEZGRkY7XHJcblxyXG4gICAgdmFyIGI0OCA9IGFkZGVuZC5oaWdoID4+PiAxNjtcclxuICAgIHZhciBiMzIgPSBhZGRlbmQuaGlnaCAmIDB4RkZGRjtcclxuICAgIHZhciBiMTYgPSBhZGRlbmQubG93ID4+PiAxNjtcclxuICAgIHZhciBiMDAgPSBhZGRlbmQubG93ICYgMHhGRkZGO1xyXG5cclxuICAgIHZhciBjNDggPSAwLCBjMzIgPSAwLCBjMTYgPSAwLCBjMDAgPSAwO1xyXG4gICAgYzAwICs9IGEwMCArIGIwMDtcclxuICAgIGMxNiArPSBjMDAgPj4+IDE2O1xyXG4gICAgYzAwICY9IDB4RkZGRjtcclxuICAgIGMxNiArPSBhMTYgKyBiMTY7XHJcbiAgICBjMzIgKz0gYzE2ID4+PiAxNjtcclxuICAgIGMxNiAmPSAweEZGRkY7XHJcbiAgICBjMzIgKz0gYTMyICsgYjMyO1xyXG4gICAgYzQ4ICs9IGMzMiA+Pj4gMTY7XHJcbiAgICBjMzIgJj0gMHhGRkZGO1xyXG4gICAgYzQ4ICs9IGE0OCArIGI0ODtcclxuICAgIGM0OCAmPSAweEZGRkY7XHJcbiAgICByZXR1cm4gZnJvbUJpdHMoKGMxNiA8PCAxNikgfCBjMDAsIChjNDggPDwgMTYpIHwgYzMyLCB0aGlzLnVuc2lnbmVkKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBkaWZmZXJlbmNlIG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy5cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBzdWJ0cmFoZW5kIFN1YnRyYWhlbmRcclxuICogQHJldHVybnMgeyFMb25nfSBEaWZmZXJlbmNlXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnN1YnRyYWN0ID0gZnVuY3Rpb24gc3VidHJhY3Qoc3VidHJhaGVuZCkge1xyXG4gICAgaWYgKCFpc0xvbmcoc3VidHJhaGVuZCkpXHJcbiAgICAgICAgc3VidHJhaGVuZCA9IGZyb21WYWx1ZShzdWJ0cmFoZW5kKTtcclxuICAgIHJldHVybiB0aGlzLmFkZChzdWJ0cmFoZW5kLm5lZygpKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBkaWZmZXJlbmNlIG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNzdWJ0cmFjdH0uXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IHN1YnRyYWhlbmQgU3VidHJhaGVuZFxyXG4gKiBAcmV0dXJucyB7IUxvbmd9IERpZmZlcmVuY2VcclxuICovXHJcbkxvbmdQcm90b3R5cGUuc3ViID0gTG9uZ1Byb3RvdHlwZS5zdWJ0cmFjdDtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBwcm9kdWN0IG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy5cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBtdWx0aXBsaWVyIE11bHRpcGxpZXJcclxuICogQHJldHVybnMgeyFMb25nfSBQcm9kdWN0XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLm11bHRpcGx5ID0gZnVuY3Rpb24gbXVsdGlwbHkobXVsdGlwbGllcikge1xyXG4gICAgaWYgKHRoaXMuaXNaZXJvKCkpXHJcbiAgICAgICAgcmV0dXJuIFpFUk87XHJcbiAgICBpZiAoIWlzTG9uZyhtdWx0aXBsaWVyKSlcclxuICAgICAgICBtdWx0aXBsaWVyID0gZnJvbVZhbHVlKG11bHRpcGxpZXIpO1xyXG5cclxuICAgIC8vIHVzZSB3YXNtIHN1cHBvcnQgaWYgcHJlc2VudFxyXG4gICAgaWYgKHdhc20pIHtcclxuICAgICAgICB2YXIgbG93ID0gd2FzbS5tdWwodGhpcy5sb3csXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaGlnaCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgbXVsdGlwbGllci5sb3csXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIG11bHRpcGxpZXIuaGlnaCk7XHJcbiAgICAgICAgcmV0dXJuIGZyb21CaXRzKGxvdywgd2FzbS5nZXRfaGlnaCgpLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAobXVsdGlwbGllci5pc1plcm8oKSlcclxuICAgICAgICByZXR1cm4gWkVSTztcclxuICAgIGlmICh0aGlzLmVxKE1JTl9WQUxVRSkpXHJcbiAgICAgICAgcmV0dXJuIG11bHRpcGxpZXIuaXNPZGQoKSA/IE1JTl9WQUxVRSA6IFpFUk87XHJcbiAgICBpZiAobXVsdGlwbGllci5lcShNSU5fVkFMVUUpKVxyXG4gICAgICAgIHJldHVybiB0aGlzLmlzT2RkKCkgPyBNSU5fVkFMVUUgOiBaRVJPO1xyXG5cclxuICAgIGlmICh0aGlzLmlzTmVnYXRpdmUoKSkge1xyXG4gICAgICAgIGlmIChtdWx0aXBsaWVyLmlzTmVnYXRpdmUoKSlcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubmVnKCkubXVsKG11bHRpcGxpZXIubmVnKCkpO1xyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubmVnKCkubXVsKG11bHRpcGxpZXIpLm5lZygpO1xyXG4gICAgfSBlbHNlIGlmIChtdWx0aXBsaWVyLmlzTmVnYXRpdmUoKSlcclxuICAgICAgICByZXR1cm4gdGhpcy5tdWwobXVsdGlwbGllci5uZWcoKSkubmVnKCk7XHJcblxyXG4gICAgLy8gSWYgYm90aCBsb25ncyBhcmUgc21hbGwsIHVzZSBmbG9hdCBtdWx0aXBsaWNhdGlvblxyXG4gICAgaWYgKHRoaXMubHQoVFdPX1BXUl8yNCkgJiYgbXVsdGlwbGllci5sdChUV09fUFdSXzI0KSlcclxuICAgICAgICByZXR1cm4gZnJvbU51bWJlcih0aGlzLnRvTnVtYmVyKCkgKiBtdWx0aXBsaWVyLnRvTnVtYmVyKCksIHRoaXMudW5zaWduZWQpO1xyXG5cclxuICAgIC8vIERpdmlkZSBlYWNoIGxvbmcgaW50byA0IGNodW5rcyBvZiAxNiBiaXRzLCBhbmQgdGhlbiBhZGQgdXAgNHg0IHByb2R1Y3RzLlxyXG4gICAgLy8gV2UgY2FuIHNraXAgcHJvZHVjdHMgdGhhdCB3b3VsZCBvdmVyZmxvdy5cclxuXHJcbiAgICB2YXIgYTQ4ID0gdGhpcy5oaWdoID4+PiAxNjtcclxuICAgIHZhciBhMzIgPSB0aGlzLmhpZ2ggJiAweEZGRkY7XHJcbiAgICB2YXIgYTE2ID0gdGhpcy5sb3cgPj4+IDE2O1xyXG4gICAgdmFyIGEwMCA9IHRoaXMubG93ICYgMHhGRkZGO1xyXG5cclxuICAgIHZhciBiNDggPSBtdWx0aXBsaWVyLmhpZ2ggPj4+IDE2O1xyXG4gICAgdmFyIGIzMiA9IG11bHRpcGxpZXIuaGlnaCAmIDB4RkZGRjtcclxuICAgIHZhciBiMTYgPSBtdWx0aXBsaWVyLmxvdyA+Pj4gMTY7XHJcbiAgICB2YXIgYjAwID0gbXVsdGlwbGllci5sb3cgJiAweEZGRkY7XHJcblxyXG4gICAgdmFyIGM0OCA9IDAsIGMzMiA9IDAsIGMxNiA9IDAsIGMwMCA9IDA7XHJcbiAgICBjMDAgKz0gYTAwICogYjAwO1xyXG4gICAgYzE2ICs9IGMwMCA+Pj4gMTY7XHJcbiAgICBjMDAgJj0gMHhGRkZGO1xyXG4gICAgYzE2ICs9IGExNiAqIGIwMDtcclxuICAgIGMzMiArPSBjMTYgPj4+IDE2O1xyXG4gICAgYzE2ICY9IDB4RkZGRjtcclxuICAgIGMxNiArPSBhMDAgKiBiMTY7XHJcbiAgICBjMzIgKz0gYzE2ID4+PiAxNjtcclxuICAgIGMxNiAmPSAweEZGRkY7XHJcbiAgICBjMzIgKz0gYTMyICogYjAwO1xyXG4gICAgYzQ4ICs9IGMzMiA+Pj4gMTY7XHJcbiAgICBjMzIgJj0gMHhGRkZGO1xyXG4gICAgYzMyICs9IGExNiAqIGIxNjtcclxuICAgIGM0OCArPSBjMzIgPj4+IDE2O1xyXG4gICAgYzMyICY9IDB4RkZGRjtcclxuICAgIGMzMiArPSBhMDAgKiBiMzI7XHJcbiAgICBjNDggKz0gYzMyID4+PiAxNjtcclxuICAgIGMzMiAmPSAweEZGRkY7XHJcbiAgICBjNDggKz0gYTQ4ICogYjAwICsgYTMyICogYjE2ICsgYTE2ICogYjMyICsgYTAwICogYjQ4O1xyXG4gICAgYzQ4ICY9IDB4RkZGRjtcclxuICAgIHJldHVybiBmcm9tQml0cygoYzE2IDw8IDE2KSB8IGMwMCwgKGM0OCA8PCAxNikgfCBjMzIsIHRoaXMudW5zaWduZWQpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhlIHByb2R1Y3Qgb2YgdGhpcyBhbmQgdGhlIHNwZWNpZmllZCBMb25nLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI211bHRpcGx5fS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gbXVsdGlwbGllciBNdWx0aXBsaWVyXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gUHJvZHVjdFxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5tdWwgPSBMb25nUHJvdG90eXBlLm11bHRpcGx5O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhpcyBMb25nIGRpdmlkZWQgYnkgdGhlIHNwZWNpZmllZC4gVGhlIHJlc3VsdCBpcyBzaWduZWQgaWYgdGhpcyBMb25nIGlzIHNpZ25lZCBvclxyXG4gKiAgdW5zaWduZWQgaWYgdGhpcyBMb25nIGlzIHVuc2lnbmVkLlxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IGRpdmlzb3IgRGl2aXNvclxyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFF1b3RpZW50XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmRpdmlkZSA9IGZ1bmN0aW9uIGRpdmlkZShkaXZpc29yKSB7XHJcbiAgICBpZiAoIWlzTG9uZyhkaXZpc29yKSlcclxuICAgICAgICBkaXZpc29yID0gZnJvbVZhbHVlKGRpdmlzb3IpO1xyXG4gICAgaWYgKGRpdmlzb3IuaXNaZXJvKCkpXHJcbiAgICAgICAgdGhyb3cgRXJyb3IoJ2RpdmlzaW9uIGJ5IHplcm8nKTtcclxuXHJcbiAgICAvLyB1c2Ugd2FzbSBzdXBwb3J0IGlmIHByZXNlbnRcclxuICAgIGlmICh3YXNtKSB7XHJcbiAgICAgICAgLy8gZ3VhcmQgYWdhaW5zdCBzaWduZWQgZGl2aXNpb24gb3ZlcmZsb3c6IHRoZSBsYXJnZXN0XHJcbiAgICAgICAgLy8gbmVnYXRpdmUgbnVtYmVyIC8gLTEgd291bGQgYmUgMSBsYXJnZXIgdGhhbiB0aGUgbGFyZ2VzdFxyXG4gICAgICAgIC8vIHBvc2l0aXZlIG51bWJlciwgZHVlIHRvIHR3bydzIGNvbXBsZW1lbnQuXHJcbiAgICAgICAgaWYgKCF0aGlzLnVuc2lnbmVkICYmXHJcbiAgICAgICAgICAgIHRoaXMuaGlnaCA9PT0gLTB4ODAwMDAwMDAgJiZcclxuICAgICAgICAgICAgZGl2aXNvci5sb3cgPT09IC0xICYmIGRpdmlzb3IuaGlnaCA9PT0gLTEpIHtcclxuICAgICAgICAgICAgLy8gYmUgY29uc2lzdGVudCB3aXRoIG5vbi13YXNtIGNvZGUgcGF0aFxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGxvdyA9ICh0aGlzLnVuc2lnbmVkID8gd2FzbS5kaXZfdSA6IHdhc20uZGl2X3MpKFxyXG4gICAgICAgICAgICB0aGlzLmxvdyxcclxuICAgICAgICAgICAgdGhpcy5oaWdoLFxyXG4gICAgICAgICAgICBkaXZpc29yLmxvdyxcclxuICAgICAgICAgICAgZGl2aXNvci5oaWdoXHJcbiAgICAgICAgKTtcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHMobG93LCB3YXNtLmdldF9oaWdoKCksIHRoaXMudW5zaWduZWQpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLmlzWmVybygpKVxyXG4gICAgICAgIHJldHVybiB0aGlzLnVuc2lnbmVkID8gVVpFUk8gOiBaRVJPO1xyXG4gICAgdmFyIGFwcHJveCwgcmVtLCByZXM7XHJcbiAgICBpZiAoIXRoaXMudW5zaWduZWQpIHtcclxuICAgICAgICAvLyBUaGlzIHNlY3Rpb24gaXMgb25seSByZWxldmFudCBmb3Igc2lnbmVkIGxvbmdzIGFuZCBpcyBkZXJpdmVkIGZyb20gdGhlXHJcbiAgICAgICAgLy8gY2xvc3VyZSBsaWJyYXJ5IGFzIGEgd2hvbGUuXHJcbiAgICAgICAgaWYgKHRoaXMuZXEoTUlOX1ZBTFVFKSkge1xyXG4gICAgICAgICAgICBpZiAoZGl2aXNvci5lcShPTkUpIHx8IGRpdmlzb3IuZXEoTkVHX09ORSkpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gTUlOX1ZBTFVFOyAgLy8gcmVjYWxsIHRoYXQgLU1JTl9WQUxVRSA9PSBNSU5fVkFMVUVcclxuICAgICAgICAgICAgZWxzZSBpZiAoZGl2aXNvci5lcShNSU5fVkFMVUUpKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIE9ORTtcclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBBdCB0aGlzIHBvaW50LCB3ZSBoYXZlIHxvdGhlcnwgPj0gMiwgc28gfHRoaXMvb3RoZXJ8IDwgfE1JTl9WQUxVRXwuXHJcbiAgICAgICAgICAgICAgICB2YXIgaGFsZlRoaXMgPSB0aGlzLnNocigxKTtcclxuICAgICAgICAgICAgICAgIGFwcHJveCA9IGhhbGZUaGlzLmRpdihkaXZpc29yKS5zaGwoMSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoYXBwcm94LmVxKFpFUk8pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRpdmlzb3IuaXNOZWdhdGl2ZSgpID8gT05FIDogTkVHX09ORTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVtID0gdGhpcy5zdWIoZGl2aXNvci5tdWwoYXBwcm94KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzID0gYXBwcm94LmFkZChyZW0uZGl2KGRpdmlzb3IpKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIGlmIChkaXZpc29yLmVxKE1JTl9WQUxVRSkpXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnVuc2lnbmVkID8gVVpFUk8gOiBaRVJPO1xyXG4gICAgICAgIGlmICh0aGlzLmlzTmVnYXRpdmUoKSkge1xyXG4gICAgICAgICAgICBpZiAoZGl2aXNvci5pc05lZ2F0aXZlKCkpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5uZWcoKS5kaXYoZGl2aXNvci5uZWcoKSk7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm5lZygpLmRpdihkaXZpc29yKS5uZWcoKTtcclxuICAgICAgICB9IGVsc2UgaWYgKGRpdmlzb3IuaXNOZWdhdGl2ZSgpKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kaXYoZGl2aXNvci5uZWcoKSkubmVnKCk7XHJcbiAgICAgICAgcmVzID0gWkVSTztcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLy8gVGhlIGFsZ29yaXRobSBiZWxvdyBoYXMgbm90IGJlZW4gbWFkZSBmb3IgdW5zaWduZWQgbG9uZ3MuIEl0J3MgdGhlcmVmb3JlXHJcbiAgICAgICAgLy8gcmVxdWlyZWQgdG8gdGFrZSBzcGVjaWFsIGNhcmUgb2YgdGhlIE1TQiBwcmlvciB0byBydW5uaW5nIGl0LlxyXG4gICAgICAgIGlmICghZGl2aXNvci51bnNpZ25lZClcclxuICAgICAgICAgICAgZGl2aXNvciA9IGRpdmlzb3IudG9VbnNpZ25lZCgpO1xyXG4gICAgICAgIGlmIChkaXZpc29yLmd0KHRoaXMpKVxyXG4gICAgICAgICAgICByZXR1cm4gVVpFUk87XHJcbiAgICAgICAgaWYgKGRpdmlzb3IuZ3QodGhpcy5zaHJ1KDEpKSkgLy8gMTUgPj4+IDEgPSA3IDsgd2l0aCBkaXZpc29yID0gOCA7IHRydWVcclxuICAgICAgICAgICAgcmV0dXJuIFVPTkU7XHJcbiAgICAgICAgcmVzID0gVVpFUk87XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUmVwZWF0IHRoZSBmb2xsb3dpbmcgdW50aWwgdGhlIHJlbWFpbmRlciBpcyBsZXNzIHRoYW4gb3RoZXI6ICBmaW5kIGFcclxuICAgIC8vIGZsb2F0aW5nLXBvaW50IHRoYXQgYXBwcm94aW1hdGVzIHJlbWFpbmRlciAvIG90aGVyICpmcm9tIGJlbG93KiwgYWRkIHRoaXNcclxuICAgIC8vIGludG8gdGhlIHJlc3VsdCwgYW5kIHN1YnRyYWN0IGl0IGZyb20gdGhlIHJlbWFpbmRlci4gIEl0IGlzIGNyaXRpY2FsIHRoYXRcclxuICAgIC8vIHRoZSBhcHByb3hpbWF0ZSB2YWx1ZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIHJlYWwgdmFsdWUgc28gdGhhdCB0aGVcclxuICAgIC8vIHJlbWFpbmRlciBuZXZlciBiZWNvbWVzIG5lZ2F0aXZlLlxyXG4gICAgcmVtID0gdGhpcztcclxuICAgIHdoaWxlIChyZW0uZ3RlKGRpdmlzb3IpKSB7XHJcbiAgICAgICAgLy8gQXBwcm94aW1hdGUgdGhlIHJlc3VsdCBvZiBkaXZpc2lvbi4gVGhpcyBtYXkgYmUgYSBsaXR0bGUgZ3JlYXRlciBvclxyXG4gICAgICAgIC8vIHNtYWxsZXIgdGhhbiB0aGUgYWN0dWFsIHZhbHVlLlxyXG4gICAgICAgIGFwcHJveCA9IE1hdGgubWF4KDEsIE1hdGguZmxvb3IocmVtLnRvTnVtYmVyKCkgLyBkaXZpc29yLnRvTnVtYmVyKCkpKTtcclxuXHJcbiAgICAgICAgLy8gV2Ugd2lsbCB0d2VhayB0aGUgYXBwcm94aW1hdGUgcmVzdWx0IGJ5IGNoYW5naW5nIGl0IGluIHRoZSA0OC10aCBkaWdpdCBvclxyXG4gICAgICAgIC8vIHRoZSBzbWFsbGVzdCBub24tZnJhY3Rpb25hbCBkaWdpdCwgd2hpY2hldmVyIGlzIGxhcmdlci5cclxuICAgICAgICB2YXIgbG9nMiA9IE1hdGguY2VpbChNYXRoLmxvZyhhcHByb3gpIC8gTWF0aC5MTjIpLFxyXG4gICAgICAgICAgICBkZWx0YSA9IChsb2cyIDw9IDQ4KSA/IDEgOiBwb3dfZGJsKDIsIGxvZzIgLSA0OCksXHJcblxyXG4gICAgICAgIC8vIERlY3JlYXNlIHRoZSBhcHByb3hpbWF0aW9uIHVudGlsIGl0IGlzIHNtYWxsZXIgdGhhbiB0aGUgcmVtYWluZGVyLiAgTm90ZVxyXG4gICAgICAgIC8vIHRoYXQgaWYgaXQgaXMgdG9vIGxhcmdlLCB0aGUgcHJvZHVjdCBvdmVyZmxvd3MgYW5kIGlzIG5lZ2F0aXZlLlxyXG4gICAgICAgICAgICBhcHByb3hSZXMgPSBmcm9tTnVtYmVyKGFwcHJveCksXHJcbiAgICAgICAgICAgIGFwcHJveFJlbSA9IGFwcHJveFJlcy5tdWwoZGl2aXNvcik7XHJcbiAgICAgICAgd2hpbGUgKGFwcHJveFJlbS5pc05lZ2F0aXZlKCkgfHwgYXBwcm94UmVtLmd0KHJlbSkpIHtcclxuICAgICAgICAgICAgYXBwcm94IC09IGRlbHRhO1xyXG4gICAgICAgICAgICBhcHByb3hSZXMgPSBmcm9tTnVtYmVyKGFwcHJveCwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICAgICAgICAgIGFwcHJveFJlbSA9IGFwcHJveFJlcy5tdWwoZGl2aXNvcik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBXZSBrbm93IHRoZSBhbnN3ZXIgY2FuJ3QgYmUgemVyby4uLiBhbmQgYWN0dWFsbHksIHplcm8gd291bGQgY2F1c2VcclxuICAgICAgICAvLyBpbmZpbml0ZSByZWN1cnNpb24gc2luY2Ugd2Ugd291bGQgbWFrZSBubyBwcm9ncmVzcy5cclxuICAgICAgICBpZiAoYXBwcm94UmVzLmlzWmVybygpKVxyXG4gICAgICAgICAgICBhcHByb3hSZXMgPSBPTkU7XHJcblxyXG4gICAgICAgIHJlcyA9IHJlcy5hZGQoYXBwcm94UmVzKTtcclxuICAgICAgICByZW0gPSByZW0uc3ViKGFwcHJveFJlbSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmVzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhpcyBMb25nIGRpdmlkZWQgYnkgdGhlIHNwZWNpZmllZC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNkaXZpZGV9LlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBkaXZpc29yIERpdmlzb3JcclxuICogQHJldHVybnMgeyFMb25nfSBRdW90aWVudFxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5kaXYgPSBMb25nUHJvdG90eXBlLmRpdmlkZTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyBtb2R1bG8gdGhlIHNwZWNpZmllZC5cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBkaXZpc29yIERpdmlzb3JcclxuICogQHJldHVybnMgeyFMb25nfSBSZW1haW5kZXJcclxuICovXHJcbkxvbmdQcm90b3R5cGUubW9kdWxvID0gZnVuY3Rpb24gbW9kdWxvKGRpdmlzb3IpIHtcclxuICAgIGlmICghaXNMb25nKGRpdmlzb3IpKVxyXG4gICAgICAgIGRpdmlzb3IgPSBmcm9tVmFsdWUoZGl2aXNvcik7XHJcblxyXG4gICAgLy8gdXNlIHdhc20gc3VwcG9ydCBpZiBwcmVzZW50XHJcbiAgICBpZiAod2FzbSkge1xyXG4gICAgICAgIHZhciBsb3cgPSAodGhpcy51bnNpZ25lZCA/IHdhc20ucmVtX3UgOiB3YXNtLnJlbV9zKShcclxuICAgICAgICAgICAgdGhpcy5sb3csXHJcbiAgICAgICAgICAgIHRoaXMuaGlnaCxcclxuICAgICAgICAgICAgZGl2aXNvci5sb3csXHJcbiAgICAgICAgICAgIGRpdmlzb3IuaGlnaFxyXG4gICAgICAgICk7XHJcbiAgICAgICAgcmV0dXJuIGZyb21CaXRzKGxvdywgd2FzbS5nZXRfaGlnaCgpLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcy5zdWIodGhpcy5kaXYoZGl2aXNvcikubXVsKGRpdmlzb3IpKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyBtb2R1bG8gdGhlIHNwZWNpZmllZC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNtb2R1bG99LlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBkaXZpc29yIERpdmlzb3JcclxuICogQHJldHVybnMgeyFMb25nfSBSZW1haW5kZXJcclxuICovXHJcbkxvbmdQcm90b3R5cGUubW9kID0gTG9uZ1Byb3RvdHlwZS5tb2R1bG87XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGlzIExvbmcgbW9kdWxvIHRoZSBzcGVjaWZpZWQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbW9kdWxvfS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gZGl2aXNvciBEaXZpc29yXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gUmVtYWluZGVyXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnJlbSA9IExvbmdQcm90b3R5cGUubW9kdWxvO1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhlIGJpdHdpc2UgTk9UIG9mIHRoaXMgTG9uZy5cclxuICogQHJldHVybnMgeyFMb25nfVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5ub3QgPSBmdW5jdGlvbiBub3QoKSB7XHJcbiAgICByZXR1cm4gZnJvbUJpdHMofnRoaXMubG93LCB+dGhpcy5oaWdoLCB0aGlzLnVuc2lnbmVkKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBiaXR3aXNlIEFORCBvZiB0aGlzIExvbmcgYW5kIHRoZSBzcGVjaWZpZWQuXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgTG9uZ1xyXG4gKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmFuZCA9IGZ1bmN0aW9uIGFuZChvdGhlcikge1xyXG4gICAgaWYgKCFpc0xvbmcob3RoZXIpKVxyXG4gICAgICAgIG90aGVyID0gZnJvbVZhbHVlKG90aGVyKTtcclxuICAgIHJldHVybiBmcm9tQml0cyh0aGlzLmxvdyAmIG90aGVyLmxvdywgdGhpcy5oaWdoICYgb3RoZXIuaGlnaCwgdGhpcy51bnNpZ25lZCk7XHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGUgYml0d2lzZSBPUiBvZiB0aGlzIExvbmcgYW5kIHRoZSBzcGVjaWZpZWQuXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgTG9uZ1xyXG4gKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLm9yID0gZnVuY3Rpb24gb3Iob3RoZXIpIHtcclxuICAgIGlmICghaXNMb25nKG90aGVyKSlcclxuICAgICAgICBvdGhlciA9IGZyb21WYWx1ZShvdGhlcik7XHJcbiAgICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3cgfCBvdGhlci5sb3csIHRoaXMuaGlnaCB8IG90aGVyLmhpZ2gsIHRoaXMudW5zaWduZWQpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhlIGJpdHdpc2UgWE9SIG9mIHRoaXMgTG9uZyBhbmQgdGhlIGdpdmVuIG9uZS5cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciBMb25nXHJcbiAqIEByZXR1cm5zIHshTG9uZ31cclxuICovXHJcbkxvbmdQcm90b3R5cGUueG9yID0gZnVuY3Rpb24geG9yKG90aGVyKSB7XHJcbiAgICBpZiAoIWlzTG9uZyhvdGhlcikpXHJcbiAgICAgICAgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xyXG4gICAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93IF4gb3RoZXIubG93LCB0aGlzLmhpZ2ggXiBvdGhlci5oaWdoLCB0aGlzLnVuc2lnbmVkKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgc2hpZnRlZCB0byB0aGUgbGVmdCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxyXG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5zaGlmdExlZnQgPSBmdW5jdGlvbiBzaGlmdExlZnQobnVtQml0cykge1xyXG4gICAgaWYgKGlzTG9uZyhudW1CaXRzKSlcclxuICAgICAgICBudW1CaXRzID0gbnVtQml0cy50b0ludCgpO1xyXG4gICAgaWYgKChudW1CaXRzICY9IDYzKSA9PT0gMClcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIGVsc2UgaWYgKG51bUJpdHMgPCAzMilcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3cgPDwgbnVtQml0cywgKHRoaXMuaGlnaCA8PCBudW1CaXRzKSB8ICh0aGlzLmxvdyA+Pj4gKDMyIC0gbnVtQml0cykpLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgIGVsc2VcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHMoMCwgdGhpcy5sb3cgPDwgKG51bUJpdHMgLSAzMiksIHRoaXMudW5zaWduZWQpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBzaGlmdGVkIHRvIHRoZSBsZWZ0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRMZWZ0fS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnNobCA9IExvbmdQcm90b3R5cGUuc2hpZnRMZWZ0O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBhcml0aG1ldGljYWxseSBzaGlmdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxyXG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5zaGlmdFJpZ2h0ID0gZnVuY3Rpb24gc2hpZnRSaWdodChudW1CaXRzKSB7XHJcbiAgICBpZiAoaXNMb25nKG51bUJpdHMpKVxyXG4gICAgICAgIG51bUJpdHMgPSBudW1CaXRzLnRvSW50KCk7XHJcbiAgICBpZiAoKG51bUJpdHMgJj0gNjMpID09PSAwKVxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgZWxzZSBpZiAobnVtQml0cyA8IDMyKVxyXG4gICAgICAgIHJldHVybiBmcm9tQml0cygodGhpcy5sb3cgPj4+IG51bUJpdHMpIHwgKHRoaXMuaGlnaCA8PCAoMzIgLSBudW1CaXRzKSksIHRoaXMuaGlnaCA+PiBudW1CaXRzLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgIGVsc2VcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHModGhpcy5oaWdoID4+IChudW1CaXRzIC0gMzIpLCB0aGlzLmhpZ2ggPj0gMCA/IDAgOiAtMSwgdGhpcy51bnNpZ25lZCk7XHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIGFyaXRobWV0aWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRSaWdodH0uXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5zaHIgPSBMb25nUHJvdG90eXBlLnNoaWZ0UmlnaHQ7XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIGxvZ2ljYWxseSBzaGlmdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxyXG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5zaGlmdFJpZ2h0VW5zaWduZWQgPSBmdW5jdGlvbiBzaGlmdFJpZ2h0VW5zaWduZWQobnVtQml0cykge1xyXG4gICAgaWYgKGlzTG9uZyhudW1CaXRzKSlcclxuICAgICAgICBudW1CaXRzID0gbnVtQml0cy50b0ludCgpO1xyXG4gICAgbnVtQml0cyAmPSA2MztcclxuICAgIGlmIChudW1CaXRzID09PSAwKVxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgdmFyIGhpZ2ggPSB0aGlzLmhpZ2g7XHJcbiAgICAgICAgaWYgKG51bUJpdHMgPCAzMikge1xyXG4gICAgICAgICAgICB2YXIgbG93ID0gdGhpcy5sb3c7XHJcbiAgICAgICAgICAgIHJldHVybiBmcm9tQml0cygobG93ID4+PiBudW1CaXRzKSB8IChoaWdoIDw8ICgzMiAtIG51bUJpdHMpKSwgaGlnaCA+Pj4gbnVtQml0cywgdGhpcy51bnNpZ25lZCk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChudW1CaXRzID09PSAzMilcclxuICAgICAgICAgICAgcmV0dXJuIGZyb21CaXRzKGhpZ2gsIDAsIHRoaXMudW5zaWduZWQpO1xyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgcmV0dXJuIGZyb21CaXRzKGhpZ2ggPj4+IChudW1CaXRzIC0gMzIpLCAwLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgIH1cclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgbG9naWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRSaWdodFVuc2lnbmVkfS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnNocnUgPSBMb25nUHJvdG90eXBlLnNoaWZ0UmlnaHRVbnNpZ25lZDtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgbG9naWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRSaWdodFVuc2lnbmVkfS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnNocl91ID0gTG9uZ1Byb3RvdHlwZS5zaGlmdFJpZ2h0VW5zaWduZWQ7XHJcblxyXG4vKipcclxuICogQ29udmVydHMgdGhpcyBMb25nIHRvIHNpZ25lZC5cclxuICogQHJldHVybnMgeyFMb25nfSBTaWduZWQgbG9uZ1xyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS50b1NpZ25lZCA9IGZ1bmN0aW9uIHRvU2lnbmVkKCkge1xyXG4gICAgaWYgKCF0aGlzLnVuc2lnbmVkKVxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93LCB0aGlzLmhpZ2gsIGZhbHNlKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gdW5zaWduZWQuXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gVW5zaWduZWQgbG9uZ1xyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS50b1Vuc2lnbmVkID0gZnVuY3Rpb24gdG9VbnNpZ25lZCgpIHtcclxuICAgIGlmICh0aGlzLnVuc2lnbmVkKVxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93LCB0aGlzLmhpZ2gsIHRydWUpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIENvbnZlcnRzIHRoaXMgTG9uZyB0byBpdHMgYnl0ZSByZXByZXNlbnRhdGlvbi5cclxuICogQHBhcmFtIHtib29sZWFuPX0gbGUgV2hldGhlciBsaXR0bGUgb3IgYmlnIGVuZGlhbiwgZGVmYXVsdHMgdG8gYmlnIGVuZGlhblxyXG4gKiBAcmV0dXJucyB7IUFycmF5LjxudW1iZXI+fSBCeXRlIHJlcHJlc2VudGF0aW9uXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnRvQnl0ZXMgPSBmdW5jdGlvbiB0b0J5dGVzKGxlKSB7XHJcbiAgICByZXR1cm4gbGUgPyB0aGlzLnRvQnl0ZXNMRSgpIDogdGhpcy50b0J5dGVzQkUoKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gaXRzIGxpdHRsZSBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvbi5cclxuICogQHJldHVybnMgeyFBcnJheS48bnVtYmVyPn0gTGl0dGxlIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnRvQnl0ZXNMRSA9IGZ1bmN0aW9uIHRvQnl0ZXNMRSgpIHtcclxuICAgIHZhciBoaSA9IHRoaXMuaGlnaCxcclxuICAgICAgICBsbyA9IHRoaXMubG93O1xyXG4gICAgcmV0dXJuIFtcclxuICAgICAgICBsbyAgICAgICAgJiAweGZmLFxyXG4gICAgICAgIGxvID4+PiAgOCAmIDB4ZmYsXHJcbiAgICAgICAgbG8gPj4+IDE2ICYgMHhmZixcclxuICAgICAgICBsbyA+Pj4gMjQgICAgICAgLFxyXG4gICAgICAgIGhpICAgICAgICAmIDB4ZmYsXHJcbiAgICAgICAgaGkgPj4+ICA4ICYgMHhmZixcclxuICAgICAgICBoaSA+Pj4gMTYgJiAweGZmLFxyXG4gICAgICAgIGhpID4+PiAyNFxyXG4gICAgXTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gaXRzIGJpZyBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvbi5cclxuICogQHJldHVybnMgeyFBcnJheS48bnVtYmVyPn0gQmlnIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnRvQnl0ZXNCRSA9IGZ1bmN0aW9uIHRvQnl0ZXNCRSgpIHtcclxuICAgIHZhciBoaSA9IHRoaXMuaGlnaCxcclxuICAgICAgICBsbyA9IHRoaXMubG93O1xyXG4gICAgcmV0dXJuIFtcclxuICAgICAgICBoaSA+Pj4gMjQgICAgICAgLFxyXG4gICAgICAgIGhpID4+PiAxNiAmIDB4ZmYsXHJcbiAgICAgICAgaGkgPj4+ICA4ICYgMHhmZixcclxuICAgICAgICBoaSAgICAgICAgJiAweGZmLFxyXG4gICAgICAgIGxvID4+PiAyNCAgICAgICAsXHJcbiAgICAgICAgbG8gPj4+IDE2ICYgMHhmZixcclxuICAgICAgICBsbyA+Pj4gIDggJiAweGZmLFxyXG4gICAgICAgIGxvICAgICAgICAmIDB4ZmZcclxuICAgIF07XHJcbn07XHJcblxyXG4vKipcclxuICogQ3JlYXRlcyBhIExvbmcgZnJvbSBpdHMgYnl0ZSByZXByZXNlbnRhdGlvbi5cclxuICogQHBhcmFtIHshQXJyYXkuPG51bWJlcj59IGJ5dGVzIEJ5dGUgcmVwcmVzZW50YXRpb25cclxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxyXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSBsZSBXaGV0aGVyIGxpdHRsZSBvciBiaWcgZW5kaWFuLCBkZWZhdWx0cyB0byBiaWcgZW5kaWFuXHJcbiAqIEByZXR1cm5zIHtMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXHJcbiAqL1xyXG5Mb25nLmZyb21CeXRlcyA9IGZ1bmN0aW9uIGZyb21CeXRlcyhieXRlcywgdW5zaWduZWQsIGxlKSB7XHJcbiAgICByZXR1cm4gbGUgPyBMb25nLmZyb21CeXRlc0xFKGJ5dGVzLCB1bnNpZ25lZCkgOiBMb25nLmZyb21CeXRlc0JFKGJ5dGVzLCB1bnNpZ25lZCk7XHJcbn07XHJcblxyXG4vKipcclxuICogQ3JlYXRlcyBhIExvbmcgZnJvbSBpdHMgbGl0dGxlIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uLlxyXG4gKiBAcGFyYW0geyFBcnJheS48bnVtYmVyPn0gYnl0ZXMgTGl0dGxlIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uXHJcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcclxuICogQHJldHVybnMge0xvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcclxuICovXHJcbkxvbmcuZnJvbUJ5dGVzTEUgPSBmdW5jdGlvbiBmcm9tQnl0ZXNMRShieXRlcywgdW5zaWduZWQpIHtcclxuICAgIHJldHVybiBuZXcgTG9uZyhcclxuICAgICAgICBieXRlc1swXSAgICAgICB8XHJcbiAgICAgICAgYnl0ZXNbMV0gPDwgIDggfFxyXG4gICAgICAgIGJ5dGVzWzJdIDw8IDE2IHxcclxuICAgICAgICBieXRlc1szXSA8PCAyNCxcclxuICAgICAgICBieXRlc1s0XSAgICAgICB8XHJcbiAgICAgICAgYnl0ZXNbNV0gPDwgIDggfFxyXG4gICAgICAgIGJ5dGVzWzZdIDw8IDE2IHxcclxuICAgICAgICBieXRlc1s3XSA8PCAyNCxcclxuICAgICAgICB1bnNpZ25lZFxyXG4gICAgKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBDcmVhdGVzIGEgTG9uZyBmcm9tIGl0cyBiaWcgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb24uXHJcbiAqIEBwYXJhbSB7IUFycmF5LjxudW1iZXI+fSBieXRlcyBCaWcgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb25cclxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxyXG4gKiBAcmV0dXJucyB7TG9uZ30gVGhlIGNvcnJlc3BvbmRpbmcgTG9uZyB2YWx1ZVxyXG4gKi9cclxuTG9uZy5mcm9tQnl0ZXNCRSA9IGZ1bmN0aW9uIGZyb21CeXRlc0JFKGJ5dGVzLCB1bnNpZ25lZCkge1xyXG4gICAgcmV0dXJuIG5ldyBMb25nKFxyXG4gICAgICAgIGJ5dGVzWzRdIDw8IDI0IHxcclxuICAgICAgICBieXRlc1s1XSA8PCAxNiB8XHJcbiAgICAgICAgYnl0ZXNbNl0gPDwgIDggfFxyXG4gICAgICAgIGJ5dGVzWzddLFxyXG4gICAgICAgIGJ5dGVzWzBdIDw8IDI0IHxcclxuICAgICAgICBieXRlc1sxXSA8PCAxNiB8XHJcbiAgICAgICAgYnl0ZXNbMl0gPDwgIDggfFxyXG4gICAgICAgIGJ5dGVzWzNdLFxyXG4gICAgICAgIHVuc2lnbmVkXHJcbiAgICApO1xyXG59O1xyXG5cblxuLyoqKi8gfSlcbi8qKioqKiovIF0pOyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgQlNPTiBmcm9tICcuLy4uLy4uLy4uLy4uL3RoaXJkX3BhcnR5L2Jzb24uY29tbW9uLmpzJztcblxuY29uc3QgYnNvbiA9IEJTT04uYnNvbjtcblxuY2xhc3MgQnNvbiB7XG4gICAgLyoqXG4gICAgICogU2VyaWFsaXplIGEgSmF2YXNjcmlwdCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gb2JqZWN0IFRoZSBKYXZhc2NyaXB0IG9iamVjdCB0byBzZXJpYWxpemUuXG4gICAgICogQHJldHVybiBUaGUgQnVmZmVyIG9iamVjdCBjb250YWluaW5nIHRoZSBzZXJpYWxpemVkIG9iamVjdC5cbiAgICAgKi9cbiAgICBzdGF0aWMgc2VyaWFsaXplIChvYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIGJzb24uc2VyaWFsaXplKG9iamVjdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVzZXJpYWxpemUgZGF0YSBhcyBCU09OLlxuICAgICAqXG4gICAgICogQHBhcmFtIGJ1ZmZlciBUaGUgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIHNlcmlhbGl6ZWQgc2V0IG9mIEJTT04gZG9jdW1lbnRzLlxuICAgICAqIEByZXR1cm5zIFRoZSBkZXNlcmlhbGl6ZWQgSmF2YXNjcmlwdCBPYmplY3QuXG4gICAgICovXG4gICAgc3RhdGljIGRlc2VyaWFsaXplIChvYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIGJzb24uZGVzZXJpYWxpemUob2JqZWN0KTtcbiAgICB9XG59XG5cbmV4cG9ydCB7IEJzb24gfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnJhbWVUeXBlIH0gZnJvbSAnLi9lbnVtcy9GcmFtZVR5cGUuanMnO1xuaW1wb3J0ICB7IEJzb24gfSBmcm9tICcuLy4uL3V0aWwvQnNvbi5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gU2RsUGFja2V0XG4gKiBAcHJvcGVydHkge251bWJlcn0gRVhUUkFfUEFSQ0VMX0RBVEFfTEVOR1RIXG4gKiBAcHJvcGVydHkge251bWJlcn0gSEVBREVSX1NJWkVcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBIRUFERVJfU0laRV9WMVxuICogQHByb3BlcnR5IHtudW1iZXJ9IEVOQ1JZUFRJT05fTUFTS1xuICogQHByb3BlcnR5IHtudW1iZXJ9IFNFUlZJQ0VfVFlQRV9DT05UUk9MXG4gKiBAcHJvcGVydHkge251bWJlcn0gU0VSVklDRV9UWVBFX1JQQ1xuICogQHByb3BlcnR5IHtudW1iZXJ9IFNFUlZJQ0VfVFlQRV9QQ01cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBTRVJWSUNFX1RZUEVfVklERU9cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBTRVJWSUNFX1RZUEVfQlVMS19EQVRBXG4gKiBAcHJvcGVydHkge251bWJlcn0gRlJBTUVfSU5GT19IRUFSVF9CRUFUXG4gKiBAcHJvcGVydHkge251bWJlcn0gRlJBTUVfSU5GT19TVEFSVF9TRVJWSUNFXG4gKiBAcHJvcGVydHkge251bWJlcn0gRlJBTUVfSU5GT19TVEFSVF9TRVJWSUNFX0FDS1xuICogQHByb3BlcnR5IHtudW1iZXJ9IEZSQU1FX0lORk9fU1RBUlRfU0VSVklDRV9OQUtcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGUkFNRV9JTkZPX0VORF9TRVJWSUNFXG4gKiBAcHJvcGVydHkge251bWJlcn0gRlJBTUVfSU5GT19FTkRfU0VSVklDRV9BQ0tcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGUkFNRV9JTkZPX0VORF9TRVJWSUNFX05BS1xuICogQHByb3BlcnR5IHtudW1iZXJ9IEZSQU1FX0lORk9fUkVHSVNURVJfU0VDT05EQVJZX1RSQU5TUE9SVFxuICogQHByb3BlcnR5IHtudW1iZXJ9IEZSQU1FX0lORk9fUkVHSVNURVJfU0VDT05EQVJZX1RSQU5TUE9SVF9BQ0tcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGUkFNRV9JTkZPX1JFR0lTVEVSX1NFQ09OREFSWV9UUkFOU1BPUlRfTkFLXG4gKiBAcHJvcGVydHkge251bWJlcn0gRlJBTUVfSU5GT19UUkFOU1BPUlRfRVZFTlRfVVBEQVRFXG4gKiBAcHJvcGVydHkge251bWJlcn0gRlJBTUVfSU5GT19TRVJWSUNFX0RBVEFfQUNLXG4gKiBAcHJvcGVydHkge251bWJlcn0gRlJBTUVfSU5GT19IRUFSVF9CRUFUX0FDS1xuICogQHByb3BlcnR5IHtudW1iZXJ9IEZSQU1FX0lORk9fRklOQUxfQ09OTkVTQ1VUSVZFX0ZSQU1FXG4gKiBAcHJvcGVydHkge251bWJlcn0gRlJBTUVfSU5GT19SRVNFUlZFRFxuXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBnZXRWZXJzaW9uXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBnZXRFbmNyeXB0aW9uXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBnZXRTZXJ2aWNlVHlwZVxuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gZ2V0RnJhbWVJbmZvXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBnZXRTZXNzaW9uSURcbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IGdldE1lc3NhZ2VJRFxuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gZ2V0RGF0YVNpemVcbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IHNldFBheWxvYWRcbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IGdldFBheWxvYWRcbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IGdldEVuY3J5cHRpb25CaXRcbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IGdldEZyYW1lVHlwZVxuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gdG9VaW50OEFycmF5XG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSB0b1N0cmluZ1xuICogQHByb3BlcnR5IHtmdW5jdGlvbn0gY29uc3RydWN0UGFja2V0XG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBwdXRUYWdcbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IGdldFRhZ1xuICovXG5cbmNsYXNzIFNkbFBhY2tldCB7XG4gICAgLyoqXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSB2ZXJzaW9uIC0gUHJvdG9jb2wgdmVyc2lvbiB0byB1c2VcbiAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gZW5jcnlwdGlvbiAtIFdoZXRoZXIgb3Igbm90IHRoZSBwYXlsb2FkIGluIHRoaXMgcGFja2V0IGlzIGVuY3J5cHRlZFxuICAgICogQHBhcmFtIHtGcmFtZVR5cGV9IGZyYW1lVHlwZSAtIEEgbnVtYmVyIHJlcHJlc2VudGluZyB0aGUgcGFja2V0IGZyYW1lIHR5cGVcbiAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlIC0gVGhlIHNlcnZpY2UgdGhhdCB0aGlzIHBhY2tldCBpcyBhc3NvY2lhdGVkIHdpdGhcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSBmcmFtZUluZm8gLSBTcGVjaWZpYyBmcmFtZSBpbmZvIHJlbGF0ZWQgdG8gdGhpcyBwYWNrZXRcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSBzZXNzaW9uSUQgLSBJRCB0aGlzIHBhY2tldCBpcyBhc3NvY2lhdGVkIHdpdGhcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSBkYXRhU2l6ZSAtIFNpemUgb2YgdGhlIHBheWxvYWQgdGhhdCB3aWxsIGJlIGFkZGVkXG4gICAgKiBAcGFyYW0ge051bWJlcn0gbWVzc2FnZUlEIC0gSUQgb2YgdGhpcyBzcGVjaWZpYyBwYWNrZXRcbiAgICAqIEBwYXJhbSB7VWludDhBcnJheX0gcGF5bG9hZCAtIFJhdyBkYXRhIHRoYXQgd2lsbCBiZSBhdHRhY2hlZCB0byB0aGUgcGFja2V0IChSUEMgbWVzc2FnZSwgcmF3IGJ5dGVzLCBldGMpXG4gICAgKiBAcGFyYW0ge051bWJlcn0gb2Zmc2V0XG4gICAgKiBAcGFyYW0ge051bWJlcn0gYnl0ZXNUb1dyaXRlXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAodmVyc2lvbiA9IDEsIGVuY3J5cHRpb24gPSBmYWxzZSwgZnJhbWVUeXBlID0gLTEsIHNlcnZpY2VUeXBlID0gLTEsIGZyYW1lSW5mbyA9IC0xLCBzZXNzaW9uSUQgPSAwLCBkYXRhU2l6ZSA9IDAsIG1lc3NhZ2VJRCA9IDAsIHBheWxvYWQgPSBudWxsLCBvZmZzZXQgPSAwLCBieXRlc1RvV3JpdGUgPSAwKSB7XG4gICAgICAgIHRoaXMuX3ZlcnNpb24gPSB2ZXJzaW9uO1xuICAgICAgICB0aGlzLl9lbmNyeXB0aW9uID0gZW5jcnlwdGlvbjtcbiAgICAgICAgdGhpcy5fZnJhbWVUeXBlID0gZnJhbWVUeXBlO1xuICAgICAgICB0aGlzLl9zZXJ2aWNlVHlwZSA9IHNlcnZpY2VUeXBlO1xuICAgICAgICB0aGlzLl9mcmFtZUluZm8gPSBmcmFtZUluZm87XG4gICAgICAgIHRoaXMuX3Nlc3Npb25JRCA9IHNlc3Npb25JRDtcbiAgICAgICAgdGhpcy5fZGF0YVNpemUgPSBkYXRhU2l6ZTtcbiAgICAgICAgdGhpcy5fbWVzc2FnZUlEID0gbWVzc2FnZUlEO1xuICAgICAgICB0aGlzLl9wYXlsb2FkID0gcGF5bG9hZDtcbiAgICAgICAgdGhpcy5fb2Zmc2V0ID0gb2Zmc2V0O1xuICAgICAgICB0aGlzLl9ieXRlc1RvV3JpdGUgPSBieXRlc1RvV3JpdGU7XG5cbiAgICAgICAgdGhpcy5fYnNvblBheWxvYWQgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgaWYgKHBheWxvYWQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX3BheWxvYWQgPSBuZXcgVWludDhBcnJheShwYXlsb2FkLnNsaWNlKG9mZnNldCwgYnl0ZXNUb1dyaXRlICsgb2Zmc2V0KSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn0gLSBQcm90b2NvbCB2ZXJzaW9uIHVzZWQgYnkgdGhpcyBwYWNrZXRcbiAgICAqL1xuICAgIGdldFZlcnNpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdmVyc2lvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0Jvb2xlYW59IC0gV2hldGhlciBvciBub3QgdGhlIHBheWxvYWQgaW4gdGhpcyBwYWNrZXQgaXMgZW5jcnlwdGVkXG4gICAgKi9cbiAgICBnZXRFbmNyeXB0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VuY3J5cHRpb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtTZXJ2aWNlVHlwZX0gLSBUaGUgc2VydmljZSB0aGF0IHRoaXMgcGFja2V0IGlzIGFzc29jaWF0ZWQgd2l0aFxuICAgICovXG4gICAgZ2V0U2VydmljZVR5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2VydmljZVR5cGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9IC0gU3BlY2lmaWMgZnJhbWUgaW5mbyByZWxhdGVkIHRvIHRoaXMgcGFja2V0XG4gICAgKi9cbiAgICBnZXRGcmFtZUluZm8gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZnJhbWVJbmZvO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfSAtIElEIHRoaXMgcGFja2V0IGlzIGFzc29jaWF0ZWQgd2l0aFxuICAgICovXG4gICAgZ2V0U2Vzc2lvbklEICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Nlc3Npb25JRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn0gLSBJRCBvZiB0aGlzIHNwZWNpZmljIHBhY2tldFxuICAgICovXG4gICAgZ2V0TWVzc2FnZUlEICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21lc3NhZ2VJRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn0gLSBTaXplIG9mIHRoZSBwYXlsb2FkIHRoYXQgd2lsbCBiZSBhZGRlZFxuICAgICovXG4gICAgZ2V0RGF0YVNpemUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGF0YVNpemU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHBheWxvYWRcbiAgICAqIEByZXR1cm4ge1NkbFBhY2tldH1cbiAgICAqL1xuICAgIHNldFBheWxvYWQgKHBheWxvYWQpIHtcbiAgICAgICAgdGhpcy5fcGF5bG9hZCA9IHBheWxvYWQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7VWludDhBcnJheX0gLSBSYXcgZGF0YSB0aGF0IHdpbGwgYmUgYXR0YWNoZWQgdG8gdGhlIHBhY2tldCAoUlBDIG1lc3NhZ2UsIHJhdyBieXRlcywgZXRjKVxuICAgICovXG4gICAgZ2V0UGF5bG9hZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXlsb2FkO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGVuY3J5cHRpb25cbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9IC0gUmV0dXJucyBhIG51bWJlciByZXByZXNlbnRpbmcgYSBieXRlIG1hc2sgZGVwZW5kaW5nIG9uIHRoZSBib29sZWFuIHZhbHVlXG4gICAgICovXG4gICAgc3RhdGljIGdldEVuY3J5cHRpb25CaXQgKGVuY3J5cHRpb24pIHtcbiAgICAgICAgcmV0dXJuIGVuY3J5cHRpb24gPyBTZGxQYWNrZXQuRU5DUllQVElPTl9NQVNLIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge0ZyYW1lVHlwZX0gLSBBIG51bWJlciByZXByZXNlbnRpbmcgdGhlIHBhY2tldCBmcmFtZSB0eXBlXG4gICAgKi9cbiAgICBnZXRGcmFtZVR5cGUgKCkge1xuICAgICAgICBpZiAoRnJhbWVUeXBlLmtleUZvclZhbHVlKHRoaXMuX2ZyYW1lVHlwZSkgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9mcmFtZVR5cGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gRnJhbWVUeXBlLlNJTkdMRTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfSAtIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFja2V0XG4gICAgKi9cbiAgICB0b1N0cmluZyAoKSB7XG4gICAgICAgIGxldCBvdXRwdXQgPSAnKioqKiogU2RsIFBhY2tldCAqKioqKic7XG4gICAgICAgIG91dHB1dCArPSBgXFxuVmVyc2lvbjogJHt0aGlzLl92ZXJzaW9ufWA7XG4gICAgICAgIG91dHB1dCArPSBgXFxuRW5jcnlwdGlvbjogJHt0aGlzLl9lbmNyeXB0aW9ufWA7XG4gICAgICAgIG91dHB1dCArPSBgXFxuRnJhbWVUeXBlOiAke3RoaXMuX2ZyYW1lVHlwZX1gO1xuICAgICAgICBvdXRwdXQgKz0gYFxcblNlcnZpY2VUeXBlOiAke3RoaXMuX3NlcnZpY2VUeXBlfWA7XG4gICAgICAgIG91dHB1dCArPSBgXFxuRnJhbWVJbmZvOiAke3RoaXMuX2ZyYW1lSW5mb31gO1xuICAgICAgICBvdXRwdXQgKz0gYFxcblNlc3Npb25JRDogJHt0aGlzLl9zZXNzaW9uSUR9YDtcbiAgICAgICAgb3V0cHV0ICs9IGBcXG5EYXRhU2l6ZTogJHt0aGlzLl9kYXRhU2l6ZX1gO1xuXG4gICAgICAgIGlmICh0aGlzLl92ZXJzaW9uID4gMSkge1xuICAgICAgICAgICAgb3V0cHV0ICs9IGBcXG5NZXNzYWdlSUQ6ICR7dGhpcy5fbWVzc2FnZUlEfWA7XG4gICAgICAgIH1cblxuICAgICAgICBvdXRwdXQgKz0gJ1xcbioqKioqIFNkbCBQYWNrZXQgRW5kICoqKioqJztcblxuICAgICAgICByZXR1cm4gb3V0cHV0O1xuICAgIH1cblxuICAgIC8qKlxuXHQgKiBUaGlzIG1ldGhvZCB0YWtlcyBpbiB0aGUgdmFyaW91cyBjb21wb25lbnRzIHRvIHRoZSBTREwgcGFja2V0IHN0cnVjdHVyZSBhbmQgY3JlYXRlcyBhIG5ldyBieXRlIGFycmF5IHRoYXQgY2FuIGJlIHNlbnQgdmlhIHRoZSB0cmFuc3BvcnRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gdmVyc2lvbiAtIFByb3RvY29sIHZlcnNpb24gdG8gdXNlXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBlbmNyeXB0aW9uIC0gV2hldGhlciBvciBub3QgdGhlIHBheWxvYWQgaW4gdGhpcyBwYWNrZXQgaXMgZW5jcnlwdGVkXG4gICAgICogQHBhcmFtIHtGcmFtZVR5cGV9IGZyYW1lVHlwZSAtIEEgbnVtYmVyIHJlcHJlc2VudGluZyB0aGUgcGFja2V0IGZyYW1lIHR5cGVcbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZSAtIFRoZSBzZXJ2aWNlIHRoYXQgdGhpcyBwYWNrZXQgaXMgYXNzb2NpYXRlZCB3aXRoXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGNvbnRyb2xGcmFtZUluZm8gLSBTcGVjaWZpYyBmcmFtZSBpbmZvIHJlbGF0ZWQgdG8gdGhpcyBwYWNrZXRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc2Vzc2lvbklEIC0gSUQgdGhpcyBwYWNrZXQgaXMgYXNzb2NpYXRlZCB3aXRoXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGRhdGFTaXplIC0gU2l6ZSBvZiB0aGUgcGF5bG9hZCB0aGF0IHdpbGwgYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbWVzc2FnZUlEIC0gSUQgb2YgdGhpcyBzcGVjaWZpYyBwYWNrZXRcbiAgICAgKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHBheWxvYWQgLSBSYXcgZGF0YSB0aGF0IHdpbGwgYmUgYXR0YWNoZWQgdG8gdGhlIHBhY2tldCAoUlBDIG1lc3NhZ2UsIHJhdyBieXRlcywgZXRjKVxuXHQgKiBAcmV0dXJuIHtVaW50OEFycmF5fSAtIEEgYnl0ZVtdIHJlcHJlc2VudGF0aW9uIG9mIGFuIFNkbFBhY2tldCBidWlsdCB1c2luZyB0aGUgc3VwcGxpZWQgcGFyYW1zXG5cdCAqL1xuICAgIHN0YXRpYyBjb25zdHJ1Y3RQYWNrZXQgKHZlcnNpb24sIGVuY3J5cHRpb24sIGZyYW1lVHlwZSwgc2VydmljZVR5cGUsIGNvbnRyb2xGcmFtZUluZm8sIHNlc3Npb25JRCwgZGF0YVNpemUsIG1lc3NhZ2VJRCwgcGF5bG9hZCkge1xuICAgICAgICBsZXQgZGF0YVZpZXcgPSBudWxsO1xuICAgICAgICBsZXQgZGF0YVZpZXdJbmRleCA9IDA7XG5cbiAgICAgICAgaWYgKHZlcnNpb24gPiAxKSB7XG4gICAgICAgICAgICBkYXRhVmlldyA9IG5ldyBVaW50OEFycmF5KFNkbFBhY2tldC5IRUFERVJfU0laRSArIGRhdGFTaXplKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRhdGFWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoU2RsUGFja2V0LkhFQURFUl9TSVpFX1YxICsgZGF0YVNpemUpO1xuICAgICAgICB9XG5cbiAgICAgICAgZGF0YVZpZXdbZGF0YVZpZXdJbmRleCsrXSA9ICh2ZXJzaW9uIDw8IDQpICsgU2RsUGFja2V0LmdldEVuY3J5cHRpb25CaXQoZW5jcnlwdGlvbikgKyBmcmFtZVR5cGU7XG4gICAgICAgIGRhdGFWaWV3W2RhdGFWaWV3SW5kZXgrK10gPSBzZXJ2aWNlVHlwZTtcbiAgICAgICAgZGF0YVZpZXdbZGF0YVZpZXdJbmRleCsrXSA9IGNvbnRyb2xGcmFtZUluZm87XG4gICAgICAgIGRhdGFWaWV3W2RhdGFWaWV3SW5kZXgrK10gPSBzZXNzaW9uSUQ7XG4gICAgICAgIGRhdGFWaWV3W2RhdGFWaWV3SW5kZXgrK10gPSAoZGF0YVNpemUgJiAweEZGMDAwMDAwKSA+PiAyNDtcbiAgICAgICAgZGF0YVZpZXdbZGF0YVZpZXdJbmRleCsrXSA9IChkYXRhU2l6ZSAmIDB4MDBGRjAwMDApID4+IDE2O1xuICAgICAgICBkYXRhVmlld1tkYXRhVmlld0luZGV4KytdID0gKGRhdGFTaXplICYgMHgwMDAwRkYwMCkgPj4gODtcbiAgICAgICAgZGF0YVZpZXdbZGF0YVZpZXdJbmRleCsrXSA9IGRhdGFTaXplICYgMHgwMDAwMDBGRjtcblxuICAgICAgICBpZiAodmVyc2lvbiA+IDEpIHtcbiAgICAgICAgICAgIGRhdGFWaWV3W2RhdGFWaWV3SW5kZXgrK10gPSAobWVzc2FnZUlEICYgMHhGRjAwMDAwMCkgPj4gMjQ7XG4gICAgICAgICAgICBkYXRhVmlld1tkYXRhVmlld0luZGV4KytdID0gKG1lc3NhZ2VJRCAmIDB4MDBGRjAwMDApID4+IDE2O1xuICAgICAgICAgICAgZGF0YVZpZXdbZGF0YVZpZXdJbmRleCsrXSA9IChtZXNzYWdlSUQgJiAweDAwMDBGRjAwKSA+PiA4O1xuICAgICAgICAgICAgZGF0YVZpZXdbZGF0YVZpZXdJbmRleCsrXSA9IG1lc3NhZ2VJRCAmIDB4MDAwMDAwRkY7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGF5bG9hZCAhPT0gbnVsbCAmJiBwYXlsb2FkLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGRhdGFWaWV3LnNldChwYXlsb2FkLCBkYXRhVmlld0luZGV4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBkYXRhVmlldztcbiAgICB9XG5cbiAgICAvKipcblx0ICogVGhpcyBtZXRob2QgY29udmVydHMgYW4gU2RsUGFja2V0IGluc3RhbmNlIHRvIGEgbmV3IGJ5dGUgYXJyYXkgdGhhdCBjYW4gYmUgc2VudCB2aWEgdGhlIHRyYW5zcG9ydFxuXHQgKiBAcmV0dXJuIHtVaW50OEFycmF5fSAtIEEgYnl0ZVtdIHJlcHJlc2VudGF0aW9uIG9mIGFuIFNkbFBhY2tldCBidWlsdCB1c2luZyB0aGUgc3VwcGxpZWQgcGFyYW1zXG5cdCAqL1xuICAgIHRvUGFja2V0ICgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2Jzb25QYXlsb2FkKSB7XG4gICAgICAgICAgICB0aGlzLl9wYXlsb2FkID0gQnNvbi5zZXJpYWxpemUodGhpcy5fYnNvblBheWxvYWQpO1xuICAgICAgICAgICAgdGhpcy5fZGF0YVNpemUgPSB0aGlzLl9wYXlsb2FkLmxlbmd0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBTZGxQYWNrZXQuY29uc3RydWN0UGFja2V0KHRoaXMuX3ZlcnNpb24sIHRoaXMuX2VuY3J5cHRpb24sIHRoaXMuX2ZyYW1lVHlwZSwgdGhpcy5fc2VydmljZVR5cGUsIHRoaXMuX2ZyYW1lSW5mbywgdGhpcy5fc2Vzc2lvbklELCB0aGlzLl9kYXRhU2l6ZSwgdGhpcy5fbWVzc2FnZUlELCB0aGlzLl9wYXlsb2FkKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdGFnIC0gU3RyaW5nIGtleSB0byBhZGQgYXMgYSBwcm9wZXJ0eSB0byB0aGUgQlNPTiBtYXBcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YSAtIE9iamVjdCB0byBhZGQgYXMgYSB2YWx1ZSB0byB0aGUgQlNPTiBtYXBcbiAgICAgKi9cbiAgICBwdXRUYWcgKHRhZywgZGF0YSkge1xuICAgICAgICBpZiAoIXRoaXMuX2Jzb25QYXlsb2FkKSB7XG4gICAgICAgICAgICB0aGlzLl9ic29uUGF5bG9hZCA9IHt9O1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2Jzb25QYXlsb2FkW3RhZ10gPSBkYXRhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0YWcgLSBTdHJpbmcga2V5IHRvIGFkZCBhcyBhIHByb3BlcnR5IHRvIHRoZSBCU09OIG1hcFxuICAgICAqIEByZXR1cm4ge09iamVjdH0gZGF0YSAtIE9iamVjdCBhcyBhIHZhbHVlIGZvdW5kIGZyb20gdGhlIHRoZSBCU09OIG1hcFxuICAgICAqL1xuXG4gICAgZ2V0VGFnICh0YWcpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9ic29uUGF5bG9hZCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLl9wYXlsb2FkIHx8IHRoaXMuX3BheWxvYWQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9ic29uUGF5bG9hZCA9IEJzb24uZGVzZXJpYWxpemUodGhpcy5fcGF5bG9hZCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYnNvblBheWxvYWRbdGFnXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9ic29uUGF5bG9hZFt0YWddO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5TZGxQYWNrZXQuRVhUUkFfUEFSQ0VMX0RBVEFfTEVOR1RIICAgICAgICAgICAgICAgICAgICAgID0gMjQ7XG5TZGxQYWNrZXQuSEVBREVSX1NJWkUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMTI7XG5TZGxQYWNrZXQuSEVBREVSX1NJWkVfVjEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gODtcblxuU2RsUGFja2V0LkVOQ1JZUFRJT05fTUFTSyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDg7XG5cbi8qKlxuICogU2VydmljZSBUeXBlXG4gKi9cblNkbFBhY2tldC5TRVJWSUNFX1RZUEVfQ09OVFJPTCAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDAwO1xuLy8gUkVTRVJWRUQgMHgwMSAtIDB4MDZcblNkbFBhY2tldC5TRVJWSUNFX1RZUEVfUlBDICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDA3O1xuLy8gUkVTRVJWRUQgMHgwOCAtIDB4MDlcblNkbFBhY2tldC5TRVJWSUNFX1RZUEVfUENNICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDBBO1xuU2RsUGFja2V0LlNFUlZJQ0VfVFlQRV9WSURFTyAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEI7XG4vLyBSRVNFUlZFRCAweDBDIC0gMHgwRVxuU2RsUGFja2V0LlNFUlZJQ0VfVFlQRV9CVUxLX0RBVEEgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEY7XG4vLyBSRVNFUlZFRCAweDEwIC0gMHhGRlxuXG4vKipcbiAqIEZyYW1lIEluZm9cbiAqL1xuU2RsUGFja2V0LkZSQU1FX0lORk9fSEVBUlRfQkVBVCAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDA7XG5TZGxQYWNrZXQuRlJBTUVfSU5GT19TVEFSVF9TRVJWSUNFICAgICAgICAgICAgICAgICAgICAgID0gMHgwMTtcblNkbFBhY2tldC5GUkFNRV9JTkZPX1NUQVJUX1NFUlZJQ0VfQUNLICAgICAgICAgICAgICAgICAgPSAweDAyO1xuU2RsUGFja2V0LkZSQU1FX0lORk9fU1RBUlRfU0VSVklDRV9OQUsgICAgICAgICAgICAgICAgICA9IDB4MDM7XG5TZGxQYWNrZXQuRlJBTUVfSU5GT19FTkRfU0VSVklDRSAgICAgICAgICAgICAgICAgICAgICAgID0gMHgwNDtcblNkbFBhY2tldC5GUkFNRV9JTkZPX0VORF9TRVJWSUNFX0FDSyAgICAgICAgICAgICAgICAgICAgPSAweDA1O1xuU2RsUGFja2V0LkZSQU1FX0lORk9fRU5EX1NFUlZJQ0VfTkFLICAgICAgICAgICAgICAgICAgICA9IDB4MDY7XG5TZGxQYWNrZXQuRlJBTUVfSU5GT19SRUdJU1RFUl9TRUNPTkRBUllfVFJBTlNQT1JUICAgICAgID0gMHgwNztcblNkbFBhY2tldC5GUkFNRV9JTkZPX1JFR0lTVEVSX1NFQ09OREFSWV9UUkFOU1BPUlRfQUNLICAgPSAweDA4O1xuU2RsUGFja2V0LkZSQU1FX0lORk9fUkVHSVNURVJfU0VDT05EQVJZX1RSQU5TUE9SVF9OQUsgICA9IDB4MDk7XG4vLyAweDBBLTB4RkMgYXJlIHJlc2VydmVkXG5TZGxQYWNrZXQuRlJBTUVfSU5GT19UUkFOU1BPUlRfRVZFTlRfVVBEQVRFICAgICAgICAgICAgID0gMHhGRDtcblNkbFBhY2tldC5GUkFNRV9JTkZPX1NFUlZJQ0VfREFUQV9BQ0sgICAgICAgICAgICAgICAgICAgPSAweEZFO1xuU2RsUGFja2V0LkZSQU1FX0lORk9fSEVBUlRfQkVBVF9BQ0sgICAgICAgICAgICAgICAgICAgICA9IDB4RkY7XG5TZGxQYWNrZXQuRlJBTUVfSU5GT19GSU5BTF9DT05ORVNDVVRJVkVfRlJBTUUgICAgICAgICAgID0gMHgwMDtcblNkbFBhY2tldC5GUkFNRV9JTkZPX1JFU0VSVkVEICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDAwO1xuXG5leHBvcnQgeyBTZGxQYWNrZXQgfTtcbiIsImV4cG9ydCBkZWZhdWx0ICh0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDpcbiAgICAgICAgICAgIHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6XG4gICAgICAgICAgICB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pO1xuIiwiXG52YXIgbG9va3VwID0gW11cbnZhciByZXZMb29rdXAgPSBbXVxudmFyIEFyciA9IHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJyA/IFVpbnQ4QXJyYXkgOiBBcnJheVxudmFyIGluaXRlZCA9IGZhbHNlO1xuZnVuY3Rpb24gaW5pdCAoKSB7XG4gIGluaXRlZCA9IHRydWU7XG4gIHZhciBjb2RlID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBjb2RlLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgbG9va3VwW2ldID0gY29kZVtpXVxuICAgIHJldkxvb2t1cFtjb2RlLmNoYXJDb2RlQXQoaSldID0gaVxuICB9XG5cbiAgcmV2TG9va3VwWyctJy5jaGFyQ29kZUF0KDApXSA9IDYyXG4gIHJldkxvb2t1cFsnXycuY2hhckNvZGVBdCgwKV0gPSA2M1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdG9CeXRlQXJyYXkgKGI2NCkge1xuICBpZiAoIWluaXRlZCkge1xuICAgIGluaXQoKTtcbiAgfVxuICB2YXIgaSwgaiwgbCwgdG1wLCBwbGFjZUhvbGRlcnMsIGFyclxuICB2YXIgbGVuID0gYjY0Lmxlbmd0aFxuXG4gIGlmIChsZW4gJSA0ID4gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdHJpbmcuIExlbmd0aCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNCcpXG4gIH1cblxuICAvLyB0aGUgbnVtYmVyIG9mIGVxdWFsIHNpZ25zIChwbGFjZSBob2xkZXJzKVxuICAvLyBpZiB0aGVyZSBhcmUgdHdvIHBsYWNlaG9sZGVycywgdGhhbiB0aGUgdHdvIGNoYXJhY3RlcnMgYmVmb3JlIGl0XG4gIC8vIHJlcHJlc2VudCBvbmUgYnl0ZVxuICAvLyBpZiB0aGVyZSBpcyBvbmx5IG9uZSwgdGhlbiB0aGUgdGhyZWUgY2hhcmFjdGVycyBiZWZvcmUgaXQgcmVwcmVzZW50IDIgYnl0ZXNcbiAgLy8gdGhpcyBpcyBqdXN0IGEgY2hlYXAgaGFjayB0byBub3QgZG8gaW5kZXhPZiB0d2ljZVxuICBwbGFjZUhvbGRlcnMgPSBiNjRbbGVuIC0gMl0gPT09ICc9JyA/IDIgOiBiNjRbbGVuIC0gMV0gPT09ICc9JyA/IDEgOiAwXG5cbiAgLy8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG4gIGFyciA9IG5ldyBBcnIobGVuICogMyAvIDQgLSBwbGFjZUhvbGRlcnMpXG5cbiAgLy8gaWYgdGhlcmUgYXJlIHBsYWNlaG9sZGVycywgb25seSBnZXQgdXAgdG8gdGhlIGxhc3QgY29tcGxldGUgNCBjaGFyc1xuICBsID0gcGxhY2VIb2xkZXJzID4gMCA/IGxlbiAtIDQgOiBsZW5cblxuICB2YXIgTCA9IDBcblxuICBmb3IgKGkgPSAwLCBqID0gMDsgaSA8IGw7IGkgKz0gNCwgaiArPSAzKSB7XG4gICAgdG1wID0gKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTgpIHwgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMSldIDw8IDEyKSB8IChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA8PCA2KSB8IHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMyldXG4gICAgYXJyW0wrK10gPSAodG1wID4+IDE2KSAmIDB4RkZcbiAgICBhcnJbTCsrXSA9ICh0bXAgPj4gOCkgJiAweEZGXG4gICAgYXJyW0wrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICBpZiAocGxhY2VIb2xkZXJzID09PSAyKSB7XG4gICAgdG1wID0gKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMikgfCAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPj4gNClcbiAgICBhcnJbTCsrXSA9IHRtcCAmIDB4RkZcbiAgfSBlbHNlIGlmIChwbGFjZUhvbGRlcnMgPT09IDEpIHtcbiAgICB0bXAgPSAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAxMCkgfCAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPDwgNCkgfCAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAyKV0gPj4gMilcbiAgICBhcnJbTCsrXSA9ICh0bXAgPj4gOCkgJiAweEZGXG4gICAgYXJyW0wrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICByZXR1cm4gYXJyXG59XG5cbmZ1bmN0aW9uIHRyaXBsZXRUb0Jhc2U2NCAobnVtKSB7XG4gIHJldHVybiBsb29rdXBbbnVtID4+IDE4ICYgMHgzRl0gKyBsb29rdXBbbnVtID4+IDEyICYgMHgzRl0gKyBsb29rdXBbbnVtID4+IDYgJiAweDNGXSArIGxvb2t1cFtudW0gJiAweDNGXVxufVxuXG5mdW5jdGlvbiBlbmNvZGVDaHVuayAodWludDgsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHRtcFxuICB2YXIgb3V0cHV0ID0gW11cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpICs9IDMpIHtcbiAgICB0bXAgPSAodWludDhbaV0gPDwgMTYpICsgKHVpbnQ4W2kgKyAxXSA8PCA4KSArICh1aW50OFtpICsgMl0pXG4gICAgb3V0cHV0LnB1c2godHJpcGxldFRvQmFzZTY0KHRtcCkpXG4gIH1cbiAgcmV0dXJuIG91dHB1dC5qb2luKCcnKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZnJvbUJ5dGVBcnJheSAodWludDgpIHtcbiAgaWYgKCFpbml0ZWQpIHtcbiAgICBpbml0KCk7XG4gIH1cbiAgdmFyIHRtcFxuICB2YXIgbGVuID0gdWludDgubGVuZ3RoXG4gIHZhciBleHRyYUJ5dGVzID0gbGVuICUgMyAvLyBpZiB3ZSBoYXZlIDEgYnl0ZSBsZWZ0LCBwYWQgMiBieXRlc1xuICB2YXIgb3V0cHV0ID0gJydcbiAgdmFyIHBhcnRzID0gW11cbiAgdmFyIG1heENodW5rTGVuZ3RoID0gMTYzODMgLy8gbXVzdCBiZSBtdWx0aXBsZSBvZiAzXG5cbiAgLy8gZ28gdGhyb3VnaCB0aGUgYXJyYXkgZXZlcnkgdGhyZWUgYnl0ZXMsIHdlJ2xsIGRlYWwgd2l0aCB0cmFpbGluZyBzdHVmZiBsYXRlclxuICBmb3IgKHZhciBpID0gMCwgbGVuMiA9IGxlbiAtIGV4dHJhQnl0ZXM7IGkgPCBsZW4yOyBpICs9IG1heENodW5rTGVuZ3RoKSB7XG4gICAgcGFydHMucHVzaChlbmNvZGVDaHVuayh1aW50OCwgaSwgKGkgKyBtYXhDaHVua0xlbmd0aCkgPiBsZW4yID8gbGVuMiA6IChpICsgbWF4Q2h1bmtMZW5ndGgpKSlcbiAgfVxuXG4gIC8vIHBhZCB0aGUgZW5kIHdpdGggemVyb3MsIGJ1dCBtYWtlIHN1cmUgdG8gbm90IGZvcmdldCB0aGUgZXh0cmEgYnl0ZXNcbiAgaWYgKGV4dHJhQnl0ZXMgPT09IDEpIHtcbiAgICB0bXAgPSB1aW50OFtsZW4gLSAxXVxuICAgIG91dHB1dCArPSBsb29rdXBbdG1wID4+IDJdXG4gICAgb3V0cHV0ICs9IGxvb2t1cFsodG1wIDw8IDQpICYgMHgzRl1cbiAgICBvdXRwdXQgKz0gJz09J1xuICB9IGVsc2UgaWYgKGV4dHJhQnl0ZXMgPT09IDIpIHtcbiAgICB0bXAgPSAodWludDhbbGVuIC0gMl0gPDwgOCkgKyAodWludDhbbGVuIC0gMV0pXG4gICAgb3V0cHV0ICs9IGxvb2t1cFt0bXAgPj4gMTBdXG4gICAgb3V0cHV0ICs9IGxvb2t1cFsodG1wID4+IDQpICYgMHgzRl1cbiAgICBvdXRwdXQgKz0gbG9va3VwWyh0bXAgPDwgMikgJiAweDNGXVxuICAgIG91dHB1dCArPSAnPSdcbiAgfVxuXG4gIHBhcnRzLnB1c2gob3V0cHV0KVxuXG4gIHJldHVybiBwYXJ0cy5qb2luKCcnKVxufVxuIiwiXG5leHBvcnQgZnVuY3Rpb24gcmVhZCAoYnVmZmVyLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbVxuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIG5CaXRzID0gLTdcbiAgdmFyIGkgPSBpc0xFID8gKG5CeXRlcyAtIDEpIDogMFxuICB2YXIgZCA9IGlzTEUgPyAtMSA6IDFcbiAgdmFyIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV1cblxuICBpICs9IGRcblxuICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBzID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBlTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IGUgPSBlICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgbSA9IGUgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgZSA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gbUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gbSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhc1xuICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcbiAgICByZXR1cm4gbSA/IE5hTiA6ICgocyA/IC0xIDogMSkgKiBJbmZpbml0eSlcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pXG4gICAgZSA9IGUgLSBlQmlhc1xuICB9XG4gIHJldHVybiAocyA/IC0xIDogMSkgKiBtICogTWF0aC5wb3coMiwgZSAtIG1MZW4pXG59XG5cbmV4cG9ydCBmdW5jdGlvbiB3cml0ZSAoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGNcbiAgdmFyIGVMZW4gPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBydCA9IChtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMClcbiAgdmFyIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKVxuICB2YXIgZCA9IGlzTEUgPyAxIDogLTFcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgKHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDApID8gMSA6IDBcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKVxuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwXG4gICAgZSA9IGVNYXhcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMilcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS1cbiAgICAgIGMgKj0gMlxuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gY1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcylcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKytcbiAgICAgIGMgLz0gMlxuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDBcbiAgICAgIGUgPSBlTWF4XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICh2YWx1ZSAqIGMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gZSArIGVCaWFzXG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSB2YWx1ZSAqIE1hdGgucG93KDIsIGVCaWFzIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IDBcbiAgICB9XG4gIH1cblxuICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBtICYgMHhmZiwgaSArPSBkLCBtIC89IDI1NiwgbUxlbiAtPSA4KSB7fVxuXG4gIGUgPSAoZSA8PCBtTGVuKSB8IG1cbiAgZUxlbiArPSBtTGVuXG4gIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCkge31cblxuICBidWZmZXJbb2Zmc2V0ICsgaSAtIGRdIHw9IHMgKiAxMjhcbn1cbiIsInZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5leHBvcnQgZGVmYXVsdCBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uIChhcnIpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwoYXJyKSA9PSAnW29iamVjdCBBcnJheV0nO1xufTtcbiIsIi8qIVxuICogVGhlIGJ1ZmZlciBtb2R1bGUgZnJvbSBub2RlLmpzLCBmb3IgdGhlIGJyb3dzZXIuXG4gKlxuICogQGF1dGhvciAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGZlcm9zc0BmZXJvc3Mub3JnPiA8aHR0cDovL2Zlcm9zcy5vcmc+XG4gKiBAbGljZW5zZSAgTUlUXG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIG5vLXByb3RvICovXG5cblxuaW1wb3J0ICogYXMgYmFzZTY0IGZyb20gJy4vYmFzZTY0J1xuaW1wb3J0ICogYXMgaWVlZTc1NCBmcm9tICcuL2llZWU3NTQnXG5pbXBvcnQgaXNBcnJheSBmcm9tICcuL2lzQXJyYXknXG5cbmV4cG9ydCB2YXIgSU5TUEVDVF9NQVhfQllURVMgPSA1MFxuXG4vKipcbiAqIElmIGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGA6XG4gKiAgID09PSB0cnVlICAgIFVzZSBVaW50OEFycmF5IGltcGxlbWVudGF0aW9uIChmYXN0ZXN0KVxuICogICA9PT0gZmFsc2UgICBVc2UgT2JqZWN0IGltcGxlbWVudGF0aW9uIChtb3N0IGNvbXBhdGlibGUsIGV2ZW4gSUU2KVxuICpcbiAqIEJyb3dzZXJzIHRoYXQgc3VwcG9ydCB0eXBlZCBhcnJheXMgYXJlIElFIDEwKywgRmlyZWZveCA0KywgQ2hyb21lIDcrLCBTYWZhcmkgNS4xKyxcbiAqIE9wZXJhIDExLjYrLCBpT1MgNC4yKy5cbiAqXG4gKiBEdWUgdG8gdmFyaW91cyBicm93c2VyIGJ1Z3MsIHNvbWV0aW1lcyB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uIHdpbGwgYmUgdXNlZCBldmVuXG4gKiB3aGVuIHRoZSBicm93c2VyIHN1cHBvcnRzIHR5cGVkIGFycmF5cy5cbiAqXG4gKiBOb3RlOlxuICpcbiAqICAgLSBGaXJlZm94IDQtMjkgbGFja3Mgc3VwcG9ydCBmb3IgYWRkaW5nIG5ldyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YCBpbnN0YW5jZXMsXG4gKiAgICAgU2VlOiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02OTU0MzguXG4gKlxuICogICAtIENocm9tZSA5LTEwIGlzIG1pc3NpbmcgdGhlIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24uXG4gKlxuICogICAtIElFMTAgaGFzIGEgYnJva2VuIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhcnJheXMgb2ZcbiAqICAgICBpbmNvcnJlY3QgbGVuZ3RoIGluIHNvbWUgc2l0dWF0aW9ucy5cblxuICogV2UgZGV0ZWN0IHRoZXNlIGJ1Z2d5IGJyb3dzZXJzIGFuZCBzZXQgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYCB0byBgZmFsc2VgIHNvIHRoZXlcbiAqIGdldCB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uLCB3aGljaCBpcyBzbG93ZXIgYnV0IGJlaGF2ZXMgY29ycmVjdGx5LlxuICovXG5CdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCA9IGdsb2JhbC5UWVBFRF9BUlJBWV9TVVBQT1JUICE9PSB1bmRlZmluZWRcbiAgPyBnbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVFxuICA6IHRydWVcblxuLypcbiAqIEV4cG9ydCBrTWF4TGVuZ3RoIGFmdGVyIHR5cGVkIGFycmF5IHN1cHBvcnQgaXMgZGV0ZXJtaW5lZC5cbiAqL1xudmFyIF9rTWF4TGVuZ3RoID0ga01heExlbmd0aCgpXG5leHBvcnQge19rTWF4TGVuZ3RoIGFzIGtNYXhMZW5ndGh9O1xuZnVuY3Rpb24gdHlwZWRBcnJheVN1cHBvcnQgKCkge1xuICByZXR1cm4gdHJ1ZTtcbiAgLy8gcm9sbHVwIGlzc3Vlc1xuICAvLyB0cnkge1xuICAvLyAgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheSgxKVxuICAvLyAgIGFyci5fX3Byb3RvX18gPSB7XG4gIC8vICAgICBfX3Byb3RvX186IFVpbnQ4QXJyYXkucHJvdG90eXBlLFxuICAvLyAgICAgZm9vOiBmdW5jdGlvbiAoKSB7IHJldHVybiA0MiB9XG4gIC8vICAgfVxuICAvLyAgIHJldHVybiBhcnIuZm9vKCkgPT09IDQyICYmIC8vIHR5cGVkIGFycmF5IGluc3RhbmNlcyBjYW4gYmUgYXVnbWVudGVkXG4gIC8vICAgICAgIHR5cGVvZiBhcnIuc3ViYXJyYXkgPT09ICdmdW5jdGlvbicgJiYgLy8gY2hyb21lIDktMTAgbGFjayBgc3ViYXJyYXlgXG4gIC8vICAgICAgIGFyci5zdWJhcnJheSgxLCAxKS5ieXRlTGVuZ3RoID09PSAwIC8vIGllMTAgaGFzIGJyb2tlbiBgc3ViYXJyYXlgXG4gIC8vIH0gY2F0Y2ggKGUpIHtcbiAgLy8gICByZXR1cm4gZmFsc2VcbiAgLy8gfVxufVxuXG5mdW5jdGlvbiBrTWF4TGVuZ3RoICgpIHtcbiAgcmV0dXJuIEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUXG4gICAgPyAweDdmZmZmZmZmXG4gICAgOiAweDNmZmZmZmZmXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUJ1ZmZlciAodGhhdCwgbGVuZ3RoKSB7XG4gIGlmIChrTWF4TGVuZ3RoKCkgPCBsZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW52YWxpZCB0eXBlZCBhcnJheSBsZW5ndGgnKVxuICB9XG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlLCBmb3IgYmVzdCBwZXJmb3JtYW5jZVxuICAgIHRoYXQgPSBuZXcgVWludDhBcnJheShsZW5ndGgpXG4gICAgdGhhdC5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIH0gZWxzZSB7XG4gICAgLy8gRmFsbGJhY2s6IFJldHVybiBhbiBvYmplY3QgaW5zdGFuY2Ugb2YgdGhlIEJ1ZmZlciBjbGFzc1xuICAgIGlmICh0aGF0ID09PSBudWxsKSB7XG4gICAgICB0aGF0ID0gbmV3IEJ1ZmZlcihsZW5ndGgpXG4gICAgfVxuICAgIHRoYXQubGVuZ3RoID0gbGVuZ3RoXG4gIH1cblxuICByZXR1cm4gdGhhdFxufVxuXG4vKipcbiAqIFRoZSBCdWZmZXIgY29uc3RydWN0b3IgcmV0dXJucyBpbnN0YW5jZXMgb2YgYFVpbnQ4QXJyYXlgIHRoYXQgaGF2ZSB0aGVpclxuICogcHJvdG90eXBlIGNoYW5nZWQgdG8gYEJ1ZmZlci5wcm90b3R5cGVgLiBGdXJ0aGVybW9yZSwgYEJ1ZmZlcmAgaXMgYSBzdWJjbGFzcyBvZlxuICogYFVpbnQ4QXJyYXlgLCBzbyB0aGUgcmV0dXJuZWQgaW5zdGFuY2VzIHdpbGwgaGF2ZSBhbGwgdGhlIG5vZGUgYEJ1ZmZlcmAgbWV0aG9kc1xuICogYW5kIHRoZSBgVWludDhBcnJheWAgbWV0aG9kcy4gU3F1YXJlIGJyYWNrZXQgbm90YXRpb24gd29ya3MgYXMgZXhwZWN0ZWQgLS0gaXRcbiAqIHJldHVybnMgYSBzaW5nbGUgb2N0ZXQuXG4gKlxuICogVGhlIGBVaW50OEFycmF5YCBwcm90b3R5cGUgcmVtYWlucyB1bm1vZGlmaWVkLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBCdWZmZXIgKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiYgISh0aGlzIGluc3RhbmNlb2YgQnVmZmVyKSkge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgLy8gQ29tbW9uIGNhc2UuXG4gIGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykge1xuICAgIGlmICh0eXBlb2YgZW5jb2RpbmdPck9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0lmIGVuY29kaW5nIGlzIHNwZWNpZmllZCB0aGVuIHRoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nJ1xuICAgICAgKVxuICAgIH1cbiAgICByZXR1cm4gYWxsb2NVbnNhZmUodGhpcywgYXJnKVxuICB9XG4gIHJldHVybiBmcm9tKHRoaXMsIGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxuLy8gVE9ETzogTGVnYWN5LCBub3QgbmVlZGVkIGFueW1vcmUuIFJlbW92ZSBpbiBuZXh0IG1ham9yIHZlcnNpb24uXG5CdWZmZXIuX2F1Z21lbnQgPSBmdW5jdGlvbiAoYXJyKSB7XG4gIGFyci5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIHJldHVybiBhcnJcbn1cblxuZnVuY3Rpb24gZnJvbSAodGhhdCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBtdXN0IG5vdCBiZSBhIG51bWJlcicpXG4gIH1cblxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB2YWx1ZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgcmV0dXJuIGZyb21BcnJheUJ1ZmZlcih0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyh0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldClcbiAgfVxuXG4gIHJldHVybiBmcm9tT2JqZWN0KHRoYXQsIHZhbHVlKVxufVxuXG4vKipcbiAqIEZ1bmN0aW9uYWxseSBlcXVpdmFsZW50IHRvIEJ1ZmZlcihhcmcsIGVuY29kaW5nKSBidXQgdGhyb3dzIGEgVHlwZUVycm9yXG4gKiBpZiB2YWx1ZSBpcyBhIG51bWJlci5cbiAqIEJ1ZmZlci5mcm9tKHN0clssIGVuY29kaW5nXSlcbiAqIEJ1ZmZlci5mcm9tKGFycmF5KVxuICogQnVmZmVyLmZyb20oYnVmZmVyKVxuICogQnVmZmVyLmZyb20oYXJyYXlCdWZmZXJbLCBieXRlT2Zmc2V0WywgbGVuZ3RoXV0pXG4gKiovXG5CdWZmZXIuZnJvbSA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBmcm9tKG51bGwsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbmlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICBCdWZmZXIucHJvdG90eXBlLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXkucHJvdG90eXBlXG4gIEJ1ZmZlci5fX3Byb3RvX18gPSBVaW50OEFycmF5XG4gIGlmICh0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wuc3BlY2llcyAmJlxuICAgICAgQnVmZmVyW1N5bWJvbC5zcGVjaWVzXSA9PT0gQnVmZmVyKSB7XG4gICAgLy8gRml4IHN1YmFycmF5KCkgaW4gRVMyMDE2LiBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL3B1bGwvOTdcbiAgICAvLyBPYmplY3QuZGVmaW5lUHJvcGVydHkoQnVmZmVyLCBTeW1ib2wuc3BlY2llcywge1xuICAgIC8vICAgdmFsdWU6IG51bGwsXG4gICAgLy8gICBjb25maWd1cmFibGU6IHRydWVcbiAgICAvLyB9KVxuICB9XG59XG5cbmZ1bmN0aW9uIGFzc2VydFNpemUgKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3QgYmUgYSBudW1iZXInKVxuICB9IGVsc2UgaWYgKHNpemUgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIG5lZ2F0aXZlJylcbiAgfVxufVxuXG5mdW5jdGlvbiBhbGxvYyAodGhhdCwgc2l6ZSwgZmlsbCwgZW5jb2RpbmcpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICBpZiAoc2l6ZSA8PSAwKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKVxuICB9XG4gIGlmIChmaWxsICE9PSB1bmRlZmluZWQpIHtcbiAgICAvLyBPbmx5IHBheSBhdHRlbnRpb24gdG8gZW5jb2RpbmcgaWYgaXQncyBhIHN0cmluZy4gVGhpc1xuICAgIC8vIHByZXZlbnRzIGFjY2lkZW50YWxseSBzZW5kaW5nIGluIGEgbnVtYmVyIHRoYXQgd291bGRcbiAgICAvLyBiZSBpbnRlcnByZXR0ZWQgYXMgYSBzdGFydCBvZmZzZXQuXG4gICAgcmV0dXJuIHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZydcbiAgICAgID8gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpLmZpbGwoZmlsbCwgZW5jb2RpbmcpXG4gICAgICA6IGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKS5maWxsKGZpbGwpXG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqIGFsbG9jKHNpemVbLCBmaWxsWywgZW5jb2RpbmddXSlcbiAqKi9cbkJ1ZmZlci5hbGxvYyA9IGZ1bmN0aW9uIChzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICByZXR1cm4gYWxsb2MobnVsbCwgc2l6ZSwgZmlsbCwgZW5jb2RpbmcpXG59XG5cbmZ1bmN0aW9uIGFsbG9jVW5zYWZlICh0aGF0LCBzaXplKSB7XG4gIGFzc2VydFNpemUoc2l6ZSlcbiAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplIDwgMCA/IDAgOiBjaGVja2VkKHNpemUpIHwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2l6ZTsgKytpKSB7XG4gICAgICB0aGF0W2ldID0gMFxuICAgIH1cbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG4vKipcbiAqIEVxdWl2YWxlbnQgdG8gQnVmZmVyKG51bSksIGJ5IGRlZmF1bHQgY3JlYXRlcyBhIG5vbi16ZXJvLWZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKiAqL1xuQnVmZmVyLmFsbG9jVW5zYWZlID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgcmV0dXJuIGFsbG9jVW5zYWZlKG51bGwsIHNpemUpXG59XG4vKipcbiAqIEVxdWl2YWxlbnQgdG8gU2xvd0J1ZmZlcihudW0pLCBieSBkZWZhdWx0IGNyZWF0ZXMgYSBub24temVyby1maWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICovXG5CdWZmZXIuYWxsb2NVbnNhZmVTbG93ID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgcmV0dXJuIGFsbG9jVW5zYWZlKG51bGwsIHNpemUpXG59XG5cbmZ1bmN0aW9uIGZyb21TdHJpbmcgKHRoYXQsIHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycgfHwgZW5jb2RpbmcgPT09ICcnKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgfVxuXG4gIGlmICghQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJlbmNvZGluZ1wiIG11c3QgYmUgYSB2YWxpZCBzdHJpbmcgZW5jb2RpbmcnKVxuICB9XG5cbiAgdmFyIGxlbmd0aCA9IGJ5dGVMZW5ndGgoc3RyaW5nLCBlbmNvZGluZykgfCAwXG4gIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgbGVuZ3RoKVxuXG4gIHZhciBhY3R1YWwgPSB0aGF0LndyaXRlKHN0cmluZywgZW5jb2RpbmcpXG5cbiAgaWYgKGFjdHVhbCAhPT0gbGVuZ3RoKSB7XG4gICAgLy8gV3JpdGluZyBhIGhleCBzdHJpbmcsIGZvciBleGFtcGxlLCB0aGF0IGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVycyB3aWxsXG4gICAgLy8gY2F1c2UgZXZlcnl0aGluZyBhZnRlciB0aGUgZmlyc3QgaW52YWxpZCBjaGFyYWN0ZXIgdG8gYmUgaWdub3JlZC4gKGUuZy5cbiAgICAvLyAnYWJ4eGNkJyB3aWxsIGJlIHRyZWF0ZWQgYXMgJ2FiJylcbiAgICB0aGF0ID0gdGhhdC5zbGljZSgwLCBhY3R1YWwpXG4gIH1cblxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tQXJyYXlMaWtlICh0aGF0LCBhcnJheSkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoIDwgMCA/IDAgOiBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgbGVuZ3RoKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhhdFtpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5QnVmZmVyICh0aGF0LCBhcnJheSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gIGFycmF5LmJ5dGVMZW5ndGggLy8gdGhpcyB0aHJvd3MgaWYgYGFycmF5YCBpcyBub3QgYSB2YWxpZCBBcnJheUJ1ZmZlclxuXG4gIGlmIChieXRlT2Zmc2V0IDwgMCB8fCBhcnJheS5ieXRlTGVuZ3RoIDwgYnl0ZU9mZnNldCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcXCdvZmZzZXRcXCcgaXMgb3V0IG9mIGJvdW5kcycpXG4gIH1cblxuICBpZiAoYXJyYXkuYnl0ZUxlbmd0aCA8IGJ5dGVPZmZzZXQgKyAobGVuZ3RoIHx8IDApKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1xcJ2xlbmd0aFxcJyBpcyBvdXQgb2YgYm91bmRzJylcbiAgfVxuXG4gIGlmIChieXRlT2Zmc2V0ID09PSB1bmRlZmluZWQgJiYgbGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBhcnJheSA9IG5ldyBVaW50OEFycmF5KGFycmF5KVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgYXJyYXkgPSBuZXcgVWludDhBcnJheShhcnJheSwgYnl0ZU9mZnNldClcbiAgfSBlbHNlIHtcbiAgICBhcnJheSA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICB0aGF0ID0gYXJyYXlcbiAgICB0aGF0Ll9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgfSBlbHNlIHtcbiAgICAvLyBGYWxsYmFjazogUmV0dXJuIGFuIG9iamVjdCBpbnN0YW5jZSBvZiB0aGUgQnVmZmVyIGNsYXNzXG4gICAgdGhhdCA9IGZyb21BcnJheUxpa2UodGhhdCwgYXJyYXkpXG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbU9iamVjdCAodGhhdCwgb2JqKSB7XG4gIGlmIChpbnRlcm5hbElzQnVmZmVyKG9iaikpIHtcbiAgICB2YXIgbGVuID0gY2hlY2tlZChvYmoubGVuZ3RoKSB8IDBcbiAgICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIGxlbilcblxuICAgIGlmICh0aGF0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRoYXRcbiAgICB9XG5cbiAgICBvYmouY29weSh0aGF0LCAwLCAwLCBsZW4pXG4gICAgcmV0dXJuIHRoYXRcbiAgfVxuXG4gIGlmIChvYmopIHtcbiAgICBpZiAoKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICAgb2JqLmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB8fCAnbGVuZ3RoJyBpbiBvYmopIHtcbiAgICAgIGlmICh0eXBlb2Ygb2JqLmxlbmd0aCAhPT0gJ251bWJlcicgfHwgaXNuYW4ob2JqLmxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LCAwKVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZyb21BcnJheUxpa2UodGhhdCwgb2JqKVxuICAgIH1cblxuICAgIGlmIChvYmoudHlwZSA9PT0gJ0J1ZmZlcicgJiYgaXNBcnJheShvYmouZGF0YSkpIHtcbiAgICAgIHJldHVybiBmcm9tQXJyYXlMaWtlKHRoYXQsIG9iai5kYXRhKVxuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcsIEJ1ZmZlciwgQXJyYXlCdWZmZXIsIEFycmF5LCBvciBhcnJheS1saWtlIG9iamVjdC4nKVxufVxuXG5mdW5jdGlvbiBjaGVja2VkIChsZW5ndGgpIHtcbiAgLy8gTm90ZTogY2Fubm90IHVzZSBgbGVuZ3RoIDwga01heExlbmd0aCgpYCBoZXJlIGJlY2F1c2UgdGhhdCBmYWlscyB3aGVuXG4gIC8vIGxlbmd0aCBpcyBOYU4gKHdoaWNoIGlzIG90aGVyd2lzZSBjb2VyY2VkIHRvIHplcm8uKVxuICBpZiAobGVuZ3RoID49IGtNYXhMZW5ndGgoKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIGFsbG9jYXRlIEJ1ZmZlciBsYXJnZXIgdGhhbiBtYXhpbXVtICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICdzaXplOiAweCcgKyBrTWF4TGVuZ3RoKCkudG9TdHJpbmcoMTYpICsgJyBieXRlcycpXG4gIH1cbiAgcmV0dXJuIGxlbmd0aCB8IDBcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIFNsb3dCdWZmZXIgKGxlbmd0aCkge1xuICBpZiAoK2xlbmd0aCAhPSBsZW5ndGgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBlcWVxZXFcbiAgICBsZW5ndGggPSAwXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlci5hbGxvYygrbGVuZ3RoKVxufVxuQnVmZmVyLmlzQnVmZmVyID0gaXNCdWZmZXI7XG5mdW5jdGlvbiBpbnRlcm5hbElzQnVmZmVyIChiKSB7XG4gIHJldHVybiAhIShiICE9IG51bGwgJiYgYi5faXNCdWZmZXIpXG59XG5cbkJ1ZmZlci5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZSAoYSwgYikge1xuICBpZiAoIWludGVybmFsSXNCdWZmZXIoYSkgfHwgIWludGVybmFsSXNCdWZmZXIoYikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudHMgbXVzdCBiZSBCdWZmZXJzJylcbiAgfVxuXG4gIGlmIChhID09PSBiKSByZXR1cm4gMFxuXG4gIHZhciB4ID0gYS5sZW5ndGhcbiAgdmFyIHkgPSBiLmxlbmd0aFxuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBNYXRoLm1pbih4LCB5KTsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKGFbaV0gIT09IGJbaV0pIHtcbiAgICAgIHggPSBhW2ldXG4gICAgICB5ID0gYltpXVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbkJ1ZmZlci5pc0VuY29kaW5nID0gZnVuY3Rpb24gaXNFbmNvZGluZyAoZW5jb2RpbmcpIHtcbiAgc3dpdGNoIChTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKCkpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICBjYXNlICdhc2NpaSc6XG4gICAgY2FzZSAnbGF0aW4xJzpcbiAgICBjYXNlICdiaW5hcnknOlxuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgIHJldHVybiB0cnVlXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbkJ1ZmZlci5jb25jYXQgPSBmdW5jdGlvbiBjb25jYXQgKGxpc3QsIGxlbmd0aCkge1xuICBpZiAoIWlzQXJyYXkobGlzdCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RcIiBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMnKVxuICB9XG5cbiAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5hbGxvYygwKVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbGVuZ3RoID0gMFxuICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgICBsZW5ndGggKz0gbGlzdFtpXS5sZW5ndGhcbiAgICB9XG4gIH1cblxuICB2YXIgYnVmZmVyID0gQnVmZmVyLmFsbG9jVW5zYWZlKGxlbmd0aClcbiAgdmFyIHBvcyA9IDBcbiAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgYnVmID0gbGlzdFtpXVxuICAgIGlmICghaW50ZXJuYWxJc0J1ZmZlcihidWYpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RcIiBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMnKVxuICAgIH1cbiAgICBidWYuY29weShidWZmZXIsIHBvcylcbiAgICBwb3MgKz0gYnVmLmxlbmd0aFxuICB9XG4gIHJldHVybiBidWZmZXJcbn1cblxuZnVuY3Rpb24gYnl0ZUxlbmd0aCAoc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAoaW50ZXJuYWxJc0J1ZmZlcihzdHJpbmcpKSB7XG4gICAgcmV0dXJuIHN0cmluZy5sZW5ndGhcbiAgfVxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgQXJyYXlCdWZmZXIuaXNWaWV3ID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAoQXJyYXlCdWZmZXIuaXNWaWV3KHN0cmluZykgfHwgc3RyaW5nIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpKSB7XG4gICAgcmV0dXJuIHN0cmluZy5ieXRlTGVuZ3RoXG4gIH1cbiAgaWYgKHR5cGVvZiBzdHJpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgc3RyaW5nID0gJycgKyBzdHJpbmdcbiAgfVxuXG4gIHZhciBsZW4gPSBzdHJpbmcubGVuZ3RoXG4gIGlmIChsZW4gPT09IDApIHJldHVybiAwXG5cbiAgLy8gVXNlIGEgZm9yIGxvb3AgdG8gYXZvaWQgcmVjdXJzaW9uXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxlblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICBjYXNlIHVuZGVmaW5lZDpcbiAgICAgICAgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gbGVuICogMlxuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGxlbiA+Pj4gMVxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoIC8vIGFzc3VtZSB1dGY4XG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5CdWZmZXIuYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGhcblxuZnVuY3Rpb24gc2xvd1RvU3RyaW5nIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuXG4gIC8vIE5vIG5lZWQgdG8gdmVyaWZ5IHRoYXQgXCJ0aGlzLmxlbmd0aCA8PSBNQVhfVUlOVDMyXCIgc2luY2UgaXQncyBhIHJlYWQtb25seVxuICAvLyBwcm9wZXJ0eSBvZiBhIHR5cGVkIGFycmF5LlxuXG4gIC8vIFRoaXMgYmVoYXZlcyBuZWl0aGVyIGxpa2UgU3RyaW5nIG5vciBVaW50OEFycmF5IGluIHRoYXQgd2Ugc2V0IHN0YXJ0L2VuZFxuICAvLyB0byB0aGVpciB1cHBlci9sb3dlciBib3VuZHMgaWYgdGhlIHZhbHVlIHBhc3NlZCBpcyBvdXQgb2YgcmFuZ2UuXG4gIC8vIHVuZGVmaW5lZCBpcyBoYW5kbGVkIHNwZWNpYWxseSBhcyBwZXIgRUNNQS0yNjIgNnRoIEVkaXRpb24sXG4gIC8vIFNlY3Rpb24gMTMuMy4zLjcgUnVudGltZSBTZW1hbnRpY3M6IEtleWVkQmluZGluZ0luaXRpYWxpemF0aW9uLlxuICBpZiAoc3RhcnQgPT09IHVuZGVmaW5lZCB8fCBzdGFydCA8IDApIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICAvLyBSZXR1cm4gZWFybHkgaWYgc3RhcnQgPiB0aGlzLmxlbmd0aC4gRG9uZSBoZXJlIHRvIHByZXZlbnQgcG90ZW50aWFsIHVpbnQzMlxuICAvLyBjb2VyY2lvbiBmYWlsIGJlbG93LlxuICBpZiAoc3RhcnQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgfVxuXG4gIGlmIChlbmQgPD0gMCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgLy8gRm9yY2UgY29lcnNpb24gdG8gdWludDMyLiBUaGlzIHdpbGwgYWxzbyBjb2VyY2UgZmFsc2V5L05hTiB2YWx1ZXMgdG8gMC5cbiAgZW5kID4+Pj0gMFxuICBzdGFydCA+Pj49IDBcblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsYXRpbjFTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHV0ZjE2bGVTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuLy8gVGhlIHByb3BlcnR5IGlzIHVzZWQgYnkgYEJ1ZmZlci5pc0J1ZmZlcmAgYW5kIGBpcy1idWZmZXJgIChpbiBTYWZhcmkgNS03KSB0byBkZXRlY3Rcbi8vIEJ1ZmZlciBpbnN0YW5jZXMuXG5CdWZmZXIucHJvdG90eXBlLl9pc0J1ZmZlciA9IHRydWVcblxuZnVuY3Rpb24gc3dhcCAoYiwgbiwgbSkge1xuICB2YXIgaSA9IGJbbl1cbiAgYltuXSA9IGJbbV1cbiAgYlttXSA9IGlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwMTYgPSBmdW5jdGlvbiBzd2FwMTYgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDIgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDE2LWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDIpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyAxKVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDMyID0gZnVuY3Rpb24gc3dhcDMyICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSA0ICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAzMi1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgMylcbiAgICBzd2FwKHRoaXMsIGkgKyAxLCBpICsgMilcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXA2NCA9IGZ1bmN0aW9uIHN3YXA2NCAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgOCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNjQtYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gOCkge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDcpXG4gICAgc3dhcCh0aGlzLCBpICsgMSwgaSArIDYpXG4gICAgc3dhcCh0aGlzLCBpICsgMiwgaSArIDUpXG4gICAgc3dhcCh0aGlzLCBpICsgMywgaSArIDQpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nICgpIHtcbiAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoIHwgMFxuICBpZiAobGVuZ3RoID09PSAwKSByZXR1cm4gJydcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHJldHVybiB1dGY4U2xpY2UodGhpcywgMCwgbGVuZ3RoKVxuICByZXR1cm4gc2xvd1RvU3RyaW5nLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiBlcXVhbHMgKGIpIHtcbiAgaWYgKCFpbnRlcm5hbElzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiB0cnVlXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKSA9PT0gMFxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0ICgpIHtcbiAgdmFyIHN0ciA9ICcnXG4gIHZhciBtYXggPSBJTlNQRUNUX01BWF9CWVRFU1xuICBpZiAodGhpcy5sZW5ndGggPiAwKSB7XG4gICAgc3RyID0gdGhpcy50b1N0cmluZygnaGV4JywgMCwgbWF4KS5tYXRjaCgvLnsyfS9nKS5qb2luKCcgJylcbiAgICBpZiAodGhpcy5sZW5ndGggPiBtYXgpIHN0ciArPSAnIC4uLiAnXG4gIH1cbiAgcmV0dXJuICc8QnVmZmVyICcgKyBzdHIgKyAnPidcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZSAodGFyZ2V0LCBzdGFydCwgZW5kLCB0aGlzU3RhcnQsIHRoaXNFbmQpIHtcbiAgaWYgKCFpbnRlcm5hbElzQnVmZmVyKHRhcmdldCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgfVxuXG4gIGlmIChzdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgc3RhcnQgPSAwXG4gIH1cbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5kID0gdGFyZ2V0ID8gdGFyZ2V0Lmxlbmd0aCA6IDBcbiAgfVxuICBpZiAodGhpc1N0YXJ0ID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzU3RhcnQgPSAwXG4gIH1cbiAgaWYgKHRoaXNFbmQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRoaXNFbmQgPSB0aGlzLmxlbmd0aFxuICB9XG5cbiAgaWYgKHN0YXJ0IDwgMCB8fCBlbmQgPiB0YXJnZXQubGVuZ3RoIHx8IHRoaXNTdGFydCA8IDAgfHwgdGhpc0VuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ291dCBvZiByYW5nZSBpbmRleCcpXG4gIH1cblxuICBpZiAodGhpc1N0YXJ0ID49IHRoaXNFbmQgJiYgc3RhcnQgPj0gZW5kKSB7XG4gICAgcmV0dXJuIDBcbiAgfVxuICBpZiAodGhpc1N0YXJ0ID49IHRoaXNFbmQpIHtcbiAgICByZXR1cm4gLTFcbiAgfVxuICBpZiAoc3RhcnQgPj0gZW5kKSB7XG4gICAgcmV0dXJuIDFcbiAgfVxuXG4gIHN0YXJ0ID4+Pj0gMFxuICBlbmQgPj4+PSAwXG4gIHRoaXNTdGFydCA+Pj49IDBcbiAgdGhpc0VuZCA+Pj49IDBcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0KSByZXR1cm4gMFxuXG4gIHZhciB4ID0gdGhpc0VuZCAtIHRoaXNTdGFydFxuICB2YXIgeSA9IGVuZCAtIHN0YXJ0XG4gIHZhciBsZW4gPSBNYXRoLm1pbih4LCB5KVxuXG4gIHZhciB0aGlzQ29weSA9IHRoaXMuc2xpY2UodGhpc1N0YXJ0LCB0aGlzRW5kKVxuICB2YXIgdGFyZ2V0Q29weSA9IHRhcmdldC5zbGljZShzdGFydCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAodGhpc0NvcHlbaV0gIT09IHRhcmdldENvcHlbaV0pIHtcbiAgICAgIHggPSB0aGlzQ29weVtpXVxuICAgICAgeSA9IHRhcmdldENvcHlbaV1cbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG5cbiAgaWYgKHggPCB5KSByZXR1cm4gLTFcbiAgaWYgKHkgPCB4KSByZXR1cm4gMVxuICByZXR1cm4gMFxufVxuXG4vLyBGaW5kcyBlaXRoZXIgdGhlIGZpcnN0IGluZGV4IG9mIGB2YWxgIGluIGBidWZmZXJgIGF0IG9mZnNldCA+PSBgYnl0ZU9mZnNldGAsXG4vLyBPUiB0aGUgbGFzdCBpbmRleCBvZiBgdmFsYCBpbiBgYnVmZmVyYCBhdCBvZmZzZXQgPD0gYGJ5dGVPZmZzZXRgLlxuLy9cbi8vIEFyZ3VtZW50czpcbi8vIC0gYnVmZmVyIC0gYSBCdWZmZXIgdG8gc2VhcmNoXG4vLyAtIHZhbCAtIGEgc3RyaW5nLCBCdWZmZXIsIG9yIG51bWJlclxuLy8gLSBieXRlT2Zmc2V0IC0gYW4gaW5kZXggaW50byBgYnVmZmVyYDsgd2lsbCBiZSBjbGFtcGVkIHRvIGFuIGludDMyXG4vLyAtIGVuY29kaW5nIC0gYW4gb3B0aW9uYWwgZW5jb2RpbmcsIHJlbGV2YW50IGlzIHZhbCBpcyBhIHN0cmluZ1xuLy8gLSBkaXIgLSB0cnVlIGZvciBpbmRleE9mLCBmYWxzZSBmb3IgbGFzdEluZGV4T2ZcbmZ1bmN0aW9uIGJpZGlyZWN0aW9uYWxJbmRleE9mIChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcikge1xuICAvLyBFbXB0eSBidWZmZXIgbWVhbnMgbm8gbWF0Y2hcbiAgaWYgKGJ1ZmZlci5sZW5ndGggPT09IDApIHJldHVybiAtMVxuXG4gIC8vIE5vcm1hbGl6ZSBieXRlT2Zmc2V0XG4gIGlmICh0eXBlb2YgYnl0ZU9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IGJ5dGVPZmZzZXRcbiAgICBieXRlT2Zmc2V0ID0gMFxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPiAweDdmZmZmZmZmKSB7XG4gICAgYnl0ZU9mZnNldCA9IDB4N2ZmZmZmZmZcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0IDwgLTB4ODAwMDAwMDApIHtcbiAgICBieXRlT2Zmc2V0ID0gLTB4ODAwMDAwMDBcbiAgfVxuICBieXRlT2Zmc2V0ID0gK2J5dGVPZmZzZXQgIC8vIENvZXJjZSB0byBOdW1iZXIuXG4gIGlmIChpc05hTihieXRlT2Zmc2V0KSkge1xuICAgIC8vIGJ5dGVPZmZzZXQ6IGl0IGl0J3MgdW5kZWZpbmVkLCBudWxsLCBOYU4sIFwiZm9vXCIsIGV0Yywgc2VhcmNoIHdob2xlIGJ1ZmZlclxuICAgIGJ5dGVPZmZzZXQgPSBkaXIgPyAwIDogKGJ1ZmZlci5sZW5ndGggLSAxKVxuICB9XG5cbiAgLy8gTm9ybWFsaXplIGJ5dGVPZmZzZXQ6IG5lZ2F0aXZlIG9mZnNldHMgc3RhcnQgZnJvbSB0aGUgZW5kIG9mIHRoZSBidWZmZXJcbiAgaWYgKGJ5dGVPZmZzZXQgPCAwKSBieXRlT2Zmc2V0ID0gYnVmZmVyLmxlbmd0aCArIGJ5dGVPZmZzZXRcbiAgaWYgKGJ5dGVPZmZzZXQgPj0gYnVmZmVyLmxlbmd0aCkge1xuICAgIGlmIChkaXIpIHJldHVybiAtMVxuICAgIGVsc2UgYnl0ZU9mZnNldCA9IGJ1ZmZlci5sZW5ndGggLSAxXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA8IDApIHtcbiAgICBpZiAoZGlyKSBieXRlT2Zmc2V0ID0gMFxuICAgIGVsc2UgcmV0dXJuIC0xXG4gIH1cblxuICAvLyBOb3JtYWxpemUgdmFsXG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIHZhbCA9IEJ1ZmZlci5mcm9tKHZhbCwgZW5jb2RpbmcpXG4gIH1cblxuICAvLyBGaW5hbGx5LCBzZWFyY2ggZWl0aGVyIGluZGV4T2YgKGlmIGRpciBpcyB0cnVlKSBvciBsYXN0SW5kZXhPZlxuICBpZiAoaW50ZXJuYWxJc0J1ZmZlcih2YWwpKSB7XG4gICAgLy8gU3BlY2lhbCBjYXNlOiBsb29raW5nIGZvciBlbXB0eSBzdHJpbmcvYnVmZmVyIGFsd2F5cyBmYWlsc1xuICAgIGlmICh2YWwubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gLTFcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZihidWZmZXIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcilcbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIHZhbCA9IHZhbCAmIDB4RkYgLy8gU2VhcmNoIGZvciBhIGJ5dGUgdmFsdWUgWzAtMjU1XVxuICAgIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJlxuICAgICAgICB0eXBlb2YgVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaWYgKGRpcikge1xuICAgICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmxhc3RJbmRleE9mLmNhbGwoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YoYnVmZmVyLCBbIHZhbCBdLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmFsIG11c3QgYmUgc3RyaW5nLCBudW1iZXIgb3IgQnVmZmVyJylcbn1cblxuZnVuY3Rpb24gYXJyYXlJbmRleE9mIChhcnIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcikge1xuICB2YXIgaW5kZXhTaXplID0gMVxuICB2YXIgYXJyTGVuZ3RoID0gYXJyLmxlbmd0aFxuICB2YXIgdmFsTGVuZ3RoID0gdmFsLmxlbmd0aFxuXG4gIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSBTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICBpZiAoZW5jb2RpbmcgPT09ICd1Y3MyJyB8fCBlbmNvZGluZyA9PT0gJ3Vjcy0yJyB8fFxuICAgICAgICBlbmNvZGluZyA9PT0gJ3V0ZjE2bGUnIHx8IGVuY29kaW5nID09PSAndXRmLTE2bGUnKSB7XG4gICAgICBpZiAoYXJyLmxlbmd0aCA8IDIgfHwgdmFsLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgcmV0dXJuIC0xXG4gICAgICB9XG4gICAgICBpbmRleFNpemUgPSAyXG4gICAgICBhcnJMZW5ndGggLz0gMlxuICAgICAgdmFsTGVuZ3RoIC89IDJcbiAgICAgIGJ5dGVPZmZzZXQgLz0gMlxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlYWQgKGJ1ZiwgaSkge1xuICAgIGlmIChpbmRleFNpemUgPT09IDEpIHtcbiAgICAgIHJldHVybiBidWZbaV1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGJ1Zi5yZWFkVUludDE2QkUoaSAqIGluZGV4U2l6ZSlcbiAgICB9XG4gIH1cblxuICB2YXIgaVxuICBpZiAoZGlyKSB7XG4gICAgdmFyIGZvdW5kSW5kZXggPSAtMVxuICAgIGZvciAoaSA9IGJ5dGVPZmZzZXQ7IGkgPCBhcnJMZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHJlYWQoYXJyLCBpKSA9PT0gcmVhZCh2YWwsIGZvdW5kSW5kZXggPT09IC0xID8gMCA6IGkgLSBmb3VuZEluZGV4KSkge1xuICAgICAgICBpZiAoZm91bmRJbmRleCA9PT0gLTEpIGZvdW5kSW5kZXggPSBpXG4gICAgICAgIGlmIChpIC0gZm91bmRJbmRleCArIDEgPT09IHZhbExlbmd0aCkgcmV0dXJuIGZvdW5kSW5kZXggKiBpbmRleFNpemVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ICE9PSAtMSkgaSAtPSBpIC0gZm91bmRJbmRleFxuICAgICAgICBmb3VuZEluZGV4ID0gLTFcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGJ5dGVPZmZzZXQgKyB2YWxMZW5ndGggPiBhcnJMZW5ndGgpIGJ5dGVPZmZzZXQgPSBhcnJMZW5ndGggLSB2YWxMZW5ndGhcbiAgICBmb3IgKGkgPSBieXRlT2Zmc2V0OyBpID49IDA7IGktLSkge1xuICAgICAgdmFyIGZvdW5kID0gdHJ1ZVxuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCB2YWxMZW5ndGg7IGorKykge1xuICAgICAgICBpZiAocmVhZChhcnIsIGkgKyBqKSAhPT0gcmVhZCh2YWwsIGopKSB7XG4gICAgICAgICAgZm91bmQgPSBmYWxzZVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChmb3VuZCkgcmV0dXJuIGlcbiAgICB9XG4gIH1cblxuICByZXR1cm4gLTFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbmNsdWRlcyA9IGZ1bmN0aW9uIGluY2x1ZGVzICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiB0aGlzLmluZGV4T2YodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykgIT09IC0xXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uIGluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGJpZGlyZWN0aW9uYWxJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIHRydWUpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUubGFzdEluZGV4T2YgPSBmdW5jdGlvbiBsYXN0SW5kZXhPZiAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZmFsc2UpXG59XG5cbmZ1bmN0aW9uIGhleFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gYnVmLmxlbmd0aCAtIG9mZnNldFxuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9IE51bWJlcihsZW5ndGgpXG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gICAgfVxuICB9XG5cbiAgLy8gbXVzdCBiZSBhbiBldmVuIG51bWJlciBvZiBkaWdpdHNcbiAgdmFyIHN0ckxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKHN0ckxlbiAlIDIgIT09IDApIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgaGV4IHN0cmluZycpXG5cbiAgaWYgKGxlbmd0aCA+IHN0ckxlbiAvIDIpIHtcbiAgICBsZW5ndGggPSBzdHJMZW4gLyAyXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIHZhciBwYXJzZWQgPSBwYXJzZUludChzdHJpbmcuc3Vic3RyKGkgKiAyLCAyKSwgMTYpXG4gICAgaWYgKGlzTmFOKHBhcnNlZCkpIHJldHVybiBpXG4gICAgYnVmW29mZnNldCArIGldID0gcGFyc2VkXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gdXRmOFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmOFRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYXNjaWlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGFzY2lpVG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBsYXRpbjFXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBhc2NpaVdyaXRlKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYmFzZTY0V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihiYXNlNjRUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIHVjczJXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjE2bGVUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiB3cml0ZSAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpIHtcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZylcbiAgaWYgKG9mZnNldCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgZW5jb2RpbmcpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIG9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IG9mZnNldFxuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBvZmZzZXRbLCBsZW5ndGhdWywgZW5jb2RpbmddKVxuICB9IGVsc2UgaWYgKGlzRmluaXRlKG9mZnNldCkpIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gICAgaWYgKGlzRmluaXRlKGxlbmd0aCkpIHtcbiAgICAgIGxlbmd0aCA9IGxlbmd0aCB8IDBcbiAgICAgIGlmIChlbmNvZGluZyA9PT0gdW5kZWZpbmVkKSBlbmNvZGluZyA9ICd1dGY4J1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmNvZGluZyA9IGxlbmd0aFxuICAgICAgbGVuZ3RoID0gdW5kZWZpbmVkXG4gICAgfVxuICAvLyBsZWdhY3kgd3JpdGUoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0LCBsZW5ndGgpIC0gcmVtb3ZlIGluIHYwLjEzXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ0J1ZmZlci53cml0ZShzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXRbLCBsZW5ndGhdKSBpcyBubyBsb25nZXIgc3VwcG9ydGVkJ1xuICAgIClcbiAgfVxuXG4gIHZhciByZW1haW5pbmcgPSB0aGlzLmxlbmd0aCAtIG9mZnNldFxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgfHwgbGVuZ3RoID4gcmVtYWluaW5nKSBsZW5ndGggPSByZW1haW5pbmdcblxuICBpZiAoKHN0cmluZy5sZW5ndGggPiAwICYmIChsZW5ndGggPCAwIHx8IG9mZnNldCA8IDApKSB8fCBvZmZzZXQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIHdyaXRlIG91dHNpZGUgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxhdGluMVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIC8vIFdhcm5pbmc6IG1heExlbmd0aCBub3QgdGFrZW4gaW50byBhY2NvdW50IGluIGJhc2U2NFdyaXRlXG4gICAgICAgIHJldHVybiBiYXNlNjRXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdWNzMldyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTiAoKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ0J1ZmZlcicsXG4gICAgZGF0YTogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy5fYXJyIHx8IHRoaXMsIDApXG4gIH1cbn1cblxuZnVuY3Rpb24gYmFzZTY0U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBpZiAoc3RhcnQgPT09IDAgJiYgZW5kID09PSBidWYubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1ZilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmLnNsaWNlKHN0YXJ0LCBlbmQpKVxuICB9XG59XG5cbmZ1bmN0aW9uIHV0ZjhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcbiAgdmFyIHJlcyA9IFtdXG5cbiAgdmFyIGkgPSBzdGFydFxuICB3aGlsZSAoaSA8IGVuZCkge1xuICAgIHZhciBmaXJzdEJ5dGUgPSBidWZbaV1cbiAgICB2YXIgY29kZVBvaW50ID0gbnVsbFxuICAgIHZhciBieXRlc1BlclNlcXVlbmNlID0gKGZpcnN0Qnl0ZSA+IDB4RUYpID8gNFxuICAgICAgOiAoZmlyc3RCeXRlID4gMHhERikgPyAzXG4gICAgICA6IChmaXJzdEJ5dGUgPiAweEJGKSA/IDJcbiAgICAgIDogMVxuXG4gICAgaWYgKGkgKyBieXRlc1BlclNlcXVlbmNlIDw9IGVuZCkge1xuICAgICAgdmFyIHNlY29uZEJ5dGUsIHRoaXJkQnl0ZSwgZm91cnRoQnl0ZSwgdGVtcENvZGVQb2ludFxuXG4gICAgICBzd2l0Y2ggKGJ5dGVzUGVyU2VxdWVuY2UpIHtcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIGlmIChmaXJzdEJ5dGUgPCAweDgwKSB7XG4gICAgICAgICAgICBjb2RlUG9pbnQgPSBmaXJzdEJ5dGVcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHgxRikgPDwgMHg2IHwgKHNlY29uZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4QyB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKHRoaXJkQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0ZGICYmICh0ZW1wQ29kZVBvaW50IDwgMHhEODAwIHx8IHRlbXBDb2RlUG9pbnQgPiAweERGRkYpKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGZvdXJ0aEJ5dGUgPSBidWZbaSArIDNdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwICYmIChmb3VydGhCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweDEyIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweEMgfCAodGhpcmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKGZvdXJ0aEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweEZGRkYgJiYgdGVtcENvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvZGVQb2ludCA9PT0gbnVsbCkge1xuICAgICAgLy8gd2UgZGlkIG5vdCBnZW5lcmF0ZSBhIHZhbGlkIGNvZGVQb2ludCBzbyBpbnNlcnQgYVxuICAgICAgLy8gcmVwbGFjZW1lbnQgY2hhciAoVStGRkZEKSBhbmQgYWR2YW5jZSBvbmx5IDEgYnl0ZVxuICAgICAgY29kZVBvaW50ID0gMHhGRkZEXG4gICAgICBieXRlc1BlclNlcXVlbmNlID0gMVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50ID4gMHhGRkZGKSB7XG4gICAgICAvLyBlbmNvZGUgdG8gdXRmMTYgKHN1cnJvZ2F0ZSBwYWlyIGRhbmNlKVxuICAgICAgY29kZVBvaW50IC09IDB4MTAwMDBcbiAgICAgIHJlcy5wdXNoKGNvZGVQb2ludCA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMClcbiAgICAgIGNvZGVQb2ludCA9IDB4REMwMCB8IGNvZGVQb2ludCAmIDB4M0ZGXG4gICAgfVxuXG4gICAgcmVzLnB1c2goY29kZVBvaW50KVxuICAgIGkgKz0gYnl0ZXNQZXJTZXF1ZW5jZVxuICB9XG5cbiAgcmV0dXJuIGRlY29kZUNvZGVQb2ludHNBcnJheShyZXMpXG59XG5cbi8vIEJhc2VkIG9uIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIyNzQ3MjcyLzY4MDc0MiwgdGhlIGJyb3dzZXIgd2l0aFxuLy8gdGhlIGxvd2VzdCBsaW1pdCBpcyBDaHJvbWUsIHdpdGggMHgxMDAwMCBhcmdzLlxuLy8gV2UgZ28gMSBtYWduaXR1ZGUgbGVzcywgZm9yIHNhZmV0eVxudmFyIE1BWF9BUkdVTUVOVFNfTEVOR1RIID0gMHgxMDAwXG5cbmZ1bmN0aW9uIGRlY29kZUNvZGVQb2ludHNBcnJheSAoY29kZVBvaW50cykge1xuICB2YXIgbGVuID0gY29kZVBvaW50cy5sZW5ndGhcbiAgaWYgKGxlbiA8PSBNQVhfQVJHVU1FTlRTX0xFTkdUSCkge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY29kZVBvaW50cykgLy8gYXZvaWQgZXh0cmEgc2xpY2UoKVxuICB9XG5cbiAgLy8gRGVjb2RlIGluIGNodW5rcyB0byBhdm9pZCBcImNhbGwgc3RhY2sgc2l6ZSBleGNlZWRlZFwiLlxuICB2YXIgcmVzID0gJydcbiAgdmFyIGkgPSAwXG4gIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoXG4gICAgICBTdHJpbmcsXG4gICAgICBjb2RlUG9pbnRzLnNsaWNlKGksIGkgKz0gTUFYX0FSR1VNRU5UU19MRU5HVEgpXG4gICAgKVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0gJiAweDdGKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gbGF0aW4xU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gaGV4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuXG4gIGlmICghc3RhcnQgfHwgc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgfHwgZW5kIDwgMCB8fCBlbmQgPiBsZW4pIGVuZCA9IGxlblxuXG4gIHZhciBvdXQgPSAnJ1xuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIG91dCArPSB0b0hleChidWZbaV0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuXG5mdW5jdGlvbiB1dGYxNmxlU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgYnl0ZXMgPSBidWYuc2xpY2Uoc3RhcnQsIGVuZClcbiAgdmFyIHJlcyA9ICcnXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSArIGJ5dGVzW2kgKyAxXSAqIDI1NilcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbiBzbGljZSAoc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgc3RhcnQgPSB+fnN0YXJ0XG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuIDogfn5lbmRcblxuICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgKz0gbGVuXG4gICAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIH0gZWxzZSBpZiAoc3RhcnQgPiBsZW4pIHtcbiAgICBzdGFydCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IDApIHtcbiAgICBlbmQgKz0gbGVuXG4gICAgaWYgKGVuZCA8IDApIGVuZCA9IDBcbiAgfSBlbHNlIGlmIChlbmQgPiBsZW4pIHtcbiAgICBlbmQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICB2YXIgbmV3QnVmXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIG5ld0J1ZiA9IHRoaXMuc3ViYXJyYXkoc3RhcnQsIGVuZClcbiAgICBuZXdCdWYuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIHZhciBzbGljZUxlbiA9IGVuZCAtIHN0YXJ0XG4gICAgbmV3QnVmID0gbmV3IEJ1ZmZlcihzbGljZUxlbiwgdW5kZWZpbmVkKVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2xpY2VMZW47ICsraSkge1xuICAgICAgbmV3QnVmW2ldID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ld0J1ZlxufVxuXG4vKlxuICogTmVlZCB0byBtYWtlIHN1cmUgdGhhdCBidWZmZXIgaXNuJ3QgdHJ5aW5nIHRvIHdyaXRlIG91dCBvZiBib3VuZHMuXG4gKi9cbmZ1bmN0aW9uIGNoZWNrT2Zmc2V0IChvZmZzZXQsIGV4dCwgbGVuZ3RoKSB7XG4gIGlmICgob2Zmc2V0ICUgMSkgIT09IDAgfHwgb2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ29mZnNldCBpcyBub3QgdWludCcpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBsZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdUcnlpbmcgdG8gYWNjZXNzIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludExFID0gZnVuY3Rpb24gcmVhZFVJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludEJFID0gZnVuY3Rpb24gcmVhZFVJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcbiAgfVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF1cbiAgdmFyIG11bCA9IDFcbiAgd2hpbGUgKGJ5dGVMZW5ndGggPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50OCA9IGZ1bmN0aW9uIHJlYWRVSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkxFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCA4KSB8IHRoaXNbb2Zmc2V0ICsgMV1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyTEUgPSBmdW5jdGlvbiByZWFkVUludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKCh0aGlzW29mZnNldF0pIHxcbiAgICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSkgK1xuICAgICAgKHRoaXNbb2Zmc2V0ICsgM10gKiAweDEwMDAwMDApXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gKiAweDEwMDAwMDApICtcbiAgICAoKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgdGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50TEUgPSBmdW5jdGlvbiByZWFkSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50QkUgPSBmdW5jdGlvbiByZWFkSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgaSA9IGJ5dGVMZW5ndGhcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1pXVxuICB3aGlsZSAoaSA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uIHJlYWRJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIGlmICghKHRoaXNbb2Zmc2V0XSAmIDB4ODApKSByZXR1cm4gKHRoaXNbb2Zmc2V0XSlcbiAgcmV0dXJuICgoMHhmZiAtIHRoaXNbb2Zmc2V0XSArIDEpICogLTEpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2TEUgPSBmdW5jdGlvbiByZWFkSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkJFID0gZnVuY3Rpb24gcmVhZEludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgMV0gfCAodGhpc1tvZmZzZXRdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0pIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSA8PCAyNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgMjQpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRMRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdExFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRCRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdEJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFID0gZnVuY3Rpb24gcmVhZERvdWJsZUxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCA1MiwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlQkUgPSBmdW5jdGlvbiByZWFkRG91YmxlQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCA1MiwgOClcbn1cblxuZnVuY3Rpb24gY2hlY2tJbnQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAoIWludGVybmFsSXNCdWZmZXIoYnVmKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJidWZmZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyIGluc3RhbmNlJylcbiAgaWYgKHZhbHVlID4gbWF4IHx8IHZhbHVlIDwgbWluKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IGlzIG91dCBvZiBib3VuZHMnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBtYXhCeXRlcyA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSAtIDFcbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBtYXhCeXRlcywgMClcbiAgfVxuXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBtYXhCeXRlcyA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSAtIDFcbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBtYXhCeXRlcywgMClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50OCA9IGZ1bmN0aW9uIHdyaXRlVUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHhmZiwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkgdmFsdWUgPSBNYXRoLmZsb29yKHZhbHVlKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQxNiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCAyKTsgaSA8IGo7ICsraSkge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSAmICgweGZmIDw8ICg4ICogKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkpKSkgPj4+XG4gICAgICAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSAqIDhcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQzMiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4oYnVmLmxlbmd0aCAtIG9mZnNldCwgNCk7IGkgPCBqOyArK2kpIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSAodmFsdWUgPj4+IChsaXR0bGVFbmRpYW4gPyBpIDogMyAtIGkpICogOCkgJiAweGZmXG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50TEUgPSBmdW5jdGlvbiB3cml0ZUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gMFxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICBpZiAodmFsdWUgPCAwICYmIHN1YiA9PT0gMCAmJiB0aGlzW29mZnNldCArIGkgLSAxXSAhPT0gMCkge1xuICAgICAgc3ViID0gMVxuICAgIH1cbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50QkUgPSBmdW5jdGlvbiB3cml0ZUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IDBcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICBpZiAodmFsdWUgPCAwICYmIHN1YiA9PT0gMCAmJiB0aGlzW29mZnNldCArIGkgKyAxXSAhPT0gMCkge1xuICAgICAgc3ViID0gMVxuICAgIH1cbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50OCA9IGZ1bmN0aW9uIHdyaXRlSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweDdmLCAtMHg4MClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkgdmFsdWUgPSBNYXRoLmZsb29yKHZhbHVlKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmYgKyB2YWx1ZSArIDFcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmZmZmZiArIHZhbHVlICsgMVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuZnVuY3Rpb24gY2hlY2tJRUVFNzU0IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxuICBpZiAob2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvYXQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgNCwgMy40MDI4MjM0NjYzODUyODg2ZSszOCwgLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFID0gZnVuY3Rpb24gd3JpdGVGbG9hdExFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gd3JpdGVEb3VibGUgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgOCwgMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgsIC0xLjc5NzY5MzEzNDg2MjMxNTdFKzMwOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCA1MiwgOClcbiAgcmV0dXJuIG9mZnNldCArIDhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUxFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG4vLyBjb3B5KHRhcmdldEJ1ZmZlciwgdGFyZ2V0U3RhcnQ9MCwgc291cmNlU3RhcnQ9MCwgc291cmNlRW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiBjb3B5ICh0YXJnZXQsIHRhcmdldFN0YXJ0LCBzdGFydCwgZW5kKSB7XG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCAmJiBlbmQgIT09IDApIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXRTdGFydCA+PSB0YXJnZXQubGVuZ3RoKSB0YXJnZXRTdGFydCA9IHRhcmdldC5sZW5ndGhcbiAgaWYgKCF0YXJnZXRTdGFydCkgdGFyZ2V0U3RhcnQgPSAwXG4gIGlmIChlbmQgPiAwICYmIGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIC8vIENvcHkgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuIDBcbiAgaWYgKHRhcmdldC5sZW5ndGggPT09IDAgfHwgdGhpcy5sZW5ndGggPT09IDApIHJldHVybiAwXG5cbiAgLy8gRmF0YWwgZXJyb3IgY29uZGl0aW9uc1xuICBpZiAodGFyZ2V0U3RhcnQgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICB9XG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VFbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgLy8gQXJlIHdlIG9vYj9cbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0IDwgZW5kIC0gc3RhcnQpIHtcbiAgICBlbmQgPSB0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgKyBzdGFydFxuICB9XG5cbiAgdmFyIGxlbiA9IGVuZCAtIHN0YXJ0XG4gIHZhciBpXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCAmJiBzdGFydCA8IHRhcmdldFN0YXJ0ICYmIHRhcmdldFN0YXJ0IDwgZW5kKSB7XG4gICAgLy8gZGVzY2VuZGluZyBjb3B5IGZyb20gZW5kXG4gICAgZm9yIChpID0gbGVuIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2UgaWYgKGxlbiA8IDEwMDAgfHwgIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gYXNjZW5kaW5nIGNvcHkgZnJvbSBzdGFydFxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgVWludDhBcnJheS5wcm90b3R5cGUuc2V0LmNhbGwoXG4gICAgICB0YXJnZXQsXG4gICAgICB0aGlzLnN1YmFycmF5KHN0YXJ0LCBzdGFydCArIGxlbiksXG4gICAgICB0YXJnZXRTdGFydFxuICAgIClcbiAgfVxuXG4gIHJldHVybiBsZW5cbn1cblxuLy8gVXNhZ2U6XG4vLyAgICBidWZmZXIuZmlsbChudW1iZXJbLCBvZmZzZXRbLCBlbmRdXSlcbi8vICAgIGJ1ZmZlci5maWxsKGJ1ZmZlclssIG9mZnNldFssIGVuZF1dKVxuLy8gICAgYnVmZmVyLmZpbGwoc3RyaW5nWywgb2Zmc2V0WywgZW5kXV1bLCBlbmNvZGluZ10pXG5CdWZmZXIucHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbiBmaWxsICh2YWwsIHN0YXJ0LCBlbmQsIGVuY29kaW5nKSB7XG4gIC8vIEhhbmRsZSBzdHJpbmcgY2FzZXM6XG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIGlmICh0eXBlb2Ygc3RhcnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IHN0YXJ0XG4gICAgICBzdGFydCA9IDBcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZW5kID09PSAnc3RyaW5nJykge1xuICAgICAgZW5jb2RpbmcgPSBlbmRcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfVxuICAgIGlmICh2YWwubGVuZ3RoID09PSAxKSB7XG4gICAgICB2YXIgY29kZSA9IHZhbC5jaGFyQ29kZUF0KDApXG4gICAgICBpZiAoY29kZSA8IDI1Nikge1xuICAgICAgICB2YWwgPSBjb2RlXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2VuY29kaW5nIG11c3QgYmUgYSBzdHJpbmcnKVxuICAgIH1cbiAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJyAmJiAhQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgdmFsID0gdmFsICYgMjU1XG4gIH1cblxuICAvLyBJbnZhbGlkIHJhbmdlcyBhcmUgbm90IHNldCB0byBhIGRlZmF1bHQsIHNvIGNhbiByYW5nZSBjaGVjayBlYXJseS5cbiAgaWYgKHN0YXJ0IDwgMCB8fCB0aGlzLmxlbmd0aCA8IHN0YXJ0IHx8IHRoaXMubGVuZ3RoIDwgZW5kKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ091dCBvZiByYW5nZSBpbmRleCcpXG4gIH1cblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIHN0YXJ0ID0gc3RhcnQgPj4+IDBcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyB0aGlzLmxlbmd0aCA6IGVuZCA+Pj4gMFxuXG4gIGlmICghdmFsKSB2YWwgPSAwXG5cbiAgdmFyIGlcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgICAgdGhpc1tpXSA9IHZhbFxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgYnl0ZXMgPSBpbnRlcm5hbElzQnVmZmVyKHZhbClcbiAgICAgID8gdmFsXG4gICAgICA6IHV0ZjhUb0J5dGVzKG5ldyBCdWZmZXIodmFsLCBlbmNvZGluZykudG9TdHJpbmcoKSlcbiAgICB2YXIgbGVuID0gYnl0ZXMubGVuZ3RoXG4gICAgZm9yIChpID0gMDsgaSA8IGVuZCAtIHN0YXJ0OyArK2kpIHtcbiAgICAgIHRoaXNbaSArIHN0YXJ0XSA9IGJ5dGVzW2kgJSBsZW5dXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuLy8gSEVMUEVSIEZVTkNUSU9OU1xuLy8gPT09PT09PT09PT09PT09PVxuXG52YXIgSU5WQUxJRF9CQVNFNjRfUkUgPSAvW14rXFwvMC05QS1aYS16LV9dL2dcblxuZnVuY3Rpb24gYmFzZTY0Y2xlYW4gKHN0cikge1xuICAvLyBOb2RlIHN0cmlwcyBvdXQgaW52YWxpZCBjaGFyYWN0ZXJzIGxpa2UgXFxuIGFuZCBcXHQgZnJvbSB0aGUgc3RyaW5nLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgc3RyID0gc3RyaW5ndHJpbShzdHIpLnJlcGxhY2UoSU5WQUxJRF9CQVNFNjRfUkUsICcnKVxuICAvLyBOb2RlIGNvbnZlcnRzIHN0cmluZ3Mgd2l0aCBsZW5ndGggPCAyIHRvICcnXG4gIGlmIChzdHIubGVuZ3RoIDwgMikgcmV0dXJuICcnXG4gIC8vIE5vZGUgYWxsb3dzIGZvciBub24tcGFkZGVkIGJhc2U2NCBzdHJpbmdzIChtaXNzaW5nIHRyYWlsaW5nID09PSksIGJhc2U2NC1qcyBkb2VzIG5vdFxuICB3aGlsZSAoc3RyLmxlbmd0aCAlIDQgIT09IDApIHtcbiAgICBzdHIgPSBzdHIgKyAnPSdcbiAgfVxuICByZXR1cm4gc3RyXG59XG5cbmZ1bmN0aW9uIHN0cmluZ3RyaW0gKHN0cikge1xuICBpZiAoc3RyLnRyaW0pIHJldHVybiBzdHIudHJpbSgpXG4gIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpXG59XG5cbmZ1bmN0aW9uIHRvSGV4IChuKSB7XG4gIGlmIChuIDwgMTYpIHJldHVybiAnMCcgKyBuLnRvU3RyaW5nKDE2KVxuICByZXR1cm4gbi50b1N0cmluZygxNilcbn1cblxuZnVuY3Rpb24gdXRmOFRvQnl0ZXMgKHN0cmluZywgdW5pdHMpIHtcbiAgdW5pdHMgPSB1bml0cyB8fCBJbmZpbml0eVxuICB2YXIgY29kZVBvaW50XG4gIHZhciBsZW5ndGggPSBzdHJpbmcubGVuZ3RoXG4gIHZhciBsZWFkU3Vycm9nYXRlID0gbnVsbFxuICB2YXIgYnl0ZXMgPSBbXVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBjb2RlUG9pbnQgPSBzdHJpbmcuY2hhckNvZGVBdChpKVxuXG4gICAgLy8gaXMgc3Vycm9nYXRlIGNvbXBvbmVudFxuICAgIGlmIChjb2RlUG9pbnQgPiAweEQ3RkYgJiYgY29kZVBvaW50IDwgMHhFMDAwKSB7XG4gICAgICAvLyBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCFsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAgIC8vIG5vIGxlYWQgeWV0XG4gICAgICAgIGlmIChjb2RlUG9pbnQgPiAweERCRkYpIHtcbiAgICAgICAgICAvLyB1bmV4cGVjdGVkIHRyYWlsXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfSBlbHNlIGlmIChpICsgMSA9PT0gbGVuZ3RoKSB7XG4gICAgICAgICAgLy8gdW5wYWlyZWQgbGVhZFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICAvLyB2YWxpZCBsZWFkXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcblxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyAyIGxlYWRzIGluIGEgcm93XG4gICAgICBpZiAoY29kZVBvaW50IDwgMHhEQzAwKSB7XG4gICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIHZhbGlkIHN1cnJvZ2F0ZSBwYWlyXG4gICAgICBjb2RlUG9pbnQgPSAobGVhZFN1cnJvZ2F0ZSAtIDB4RDgwMCA8PCAxMCB8IGNvZGVQb2ludCAtIDB4REMwMCkgKyAweDEwMDAwXG4gICAgfSBlbHNlIGlmIChsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAvLyB2YWxpZCBibXAgY2hhciwgYnV0IGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICB9XG5cbiAgICBsZWFkU3Vycm9nYXRlID0gbnVsbFxuXG4gICAgLy8gZW5jb2RlIHV0ZjhcbiAgICBpZiAoY29kZVBvaW50IDwgMHg4MCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAxKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKGNvZGVQb2ludClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4ODAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgfCAweEMwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAzKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDIHwgMHhFMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gNCkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4MTIgfCAweEYwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGNvZGUgcG9pbnQnKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBieXRlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVRvQnl0ZXMgKHN0cikge1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICAvLyBOb2RlJ3MgY29kZSBzZWVtcyB0byBiZSBkb2luZyB0aGlzIGFuZCBub3QgJiAweDdGLi5cbiAgICBieXRlQXJyYXkucHVzaChzdHIuY2hhckNvZGVBdChpKSAmIDB4RkYpXG4gIH1cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiB1dGYxNmxlVG9CeXRlcyAoc3RyLCB1bml0cykge1xuICB2YXIgYywgaGksIGxvXG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7ICsraSkge1xuICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuXG4gICAgYyA9IHN0ci5jaGFyQ29kZUF0KGkpXG4gICAgaGkgPSBjID4+IDhcbiAgICBsbyA9IGMgJSAyNTZcbiAgICBieXRlQXJyYXkucHVzaChsbylcbiAgICBieXRlQXJyYXkucHVzaChoaSlcbiAgfVxuXG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuXG5mdW5jdGlvbiBiYXNlNjRUb0J5dGVzIChzdHIpIHtcbiAgcmV0dXJuIGJhc2U2NC50b0J5dGVBcnJheShiYXNlNjRjbGVhbihzdHIpKVxufVxuXG5mdW5jdGlvbiBibGl0QnVmZmVyIChzcmMsIGRzdCwgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGlmICgoaSArIG9mZnNldCA+PSBkc3QubGVuZ3RoKSB8fCAoaSA+PSBzcmMubGVuZ3RoKSkgYnJlYWtcbiAgICBkc3RbaSArIG9mZnNldF0gPSBzcmNbaV1cbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiBpc25hbiAodmFsKSB7XG4gIHJldHVybiB2YWwgIT09IHZhbCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNlbGYtY29tcGFyZVxufVxuXG5cbi8vIHRoZSBmb2xsb3dpbmcgaXMgZnJvbSBpcy1idWZmZXIsIGFsc28gYnkgRmVyb3NzIEFib3VraGFkaWplaCBhbmQgd2l0aCBzYW1lIGxpc2VuY2Vcbi8vIFRoZSBfaXNCdWZmZXIgY2hlY2sgaXMgZm9yIFNhZmFyaSA1LTcgc3VwcG9ydCwgYmVjYXVzZSBpdCdzIG1pc3Npbmdcbi8vIE9iamVjdC5wcm90b3R5cGUuY29uc3RydWN0b3IuIFJlbW92ZSB0aGlzIGV2ZW50dWFsbHlcbmV4cG9ydCBmdW5jdGlvbiBpc0J1ZmZlcihvYmopIHtcbiAgcmV0dXJuIG9iaiAhPSBudWxsICYmICghIW9iai5faXNCdWZmZXIgfHwgaXNGYXN0QnVmZmVyKG9iaikgfHwgaXNTbG93QnVmZmVyKG9iaikpXG59XG5cbmZ1bmN0aW9uIGlzRmFzdEJ1ZmZlciAob2JqKSB7XG4gIHJldHVybiAhIW9iai5jb25zdHJ1Y3RvciAmJiB0eXBlb2Ygb2JqLmNvbnN0cnVjdG9yLmlzQnVmZmVyID09PSAnZnVuY3Rpb24nICYmIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlcihvYmopXG59XG5cbi8vIEZvciBOb2RlIHYwLjEwIHN1cHBvcnQuIFJlbW92ZSB0aGlzIGV2ZW50dWFsbHkuXG5mdW5jdGlvbiBpc1Nsb3dCdWZmZXIgKG9iaikge1xuICByZXR1cm4gdHlwZW9mIG9iai5yZWFkRmxvYXRMRSA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2Ygb2JqLnNsaWNlID09PSAnZnVuY3Rpb24nICYmIGlzRmFzdEJ1ZmZlcihvYmouc2xpY2UoMCwgMCkpXG59XG4iLCJjbGFzcyBUZXh0RW5jb2RlciB7XG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1RleHRFbmNvZGVyI1BvbHlmaWxsXG4gICAgc3RhdGljIGVuY29kZSAoc3RyKSB7XG4gICAgICAgIGNvbnN0IExlbiA9IHN0ci5sZW5ndGg7XG4gICAgICAgIGxldCByZXNQb3MgPSAtMTtcbiAgICAgICAgLy8gVGhlIFVpbnQ4QXJyYXkncyBsZW5ndGggbXVzdCBiZSBhdCBsZWFzdCAzeCB0aGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgYmVjYXVzZSBhbiBpbnZhbGlkIFVURi0xNlxuICAgICAgICAvLyAgdGFrZXMgdXAgdGhlIGVxdWl2ZWxlbnQgc3BhY2Ugb2YgMyBVVEYtOCBjaGFyYWN0ZXJzIHRvIGVuY29kZSBpdCBwcm9wZXJseS4gSG93ZXZlciwgQXJyYXknc1xuICAgICAgICAvLyAgaGF2ZSBhbiBhdXRvIGV4cGFuZGluZyBsZW5ndGggYW5kIDEuNXggc2hvdWxkIGJlIGp1c3QgdGhlIHJpZ2h0IGJhbGFuY2UgZm9yIG1vc3QgdXNlcy5cbiAgICAgICAgY29uc3QgcmVzQXJyID0gW107XG4gICAgICAgIGZvciAobGV0IHBvaW50ID0gMCwgbmV4dGNvZGUgPSAwLCBpZHggPSAwOyBpZHggIT09IExlbjspIHtcbiAgICAgICAgICAgIHBvaW50ID0gc3RyLmNoYXJDb2RlQXQoaWR4KSwgaWR4ICs9IDE7XG4gICAgICAgICAgICBpZiAocG9pbnQgPj0gMHhEODAwICYmIHBvaW50IDw9IDB4REJGRikge1xuICAgICAgICAgICAgICAgIGlmIChpZHggPT09IExlbikge1xuICAgICAgICAgICAgICAgICAgICByZXNBcnJbcmVzUG9zICs9IDFdID0gMHhlZjtcbiAgICAgICAgICAgICAgICAgICAgcmVzQXJyW3Jlc1BvcyArPSAxXSA9IDB4YmY7XG4gICAgICAgICAgICAgICAgICAgIHJlc0FycltyZXNQb3MgKz0gMV0gPSAweGJkO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9tYXRoaWFzYnluZW5zLmJlL25vdGVzL2phdmFzY3JpcHQtZW5jb2Rpbmcjc3Vycm9nYXRlLWZvcm11bGFlXG4gICAgICAgICAgICAgICAgbmV4dGNvZGUgPSBzdHIuY2hhckNvZGVBdChpZHgpO1xuICAgICAgICAgICAgICAgIGlmIChuZXh0Y29kZSA+PSAweERDMDAgJiYgbmV4dGNvZGUgPD0gMHhERkZGKSB7XG4gICAgICAgICAgICAgICAgICAgIHBvaW50ID0gKChwb2ludCAtIDB4RDgwMCkgKiAweDQwMCkgKyBuZXh0Y29kZSAtIDB4REMwMCArIDB4MTAwMDA7XG4gICAgICAgICAgICAgICAgICAgIGlkeCArPSAxO1xuICAgICAgICAgICAgICAgICAgICBpZiAocG9pbnQgPiAweGZmZmYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc0FycltyZXNQb3MgKz0gMV0gPSAoMHgxZSA8PCAzKSB8IChwb2ludCA+Pj4gMTgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzQXJyW3Jlc1BvcyArPSAxXSA9ICgweDIgPDwgNikgfCAoKHBvaW50ID4+PiAxMikgJiAweDNmKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc0FycltyZXNQb3MgKz0gMV0gPSAoMHgyIDw8IDYpIHwgKChwb2ludCA+Pj4gNikgJiAweDNmKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc0FycltyZXNQb3MgKz0gMV0gPSAoMHgyIDw8IDYpIHwgKHBvaW50ICYgMHgzZik7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc0FycltyZXNQb3MgKz0gMV0gPSAweGVmOyByZXNBcnJbcmVzUG9zICs9IDFdID0gMHhiZjtcbiAgICAgICAgICAgICAgICAgICAgcmVzQXJyW3Jlc1BvcyArPSAxXSA9IDB4YmQ7IGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwb2ludCA8PSAweDAwN2YpIHtcbiAgICAgICAgICAgICAgICByZXNBcnJbcmVzUG9zICs9IDFdID0gKDB4MCA8PCA3KSB8IHBvaW50O1xuICAgICAgICAgICAgfSBlbHNlIGlmIChwb2ludCA8PSAweDA3ZmYpIHtcbiAgICAgICAgICAgICAgICByZXNBcnJbcmVzUG9zICs9IDFdID0gKDB4NiA8PCA1KSB8IChwb2ludCA+Pj4gNik7XG4gICAgICAgICAgICAgICAgcmVzQXJyW3Jlc1BvcyArPSAxXSA9ICgweDIgPDwgNikgfCAocG9pbnQgJiAweDNmKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzQXJyW3Jlc1BvcyArPSAxXSA9ICgweGUgPDwgNCkgfCAocG9pbnQgPj4+IDEyKTtcbiAgICAgICAgICAgICAgICByZXNBcnJbcmVzUG9zICs9IDFdID0gKDB4MiA8PCA2KSB8ICgocG9pbnQgPj4+IDYpICYgMHgzZik7XG4gICAgICAgICAgICAgICAgcmVzQXJyW3Jlc1BvcyArPSAxXSA9ICgweDIgPDwgNikgfCAocG9pbnQgJiAweDNmKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBlbHNlIC8vIElFIDYtOVxuICAgICAgICByZXNBcnIubGVuZ3RoID0gcmVzUG9zICsgMTsgLy8gdHJpbSBvZmYgZXh0cmEgd2VpZ2h0XG4gICAgICAgIHJldHVybiByZXNBcnI7XG4gICAgfVxufVxuXG5leHBvcnQgeyBUZXh0RW5jb2RlciB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBUZXh0RW5jb2RlciB9IGZyb20gJy4vVGV4dEVuY29kZXIuanMnO1xuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vcnBjL1JwY1N0cnVjdC5qcyc7XG5cbmNsYXNzIEpzb25ScGNNYXJzaGFsbGVyIHtcbiAgICAvKipcbiAgICAgKiBUYWtlcyBhbiBSUEMgbWVzc2FnZSBhbmQgY29udmVydHMgaXRcbiAgICAgKiBpbnRvIGEgYnl0ZSBhcnJheSB0aGF0IGNhbiBiZSBhZGRlZFxuICAgICAqIGFzIHBhcnQgb2YgdGhlIFNkbFBhY2tldC5cbiAgICAgKiBAcGFyYW0ge1JwY1N0cnVjdH0gcnBjU3RydWN0IC0gVGhpcyBwYXJhbSBjb250YWlucyB0aGUganNvbiBvYmplY3QgdG8gdHJhbnNmb3JtXG4gICAgICogYmFzZWQgb24gdGhlIGdldFBhcmFtZXRlcnMgbWV0aG9kLiBUaGlzIGNhbiBiZSBhbiBScGNTdHJ1Y3Qgb3Igc29tZXRoaW5nIGxpa2UgUnBjTWVzc2FnZVxuICAgICAqIHdoaWNoIGV4dGVuZHMgUnBjU3RydWN0LlxuICAgICAqIEByZXR1cm5zIHtudWxsfFVpbnQ4QXJyYXl9IC0gRWl0aGVyIHRoZSBieXRlIGFycmF5IG9yIG51bGwgb24gZXJyb3IuXG4gICAgICovXG4gICAgc3RhdGljIG1hcnNoYWxsIChycGNTdHJ1Y3QpIHtcbiAgICAgICAgbGV0IGpzb25CeXRlcyA9IG51bGw7XG4gICAgICAgIGZ1bmN0aW9uIHBhcmFtaWZ5IChycGNTdHJ1Y3QpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHJwY1N0cnVjdC5nZXRQYXJhbWV0ZXJzKCk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBwYXJhbXMpIHtcbiAgICAgICAgICAgICAgICBpZiAocGFyYW1zW2tleV0gaW5zdGFuY2VvZiBScGNTdHJ1Y3QpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1zW2tleV0gPSBwYXJhbWlmeShwYXJhbXNba2V5XSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHBhcmFtcztcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBqc29uT2JqZWN0ID0gcGFyYW1pZnkocnBjU3RydWN0KTtcbiAgICAgICAgICAgIGNvbnN0IHN0cmluZ1ZlcnNpb24gPSBKU09OLnN0cmluZ2lmeShqc29uT2JqZWN0KTtcbiAgICAgICAgICAgIGpzb25CeXRlcyA9IHRoaXMuX2VuY29kZShzdHJpbmdWZXJzaW9uKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBlbmNvZGUgbWVzc2FnZXMgdG8gSlNPTi4nLCBlcnJvcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGpzb25CeXRlcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUYWtlcyBhIGJ5dGUgYXJyYXkgYW5kIHRyYW5zZm9ybXMgaXQgaW50byBhIGpzb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7VWludDhBcnJheX0gYnl0ZXMgLSBCeXRlIGFycmF5IGNvbnRhaW5pbmcgdGhlIGpzb24gc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge251bGx8T2JqZWN0fSAtIEVpdGhlciBhIGpzb24gb2JqZWN0IG9yIG51bGwgb24gZXJyb3IgaW4gcGFyc2luZy5cbiAgICAgKi9cbiAgICBzdGF0aWMgdW5tYXJzaGFsbCAoYnl0ZXMpIHtcbiAgICAgICAgbGV0IHJldCA9IG51bGw7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBqc29uU3RyaW5nID0gdGhpcy5fZGVjb2RlKGJ5dGVzKTtcbiAgICAgICAgICAgIHJldCA9IEpTT04ucGFyc2UoanNvblN0cmluZyk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gcGFyc2UgSlNPTicsIGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyYW5zZm9ybSBhIHN0cmluZyBpbnRvIGEgYnl0ZSBhcnJheS5cbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIC0gU3RyaW5nIHRvIHRyYW5zZm9ybS5cbiAgICAgKiBAcmV0dXJucyB7VWludDhBcnJheX1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBfZW5jb2RlIChzdHIpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KFRleHRFbmNvZGVyLmVuY29kZShzdHIpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmFuc2Zvcm0gYSBieXRlIGFycmF5IGludG8gYSBzdHJpbmcuXG4gICAgICogQHBhcmFtIHtVaW50OEFycmF5fSBieXRlcyAtIEJ5dGUgYXJyYXkgdG8gdHJhbnNmb3JtLlxuICAgICAqIEByZXR1cm5zIHtTdHJpbmd9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgX2RlY29kZSAoYnl0ZXMpIHtcbiAgICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGJ5dGVzKS50b1N0cmluZygpO1xuICAgIH1cbn1cblxuZXhwb3J0IHsgSnNvblJwY01hcnNoYWxsZXIgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuLyoqXG4gKiBDb250YWlucyB0aGUgcmF3IGpzb24gZGF0YSBhbmQgYnVsayBkYXRhIGZvciBhbiBSUEMgcmVxdWVzdC9yZXNwb25zZSBhbG9uZyB3aXRoIHRoZSBiYXNpYyBoZWFkZXIgaW5mb1xuICogcnBjIHR5cGUsIGZ1bmN0aW9uIGlkLCBhbmQgY29ycmVsYXRpb24gaWQuXG4gKlxuICogVGhpcyBjbGFzcyBjYW4gcGFyc2UgaW5jb21pbmcgZGF0YSBmcm9tIHNkbCBjb3JlIGFuZCBhc3NlbWJsZSBhIGJpbmFyeSBoZWFkZXIgdG8gc2VuZCB0byBzZGwgY29yZS5cbiAqXG4gKlxuICogIEBwcml2YXRlIHtudW1iZXJ9IF9ycGNUeXBlIC0gUmVxdWVzdCA9IDAsIFJlc3BvbnNlID0gMSwgTm90aWZpY2F0aW9uID0gMi5cbiAqICBAcHJpdmF0ZSB7bnVtYmVyfSBfZnVuY3Rpb25JZCAtIE1hdGNoZXMgYSBmdW5jdGlvbiBJZCBpbiB0aGUgbW9iaWxlIGFwaSBzcGVjIGh0dHBzOi8vZ2l0aHViLmNvbS9zbWFydGRldmljZWxpbmsvcnBjX3NwZWMvYmxvYi9tYXN0ZXIvTU9CSUxFX0FQSS54bWxcbiAqICBAcHJpdmF0ZSB7bnVtYmVyfSBfY29ycmVsYXRpb25JZCAtIEZvciBhIHJlcXVlc3QgdGhpcyBpZCBpcyBwcm92aWRlZCBhbmQgdGhlIG1hdGNoaW5nIHJlc3BvbnNlIHdpbGwgaGF2ZSB0aGlzIHNhbWUgaWQuXG4gKiAgQHByaXZhdGUge251bWJlcn0gX2pzb25TaXplIC0gU2l6ZSBvZiBqc29uLlxuICogIEBwcml2YXRlIHtVaW50OEFycmF5fSBfanNvbkRhdGEgLSBSYXcganNvbiBkYXRhLiBUaGlzIGNhbiBiZSBwYXJzZWQgdXNpbmcgdGhlIEpzb25ScGNNYXJzaGFsbGVyLlxuICogIEBwcml2YXRlIHtVaW50OEFycmF5fSBfYnVsa0RhdGEgLSBCdWxrIGRhdGEgKG9wdGlvbmFsKS4gSWYgc29tZXRoaW5nIGNhbm5vdCBiZSBleHByZXNzZWQgYXMgYSBqc29uIG9iamVjdCBpdCB3aWxsIGJlIGluIHRoZSBidWxrIGRhdGEgKGVnIFB1dEZpbGUvR2V0RmlsZSBoYXMgdGhlIGZ1bGwgZmlsZSBpbiBidWxrIGRhdGEuKVxuICovXG5jbGFzcyBCaW5hcnlGcmFtZUhlYWRlciB7XG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcnBjVHlwZVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBmdW5jdGlvbklkXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGNvcnJlbGF0aW9uSWRcbiAgICAgKiBAcGFyYW0ge251bWJlcn0ganNvblNpemVcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocnBjVHlwZSwgZnVuY3Rpb25JZCwgY29ycmVsYXRpb25JZCwganNvblNpemUpIHtcbiAgICAgICAgdGhpcy5fcnBjVHlwZSA9IHJwY1R5cGU7XG4gICAgICAgIHRoaXMuX2Z1bmN0aW9uSWQgPSBmdW5jdGlvbklkO1xuICAgICAgICB0aGlzLl9jb3JyZWxhdGlvbklkID0gY29ycmVsYXRpb25JZDtcbiAgICAgICAgdGhpcy5fanNvblNpemUgPSBqc29uU2l6ZTtcbiAgICAgICAgdGhpcy5fYnVsa0RhdGEgPSBudWxsO1xuICAgICAgICB0aGlzLl9qc29uRGF0YSA9IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2l2ZW4gYSBieXRlIGFycmF5IHdpdGggdWludDggdmFsdWVzLCBhIEJpbmFyeUZyYW1lSGVhZGVyIGluc3RhbmNlIGlzIGNyZWF0ZWQuXG4gICAgICogQHBhcmFtIHthcnJheX0gYmluYXJ5RnJhbWVIZWFkZXJEYXRhIC0gQnl0ZSBhcnJheSBjb250YWluaW5nIGJhc2ljIGluZm9ybWF0aW9uIG9uIHRoZSBmcmFtZXMgdHlwZSwgbGVuZ3RoLCBhbmQgcmVsYXRlZCBpZHMuXG4gICAgICogQHJldHVybnMge0JpbmFyeUZyYW1lSGVhZGVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBmcm9tQmluYXJ5SGVhZGVyIChiaW5hcnlGcmFtZUhlYWRlckRhdGEpIHtcbiAgICAgICAgY29uc3QgcnBjVHlwZSA9IGJpbmFyeUZyYW1lSGVhZGVyRGF0YVswXSA+PiA0O1xuXG4gICAgICAgIGxldCBmdW5jdGlvbklkID0gKGJpbmFyeUZyYW1lSGVhZGVyRGF0YVswXSAmIDB4MEYpIDw8IDI0O1xuICAgICAgICBmdW5jdGlvbklkICs9IChiaW5hcnlGcmFtZUhlYWRlckRhdGFbMV0gJiAweEZGKSA8PCAxNjtcbiAgICAgICAgZnVuY3Rpb25JZCArPSAoYmluYXJ5RnJhbWVIZWFkZXJEYXRhWzJdICYgMHhGRikgPDwgODtcbiAgICAgICAgZnVuY3Rpb25JZCArPSBiaW5hcnlGcmFtZUhlYWRlckRhdGFbM10gJiAweEZGO1xuXG4gICAgICAgIGxldCBjb3JyZWxhdGlvbklkID0gKGJpbmFyeUZyYW1lSGVhZGVyRGF0YVs0XSAmIDB4RkYpIDw8IDI0O1xuICAgICAgICBjb3JyZWxhdGlvbklkICs9IChiaW5hcnlGcmFtZUhlYWRlckRhdGFbNV0gJiAweEZGKSA8PCAxNjtcbiAgICAgICAgY29ycmVsYXRpb25JZCArPSAoYmluYXJ5RnJhbWVIZWFkZXJEYXRhWzZdICYgMHhGRikgPDwgODtcbiAgICAgICAgY29ycmVsYXRpb25JZCArPSBiaW5hcnlGcmFtZUhlYWRlckRhdGFbN10gJiAweEZGO1xuXG4gICAgICAgIGxldCBqc29uU2l6ZSA9IChiaW5hcnlGcmFtZUhlYWRlckRhdGFbOF0gJiAweEZGKSA8PCAyNDtcbiAgICAgICAganNvblNpemUgKz0gKGJpbmFyeUZyYW1lSGVhZGVyRGF0YVs5XSAmIDB4RkYpIDw8IDE2O1xuICAgICAgICBqc29uU2l6ZSArPSAoYmluYXJ5RnJhbWVIZWFkZXJEYXRhWzEwXSAmIDB4RkYpIDw8IDg7XG4gICAgICAgIGpzb25TaXplICs9IGJpbmFyeUZyYW1lSGVhZGVyRGF0YVsxMV0gJiAweEZGO1xuXG4gICAgICAgIGNvbnN0IGJpbmFyeUZyYW1lSGVhZGVyID0gbmV3IEJpbmFyeUZyYW1lSGVhZGVyKHJwY1R5cGUsIGZ1bmN0aW9uSWQsIGNvcnJlbGF0aW9uSWQsIGpzb25TaXplKTtcblxuICAgICAgICBjb25zdCBqc29uRGF0YVN0YXJ0ID0gQmluYXJ5RnJhbWVIZWFkZXIuSEVBREVSX1NJWkU7XG4gICAgICAgIGNvbnN0IGpzb25EYXRhRW5kID0gQmluYXJ5RnJhbWVIZWFkZXIuSEVBREVSX1NJWkUgKyBqc29uU2l6ZTtcblxuICAgICAgICBiaW5hcnlGcmFtZUhlYWRlci5zZXRKc29uRGF0YShiaW5hcnlGcmFtZUhlYWRlckRhdGEuc2xpY2UoanNvbkRhdGFTdGFydCwganNvbkRhdGFFbmQpKTtcblxuICAgICAgICAvLyBhbnkgZGF0YSBhZnRlciB0aGUgSlNPTiBkYXRhIGlzIHRoZSBidWxrIGRhdGEgKGVnIFB1dEZpbGUgY29udGFpbnMgdGhlIGZpbGUgYWZ0ZXIgdGhlIG1haW4ganNvbilcbiAgICAgICAgaWYgKGJpbmFyeUZyYW1lSGVhZGVyRGF0YS5sZW5ndGggPiBqc29uRGF0YUVuZCkge1xuICAgICAgICAgICAgY29uc3QgYnVsa0RhdGEgPSBiaW5hcnlGcmFtZUhlYWRlckRhdGEuc2xpY2UoanNvbkRhdGFFbmQpO1xuICAgICAgICAgICAgYmluYXJ5RnJhbWVIZWFkZXIuc2V0QnVsa0RhdGEoYnVsa0RhdGEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiaW5hcnlGcmFtZUhlYWRlcjtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEFzc2VtYmxlcyBiaW5hcnkgaGVhZGVyIGRhdGEuXG4gICAgICogQHJldHVybnMge2FycmF5fVxuICAgICAqL1xuICAgIGFzc2VtYmxlSGVhZGVyQnl0ZXMgKCkge1xuICAgICAgICBjb25zdCBidWZmZXIgPSBbXTtcbiAgICAgICAgY29uc3QgZnVuY3Rpb25JZCA9IHRoaXMuX2Z1bmN0aW9uSWQ7XG4gICAgICAgIGNvbnN0IGNvcnJlbGF0aW9uSWQgPSB0aGlzLl9jb3JyZWxhdGlvbklkO1xuICAgICAgICBjb25zdCBycGNUeXBlID0gdGhpcy5fcnBjVHlwZTtcblxuICAgICAgICBidWZmZXIucHVzaCgoZnVuY3Rpb25JZCAmIDB4MEYwMDAwMDApID4+IDI0KSArIChycGNUeXBlIDw8IDQpO1xuICAgICAgICBidWZmZXIucHVzaCgoZnVuY3Rpb25JZCAmIDB4MDBGRjAwMDApID4+IDE2KTtcbiAgICAgICAgYnVmZmVyLnB1c2goKGZ1bmN0aW9uSWQgJiAweDAwMDBGRjAwKSA+PiA4KTtcbiAgICAgICAgYnVmZmVyLnB1c2goZnVuY3Rpb25JZCAmIDB4MDAwMDAwRkYpO1xuXG4gICAgICAgIGJ1ZmZlci5wdXNoKChjb3JyZWxhdGlvbklkICYgMHhGRjAwMDAwMCkgPj4gMjQpO1xuICAgICAgICBidWZmZXIucHVzaCgoY29ycmVsYXRpb25JZCAmIDB4MDBGRjAwMDApID4+IDE2KTtcbiAgICAgICAgYnVmZmVyLnB1c2goKGNvcnJlbGF0aW9uSWQgJiAweDAwMDBGRjAwKSA+PiA4KTtcbiAgICAgICAgYnVmZmVyLnB1c2goY29ycmVsYXRpb25JZCAmIDB4MDAwMDAwRkYpO1xuXG4gICAgICAgIGNvbnN0IGpzb25TaXplID0gdGhpcy5fanNvblNpemU7XG4gICAgICAgIGJ1ZmZlci5wdXNoKChqc29uU2l6ZSAmIDB4RkYwMDAwMDApID4+IDI0KTtcbiAgICAgICAgYnVmZmVyLnB1c2goKGpzb25TaXplICYgMHgwMEZGMDAwMCkgPj4gMTYpO1xuICAgICAgICBidWZmZXIucHVzaCgoanNvblNpemUgJiAweDAwMDBGRjAwKSA+PiA4KTtcbiAgICAgICAgYnVmZmVyLnB1c2goanNvblNpemUgJiAweDAwMDAwMEZGKTtcblxuICAgICAgICByZXR1cm4gYnVmZmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHJwYyB0eXBlIG9mIHRoZSBiaW5hcnkgaGVhZGVyLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB0eXBlXG4gICAgICogQHJldHVybnMge0JpbmFyeUZyYW1lSGVhZGVyfVxuICAgICAqL1xuICAgIHNldFJwY1R5cGUgKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fcnBjVHlwZSA9IHR5cGU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHJwYyB0eXBlIG9mIHRoZSBiaW5hcnkgaGVhZGVyXG4gICAgICogQHJldHVybnMge251bWJlcn1cbiAgICAgKi9cbiAgICBnZXRScGNUeXBlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JwY1R5cGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgZnVuY3Rpb24gaWQgb2YgdGhlIGJpbmFyeSBoZWFkZXIuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGlkXG4gICAgICogQHJldHVybnMge0JpbmFyeUZyYW1lSGVhZGVyfVxuICAgICAqL1xuICAgIHNldEZ1bmN0aW9uSWQgKGlkKSB7XG4gICAgICAgIHRoaXMuX2Z1bmN0aW9uSWQgPSBpZDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgZnVuY3Rpb24gSWQgb2YgdGhlIGJpbmFyeSBoZWFkZXIuXG4gICAgICogQHJldHVybnMge251bWJlcn1cbiAgICAgKi9cbiAgICBnZXRGdW5jdGlvbklkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Z1bmN0aW9uSWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgY29ycmVsYXRpb24gSWQgb2YgdGhlIGJpbmFyeSBoZWFkZXIuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGlkXG4gICAgICogQHJldHVybnMge0JpbmFyeUZyYW1lSGVhZGVyfVxuICAgICAqL1xuICAgIHNldENvcnJlbGF0aW9uSWQgKGlkKSB7XG4gICAgICAgIHRoaXMuX2NvcnJlbGF0aW9uSWQgPSBpZDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgY29ycmVsYXRpb24gSWQgb2YgdGhlIGJpbmFyeSBoZWFkZXIuXG4gICAgICovXG4gICAgZ2V0Q29ycmVsYXRpb25JZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb3JyZWxhdGlvbklkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGpzb24gc2l6ZSBvZiB0aGUgYmluYXJ5IGhlYWRlci5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc2l6ZVxuICAgICAqIEByZXR1cm5zIHtCaW5hcnlGcmFtZUhlYWRlcn1cbiAgICAgKi9cbiAgICBzZXRKc29uU2l6ZSAoc2l6ZSkge1xuICAgICAgICB0aGlzLl9qc29uU2l6ZSA9IHNpemU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdlc3QgdGhlIGpzb24gc2l6ZSBvZiB0aGUgYmluYXJ5IGhlYWRlci5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxuICAgICAqL1xuICAgIGdldEpzb25TaXplICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2pzb25TaXplO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGpzb24gZGF0YSBhcyBhIGJ5dGUgYXJyYXkuXG4gICAgICogQHJldHVybnMge2FycmF5fSAtIEJ5dGUgYXJyYXkgb2YganNvbiBkYXRhLlxuICAgICAqL1xuICAgIGdldEpzb25EYXRhICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2pzb25EYXRhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGpzb24gZGF0YSBvZiB0aGUgYmluYXJ5IGhlYWRlci5cbiAgICAgKiBAcGFyYW0ge2FycmF5fSBkYXRhIC0gQnl0ZSBhcnJheSBvZiBqc29uIGRhdGFcbiAgICAgKiBAcmV0dXJucyB7QmluYXJ5RnJhbWVIZWFkZXJ9XG4gICAgICovXG4gICAgc2V0SnNvbkRhdGEgKGRhdGEpIHtcbiAgICAgICAgdGhpcy5fanNvbkRhdGEgPSBkYXRhO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBidWxrIGRhdGEgb2YgdGhlIGJpbmFyeSBoZWFkZXIuXG4gICAgICogU3VwcG9ydGVkIGJ5IHByb3Rjb2wgMiBhbmQgdXAuXG4gICAgICogQHBhcmFtIHthcnJheX0gZGF0YSAtIEJ5dGUgYXJyYXkgb2YgYnVsayBkYXRhXG4gICAgICovXG4gICAgc2V0QnVsa0RhdGEgKGRhdGEpIHtcbiAgICAgICAgdGhpcy5fYnVsa0RhdGEgPSBkYXRhO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBidWxrIGRhdGEgb2YgdGhlIGJpbmFyeSBoZWFkZXIuXG4gICAgICogU3VwcG9ydGVkIGJ5IHByb3Rjb2wgMiBhbmQgdXAuXG4gICAgICogQHJldHVybnMge2FycmF5fSAtIEJ5dGUgYXJyYXkgb2YgYnVsayBkYXRhXG4gICAgICovXG4gICAgZ2V0QnVsa0RhdGEgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnVsa0RhdGE7XG4gICAgfVxufVxuXG5CaW5hcnlGcmFtZUhlYWRlci5IRUFERVJfU0laRSA9IDEyO1xuXG5leHBvcnQgeyBCaW5hcnlGcmFtZUhlYWRlciB9O1xuXG5cbiIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuaW1wb3J0IHsgRnJhbWVUeXBlIH0gZnJvbSAnLi9lbnVtcy9GcmFtZVR5cGUuanMnO1xuaW1wb3J0IHsgU2RsUGFja2V0IH0gZnJvbSAnLi9TZGxQYWNrZXQuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4vLi4vcnBjL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgSnNvblJwY01hcnNoYWxsZXIgfSBmcm9tICcuLy4uL3V0aWwvSnNvblJwY01hcnNoYWxsZXIuanMnO1xuaW1wb3J0IHsgQmluYXJ5RnJhbWVIZWFkZXIgfSBmcm9tICcuL0JpbmFyeUZyYW1lSGVhZGVyLmpzJztcblxuXG4vKipcbiAqIFRha2VzIGFuIHJwYyBtZXNzYWdlIGFuZCBjb252ZXJ0cyBpdCBpbnRvIHBhY2tldHMgcmVhZHkgdG8gc2VuZC5cbiAqL1xuY2xhc3MgTWVzc2FnZUZyYW1lRGlzYXNzZW1ibGVyIHtcbiAgICAvKipcbiAgICAgICpcbiAgICAgICogQHBhcmFtIHtScGNSZXF1ZXN0fSBycGNSZXF1ZXN0IC0gUlBDIG1lc3NhZ2UgdGhhdCB3aWxsIHNwbGl0IGludG8gc21hbGxlciBzZGwgcGFja2V0cy5cbiAgICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlc3Npb25JZCAtIHNlc3Npb25JZCBmb3IgcGFja2V0c1xuICAgICAgKiBAcGFyYW0ge051bWJlcn0gbWVzc2FnZUlkIC0gbWVzc2FnZUlkIGZvciBwYWNrZXRzLlxuICAgICAgKiBAcGFyYW0ge051bWJlcn0gbXR1IC0gbWF4IHRyYW5zcG9ydCB1bml0LCB1c2VkIHRvIGRldGVybWluZSBwYWNrZXQgc2l6ZSB0byBzZW5kLlxuICAgICAgKiBAcGFyYW0ge051bWJlcn0gdmVyc2lvbiAtIG1ham9yIHZlcnNpb25cbiAgICAgICogQHBhcmFtIHtCb29sZWFufSBpc0VuY3J5cHRlZCAtIHBhY2tldCBpcyBlbmNyeXB0ZWRcbiAgICAgICogQHBhcmFtIHtjYn0gcGFja2V0Q2FsbGJhY2sgLSBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkIHdoZW4gYSBwYWNrZXQgaXMgcmVhZHkgdG8gc2VuZC5cbiAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChycGNSZXF1ZXN0LCBzZXNzaW9uSWQsIG1lc3NhZ2VJZCwgbXR1LCB2ZXJzaW9uLCBpc0VuY3J5cHRlZCwgcGFja2V0Q2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fcnBjUmVxdWVzdCA9IHJwY1JlcXVlc3Q7XG4gICAgICAgIHRoaXMuX3Nlc3Npb25JZCA9IHNlc3Npb25JZDtcbiAgICAgICAgdGhpcy5fbWVzc2FnZUlkID0gbWVzc2FnZUlkO1xuICAgICAgICB0aGlzLl9pc0VuY3J5cHRlZCA9IGlzRW5jcnlwdGVkO1xuXG4gICAgICAgIGlmICghbXR1KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01UVSBtdXN0IGJlIHNwZWNpZmllZC4nKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9tdHUgPSBtdHU7XG5cbiAgICAgICAgaWYgKCF2ZXJzaW9uKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1ZlcnNpb24gbXVzdCBiZSBzcGVjaWZpZWQuJyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdmVyc2lvbiA9IHZlcnNpb247XG4gICAgICAgIHRoaXMuX3BhY2tldENhbGxiYWNrID0gcGFja2V0Q2FsbGJhY2s7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICAqIEltbWVkaWF0ZWx5IGJ1aWxkIHJwYyBhbmQgcmVzcG9uZCB0byBwYWNrZXRjYWxsYmFjayB3aXRoIHBhY2tldHMgdG8gc2VuZC5cbiAgICAgICogQHBhcmFtIHtScGNSZXF1ZXN0fSBycGNNZXNzYWdlIC0gUlBDIG1lc3NhZ2UgdGhhdCB3aWxsIHNwbGl0IGludG8gc21hbGxlciBzZGwgcGFja2V0cy5cbiAgICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlc3Npb25JZCAtIHNlc3Npb25JZCBmb3IgcGFja2V0c1xuICAgICAgKiBAcGFyYW0ge051bWJlcn0gbWVzc2FnZUlkIC0gbWVzc2FnZUlkIGZvciBwYWNrZXRzLlxuICAgICAgKiBAcGFyYW0ge051bWJlcn0gbXR1IC0gbWF4IHRyYW5zcG9ydCB1bml0LCB1c2VkIHRvIGRldGVybWluZSBwYWNrZXQgc2l6ZSB0byBzZW5kLlxuICAgICAgKiBAcGFyYW0ge051bWJlcn0gdmVyc2lvbiAtIG1ham9yIHZlcnNpb25cbiAgICAgICogQHBhcmFtIHtCb29sZWFufSBpc0VuY3J5cHRlZCAtIHBhY2tldCBpcyBlbmNyeXB0ZWRcbiAgICAgICogQHBhcmFtIHtjYn0gcGFja2V0Q2FsbGJhY2sgLSBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkIHdoZW4gYSBwYWNrZXQgaXMgcmVhZHkgdG8gc2VuZC5cbiAgICAgICovXG4gICAgc3RhdGljIGJ1aWxkUlBDIChycGNSZXF1ZXN0LCBzZXNzaW9uSWQsIG1lc3NhZ2VJZCwgbXR1LCB2ZXJzaW9uLCBpc0VuY3J5cHRlZCwgY2IpIHtcbiAgICAgICAgY29uc3Qgb2JqID0gbmV3IE1lc3NhZ2VGcmFtZURpc2Fzc2VtYmxlcihycGNSZXF1ZXN0LCBzZXNzaW9uSWQsIG1lc3NhZ2VJZCwgbXR1LCB2ZXJzaW9uLCBpc0VuY3J5cHRlZCwgY2IpO1xuICAgICAgICBvYmouZG9SZXF1ZXN0KCk7XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIHRoZSBtYWluIEJpbmFyeUZyYW1lSGVhZGVyIGJ1ZmZlci5cbiAgICAgKiBAcmV0dXJucyB7VW5pdDhBcnJheX1cbiAgICAgKi9cbiAgICBfYnVpbGRSUENNYWluQnVmZmVyICgpIHtcbiAgICAgICAgY29uc3QgcnBjQnVsa0RhdGEgPSB0aGlzLl9ycGNSZXF1ZXN0LmdldEJ1bGtEYXRhKCk7XG4gICAgICAgIGNvbnN0IGNvcnJlbGF0aW9uSWQgPSB0aGlzLl9ycGNSZXF1ZXN0LmdldENvcnJlbGF0aW9uSWQoKTtcbiAgICAgICAgY29uc3QgcnBjVHlwZSA9ICB0aGlzLl9ycGNSZXF1ZXN0LmdldFJQQ1R5cGUoKTtcblxuICAgICAgICBjb25zdCBmdW5jdGlvbk5hbWUgPSB0aGlzLl9ycGNSZXF1ZXN0LmdldEZ1bmN0aW9uTmFtZSgpO1xuICAgICAgICBjb25zdCBmdW5jdGlvbklkID0gRnVuY3Rpb25JRC52YWx1ZUZvcktleShmdW5jdGlvbk5hbWUpO1xuICAgICAgICBpZiAoIWZ1bmN0aW9uSWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGZpbmQgZnVuY3Rpb24gJHtmdW5jdGlvbk5hbWV9YCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBqc29uQnVmZmVyID0gSnNvblJwY01hcnNoYWxsZXIubWFyc2hhbGwodGhpcy5fcnBjUmVxdWVzdCk7XG4gICAgICAgIGNvbnN0IGpzb25TaXplID0ganNvbkJ1ZmZlci5sZW5ndGg7XG5cbiAgICAgICAgY29uc3QgYmZoID0gbmV3IEJpbmFyeUZyYW1lSGVhZGVyKHJwY1R5cGUsIGZ1bmN0aW9uSWQsIGNvcnJlbGF0aW9uSWQpO1xuICAgICAgICBiZmguc2V0SnNvbkRhdGEoanNvbkJ1ZmZlcik7XG4gICAgICAgIGJmaC5zZXRKc29uU2l6ZShqc29uU2l6ZSk7XG4gICAgICAgIGJmaC5zZXRCdWxrRGF0YShycGNCdWxrRGF0YSk7XG4gICAgICAgIGNvbnN0IGhlYWRlclNpemUgPSAxMjtcbiAgICAgICAgY29uc3QgYnVsa0RhdGEgPSBiZmguZ2V0QnVsa0RhdGEoKTtcbiAgICAgICAgbGV0IGJ1bGtEYXRhU2l6ZSA9IDA7XG4gICAgICAgIGlmIChidWxrRGF0YSkge1xuICAgICAgICAgICAgYnVsa0RhdGFTaXplID0gYnVsa0RhdGEubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHRvdGFsTWVzc2FnZVNpemUgPSBoZWFkZXJTaXplICsganNvblNpemUgKyBidWxrRGF0YVNpemU7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBuZXcgVWludDhBcnJheSh0b3RhbE1lc3NhZ2VTaXplKTtcbiAgICAgICAgZGF0YS5zZXQoYmZoLmFzc2VtYmxlSGVhZGVyQnl0ZXMoKSwgMCk7XG4gICAgICAgIGRhdGEuc2V0KGpzb25CdWZmZXIsIGhlYWRlclNpemUpO1xuICAgICAgICBpZiAoYnVsa0RhdGEpIHtcbiAgICAgICAgICAgIGRhdGEuc2V0KGJ1bGtEYXRhLCBoZWFkZXJTaXplICsganNvblNpemUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIFJQQyByZXF1ZXN0IGFuZCB1c2UgY2FsbGJhY2sgdG8gc2VuZFxuICAgICAqIHNkbCBwYWNrZXRzIG9mIHRoZSBhcHByb3ByaWF0ZSBzaXplLlxuICAgICAqL1xuICAgIGRvUmVxdWVzdCAoKSB7XG4gICAgICAgIGNvbnN0IHZlcnNpb24gPSB0aGlzLl92ZXJzaW9uO1xuICAgICAgICBjb25zdCBmcmFtZUluZm8gPSAwO1xuICAgICAgICBjb25zdCBmcmFtZVR5cGUgPSBGcmFtZVR5cGUuU0lOR0xFO1xuXG4gICAgICAgIGNvbnN0IHNlcnZpY2VUeXBlID0gU2RsUGFja2V0LlNFUlZJQ0VfVFlQRV9SUEM7XG4gICAgICAgIGNvbnN0IHNlc3Npb25JZCA9IHRoaXMuX3Nlc3Npb25JZDtcbiAgICAgICAgY29uc3QgbWVzc2FnZUlkID0gdGhpcy5fbWVzc2FnZUlkO1xuXG4gICAgICAgIGNvbnN0IGlzRW5jcnlwdGVkID0gdGhpcy5faXNFbmNyeXB0ZWQ7XG4gICAgICAgIGNvbnN0IG1haW5CdWZmZXIgPSB0aGlzLl9idWlsZFJQQ01haW5CdWZmZXIoKTtcbiAgICAgICAgY29uc3QgbXR1ID0gdGhpcy5fbXR1O1xuXG4gICAgICAgIGNvbnN0IGZyYW1lQ291bnQgPSBNYXRoLmNlaWwobWFpbkJ1ZmZlci5sZW5ndGggLyBtdHUpO1xuXG4gICAgICAgIGlmIChmcmFtZUNvdW50IDw9IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IGZ1bGxQYWNrZXQgPSB0aGlzLl9jb25zdHJ1Y3RQYWNrZXQoXG4gICAgICAgICAgICAgICAgdmVyc2lvbixcbiAgICAgICAgICAgICAgICBzZXJ2aWNlVHlwZSxcbiAgICAgICAgICAgICAgICBmcmFtZUluZm8sXG4gICAgICAgICAgICAgICAgc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2VJZCxcbiAgICAgICAgICAgICAgICBmcmFtZVR5cGUsXG4gICAgICAgICAgICAgICAgbWFpbkJ1ZmZlcixcbiAgICAgICAgICAgICAgICBpc0VuY3J5cHRlZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuX3BhY2tldENhbGxiYWNrKGZ1bGxQYWNrZXQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKDgpOyAvLyBJbnQzMiBoYXMgOCBieXRlc1xuICAgICAgICAgICAgY29uc3QgdmlldyA9IG5ldyBEYXRhVmlldyhidWZmZXIpO1xuICAgICAgICAgICAgdmlldy5zZXRVaW50MzIoMCwgbWFpbkJ1ZmZlci5sZW5ndGgsIGZhbHNlKTtcbiAgICAgICAgICAgIHZpZXcuc2V0VWludDMyKDQsIGZyYW1lQ291bnQsIGZhbHNlKTtcbiAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBuZXcgVWludDhBcnJheShidWZmZXIpO1xuXG4gICAgICAgICAgICBjb25zdCBmaXJzdEhlYWRlciA9IHRoaXMuX2NvbnN0cnVjdFBhY2tldCh2ZXJzaW9uLCBzZXJ2aWNlVHlwZSwgZnJhbWVJbmZvLCBzZXNzaW9uSWQsIG1lc3NhZ2VJZCwgRnJhbWVUeXBlLkZJUlNULCBwYXlsb2FkLCBpc0VuY3J5cHRlZCk7XG4gICAgICAgICAgICB0aGlzLl9wYWNrZXRDYWxsYmFjayhmaXJzdEhlYWRlcik7XG5cbiAgICAgICAgICAgIHRoaXMuX2J1aWxkQ29uc2VjdXRpdmVGcmFtZXMoXG4gICAgICAgICAgICAgICAgdmVyc2lvbixcbiAgICAgICAgICAgICAgICBzZXJ2aWNlVHlwZSxcbiAgICAgICAgICAgICAgICBzZXNzaW9uSWQsXG4gICAgICAgICAgICAgICAgbWVzc2FnZUlkLFxuICAgICAgICAgICAgICAgIG1haW5CdWZmZXIsXG4gICAgICAgICAgICAgICAgbXR1LFxuICAgICAgICAgICAgICAgIGlzRW5jcnlwdGVkXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIHNkbCBwYWNrZXQuXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHZlcnNpb25cbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBmcmFtZUluZm9cbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc2Vzc2lvbklkXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG1lc3NhZ2VJZFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBmcmFtZVR5cGVcbiAgICAgKiBAcGFyYW0ge1VuaXQ4QXJyYXl9IHBheWxvYWRcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGlzRW5jcnlwdGVkXG4gICAgICogQHJldHVybnMge1NkbFBhY2tldH1cbiAgICAgKi9cbiAgICBfY29uc3RydWN0UGFja2V0ICh2ZXJzaW9uLCBzZXJ2aWNlVHlwZSwgZnJhbWVJbmZvLCBzZXNzaW9uSWQsIG1lc3NhZ2VJZCwgZnJhbWVUeXBlLCBwYXlsb2FkLCBpc0VuY3J5cHRlZCkge1xuICAgICAgICBjb25zdCBkYXRhU2l6ZSA9IHBheWxvYWQubGVuZ3RoO1xuICAgICAgICBjb25zdCBvZmZzZXQgPSAwO1xuICAgICAgICBjb25zdCBieXRlc1RvV3JpdGUgPSBkYXRhU2l6ZTtcbiAgICAgICAgY29uc3Qgc2RsUGFja2V0ID0gbmV3IFNkbFBhY2tldCh2ZXJzaW9uLCBpc0VuY3J5cHRlZCwgZnJhbWVUeXBlLCBzZXJ2aWNlVHlwZSwgZnJhbWVJbmZvLCBzZXNzaW9uSWQsIGRhdGFTaXplLCBtZXNzYWdlSWQsIHBheWxvYWQsIG9mZnNldCwgYnl0ZXNUb1dyaXRlKTtcbiAgICAgICAgcmV0dXJuIHNkbFBhY2tldDtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEJ1aWxkcyBjb25zZWN1dGl2ZSBmcmFtZXMgYWZ0ZXIgdGhlIGluaXRhbCBmcmFtZSBpcyBzZW50IGZvciBhIG11bHRpLWZyYW1lIG1lc3NhZ2UuXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHZlcnNpb25cbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzZXNzaW9uSWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbWVzc2FnZUlkXG4gICAgICogQHBhcmFtIHtCdWZmZXJ9IGJ1ZmZlclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBsZW5ndGhcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGlzRW5jcnlwdGVkXG4gICAgICovXG4gICAgX2J1aWxkQ29uc2VjdXRpdmVGcmFtZXMgKHZlcnNpb24sIHNlcnZpY2VUeXBlLCBzZXNzaW9uSWQsIG1lc3NhZ2VJZCwgYnVmZmVyLCBsZW5ndGgsIGlzRW5jcnlwdGVkKSB7XG4gICAgICAgIGxldCBmcmFtZVNlcXVlbmNlTnVtYmVyO1xuICAgICAgICBsZXQgY291bnQgPSAwO1xuICAgICAgICBsZXQgb2Zmc2V0ID0gMDtcblxuICAgICAgICB3aGlsZSAoZnJhbWVTZXF1ZW5jZU51bWJlciAhPT0gMCkge1xuICAgICAgICAgICAgaWYgKG9mZnNldCArIGxlbmd0aCA+PSBidWZmZXIubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgZnJhbWVTZXF1ZW5jZU51bWJlciA9IDA7IC8vIGxhc3QgZnJhbWVcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZnJhbWVTZXF1ZW5jZU51bWJlciA9IChjb3VudCAlIDI1NSkgKyAxOyAvLyAxLDIsMywuLi4sMjU1LDFcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgaGVhZGVyID0gdGhpcy5fY29uc3RydWN0UGFja2V0KFxuICAgICAgICAgICAgICAgIHZlcnNpb24sXG4gICAgICAgICAgICAgICAgc2VydmljZVR5cGUsXG4gICAgICAgICAgICAgICAgZnJhbWVTZXF1ZW5jZU51bWJlcixcbiAgICAgICAgICAgICAgICBzZXNzaW9uSWQsXG4gICAgICAgICAgICAgICAgbWVzc2FnZUlkLFxuICAgICAgICAgICAgICAgIEZyYW1lVHlwZS5DT05TRUNVVElWRSxcbiAgICAgICAgICAgICAgICBidWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBsZW5ndGgpLFxuICAgICAgICAgICAgICAgIGlzRW5jcnlwdGVkXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5fcGFja2V0Q2FsbGJhY2soaGVhZGVyKTtcbiAgICAgICAgICAgIGNvdW50Kys7XG4gICAgICAgICAgICBvZmZzZXQgKz0gbGVuZ3RoO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5cblxuZXhwb3J0IHsgTWVzc2FnZUZyYW1lRGlzYXNzZW1ibGVyIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmNsYXNzIFRyYW5zcG9ydExpc3RlbmVyIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHRoaXMuX29uVHJhbnNwb3J0Q29ubmVjdGVkID0gbnVsbDtcbiAgICAgICAgdGhpcy5fb25UcmFuc3BvcnREaXNjb25uZWN0ZWQgPSBudWxsO1xuICAgICAgICB0aGlzLl9vbkVycm9yID0gbnVsbDtcbiAgICAgICAgdGhpcy5fb25QYWNrZXRSZWNlaXZlZCA9IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuY1xuICAgICAqIEByZXR1cm4ge1RyYW5zcG9ydExpc3RlbmVyfVxuICAgICAqL1xuICAgIHNldE9uVHJhbnNwb3J0Q29ubmVjdGVkIChmdW5jKSB7XG4gICAgICAgIHRoaXMuX29uVHJhbnNwb3J0Q29ubmVjdGVkID0gZnVuYztcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jXG4gICAgICogQHJldHVybiB7VHJhbnNwb3J0TGlzdGVuZXJ9XG4gICAgICovXG4gICAgc2V0T25UcmFuc3BvcnREaXNjb25uZWN0ZWQgKGZ1bmMpIHtcbiAgICAgICAgdGhpcy5fb25UcmFuc3BvcnREaXNjb25uZWN0ZWQgPSBmdW5jO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmNcbiAgICAgKiBAcmV0dXJuIHtUcmFuc3BvcnRMaXN0ZW5lcn1cbiAgICAgKi9cbiAgICBzZXRPbkVycm9yIChmdW5jKSB7XG4gICAgICAgIHRoaXMuX29uRXJyb3IgPSBmdW5jO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmNcbiAgICAgKiBAcmV0dXJuIHtUcmFuc3BvcnRMaXN0ZW5lcn1cbiAgICAgKi9cbiAgICBzZXRPblBhY2tldFJlY2VpdmVkIChmdW5jKSB7XG4gICAgICAgIHRoaXMuX29uUGFja2V0UmVjZWl2ZWQgPSBmdW5jO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgb25UcmFuc3BvcnRDb25uZWN0ZWQgKCkge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX29uVHJhbnNwb3J0Q29ubmVjdGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9vblRyYW5zcG9ydENvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25UcmFuc3BvcnREaXNjb25uZWN0ZWQgKCkge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX29uVHJhbnNwb3J0RGlzY29ubmVjdGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9vblRyYW5zcG9ydERpc2Nvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25FcnJvciAoZXJyb3IgPSBudWxsKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fb25FcnJvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5fb25FcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvblBhY2tldFJlY2VpdmVkIChzZGxQYWNrZXQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9vblBhY2tldFJlY2VpdmVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9vblBhY2tldFJlY2VpdmVkKHNkbFBhY2tldCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCB7IFRyYW5zcG9ydExpc3RlbmVyIH07XG4iLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuY2xhc3MgVmVyc2lvbiB7XG4gICAgLyoqXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChtYWpvciwgbWlub3IsIHBhdGNoKSB7XG4gICAgICAgIHRoaXMuc2V0TWFqb3IobWFqb3IpO1xuICAgICAgICB0aGlzLnNldE1pbm9yKG1pbm9yKTtcbiAgICAgICAgdGhpcy5zZXRQYXRjaChwYXRjaCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge051bWJlcn0gbWFqb3JcbiAgICAqIEByZXR1cm4ge1ZlcnNpb259XG4gICAgKi9cbiAgICBzZXRNYWpvciAobWFqb3IpIHtcbiAgICAgICAgdGhpcy5fbWFqb3IgPSBwYXJzZUludChtYWpvcikgfHwgMDtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIGdldE1ham9yICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21ham9yO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtOdW1iZXJ9IG1pbm9yXG4gICAgKiBAcmV0dXJuIHtWZXJzaW9ufVxuICAgICovXG4gICAgc2V0TWlub3IgKG1pbm9yKSB7XG4gICAgICAgIHRoaXMuX21pbm9yID0gcGFyc2VJbnQobWlub3IpIHx8IDA7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBnZXRNaW5vciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9taW5vcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7TnVtYmVyfSBwYXRjaFxuICAgICogQHJldHVybiB7VmVyc2lvbn1cbiAgICAqL1xuICAgIHNldFBhdGNoIChwYXRjaCkge1xuICAgICAgICB0aGlzLl9wYXRjaCA9IHBhcnNlSW50KHBhdGNoKSB8fCAwO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgZ2V0UGF0Y2ggKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGF0Y2g7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gdmVyc2lvbiAtIFBhcnNlIHRoaXMgc3RyaW5nIHRvIGEgVmVyc2lvbiBvYmplY3RcbiAgICAqIEByZXR1cm4ge1ZlcnNpb259XG4gICAgKi9cbiAgICBmcm9tU3RyaW5nICh2ZXJzaW9uKSB7XG4gICAgICAgIGNvbnN0IHZlcnNpb25zID0gdmVyc2lvbi5zcGxpdCgnLicpO1xuICAgICAgICBpZiAodmVyc2lvbnMubGVuZ3RoICE9PSAzKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0luY29ycmVjdCB2ZXJzaW9uIHN0cmluZyBmb3JtYXQnKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldE1ham9yKHZlcnNpb25zWzBdKTtcbiAgICAgICAgdGhpcy5zZXRNaW5vcih2ZXJzaW9uc1sxXSk7XG4gICAgICAgIHRoaXMuc2V0UGF0Y2godmVyc2lvbnNbMl0pO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICovXG4gICAgdG9TdHJpbmcgKCkge1xuICAgICAgICByZXR1cm4gYCR7dGhpcy5nZXRNYWpvcigpfS4ke3RoaXMuZ2V0TWlub3IoKX0uJHt0aGlzLmdldFBhdGNoKCl9YDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIE1ldGhvZCB0byB0ZXN0IGlmIHRoaXMgaW5zdGFuY2Ugb2YgVmVyc2lvbiBpcyBuZXdlciB0aGFuIHRoZSBzdXBwbGllZCBvbmUuXG4gICAgKiBAcGFyYW0gdmVyc2lvbiAtIHRoZSB2ZXJzaW9uIHRvIGNoZWNrIGFnYWluc3RcbiAgICAqIEByZXR1cm4ge051bWJlcn0gLSAxIGlmIHRoaXMgaW5zdGFuY2UgaXMgbmV3ZXIsIC0xIGlmIHN1cHBsaWVkIHZlcnNpb24gaXMgbmV3ZXIsIGFuZCAwIGlmIHRoZXkgYXJlIGVxdWFsXG4gICAgKi9cbiAgICBpc05ld2VyVGhhbiAodmVyc2lvbikge1xuICAgICAgICBpZiAodGhpcy5nZXRNYWpvcigpID4gdmVyc2lvbi5nZXRNYWpvcigpKSB7XG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmdldE1ham9yKCkgPT09IHZlcnNpb24uZ2V0TWFqb3IoKSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuZ2V0TWlub3IoKSA+IHZlcnNpb24uZ2V0TWlub3IoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmdldE1pbm9yKCkgPT09IHZlcnNpb24uZ2V0TWlub3IoKSkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmdldFBhdGNoKCkgPiB2ZXJzaW9uLmdldFBhdGNoKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmdldFBhdGNoKCkgPT09IHZlcnNpb24uZ2V0UGF0Y2goKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cbn1cblxuZXhwb3J0IHsgVmVyc2lvbiB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gU2VydmljZVR5cGVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIFNlcnZpY2VUeXBlIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ09OVFJPTCAoKSB7XG4gICAgICAgIHJldHVybiBTZXJ2aWNlVHlwZS5fTUFQLkNPTlRST0w7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJQQyAoKSB7XG4gICAgICAgIHJldHVybiBTZXJ2aWNlVHlwZS5fTUFQLlJQQztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgQVVESU8gKCkge1xuICAgICAgICByZXR1cm4gU2VydmljZVR5cGUuX01BUC5BVURJTztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgVklERU8gKCkge1xuICAgICAgICByZXR1cm4gU2VydmljZVR5cGUuX01BUC5WSURFTztcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgSFlCUklEICgpIHtcbiAgICAgICAgcmV0dXJuIFNlcnZpY2VUeXBlLl9NQVAuSFlCUklEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgKiBAcGFyYW0gdmFsdWUgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBTZXJ2aWNlVHlwZS5fdmFsdWVGb3JLZXkoa2V5LCBTZXJ2aWNlVHlwZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gU2VydmljZVR5cGUuX2tleUZvclZhbHVlKHZhbHVlLCBTZXJ2aWNlVHlwZS5fTUFQKTtcbiAgICB9XG59XG5cblNlcnZpY2VUeXBlLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnQ09OVFJPTCc6IDB4MDAsXG4gICAgJ1JQQyc6IDB4MDcsXG4gICAgJ0FVRElPJzogMHgwQSxcbiAgICAnVklERU8nOiAweDBCLFxuICAgICdIWUJSSUQnOjB4MEYsXG59KTtcblxuZXhwb3J0IHsgU2VydmljZVR5cGUgfTtcbiIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBGcmFtZVR5cGUgfSBmcm9tICcuL2VudW1zL0ZyYW1lVHlwZS5qcyc7XG5pbXBvcnQgeyBTZGxQYWNrZXQgfSBmcm9tICcuL1NkbFBhY2tldC5qcyc7XG5cbi8qKlxuICogQ2FsbGJhY2sgZm9yIGZpbmlzaGVkIHBhY2tldC5cbiAqIEBjYWxsYmFjayBjYlxuICogQHBhcmFtIHtzdHJpbmd9IGVycm9yIC0gSWYgdGhlcmUgaXMgYW4gZXJyb3IgdGhhdCBjYW5ub3QgYmUgcmVjb3ZlcmVkIGZyb20gaXQgd2lsbCBiZSByZXR1cm5lZC5cbiAqIEBwYXJhbSB7U2RsUGFja2V0fSBzZGxQYWNrZXQgLSBGaW5pc2hlZCBzZGwgcGFja2V0LlxuICovXG5cbi8qKlxuICogQXNzZW1ibGVzIHNkbCBwYWNrZXRzIHdoaWNoIG1heSBjb21lIGluIHNlcGVyYXRlIGNodW5rcyBpZiB0aGUgZGF0YSBleGNlZWRzIHRoZVxuICogbWF4IHRyYW5zcG9ydCB1bml0IGFsbG93ZWQgYnkgc2RsIGNvcmUuXG4gKlxuICogQHByaXZhdGUge2NifSBfY2FsbGJhY2sgLSBDYWxsYmFjayBmb3IgY29tYmluZWQgcGFja2V0LlxuICogQHByaXZhdGUge251bWJlcn0gX3RvdGFsQ29uc2VjdXRpdmVGcmFtZXMgLSBUb3RhbCBjb25zZWN1dGl2ZSBmcmFtZXMgZXhwZWN0ZWQgZm9yIGEgbXVsdGlmcmFtZSBwYWNrZXQuXG4gKiBAcHJpdmF0ZSB7bnVtYmVyfSBfY29uc2VjdXRpdmVGcmFtZXNEYXRhTGVuZ3RoIC0gRXhwZWN0ZWQgZGF0YSBsZW5ndGggb2YgZmluaXNoZWQgbXVsdGlmcmFtZSBwYWNrZXQuXG4gKiBAcHJpdmF0ZSB7bnVtYmVyfSBfY29uc2VjdXRpdmVGcmFtZXNIYW5kbGVkQ291bnQgLSBSdW5uaW5nIHRvdGFsIG9mIGNvbnNlY3V0aXZlIGZyYW1lcyByZWNlaXZlZCBhbmQgaGFuZGxlZC5cbiAqIEBwcml2YXRlIHthcnJheX0gX2FjY3VtdWxhdG9yIENvbWJpbmVzIGluY29taW5nIGJ5dGVzIGZyb20gY29uc2VjdXRpdmUgZnJhbWVzLlxuICovXG5jbGFzcyBNZXNzYWdlRnJhbWVBc3NlbWJsZXIge1xuICAgIC8qKlxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKiBAcGFyYW0ge2NifSBjYWxsYmFja1xuICAgICovXG4gICAgY29uc3RydWN0b3IgKGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ2FsbGJhY2sgbm90IG9mIGV4cGVjdGVkIHR5cGUgKGZ1bmN0aW9uKSBmb3IgTWVzc2FnZUZyYW1lQXNzZW1ibGVyJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9jYWxsYmFjayA9IGNhbGxiYWNrO1xuXG4gICAgICAgIHRoaXMuX2FjY3VtdWxhdG9yID0gW107XG4gICAgICAgIHRoaXMuX3RvdGFsQ29uc2VjdXRpdmVGcmFtZXMgPSAwO1xuICAgICAgICB0aGlzLl9jb25zZWN1dGl2ZUZyYW1lc0hhbmRsZWRDb3VudCA9IDA7XG4gICAgICAgIHRoaXMuX2NvbnNlY3V0aXZlRnJhbWVzRGF0YUxlbmd0aCA9IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWNjZXB0cyBhIHNpbmdsZSBmcmFtZSBvciBtdWx0aWZyYW1lIHBhY2tldC4gVGhlIGNhbGxiYWNrIGlzIHVzZWQgd2hlbiB0aGUgcGFja2V0XG4gICAgICogaXMgY29tcGxldGVseSByZWFkLiBGb3IgYSBzaW5nbGUgZnJhbWUgdGhpcyBpcyBpbW1lZGlhdGVseS4gRm9yIGEgbXVsdGkgZnJhbWUgcGFja2V0XG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldCAtIEluY29taW5nIHNkbCBwYWNrZXQgdG8gYmUgcmVhZC5cbiAgICAqL1xuICAgIGhhbmRsZUZyYW1lIChzZGxQYWNrZXQpIHtcbiAgICAgICAgY29uc3QgZnJhbWVUeXBlID0gc2RsUGFja2V0LmdldEZyYW1lVHlwZSgpO1xuICAgICAgICAvLyBJZiB0aGUgc2RsIHBhY2tldCBpcyBhIHNpbmdsZSBmcmFtZSBub3RoaW5nIG5lZWRzIHRvIGJlIGFzc2VtYmxlZCBhbmQgdGhpcyBjYW4gYmUgcmV0dXJuZWQgaW1tZWRpYXRlbHkuXG4gICAgICAgIGlmIChmcmFtZVR5cGUgIT09IEZyYW1lVHlwZS5GSVJTVCAmJiBmcmFtZVR5cGUgIT09IEZyYW1lVHlwZS5DT05TRUNVVElWRSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NhbGxiYWNrKG51bGwsIHNkbFBhY2tldCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2hhbmRsZU11bHRpRnJhbWVNZXNzYWdlKHNkbFBhY2tldCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlcyB0aGUgZmlyc3QgZGF0YSBmcmFtZS4gU2V0cyB0aGUgZXhwZWN0ZWQgZnJhbWUgY291bnQgYW5kIGRhdGEgbGVuZ3RoLlxuICAgICAqIEBwYXJhbSB7U2RsUGFja2V0fSBzZGxQYWNrZXRcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9oYW5kbGVGaXJzdERhdGFGcmFtZSAoc2RsUGFja2V0KSB7XG4gICAgICAgIC8qKiBAdHlwZSB7YXJyYXl9IEFycmF5IG9mIHVpbnQ4ICovXG4gICAgICAgIGNvbnN0IHBheWxvYWQgPSBzZGxQYWNrZXQuZ2V0UGF5bG9hZCgpO1xuXG4gICAgICAgIGlmIChwYXlsb2FkIGluc3RhbmNlb2YgVWludDhBcnJheSAhPT0gdHJ1ZSB8fCBwYXlsb2FkLmxlbmd0aCAhPT0gOCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFcnJvciBoYW5kbGluZyBmaXJzdCBmcmFtZS4gUGF5bG9hZCBpcyBhbiBpbnZhbGlkIGxlbmd0aCBzaG91bGQgYmUgbGVuZ3RoIDguJyk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChjb25zdCBieXRlIGluIHBheWxvYWQpIHtcbiAgICAgICAgICAgIGlmIChieXRlIDwgMHgwMCB8fCBieXRlID4gMHhGRikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBwYXlsb2FkLiBNdXN0IGJlIGFuIGFycmF5IG9mIHVpbnQ4IGJ5dGVzLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gZmlyc3QgNCA4LWJpdCBpbnRlZ2VycyBjb250YWluIHRoZSBkYXRhIGxlbmd0aC5cbiAgICAgICAgbGV0IGRhdGFMZW5ndGggPSAocGF5bG9hZFswXSAmIDB4MEYpIDw8IDI0OyAvLyA4LWJpdCB4IDNcbiAgICAgICAgZGF0YUxlbmd0aCArPSAocGF5bG9hZFsxXSAmIDB4RkYpIDw8IDE2OyAvLyA4IHggMlxuICAgICAgICBkYXRhTGVuZ3RoICs9IChwYXlsb2FkWzJdICYgMHhGRikgPDwgODsgLy8gOCB4IDFcbiAgICAgICAgZGF0YUxlbmd0aCArPSBwYXlsb2FkWzNdICYgMHhGRjsgLy8gOCB4IDBcblxuICAgICAgICBsZXQgZnJhbWVDb3VudCA9IChwYXlsb2FkWzRdICYgMHhGRikgPDwgMjQ7XG4gICAgICAgIGZyYW1lQ291bnQgKz0gKHBheWxvYWRbNV0gJiAweEZGKSA8PCAxNjtcbiAgICAgICAgZnJhbWVDb3VudCArPSAocGF5bG9hZFs2XSAmIDB4RkYpIDw8IDg7XG4gICAgICAgIGZyYW1lQ291bnQgKz0gcGF5bG9hZFs3XSAmIDB4RkY7XG5cbiAgICAgICAgdGhpcy5fdG90YWxDb25zZWN1dGl2ZUZyYW1lcyA9IGZyYW1lQ291bnQ7XG4gICAgICAgIHRoaXMuX2NvbnNlY3V0aXZlRnJhbWVzRGF0YUxlbmd0aCA9IGRhdGFMZW5ndGg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmlyc3QgZnJhbWUgc2hvdWxkIGJlIHJlYWQgaW4gYmVmb3JlIHRoaXMgaXMgY2FsbGVkLiBPbmNlIHRoZSBsYXN0XG4gICAgICogZnJhbWUgaXMgcmVhZCwgY2FsbGJhY2sgaXMgdXNlZC5cbiAgICAgKiBAcGFyYW0ge1NkbFBhY2tldH0gc2RsUGFja2V0XG4gICAgICovXG4gICAgX2hhbmRsZUNvbnNlY3V0aXZlRnJhbWUgKHNkbFBhY2tldCkge1xuICAgICAgICB0aGlzLl9jb25zZWN1dGl2ZUZyYW1lc0hhbmRsZWRDb3VudCsrO1xuXG4gICAgICAgIGNvbnN0IGZyYW1lVHlwZSA9IHNkbFBhY2tldC5nZXRGcmFtZVR5cGUoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGZyYW1lU2VxdWVuY2UgbnRoIGZyYW1lLCBvciAwIGZvciBsYXN0IGZyYW1lLFxuICAgICAgICAgKiA4IGJpdHMgYXJlIHVzZWQgdG8gc3RvcmUgdGhpcyBpbmZvIHNvIHRoZSBjb3VudCByZXZlcnRzIHRvIDEgYWZ0ZXIgMjU1XG4gICAgICAgICAqIFRoaXMgZG9lc24ndCBhZmZlY3QgcmVhZGluZyB0aGUgcGFja2V0IGJ1dCBpdCBpcyBub3RhYmxlIGlmIGZyYW1lIHNlcXVlbmNlIGlzIHJlbGllZCBvbi5cbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IGZyYW1lU2VxdWVuY2UgPSBzZGxQYWNrZXQuZ2V0RnJhbWVJbmZvKCk7XG5cbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IHNkbFBhY2tldC5nZXRQYXlsb2FkKCk7XG5cbiAgICAgICAgZm9yIChjb25zdCBieXRlIG9mIHBheWxvYWQpIHtcbiAgICAgICAgICAgIHRoaXMuX2FjY3VtdWxhdG9yLnB1c2goYnl0ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBUaGlzIGlzIHRoZSBsYXN0IGZyYW1lLCBmaW5pc2ggdGhpbmdzIHVwIGFuZCB1c2UgY2FsbGJhY2suXG4gICAgICAgIGlmIChmcmFtZVNlcXVlbmNlID09PSAwKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fY29uc2VjdXRpdmVGcmFtZXNIYW5kbGVkQ291bnQgIT09IHRoaXMuX3RvdGFsQ29uc2VjdXRpdmVGcmFtZXMpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYFRvdGFsIGZyYW1lcyBleHBlY3RlZCAke3RoaXMuX3RvdGFsQ29uc2VjdXRpdmVGcmFtZXN9IGRvZXMgbm90IG1hdGNoIHRvdGFsIGZyYW1lcyByZWNlaXZlZCAke3RoaXMuX2NvbnNlY3V0aXZlRnJhbWVzSGFuZGxlZENvdW50fWApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5fY29uc2VjdXRpdmVGcmFtZXNEYXRhTGVuZ3RoICE9PSB0aGlzLl9hY2N1bXVsYXRvci5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYFRvdGFsIGRhdGEgZXhwZWN0ZWQgJHt0aGlzLl9jb25zZWN1dGl2ZUZyYW1lc0RhdGFMZW5ndGh9IGRvZXMgbm90IG1hdGNoIHRvdGFsIGRhdGEgcmVjZWl2ZWQgJHt0aGlzLl9hY2N1bXVsYXRvci5sZW5ndGh9YCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGZpbmlzaGVkU2RsUGFja2V0ID0gbmV3IFNkbFBhY2tldChcbiAgICAgICAgICAgICAgICBzZGxQYWNrZXQuZ2V0VmVyc2lvbigpLFxuICAgICAgICAgICAgICAgIHNkbFBhY2tldC5nZXRFbmNyeXB0aW9uKCksXG4gICAgICAgICAgICAgICAgZnJhbWVUeXBlLFxuICAgICAgICAgICAgICAgIHNkbFBhY2tldC5nZXRTZXJ2aWNlVHlwZSgpLFxuICAgICAgICAgICAgICAgIGZyYW1lU2VxdWVuY2UsXG4gICAgICAgICAgICAgICAgc2RsUGFja2V0LmdldFNlc3Npb25JRCgpLFxuICAgICAgICAgICAgICAgIHRoaXMuX2FjY3VtdWxhdG9yLmxlbmd0aCxcbiAgICAgICAgICAgICAgICBzZGxQYWNrZXQuZ2V0TWVzc2FnZUlEKCksXG4gICAgICAgICAgICAgICAgdGhpcy5fYWNjdW11bGF0b3IsXG4gICAgICAgICAgICAgICAgMCwgLy8gbm8gb2Zmc2V0XG4gICAgICAgICAgICAgICAgdGhpcy5fYWNjdW11bGF0b3IubGVuZ3RoIC8vIHJlYWQgdGhlIGVudGlyZSBidWZmZXJcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrKG51bGwsIGZpbmlzaGVkU2RsUGFja2V0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhhbmRsZSB0aGUgc2RsIHBhY2tldCBiYXNlZCBvbiBpdHMgZnJhbWUgdHlwZSwgRklSU1Qgb3IgQ09OU0VDVVRJVkUuXG4gICAgICogQ2FsbGJhY2sgaXMgdXNlZCB3aGVuIGZpbmFsIHBhY2tldCBpcyByZWFkLlxuICAgICAqIEBwYXJhbSB7U2RsUGFja2V0fSBzZGxQYWNrZXQgLSBTZGwgcGFja2V0IHRvIGJlIHJlYWQuXG4gICAgICovXG4gICAgX2hhbmRsZU11bHRpRnJhbWVNZXNzYWdlIChzZGxQYWNrZXQpIHtcbiAgICAgICAgY29uc3QgZnJhbWVUeXBlID0gc2RsUGFja2V0LmdldEZyYW1lVHlwZSgpO1xuICAgICAgICBpZiAoZnJhbWVUeXBlID09PSBGcmFtZVR5cGUuRklSU1QpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVGaXJzdERhdGFGcmFtZShzZGxQYWNrZXQpO1xuICAgICAgICB9IGVsc2UgeyAvLyBGcmFtZVR5cGUuQ29uc2VjdXRpdmVcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVDb25zZWN1dGl2ZUZyYW1lKHNkbFBhY2tldCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cblxuXG5leHBvcnQgeyBNZXNzYWdlRnJhbWVBc3NlbWJsZXIgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuY2xhc3MgQ29udHJvbEZyYW1lVGFncyB7XG59XG5cbi8vIGhpZGRlbiBpbm5lciBvYmplY3RzXG5cbmNvbnN0IFN0YXJ0U2VydmljZUFDS0Jhc2UgPSB7XG4gICAgTVRVOiAnbXR1Jyxcbn07XG5cbmNvbnN0IE5BS0Jhc2UgPSB7XG4gICAgUkVKRUNURURfUEFSQU1TOiAncmVqZWN0ZWRQYXJhbXMnLFxufTtcblxuY29uc3QgU3RhcnRTZXJ2aWNlUHJvdG9jb2xWZXJzaW9uID0ge1xuICAgIC8qKiBUaGUgbmVnb3RpYXRlZCB2ZXJzaW9uIG9mIHRoZSBwcm90b2NvbC4gTXVzdCBiZSBpbiB0aGUgZm9ybWF0IFwiTWFqb3IuTWlub3IuUGF0Y2hcIiovXG4gICAgUFJPVE9DT0xfVkVSU0lPTjogJ3Byb3RvY29sVmVyc2lvbicsXG59O1xuXG5jb25zdCBTdGFydFNlcnZpY2VIYXNoSWQgPSB7XG4gICAgLyoqIEhhc2ggSUQgdG8gaWRlbnRpZnkgdGhpcyBzZXJ2aWNlIGFuZCB1c2VkIHdoZW4gc2VuZGluZyBhbiBFbmRTZXJ2aWNlIGNvbnRyb2wgZnJhbWUqL1xuICAgIEhBU0hfSUQ6ICdoYXNoSWQnLFxufTtcblxuY29uc3QgU3RhcnRTZXJ2aWNlRGltZW5zaW9ucyA9IHtcbiAgICBIRUlHSFQ6ICdoZWlnaHQnLFxuICAgIFdJRFRIOiAnd2lkdGgnLFxufTtcblxuLy8gc3RhdGljIG1lbWJlcnNcblxuQ29udHJvbEZyYW1lVGFncy5SUEMgPSBPYmplY3QuZnJlZXplKHtcbiAgICBTdGFydFNlcnZpY2U6IFN0YXJ0U2VydmljZVByb3RvY29sVmVyc2lvbixcblxuICAgIFN0YXJ0U2VydmljZUFDSzogT2JqZWN0LmFzc2lnbih7XG4gICAgICAgIC8qKiBIVSBhbGxvd2VkIHRyYW5zcG9ydCBmb3Igc2Vjb25kYXJ5IGNvbm5lY3Rpb24gKi9cbiAgICAgICAgU0VDT05EQVJZX1RSQU5TUE9SVFM6ICdzZWNvbmRhcnlUcmFuc3BvcnRzJyxcbiAgICAgICAgLyoqIEhVIGFsbG93ZWQgdHJhbnNwb3J0cyBmb3IgYXVkaW8gYW5kIHZpZGVvIHNlcnZpY2VzICgxID09IFByaW1hcnksIDIgPT0gU2Vjb25kYXJ5KSAqL1xuICAgICAgICBBVURJT19TRVJWSUNFX1RSQU5TUE9SVFM6ICdhdWRpb1NlcnZpY2VUcmFuc3BvcnRzJyxcbiAgICAgICAgVklERU9fU0VSVklDRV9UUkFOU1BPUlRTOiAndmlkZW9TZXJ2aWNlVHJhbnNwb3J0cycsXG4gICAgICAgIC8qKiBBdXRoIHRva2VuIHRvIGJlIHVzZWQgZm9yIGxvZyBpbiBpbnRvIHNlcnZpY2VzICoqL1xuICAgICAgICBBVVRIX1RPS0VOOiAnYXV0aFRva2VuJyxcbiAgICB9LCBTdGFydFNlcnZpY2VBQ0tCYXNlLCBTdGFydFNlcnZpY2VQcm90b2NvbFZlcnNpb24sIFN0YXJ0U2VydmljZUhhc2hJZCksXG5cbiAgICBTdGFydFNlcnZpY2VOQUs6IE5BS0Jhc2UsXG5cbiAgICBFbmRTZXJ2aWNlOiBTdGFydFNlcnZpY2VIYXNoSWQsXG5cbiAgICBFbmRTZXJ2aWNlQUNLOiB7fSxcblxuICAgIEVuZFNlcnZpY2VOQUs6IE5BS0Jhc2UsXG5cbiAgICBUcmFuc3BvcnRFdmVudFVwZGF0ZToge1xuICAgICAgICBUQ1BfSVBfQUREUkVTUzogJ3RjcElwQWRkcmVzcycsXG4gICAgICAgIFRDUF9QT1JUOiAndGNwUG9ydCcsXG4gICAgfSxcblxuICAgIFJlZ2lzdGVyU2Vjb25kYXJ5VHJhbnNwb3J0OiB7fSxcblxuICAgIFJlZ2lzdGVyU2Vjb25kYXJ5VHJhbnNwb3J0QUNLOiB7fSxcblxuICAgIFJlZ2lzdGVyU2Vjb25kYXJ5VHJhbnNwb3J0TkFLOiBPYmplY3QuYXNzaWduKHtcbiAgICAgICAgUkVBU09OOiAncmVhc29uJyxcbiAgICB9LCBOQUtCYXNlKSxcbn0pO1xuXG5Db250cm9sRnJhbWVUYWdzLkF1ZGlvID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgU3RhcnRTZXJ2aWNlOiB7fSxcblxuICAgIFN0YXJ0U2VydmljZUFDSzogU3RhcnRTZXJ2aWNlQUNLQmFzZSxcblxuICAgIFN0YXJ0U2VydmljZU5BSzogTkFLQmFzZSxcblxuICAgIEVuZFNlcnZpY2U6IHt9LFxuXG4gICAgRW5kU2VydmljZUFDSzoge30sXG5cbiAgICBFbmRTZXJ2aWNlTkFLOiBOQUtCYXNlLFxufSk7XG5cbkNvbnRyb2xGcmFtZVRhZ3MuVmlkZW8gPSBPYmplY3QuZnJlZXplKHtcbiAgICBTdGFydFNlcnZpY2U6IE9iamVjdC5hc3NpZ24oe1xuICAgICAgICBWSURFT19QUk9UT0NPTDogJ3ZpZGVvUHJvdG9jb2wnLFxuICAgICAgICBWSURFT19DT0RFQzogJ3ZpZGVvQ29kZWMnLFxuICAgIH0sIFN0YXJ0U2VydmljZURpbWVuc2lvbnMpLFxuXG4gICAgU3RhcnRTZXJ2aWNlQUNLOiBPYmplY3QuYXNzaWduKHtcbiAgICAgICAgVklERU9fUFJPVE9DT0w6ICd2aWRlb1Byb3RvY29sJyxcbiAgICAgICAgVklERU9fQ09ERUM6ICd2aWRlb0NvZGVjJyxcbiAgICB9LCBTdGFydFNlcnZpY2VBQ0tCYXNlLCBTdGFydFNlcnZpY2VEaW1lbnNpb25zKSxcblxuICAgIFN0YXJ0U2VydmljZU5BSzogTkFLQmFzZSxcblxuICAgIEVuZFNlcnZpY2U6IHt9LFxuXG4gICAgRW5kU2VydmljZUFDSzoge30sXG5cbiAgICBFbmRTZXJ2aWNlTkFLOiBOQUtCYXNlLFxufSk7XG5cbmV4cG9ydCB7IENvbnRyb2xGcmFtZVRhZ3MgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuY2xhc3MgQml0Q29udmVydGVyIHtcbiAgICAvKipcblx0ICogQHBhcmFtIHtBcnJheUJ1ZmZlcn0gYnVmZmVyIC0gYnVmZmVyIHRoYXQgd2lsbCBiZSBjb252ZXJ0ZWQgdG8gaW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG9mZnNldCAtIGludCBvcHRpb25hbCwgdGhlIG9mZnNldCBzaGlmdFxuXHQgKiBAcmV0dXJuIHtOdW1iZXJ9IGludCBjb252ZXJ0ZWQgZnJvbSBidWZmZXIgb3IgLTEgaWYgYnVmZmVyIGlzIG51bGxcblx0ICovXG4gICAgc3RhdGljIGFycmF5QnVmZmVyVG9JbnQzMiAoYnVmZmVyLCBvZmZzZXQgPSAwKSB7XG4gICAgICAgIGlmICghYnVmZmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdmlldyA9IG5ldyBEYXRhVmlldyhidWZmZXIpO1xuICAgICAgICByZXR1cm4gdmlldy5nZXRVaW50MzIob2Zmc2V0KTtcbiAgICB9XG5cbiAgICAvKipcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHZhbHVlIC0gdGhlIGludGVnZXIgdG8gYmUgY29udmVydGVkXG5cdCAqIEByZXR1cm4ge0FycmF5QnVmZmVyfSBidWZmZXIgY29udmVydGVkIGZyb20gaW5wdXQgdmFsdWVcblx0ICovXG4gICAgc3RhdGljIGludDMyVG9BcnJheUJ1ZmZlciAodmFsdWUpIHtcbiAgICAgICAgY29uc3QgYnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKDQpOyAvLyBJbnQzMiBoYXMgNCBieXRlc1xuICAgICAgICBjb25zdCB2aWV3ID0gbmV3IERhdGFWaWV3KGJ1ZmZlcik7XG4gICAgICAgIHZpZXcuc2V0VWludDMyKDAsIHZhbHVlLCBmYWxzZSk7XG4gICAgICAgIHJldHVybiBidWZmZXI7XG4gICAgfVxufVxuXG5leHBvcnQgeyBCaXRDb252ZXJ0ZXIgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgU2RsUGFja2V0IH0gZnJvbSAnLi9TZGxQYWNrZXQuanMnO1xuaW1wb3J0IHsgQ29udHJvbEZyYW1lVGFncyB9IGZyb20gJy4vZW51bXMvQ29udHJvbEZyYW1lVGFncy5qcyc7XG5pbXBvcnQgeyBCaXRDb252ZXJ0ZXIgfSBmcm9tICcuLy4uL3V0aWwvQml0Q29udmVydGVyLmpzJztcbmltcG9ydCB7IEZyYW1lVHlwZSB9IGZyb20gJy4vZW51bXMvRnJhbWVUeXBlLmpzJztcblxuLyoqXG4gKiBDcmVhdGVzIGNvbnRyb2wgcGFja2V0cy5cbiAqIEZvciByZWd1bGFyIFJQQyBSUENNZXNzYWdlIHNob3VsZCBiZSB1c2VkLlxuICovXG5jbGFzcyBTZGxQYWNrZXRGYWN0b3J5IHtcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgaGVhcnRiZWF0IGFja25vd2xlZ2VtZW50IHBhY2tldC5cbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzZXNzaW9uSURcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gdmVyc2lvblxuICAgICAqIEByZXR1cm5zIHtTZGxQYWNrZXR9XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZUhlYXJ0YmVhdEFDSyAoc2VydmljZVR5cGUsIHNlc3Npb25JRCwgdmVyc2lvbikge1xuICAgICAgICByZXR1cm4gbmV3IFNkbFBhY2tldCh2ZXJzaW9uLCBmYWxzZSwgRnJhbWVUeXBlLkNPTlRST0wsXG4gICAgICAgICAgICBzZXJ2aWNlVHlwZSwgU2RsUGFja2V0LkZSQU1FX0lORk9fSEVBUlRfQkVBVF9BQ0ssIHNlc3Npb25JRCxcbiAgICAgICAgICAgIDAsIDAsIG51bGwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gZW5kIHNlc3Npb24gcGFja2V0LlxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlc3Npb25JRFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBtZXNzYWdlSURcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gdmVyc2lvblxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBoYXNoSURcbiAgICAgKi9cbiAgICBzdGF0aWMgY3JlYXRlRW5kU2Vzc2lvbiAoc2VydmljZVR5cGUsIHNlc3Npb25JRCwgbWVzc2FnZUlELCB2ZXJzaW9uLCBoYXNoSUQpIHtcbiAgICAgICAgaWYgKHZlcnNpb24gPCA1KSB7XG4gICAgICAgICAgICBjb25zdCBwYXlsb2FkID0gbmV3IFVpbnQ4QXJyYXkoQml0Q29udmVydGVyLmludDMyVG9BcnJheUJ1ZmZlcihoYXNoSUQpKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgU2RsUGFja2V0KHZlcnNpb24sIGZhbHNlLCBGcmFtZVR5cGUuQ09OVFJPTCxcbiAgICAgICAgICAgICAgICBzZXJ2aWNlVHlwZSwgU2RsUGFja2V0LkZSQU1FX0lORk9fRU5EX1NFUlZJQ0UsIHNlc3Npb25JRCxcbiAgICAgICAgICAgICAgICBwYXlsb2FkLmxlbmd0aCwgbWVzc2FnZUlELCBwYXlsb2FkLCAwLCBwYXlsb2FkLmxlbmd0aCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBlbmRTZXNzaW9uID0gbmV3IFNkbFBhY2tldCh2ZXJzaW9uLCBmYWxzZSwgRnJhbWVUeXBlLkNPTlRST0wsXG4gICAgICAgICAgICAgICAgc2VydmljZVR5cGUsIFNkbFBhY2tldC5GUkFNRV9JTkZPX0VORF9TRVJWSUNFLCBzZXNzaW9uSUQsXG4gICAgICAgICAgICAgICAgMCwgbWVzc2FnZUlELCBudWxsKTtcbiAgICAgICAgICAgIGVuZFNlc3Npb24ucHV0VGFnKENvbnRyb2xGcmFtZVRhZ3MuUlBDLkVuZFNlcnZpY2UuSEFTSF9JRCwgaGFzaElEKTtcbiAgICAgICAgICAgIHJldHVybiBlbmRTZXNzaW9uO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgeyBTZGxQYWNrZXRGYWN0b3J5IH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcblxuLyoqXG4gKiBDb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCBhIFNvZnRCdXR0b24ncyBjYXBhYmlsaXRpZXMuXG4gKi9cbmNsYXNzIFNvZnRCdXR0b25DYXBhYmlsaXRpZXMgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlIC0gVGhlIGJ1dHRvbiBzdXBwb3J0cyBhIHNob3J0IHByZXNzLiBXaGVuZXZlciB0aGUgYnV0dG9uIGlzIHByZXNzZWQgc2hvcnQsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkJ1dHRvblByZXNzZWQoIFNIT1JUKSB3aWxsIGJlIGludm9rZWQuXG4gICAgICogQHJldHVybiB7U29mdEJ1dHRvbkNhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRTaG9ydFByZXNzQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU29mdEJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfU0hPUlRfUFJFU1NfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFNob3J0UHJlc3NBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU29mdEJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfU0hPUlRfUFJFU1NfQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGF2YWlsYWJsZSAtIFRoZSBidXR0b24gc3VwcG9ydHMgYSBMT05HIHByZXNzLiBXaGVuZXZlciB0aGUgYnV0dG9uIGlzIHByZXNzZWQgbG9uZyxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQnV0dG9uUHJlc3NlZCggTE9ORykgd2lsbCBiZSBpbnZva2VkLlxuICAgICAqIEByZXR1cm4ge1NvZnRCdXR0b25DYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0TG9uZ1ByZXNzQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU29mdEJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfTE9OR19QUkVTU19BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0TG9uZ1ByZXNzQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNvZnRCdXR0b25DYXBhYmlsaXRpZXMuS0VZX0xPTkdfUFJFU1NfQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGF2YWlsYWJsZSAtIFRoZSBidXR0b24gc3VwcG9ydHMgXCJidXR0b24gZG93blwiIGFuZCBcImJ1dHRvbiB1cFwiLiBXaGVuZXZlciB0aGUgYnV0dG9uIGlzIHByZXNzZWQsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkJ1dHRvbkV2ZW50KCBET1dOKSB3aWxsIGJlIGludm9rZWQuIFdoZW5ldmVyIHRoZSBidXR0b24gaXMgcmVsZWFzZWQsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkJ1dHRvbkV2ZW50KCBVUCkgd2lsbCBiZSBpbnZva2VkLlxuICAgICAqIEByZXR1cm4ge1NvZnRCdXR0b25DYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0VXBEb3duQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU29mdEJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfVVBfRE9XTl9BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0VXBEb3duQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNvZnRCdXR0b25DYXBhYmlsaXRpZXMuS0VZX1VQX0RPV05fQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHN1cHBvcnRlZCAtIFRoZSBidXR0b24gc3VwcG9ydHMgcmVmZXJlbmNpbmcgYSBzdGF0aWMgb3IgZHluYW1pYyBpbWFnZS5cbiAgICAgKiBAcmV0dXJuIHtTb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldEltYWdlU3VwcG9ydGVkIChzdXBwb3J0ZWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU29mdEJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfSU1BR0VfU1VQUE9SVEVELCBzdXBwb3J0ZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEltYWdlU3VwcG9ydGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNvZnRCdXR0b25DYXBhYmlsaXRpZXMuS0VZX0lNQUdFX1NVUFBPUlRFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBzdXBwb3J0ZWQgLSBUaGUgYnV0dG9uIHN1cHBvcnRzIHRoZSB1c2Ugb2YgdGV4dC4gSWYgbm90IGluY2x1ZGVkLCB0aGUgZGVmYXVsdCB2YWx1ZSBzaG91bGQgYmVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNpZGVyZWQgdHJ1ZSB0aGF0IHRoZSBidXR0b24gd2lsbCBzdXBwb3J0IHRleHQuXG4gICAgICogQHJldHVybiB7U29mdEJ1dHRvbkNhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRUZXh0U3VwcG9ydGVkIChzdXBwb3J0ZWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU29mdEJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfVEVYVF9TVVBQT1JURUQsIHN1cHBvcnRlZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0VGV4dFN1cHBvcnRlZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzLktFWV9URVhUX1NVUFBPUlRFRCk7XG4gICAgfVxufVxuXG5Tb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzLktFWV9TSE9SVF9QUkVTU19BVkFJTEFCTEUgPSAnc2hvcnRQcmVzc0F2YWlsYWJsZSc7XG5Tb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzLktFWV9MT05HX1BSRVNTX0FWQUlMQUJMRSA9ICdsb25nUHJlc3NBdmFpbGFibGUnO1xuU29mdEJ1dHRvbkNhcGFiaWxpdGllcy5LRVlfVVBfRE9XTl9BVkFJTEFCTEUgPSAndXBEb3duQXZhaWxhYmxlJztcblNvZnRCdXR0b25DYXBhYmlsaXRpZXMuS0VZX0lNQUdFX1NVUFBPUlRFRCA9ICdpbWFnZVN1cHBvcnRlZCc7XG5Tb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzLktFWV9URVhUX1NVUFBPUlRFRCA9ICd0ZXh0U3VwcG9ydGVkJztcblxuZXhwb3J0IHsgU29mdEJ1dHRvbkNhcGFiaWxpdGllcyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIENvbnRhaW5zIGEgbGlzdCBvZiBwcmVyZWNvcmRlZCBzcGVlY2ggaXRlbXMgcHJlc2VudCBvbiB0aGUgcGxhdGZvcm0uXG4gKiBAdHlwZWRlZiB7RW51bX0gUHJlcmVjb3JkZWRTcGVlY2hcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIFByZXJlY29yZGVkU3BlZWNoIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEhFTFBfSklOR0xFICgpIHtcbiAgICAgICAgcmV0dXJuIFByZXJlY29yZGVkU3BlZWNoLl9NQVAuSEVMUF9KSU5HTEU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSU5JVElBTF9KSU5HTEUgKCkge1xuICAgICAgICByZXR1cm4gUHJlcmVjb3JkZWRTcGVlY2guX01BUC5JTklUSUFMX0pJTkdMRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBMSVNURU5fSklOR0xFICgpIHtcbiAgICAgICAgcmV0dXJuIFByZXJlY29yZGVkU3BlZWNoLl9NQVAuTElTVEVOX0pJTkdMRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBQT1NJVElWRV9KSU5HTEUgKCkge1xuICAgICAgICByZXR1cm4gUHJlcmVjb3JkZWRTcGVlY2guX01BUC5QT1NJVElWRV9KSU5HTEU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTkVHQVRJVkVfSklOR0xFICgpIHtcbiAgICAgICAgcmV0dXJuIFByZXJlY29yZGVkU3BlZWNoLl9NQVAuTkVHQVRJVkVfSklOR0xFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFByZXJlY29yZGVkU3BlZWNoLl92YWx1ZUZvcktleShrZXksIFByZXJlY29yZGVkU3BlZWNoLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gUHJlcmVjb3JkZWRTcGVlY2guX2tleUZvclZhbHVlKHZhbHVlLCBQcmVyZWNvcmRlZFNwZWVjaC5fTUFQKTtcbiAgICB9XG59XG5cblByZXJlY29yZGVkU3BlZWNoLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnSEVMUF9KSU5HTEUnOiAnSEVMUF9KSU5HTEUnLFxuICAgICdJTklUSUFMX0pJTkdMRSc6ICdJTklUSUFMX0pJTkdMRScsXG4gICAgJ0xJU1RFTl9KSU5HTEUnOiAnTElTVEVOX0pJTkdMRScsXG4gICAgJ1BPU0lUSVZFX0pJTkdMRSc6ICdQT1NJVElWRV9KSU5HTEUnLFxuICAgICdORUdBVElWRV9KSU5HTEUnOiAnTkVHQVRJVkVfSklOR0xFJyxcbn0pO1xuXG5leHBvcnQgeyBQcmVyZWNvcmRlZFNwZWVjaCB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5cbi8qKlxuICogQ29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgb24tc2NyZWVuIHByZXNldCBjYXBhYmlsaXRpZXMuXG4gKi9cbmNsYXNzIFByZXNldEJhbmtDYXBhYmlsaXRpZXMgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlIC0gT25zY3JlZW4gY3VzdG9tIHByZXNldHMgYXJlIGF2YWlsYWJsZS5cbiAgICAgKiBAcmV0dXJuIHtQcmVzZXRCYW5rQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldE9uU2NyZWVuUHJlc2V0c0F2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFByZXNldEJhbmtDYXBhYmlsaXRpZXMuS0VZX09OX1NDUkVFTl9QUkVTRVRTX0FWQUlMQUJMRSwgYXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRPblNjcmVlblByZXNldHNBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUHJlc2V0QmFua0NhcGFiaWxpdGllcy5LRVlfT05fU0NSRUVOX1BSRVNFVFNfQVZBSUxBQkxFKTtcbiAgICB9XG59XG5cblByZXNldEJhbmtDYXBhYmlsaXRpZXMuS0VZX09OX1NDUkVFTl9QUkVTRVRTX0FWQUlMQUJMRSA9ICdvblNjcmVlblByZXNldHNBdmFpbGFibGUnO1xuXG5leHBvcnQgeyBQcmVzZXRCYW5rQ2FwYWJpbGl0aWVzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcblxuY2xhc3MgVmVoaWNsZVR5cGUgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtYWtlIC0gTWFrZSBvZiB0aGUgdmVoaWNsZSwgZS5nLiBGb3JkXG4gICAgICogQHJldHVybiB7VmVoaWNsZVR5cGV9XG4gICAgICovXG4gICAgc2V0TWFrZSAobWFrZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihWZWhpY2xlVHlwZS5LRVlfTUFLRSwgbWFrZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRNYWtlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFZlaGljbGVUeXBlLktFWV9NQUtFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbW9kZWwgLSBNb2RlbCBvZiB0aGUgdmVoaWNsZSwgZS5nLiBGaWVzdGFcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlVHlwZX1cbiAgICAgKi9cbiAgICBzZXRNb2RlbCAobW9kZWwpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVmVoaWNsZVR5cGUuS0VZX01PREVMLCBtb2RlbCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRNb2RlbCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihWZWhpY2xlVHlwZS5LRVlfTU9ERUwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB5ZWFyIC0gTW9kZWwgWWVhciBvZiB0aGUgdmVoaWNsZSwgZS5nLiAyMDEzXG4gICAgICogQHJldHVybiB7VmVoaWNsZVR5cGV9XG4gICAgICovXG4gICAgc2V0TW9kZWxZZWFyICh5ZWFyKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFZlaGljbGVUeXBlLktFWV9NT0RFTF9ZRUFSLCB5ZWFyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldE1vZGVsWWVhciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihWZWhpY2xlVHlwZS5LRVlfTU9ERUxfWUVBUik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHRyaW0gLSBUcmltIG9mIHRoZSB2ZWhpY2xlLCBlLmcuIFNFXG4gICAgICogQHJldHVybiB7VmVoaWNsZVR5cGV9XG4gICAgICovXG4gICAgc2V0VHJpbSAodHJpbSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihWZWhpY2xlVHlwZS5LRVlfVFJJTSwgdHJpbSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRUcmltICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFZlaGljbGVUeXBlLktFWV9UUklNKTtcbiAgICB9XG59XG5cblZlaGljbGVUeXBlLktFWV9NQUtFID0gJ21ha2UnO1xuVmVoaWNsZVR5cGUuS0VZX01PREVMID0gJ21vZGVsJztcblZlaGljbGVUeXBlLktFWV9NT0RFTF9ZRUFSID0gJ21vZGVsWWVhcic7XG5WZWhpY2xlVHlwZS5LRVlfVFJJTSA9ICd0cmltJztcblxuZXhwb3J0IHsgVmVoaWNsZVR5cGUgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBDb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgSE1JIHpvbmUgY2FwYWJpbGl0aWVzLiBGb3IgZnV0dXJlIHVzZS5cbiAqIEB0eXBlZGVmIHtFbnVtfSBIbWlab25lQ2FwYWJpbGl0aWVzXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBIbWlab25lQ2FwYWJpbGl0aWVzIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEZST05UICgpIHtcbiAgICAgICAgcmV0dXJuIEhtaVpvbmVDYXBhYmlsaXRpZXMuX01BUC5GUk9OVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBCQUNLICgpIHtcbiAgICAgICAgcmV0dXJuIEhtaVpvbmVDYXBhYmlsaXRpZXMuX01BUC5CQUNLO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIEhtaVpvbmVDYXBhYmlsaXRpZXMuX3ZhbHVlRm9yS2V5KGtleSwgSG1pWm9uZUNhcGFiaWxpdGllcy5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIEhtaVpvbmVDYXBhYmlsaXRpZXMuX2tleUZvclZhbHVlKHZhbHVlLCBIbWlab25lQ2FwYWJpbGl0aWVzLl9NQVApO1xuICAgIH1cbn1cblxuSG1pWm9uZUNhcGFiaWxpdGllcy5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0ZST05UJzogJ0ZST05UJyxcbiAgICAnQkFDSyc6ICdCQUNLJyxcbn0pO1xuXG5leHBvcnQgeyBIbWlab25lQ2FwYWJpbGl0aWVzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYge0VudW19IE1lZGlhQ2xvY2tGb3JtYXRcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIE1lZGlhQ2xvY2tGb3JtYXQgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogbWludXRlc0ZpZWxkV2lkdGggPSAyO21pbnV0ZXNGaWVsZE1heCA9IDE5O3NlY29uZHNGaWVsZFdpZHRoID0gMjtzZWNvbmRzRmllbGRNYXggPSA5OTttYXhIb3VycyA9IDE5O21heE1pbnV0ZXNcbiAgICAgKiA9IDU5O21heFNlY29uZHMgPSA1OTsgdXNlZCBmb3IgVHlwZSBJSSBhbmQgQ0lEIGhlYWR1bml0c1xuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENMT0NLMSAoKSB7XG4gICAgICAgIHJldHVybiBNZWRpYUNsb2NrRm9ybWF0Ll9NQVAuQ0xPQ0sxO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIG1pbnV0ZXNGaWVsZFdpZHRoID0gMzttaW51dGVzRmllbGRNYXggPSAxOTk7c2Vjb25kc0ZpZWxkV2lkdGggPSAyO3NlY29uZHNGaWVsZE1heCA9IDk5O21heEhvdXJzID0gNTk7bWF4TWludXRlc1xuICAgICAqID0gNTk7bWF4U2Vjb25kcyA9IDU5OyB1c2VkIGZvciBUeXBlIFYgaGVhZHVuaXRcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDTE9DSzIgKCkge1xuICAgICAgICByZXR1cm4gTWVkaWFDbG9ja0Zvcm1hdC5fTUFQLkNMT0NLMjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBtaW51dGVzRmllbGRXaWR0aCA9IDI7bWludXRlc0ZpZWxkTWF4ID0gNTk7c2Vjb25kc0ZpZWxkV2lkdGggPSAyO3NlY29uZHNGaWVsZE1heCA9IDU5O21heEhvdXJzID0gOTttYXhNaW51dGVzID1cbiAgICAgKiA1OTttYXhTZWNvbmRzID0gNTk7IHVzZWQgZm9yIEdFTjEuMSBNRkQzLzQvNSBoZWFkdW5pdHNcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDTE9DSzMgKCkge1xuICAgICAgICByZXR1cm4gTWVkaWFDbG9ja0Zvcm1hdC5fTUFQLkNMT0NLMztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiA1IGNoYXJhY3RlcnMgcG9zc2libGUgRm9ybWF0OiAxfHNwIGMgOnxzcCBjIGMgMXxzcCA6IGRpZ2l0IFwiMVwiIG9yIHNwYWNlIGMgOiBjaGFyYWN0ZXIgb3V0IG9mIGZvbGxvd2luZ1xuICAgICAqIGNoYXJhY3RlciBzZXQ6IHNwfDAtOXxbbGV0dGVycywgc2VlIFR5cGVJSSBjb2x1bW4gaW4gWExTLiBTZWUgOnxzcCA6IGNvbG9uIG9yIHNwYWNlIHVzZWQgZm9yIFR5cGUgSUkgaGVhZHVuaXRcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDTE9DS1RFWFQxICgpIHtcbiAgICAgICAgcmV0dXJuIE1lZGlhQ2xvY2tGb3JtYXQuX01BUC5DTE9DS1RFWFQxO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIDUgY2hhcnMgcG9zc2libGUgRm9ybWF0OiAxfHNwIGMgOnxzcCBjIGMgMXxzcCA6IGRpZ2l0IFwiMVwiIG9yIHNwYWNlIGMgOiBjaGFyYWN0ZXIgb3V0IG9mIGZvbGxvd2luZyBjaGFyYWN0ZXJcbiAgICAgKiBzZXQ6IHNwfDAtOXxbbGV0dGVycywgc2VlIENJRCBjb2x1bW4gaW4gWExTLiBTZWUgOnxzcCA6IGNvbG9uIG9yIHNwYWNlIHVzZWQgZm9yIENJRCBoZWFkdW5pdCBOT1RFOiBkaWZmZXJlbmNlXG4gICAgICogYmV0d2VlbiBDTE9DS1RFWFQxIGFuZCBDTE9DS1RFWFQyIGlzIHRoZSBzdXBwb3J0ZWQgY2hhcmFjdGVyIHNldFxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENMT0NLVEVYVDIgKCkge1xuICAgICAgICByZXR1cm4gTWVkaWFDbG9ja0Zvcm1hdC5fTUFQLkNMT0NLVEVYVDI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogNiBjaGFycyBwb3NzaWJsZSBGb3JtYXQ6IDF8c3AgYyBjIDp8c3AgYyBjIDF8c3AgOiBkaWdpdCBcIjFcIiBvciBzcGFjZSBjIDogY2hhcmFjdGVyIG91dCBvZiBmb2xsb3dpbmcgY2hhcmFjdGVyXG4gICAgICogc2V0OiBzcHwwLTl8W2xldHRlcnMsIHNlZSBUeXBlIDUgY29sdW1uIGluIFhMU10uIFNlZSA6fHNwIDogY29sb24gb3Igc3BhY2UgdXNlZCBmb3IgVHlwZSBWIGhlYWR1bml0XG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ0xPQ0tURVhUMyAoKSB7XG4gICAgICAgIHJldHVybiBNZWRpYUNsb2NrRm9ybWF0Ll9NQVAuQ0xPQ0tURVhUMztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiA2IGNoYXJzIHBvc3NpYmxlIEZvcm1hdDogYyA6fHNwIGMgYyA6IGMgYyA6fHNwIDogY29sb24gb3Igc3BhY2UgYyA6IGNoYXJhY3RlciBvdXQgb2YgZm9sbG93aW5nIGNoYXJhY3RlciBzZXQ6XG4gICAgICogc3B8MC05fFtsZXR0ZXJzXS4gdXNlZCBmb3IgR0VOMS4xIE1GRDMvNC81IGhlYWR1bml0c1xuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENMT0NLVEVYVDQgKCkge1xuICAgICAgICByZXR1cm4gTWVkaWFDbG9ja0Zvcm1hdC5fTUFQLkNMT0NLVEVYVDQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gTWVkaWFDbG9ja0Zvcm1hdC5fdmFsdWVGb3JLZXkoa2V5LCBNZWRpYUNsb2NrRm9ybWF0Ll9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gTWVkaWFDbG9ja0Zvcm1hdC5fa2V5Rm9yVmFsdWUodmFsdWUsIE1lZGlhQ2xvY2tGb3JtYXQuX01BUCk7XG4gICAgfVxufVxuXG5NZWRpYUNsb2NrRm9ybWF0Ll9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnQ0xPQ0sxJzogJ0NMT0NLMScsXG4gICAgJ0NMT0NLMic6ICdDTE9DSzInLFxuICAgICdDTE9DSzMnOiAnQ0xPQ0szJyxcbiAgICAnQ0xPQ0tURVhUMSc6ICdDTE9DS1RFWFQxJyxcbiAgICAnQ0xPQ0tURVhUMic6ICdDTE9DS1RFWFQyJyxcbiAgICAnQ0xPQ0tURVhUMyc6ICdDTE9DS1RFWFQzJyxcbiAgICAnQ0xPQ0tURVhUNCc6ICdDTE9DS1RFWFQ0Jyxcbn0pO1xuXG5leHBvcnQgeyBNZWRpYUNsb2NrRm9ybWF0IH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcblxuY2xhc3MgSW1hZ2VSZXNvbHV0aW9uIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gd2lkdGggLSBUaGUgaW1hZ2UgcmVzb2x1dGlvbiB3aWR0aC5cbiAgICAgKiBAcmV0dXJuIHtJbWFnZVJlc29sdXRpb259XG4gICAgICovXG4gICAgc2V0UmVzb2x1dGlvbldpZHRoICh3aWR0aCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihJbWFnZVJlc29sdXRpb24uS0VZX1JFU09MVVRJT05fV0lEVEgsIHdpZHRoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFJlc29sdXRpb25XaWR0aCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihJbWFnZVJlc29sdXRpb24uS0VZX1JFU09MVVRJT05fV0lEVEgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBoZWlnaHQgLSBUaGUgaW1hZ2UgcmVzb2x1dGlvbiBoZWlnaHQuXG4gICAgICogQHJldHVybiB7SW1hZ2VSZXNvbHV0aW9ufVxuICAgICAqL1xuICAgIHNldFJlc29sdXRpb25IZWlnaHQgKGhlaWdodCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihJbWFnZVJlc29sdXRpb24uS0VZX1JFU09MVVRJT05fSEVJR0hULCBoZWlnaHQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0UmVzb2x1dGlvbkhlaWdodCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihJbWFnZVJlc29sdXRpb24uS0VZX1JFU09MVVRJT05fSEVJR0hUKTtcbiAgICB9XG59XG5cbkltYWdlUmVzb2x1dGlvbi5LRVlfUkVTT0xVVElPTl9XSURUSCA9ICdyZXNvbHV0aW9uV2lkdGgnO1xuSW1hZ2VSZXNvbHV0aW9uLktFWV9SRVNPTFVUSU9OX0hFSUdIVCA9ICdyZXNvbHV0aW9uSGVpZ2h0JztcblxuZXhwb3J0IHsgSW1hZ2VSZXNvbHV0aW9uIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcblxuY2xhc3MgVG91Y2hFdmVudENhcGFiaWxpdGllcyBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhdmFpbGFibGVcbiAgICAgKiBAcmV0dXJuIHtUb3VjaEV2ZW50Q2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldFByZXNzQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVG91Y2hFdmVudENhcGFiaWxpdGllcy5LRVlfUFJFU1NfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFByZXNzQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFRvdWNoRXZlbnRDYXBhYmlsaXRpZXMuS0VZX1BSRVNTX0FWQUlMQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhdmFpbGFibGVcbiAgICAgKiBAcmV0dXJuIHtUb3VjaEV2ZW50Q2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldE11bHRpVG91Y2hBdmFpbGFibGUgKGF2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihUb3VjaEV2ZW50Q2FwYWJpbGl0aWVzLktFWV9NVUxUSV9UT1VDSF9BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0TXVsdGlUb3VjaEF2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihUb3VjaEV2ZW50Q2FwYWJpbGl0aWVzLktFWV9NVUxUSV9UT1VDSF9BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlXG4gICAgICogQHJldHVybiB7VG91Y2hFdmVudENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXREb3VibGVQcmVzc0F2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFRvdWNoRXZlbnRDYXBhYmlsaXRpZXMuS0VZX0RPVUJMRV9QUkVTU19BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0RG91YmxlUHJlc3NBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoVG91Y2hFdmVudENhcGFiaWxpdGllcy5LRVlfRE9VQkxFX1BSRVNTX0FWQUlMQUJMRSk7XG4gICAgfVxufVxuXG5Ub3VjaEV2ZW50Q2FwYWJpbGl0aWVzLktFWV9QUkVTU19BVkFJTEFCTEUgPSAncHJlc3NBdmFpbGFibGUnO1xuVG91Y2hFdmVudENhcGFiaWxpdGllcy5LRVlfTVVMVElfVE9VQ0hfQVZBSUxBQkxFID0gJ211bHRpVG91Y2hBdmFpbGFibGUnO1xuVG91Y2hFdmVudENhcGFiaWxpdGllcy5LRVlfRE9VQkxFX1BSRVNTX0FWQUlMQUJMRSA9ICdkb3VibGVQcmVzc0F2YWlsYWJsZSc7XG5cbmV4cG9ydCB7IFRvdWNoRXZlbnRDYXBhYmlsaXRpZXMgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgSW1hZ2VSZXNvbHV0aW9uIH0gZnJvbSAnLi9JbWFnZVJlc29sdXRpb24uanMnO1xuaW1wb3J0IHsgVG91Y2hFdmVudENhcGFiaWxpdGllcyB9IGZyb20gJy4vVG91Y2hFdmVudENhcGFiaWxpdGllcy5qcyc7XG5cbmNsYXNzIFNjcmVlblBhcmFtcyBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtJbWFnZVJlc29sdXRpb259IHJlc29sdXRpb24gLSBUaGUgcmVzb2x1dGlvbiBvZiB0aGUgcHJlc2NyaWJlZCBzY3JlZW4gYXJlYS5cbiAgICAgKiBAcmV0dXJuIHtTY3JlZW5QYXJhbXN9XG4gICAgICovXG4gICAgc2V0UmVzb2x1dGlvbiAocmVzb2x1dGlvbikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShJbWFnZVJlc29sdXRpb24sIHJlc29sdXRpb24pO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTY3JlZW5QYXJhbXMuS0VZX1JFU09MVVRJT04sIHJlc29sdXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtJbWFnZVJlc29sdXRpb259XG4gICAgICovXG4gICAgZ2V0UmVzb2x1dGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChJbWFnZVJlc29sdXRpb24sIFNjcmVlblBhcmFtcy5LRVlfUkVTT0xVVElPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtUb3VjaEV2ZW50Q2FwYWJpbGl0aWVzfSBhdmFpbGFibGUgLSBUeXBlcyBvZiBzY3JlZW4gdG91Y2ggZXZlbnRzIGF2YWlsYWJsZSBpbiBzY3JlZW4gYXJlYS5cbiAgICAgKiBAcmV0dXJuIHtTY3JlZW5QYXJhbXN9XG4gICAgICovXG4gICAgc2V0VG91Y2hFdmVudEF2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFRvdWNoRXZlbnRDYXBhYmlsaXRpZXMsIGF2YWlsYWJsZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNjcmVlblBhcmFtcy5LRVlfVE9VQ0hfRVZFTlRfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtUb3VjaEV2ZW50Q2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIGdldFRvdWNoRXZlbnRBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVG91Y2hFdmVudENhcGFiaWxpdGllcywgU2NyZWVuUGFyYW1zLktFWV9UT1VDSF9FVkVOVF9BVkFJTEFCTEUpO1xuICAgIH1cbn1cblxuU2NyZWVuUGFyYW1zLktFWV9SRVNPTFVUSU9OID0gJ3Jlc29sdXRpb24nO1xuU2NyZWVuUGFyYW1zLktFWV9UT1VDSF9FVkVOVF9BVkFJTEFCTEUgPSAndG91Y2hFdmVudEF2YWlsYWJsZSc7XG5cbmV4cG9ydCB7IFNjcmVlblBhcmFtcyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBJbWFnZUZpZWxkTmFtZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgSW1hZ2VGaWVsZE5hbWUgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGltYWdlIGZpZWxkIGZvciBTb2Z0QnV0dG9uXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgc29mdEJ1dHRvbkltYWdlICgpIHtcbiAgICAgICAgcmV0dXJuIEltYWdlRmllbGROYW1lLl9NQVAuc29mdEJ1dHRvbkltYWdlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBmaXJzdCBpbWFnZSBmaWVsZCBmb3IgQ2hvaWNlXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgY2hvaWNlSW1hZ2UgKCkge1xuICAgICAgICByZXR1cm4gSW1hZ2VGaWVsZE5hbWUuX01BUC5jaG9pY2VJbWFnZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgc2Vjb25kYXJ5IGltYWdlIGZpZWxkIGZvciBDaG9pY2VcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBjaG9pY2VTZWNvbmRhcnlJbWFnZSAoKSB7XG4gICAgICAgIHJldHVybiBJbWFnZUZpZWxkTmFtZS5fTUFQLmNob2ljZVNlY29uZGFyeUltYWdlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBpbWFnZSBmaWVsZCBmb3IgdnJIZWxwSXRlbVxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IHZySGVscEl0ZW0gKCkge1xuICAgICAgICByZXR1cm4gSW1hZ2VGaWVsZE5hbWUuX01BUC52ckhlbHBJdGVtO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBpbWFnZSBmaWVsZCBmb3IgVHVyblxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IHR1cm5JY29uICgpIHtcbiAgICAgICAgcmV0dXJuIEltYWdlRmllbGROYW1lLl9NQVAudHVybkljb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGltYWdlIGZpZWxkIGZvciB0aGUgbWVudSBpY29uIGluIFNldEdsb2JhbFByb3BlcnRpZXNcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBtZW51SWNvbiAoKSB7XG4gICAgICAgIHJldHVybiBJbWFnZUZpZWxkTmFtZS5fTUFQLm1lbnVJY29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBpbWFnZSBmaWVsZCBmb3IgQWRkQ29tbWFuZFxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IGNtZEljb24gKCkge1xuICAgICAgICByZXR1cm4gSW1hZ2VGaWVsZE5hbWUuX01BUC5jbWRJY29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBpbWFnZSBmaWVsZCBmb3IgdGhlIGFwcCBpY29uIChzZXQgYnkgc2V0QXBwSWNvbilcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBhcHBJY29uICgpIHtcbiAgICAgICAgcmV0dXJuIEltYWdlRmllbGROYW1lLl9NQVAuYXBwSWNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcHJpbWFyeSBpbWFnZSBmaWVsZCBmb3IgU2hvd1xuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IGdyYXBoaWMgKCkge1xuICAgICAgICByZXR1cm4gSW1hZ2VGaWVsZE5hbWUuX01BUC5ncmFwaGljO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBzZWNvbmRhcnkgaW1hZ2UgZmllbGQgZm9yIFNob3dcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBzZWNvbmRhcnlHcmFwaGljICgpIHtcbiAgICAgICAgcmV0dXJuIEltYWdlRmllbGROYW1lLl9NQVAuc2Vjb25kYXJ5R3JhcGhpYztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcHJpbWFyeSBpbWFnZSBmaWVsZCBmb3IgU2hvd0NvbnN0YW50VEJUXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgc2hvd0NvbnN0YW50VEJUSWNvbiAoKSB7XG4gICAgICAgIHJldHVybiBJbWFnZUZpZWxkTmFtZS5fTUFQLnNob3dDb25zdGFudFRCVEljb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIHNlY29uZGFyeSBpbWFnZSBmaWVsZCBmb3IgU2hvd0NvbnN0YW50VEJUXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgc2hvd0NvbnN0YW50VEJUTmV4dFR1cm5JY29uICgpIHtcbiAgICAgICAgcmV0dXJuIEltYWdlRmllbGROYW1lLl9NQVAuc2hvd0NvbnN0YW50VEJUTmV4dFR1cm5JY29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBvcHRpb25hbCBpbWFnZSBvZiBhIGRlc3RpbmF0aW9uIC8gbG9jYXRpb25cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBsb2NhdGlvbkltYWdlICgpIHtcbiAgICAgICAgcmV0dXJuIEltYWdlRmllbGROYW1lLl9NQVAubG9jYXRpb25JbWFnZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgaW1hZ2UgZmllbGQgZm9yIEFsZXJ0XG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgYWxlcnRJY29uICgpIHtcbiAgICAgICAgcmV0dXJuIEltYWdlRmllbGROYW1lLl9NQVAuYWxlcnRJY29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIEltYWdlRmllbGROYW1lLl92YWx1ZUZvcktleShrZXksIEltYWdlRmllbGROYW1lLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gSW1hZ2VGaWVsZE5hbWUuX2tleUZvclZhbHVlKHZhbHVlLCBJbWFnZUZpZWxkTmFtZS5fTUFQKTtcbiAgICB9XG59XG5cbkltYWdlRmllbGROYW1lLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnc29mdEJ1dHRvbkltYWdlJzogJ3NvZnRCdXR0b25JbWFnZScsXG4gICAgJ2Nob2ljZUltYWdlJzogJ2Nob2ljZUltYWdlJyxcbiAgICAnY2hvaWNlU2Vjb25kYXJ5SW1hZ2UnOiAnY2hvaWNlU2Vjb25kYXJ5SW1hZ2UnLFxuICAgICd2ckhlbHBJdGVtJzogJ3ZySGVscEl0ZW0nLFxuICAgICd0dXJuSWNvbic6ICd0dXJuSWNvbicsXG4gICAgJ21lbnVJY29uJzogJ21lbnVJY29uJyxcbiAgICAnY21kSWNvbic6ICdjbWRJY29uJyxcbiAgICAnYXBwSWNvbic6ICdhcHBJY29uJyxcbiAgICAnZ3JhcGhpYyc6ICdncmFwaGljJyxcbiAgICAnc2Vjb25kYXJ5R3JhcGhpYyc6ICdzZWNvbmRhcnlHcmFwaGljJyxcbiAgICAnc2hvd0NvbnN0YW50VEJUSWNvbic6ICdzaG93Q29uc3RhbnRUQlRJY29uJyxcbiAgICAnc2hvd0NvbnN0YW50VEJUTmV4dFR1cm5JY29uJzogJ3Nob3dDb25zdGFudFRCVE5leHRUdXJuSWNvbicsXG4gICAgJ2xvY2F0aW9uSW1hZ2UnOiAnbG9jYXRpb25JbWFnZScsXG4gICAgJ2FsZXJ0SWNvbic6ICdhbGVydEljb24nLFxufSk7XG5cbmV4cG9ydCB7IEltYWdlRmllbGROYW1lIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogRW51bWVyYXRpb24gbGlzdGluZyBwb3NzaWJsZSBmaWxlIHR5cGVzLlxuICogQHR5cGVkZWYge0VudW19IEZpbGVUeXBlXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBGaWxlVHlwZSBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBHUkFQSElDX0JNUCAoKSB7XG4gICAgICAgIHJldHVybiBGaWxlVHlwZS5fTUFQLkdSQVBISUNfQk1QO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEdSQVBISUNfSlBFRyAoKSB7XG4gICAgICAgIHJldHVybiBGaWxlVHlwZS5fTUFQLkdSQVBISUNfSlBFRztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBHUkFQSElDX1BORyAoKSB7XG4gICAgICAgIHJldHVybiBGaWxlVHlwZS5fTUFQLkdSQVBISUNfUE5HO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFVRElPX1dBVkUgKCkge1xuICAgICAgICByZXR1cm4gRmlsZVR5cGUuX01BUC5BVURJT19XQVZFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFVRElPX01QMyAoKSB7XG4gICAgICAgIHJldHVybiBGaWxlVHlwZS5fTUFQLkFVRElPX01QMztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBBVURJT19BQUMgKCkge1xuICAgICAgICByZXR1cm4gRmlsZVR5cGUuX01BUC5BVURJT19BQUM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQklOQVJZICgpIHtcbiAgICAgICAgcmV0dXJuIEZpbGVUeXBlLl9NQVAuQklOQVJZO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEpTT04gKCkge1xuICAgICAgICByZXR1cm4gRmlsZVR5cGUuX01BUC5KU09OO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIEZpbGVUeXBlLl92YWx1ZUZvcktleShrZXksIEZpbGVUeXBlLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gRmlsZVR5cGUuX2tleUZvclZhbHVlKHZhbHVlLCBGaWxlVHlwZS5fTUFQKTtcbiAgICB9XG59XG5cbkZpbGVUeXBlLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnR1JBUEhJQ19CTVAnOiAnR1JBUEhJQ19CTVAnLFxuICAgICdHUkFQSElDX0pQRUcnOiAnR1JBUEhJQ19KUEVHJyxcbiAgICAnR1JBUEhJQ19QTkcnOiAnR1JBUEhJQ19QTkcnLFxuICAgICdBVURJT19XQVZFJzogJ0FVRElPX1dBVkUnLFxuICAgICdBVURJT19NUDMnOiAnQVVESU9fTVAzJyxcbiAgICAnQVVESU9fQUFDJzogJ0FVRElPX0FBQycsXG4gICAgJ0JJTkFSWSc6ICdCSU5BUlknLFxuICAgICdKU09OJzogJ0pTT04nLFxufSk7XG5cbmV4cG9ydCB7IEZpbGVUeXBlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IEltYWdlUmVzb2x1dGlvbiB9IGZyb20gJy4vSW1hZ2VSZXNvbHV0aW9uLmpzJztcbmltcG9ydCB7IEltYWdlRmllbGROYW1lIH0gZnJvbSAnLi4vZW51bXMvSW1hZ2VGaWVsZE5hbWUuanMnO1xuaW1wb3J0IHsgRmlsZVR5cGUgfSBmcm9tICcuLi9lbnVtcy9GaWxlVHlwZS5qcyc7XG5cbmNsYXNzIEltYWdlRmllbGQgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7SW1hZ2VGaWVsZE5hbWV9IG5hbWUgLSBUaGUgbmFtZSB0aGF0IGlkZW50aWZpZXMgdGhlIGZpZWxkLiBTZWUgSW1hZ2VGaWVsZE5hbWUuXG4gICAgICogQHJldHVybiB7SW1hZ2VGaWVsZH1cbiAgICAgKi9cbiAgICBzZXROYW1lIChuYW1lKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEltYWdlRmllbGROYW1lLCBuYW1lKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoSW1hZ2VGaWVsZC5LRVlfTkFNRSwgbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0ltYWdlRmllbGROYW1lfVxuICAgICAqL1xuICAgIGdldE5hbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoSW1hZ2VGaWVsZE5hbWUsIEltYWdlRmllbGQuS0VZX05BTUUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RmlsZVR5cGVbXX0gc3VwcG9ydGVkIC0gVGhlIGltYWdlIHR5cGVzIHRoYXQgYXJlIHN1cHBvcnRlZCBpbiB0aGlzIGZpZWxkLiBTZWUgRmlsZVR5cGUuXG4gICAgICogQHJldHVybiB7SW1hZ2VGaWVsZH1cbiAgICAgKi9cbiAgICBzZXRJbWFnZVR5cGVTdXBwb3J0ZWQgKHN1cHBvcnRlZCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShGaWxlVHlwZSwgc3VwcG9ydGVkLCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoSW1hZ2VGaWVsZC5LRVlfSU1BR0VfVFlQRV9TVVBQT1JURUQsIHN1cHBvcnRlZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0ZpbGVUeXBlW119XG4gICAgICovXG4gICAgZ2V0SW1hZ2VUeXBlU3VwcG9ydGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEZpbGVUeXBlLCBJbWFnZUZpZWxkLktFWV9JTUFHRV9UWVBFX1NVUFBPUlRFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtJbWFnZVJlc29sdXRpb259IHJlc29sdXRpb24gLSBUaGUgaW1hZ2UgcmVzb2x1dGlvbiBvZiB0aGlzIGZpZWxkLlxuICAgICAqIEByZXR1cm4ge0ltYWdlRmllbGR9XG4gICAgICovXG4gICAgc2V0SW1hZ2VSZXNvbHV0aW9uIChyZXNvbHV0aW9uKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEltYWdlUmVzb2x1dGlvbiwgcmVzb2x1dGlvbik7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEltYWdlRmllbGQuS0VZX0lNQUdFX1JFU09MVVRJT04sIHJlc29sdXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtJbWFnZVJlc29sdXRpb259XG4gICAgICovXG4gICAgZ2V0SW1hZ2VSZXNvbHV0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEltYWdlUmVzb2x1dGlvbiwgSW1hZ2VGaWVsZC5LRVlfSU1BR0VfUkVTT0xVVElPTik7XG4gICAgfVxufVxuXG5JbWFnZUZpZWxkLktFWV9OQU1FID0gJ25hbWUnO1xuSW1hZ2VGaWVsZC5LRVlfSU1BR0VfVFlQRV9TVVBQT1JURUQgPSAnaW1hZ2VUeXBlU3VwcG9ydGVkJztcbkltYWdlRmllbGQuS0VZX0lNQUdFX1JFU09MVVRJT04gPSAnaW1hZ2VSZXNvbHV0aW9uJztcblxuZXhwb3J0IHsgSW1hZ2VGaWVsZCB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIFNlZSBEQUVTIGZvciBmdXJ0aGVyIGluZm9zIHJlZ2FyZGluZyB0aGUgZGlzcGxheXNcbiAqIEBkZXByZWNhdGVkXG4gKiBAdHlwZWRlZiB7RW51bX0gRGlzcGxheVR5cGVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIERpc3BsYXlUeXBlIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDSUQgKCkge1xuICAgICAgICByZXR1cm4gRGlzcGxheVR5cGUuX01BUC5DSUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBUWVBFMiAoKSB7XG4gICAgICAgIHJldHVybiBEaXNwbGF5VHlwZS5fTUFQLlRZUEUyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVFlQRTUgKCkge1xuICAgICAgICByZXR1cm4gRGlzcGxheVR5cGUuX01BUC5UWVBFNTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5HTiAoKSB7XG4gICAgICAgIHJldHVybiBEaXNwbGF5VHlwZS5fTUFQLk5HTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEdFTjJfOF9ETUEgKCkge1xuICAgICAgICByZXR1cm4gRGlzcGxheVR5cGUuX01BUC5HRU4yXzhfRE1BO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgR0VOMl82X0RNQSAoKSB7XG4gICAgICAgIHJldHVybiBEaXNwbGF5VHlwZS5fTUFQLkdFTjJfNl9ETUE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBNRkQzICgpIHtcbiAgICAgICAgcmV0dXJuIERpc3BsYXlUeXBlLl9NQVAuTUZEMztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE1GRDQgKCkge1xuICAgICAgICByZXR1cm4gRGlzcGxheVR5cGUuX01BUC5NRkQ0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTUZENSAoKSB7XG4gICAgICAgIHJldHVybiBEaXNwbGF5VHlwZS5fTUFQLk1GRDU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBHRU4zXzhfSU5DSCAoKSB7XG4gICAgICAgIHJldHVybiBEaXNwbGF5VHlwZS5fTUFQLkdFTjNfOF9JTkNIO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0RMX0dFTkVSSUMgKCkge1xuICAgICAgICByZXR1cm4gRGlzcGxheVR5cGUuX01BUC5TRExfR0VORVJJQztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBEaXNwbGF5VHlwZS5fdmFsdWVGb3JLZXkoa2V5LCBEaXNwbGF5VHlwZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIERpc3BsYXlUeXBlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgRGlzcGxheVR5cGUuX01BUCk7XG4gICAgfVxufVxuXG5EaXNwbGF5VHlwZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0NJRCc6ICdDSUQnLFxuICAgICdUWVBFMic6ICdUWVBFMicsXG4gICAgJ1RZUEU1JzogJ1RZUEU1JyxcbiAgICAnTkdOJzogJ05HTicsXG4gICAgJ0dFTjJfOF9ETUEnOiAnR0VOMl84X0RNQScsXG4gICAgJ0dFTjJfNl9ETUEnOiAnR0VOMl82X0RNQScsXG4gICAgJ01GRDMnOiAnTUZEMycsXG4gICAgJ01GRDQnOiAnTUZENCcsXG4gICAgJ01GRDUnOiAnTUZENScsXG4gICAgJ0dFTjNfOF9JTkNIJzogJ0dFTjNfOC1JTkNIJyxcbiAgICAnU0RMX0dFTkVSSUMnOiAnU0RMX0dFTkVSSUMnLFxufSk7XG5cbmV4cG9ydCB7IERpc3BsYXlUeXBlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYge0VudW19IFRleHRGaWVsZE5hbWVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIFRleHRGaWVsZE5hbWUgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGZpcnN0IGxpbmUgb2YgZmlyc3Qgc2V0IG9mIG1haW4gZmllbGRzIG9mIHRoZSBwZXJzaXN0ZW50IGRpc3BsYXk7IGFwcGxpZXMgdG8gXCJTaG93XCJcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBtYWluRmllbGQxICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5tYWluRmllbGQxO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBzZWNvbmQgbGluZSBvZiBmaXJzdCBzZXQgb2YgbWFpbiBmaWVsZHMgb2YgdGhlIHBlcnNpc3RlbnQgZGlzcGxheTsgYXBwbGllcyB0byBcIlNob3dcIlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IG1haW5GaWVsZDIgKCkge1xuICAgICAgICByZXR1cm4gVGV4dEZpZWxkTmFtZS5fTUFQLm1haW5GaWVsZDI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGZpcnN0IGxpbmUgb2Ygc2Vjb25kIHNldCBvZiBtYWluIGZpZWxkcyBvZiBwZXJzaXN0ZW50IGRpc3BsYXk7IGFwcGxpZXMgdG8gXCJTaG93XCJcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBtYWluRmllbGQzICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5tYWluRmllbGQzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBzZWNvbmQgbGluZSBvZiBzZWNvbmQgc2V0IG9mIG1haW4gZmllbGRzIG9mIHRoZSBwZXJzaXN0ZW50IGRpc3BsYXk7IGFwcGxpZXMgdG8gXCJTaG93XCJcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBtYWluRmllbGQ0ICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5tYWluRmllbGQ0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBzdGF0dXMgYmFyIG9uIE5HTjsgYXBwbGllcyB0byBcIlNob3dcIlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IHN0YXR1c0JhciAoKSB7XG4gICAgICAgIHJldHVybiBUZXh0RmllbGROYW1lLl9NQVAuc3RhdHVzQmFyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRleHQgdmFsdWUgZm9yIE1lZGlhQ2xvY2sgZmllbGQ7IGFwcGxpZXMgdG8gXCJTaG93XCJcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBtZWRpYUNsb2NrICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5tZWRpYUNsb2NrO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSB0cmFjayBmaWVsZCBvZiBOR04gYW5kIEdFTjEuMSBNRkQgZGlzcGxheXMuIFRoaXMgZmllbGQgaXMgb25seSBhdmFpbGFibGUgZm9yIG1lZGlhIGFwcGxpY2F0aW9uczsgYXBwbGllcyB0b1xuICAgICAqIFwiU2hvd1wiXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgbWVkaWFUcmFjayAoKSB7XG4gICAgICAgIHJldHVybiBUZXh0RmllbGROYW1lLl9NQVAubWVkaWFUcmFjaztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgdGl0bGUgb2YgdGhlIG5ldyB0ZW1wbGF0ZSB0aGF0IHdpbGwgYmUgZGlzcGxheWVkOyBhcHBsaWVzIHRvIFwiU2hvd1wiXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgdGVtcGxhdGVUaXRsZSAoKSB7XG4gICAgICAgIHJldHVybiBUZXh0RmllbGROYW1lLl9NQVAudGVtcGxhdGVUaXRsZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgZmlyc3QgbGluZSBvZiB0aGUgYWxlcnQgdGV4dCBmaWVsZDsgYXBwbGllcyB0byBcIkFsZXJ0XCJcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBhbGVydFRleHQxICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5hbGVydFRleHQxO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBzZWNvbmQgbGluZSBvZiB0aGUgYWxlcnQgdGV4dCBmaWVsZDsgYXBwbGllcyB0byBcIkFsZXJ0XCJcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBhbGVydFRleHQyICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5hbGVydFRleHQyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSB0aGlyZCBsaW5lIG9mIHRoZSBhbGVydCB0ZXh0IGZpZWxkOyBhcHBsaWVzIHRvIFwiQWxlcnRcIlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IGFsZXJ0VGV4dDMgKCkge1xuICAgICAgICByZXR1cm4gVGV4dEZpZWxkTmFtZS5fTUFQLmFsZXJ0VGV4dDM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTG9uZyBmb3JtIGJvZHkgb2YgdGV4dCB0aGF0IGNhbiBpbmNsdWRlIG5ld2xpbmVzIGFuZCB0YWJzOyBhcHBsaWVzIHRvIFwiU2Nyb2xsYWJsZU1lc3NhZ2VcIlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IHNjcm9sbGFibGVNZXNzYWdlQm9keSAoKSB7XG4gICAgICAgIHJldHVybiBUZXh0RmllbGROYW1lLl9NQVAuc2Nyb2xsYWJsZU1lc3NhZ2VCb2R5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZpcnN0IGxpbmUgc3VnZ2VzdGlvbiBmb3IgYSB1c2VyIHJlc3BvbnNlIChpbiB0aGUgY2FzZSBvZiBWUiBlbmFibGVkIGludGVyYWN0aW9uKVxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IGluaXRpYWxJbnRlcmFjdGlvblRleHQgKCkge1xuICAgICAgICByZXR1cm4gVGV4dEZpZWxkTmFtZS5fTUFQLmluaXRpYWxJbnRlcmFjdGlvblRleHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmlyc3QgbGluZSBvZiBuYXZpZ2F0aW9uIHRleHRcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBuYXZpZ2F0aW9uVGV4dDEgKCkge1xuICAgICAgICByZXR1cm4gVGV4dEZpZWxkTmFtZS5fTUFQLm5hdmlnYXRpb25UZXh0MTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWNvbmQgbGluZSBvZiBuYXZpZ2F0aW9uIHRleHRcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBuYXZpZ2F0aW9uVGV4dDIgKCkge1xuICAgICAgICByZXR1cm4gVGV4dEZpZWxkTmFtZS5fTUFQLm5hdmlnYXRpb25UZXh0MjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFc3RpbWF0ZWQgVGltZSBvZiBBcnJpdmFsIHRpbWUgZm9yIG5hdmlnYXRpb25cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFVEEgKCkge1xuICAgICAgICByZXR1cm4gVGV4dEZpZWxkTmFtZS5fTUFQLkVUQTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUb3RhbCBkaXN0YW5jZSB0byBkZXN0aW5hdGlvbiBmb3IgbmF2aWdhdGlvblxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IHRvdGFsRGlzdGFuY2UgKCkge1xuICAgICAgICByZXR1cm4gVGV4dEZpZWxkTmFtZS5fTUFQLnRvdGFsRGlzdGFuY2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmlyc3QgbGluZSBvZiB0ZXh0IGZvciBhdWRpbyBwYXNzIHRocnVcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBhdWRpb1Bhc3NUaHJ1RGlzcGxheVRleHQxICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5hdWRpb1Bhc3NUaHJ1RGlzcGxheVRleHQxO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlY29uZCBsaW5lIG9mIHRleHQgZm9yIGF1ZGlvIHBhc3MgdGhydVxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IGF1ZGlvUGFzc1RocnVEaXNwbGF5VGV4dDIgKCkge1xuICAgICAgICByZXR1cm4gVGV4dEZpZWxkTmFtZS5fTUFQLmF1ZGlvUGFzc1RocnVEaXNwbGF5VGV4dDI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGVhZGVyIHRleHQgZm9yIHNsaWRlclxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IHNsaWRlckhlYWRlciAoKSB7XG4gICAgICAgIHJldHVybiBUZXh0RmllbGROYW1lLl9NQVAuc2xpZGVySGVhZGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZvb3RlciB0ZXh0IGZvciBzbGlkZXJcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBzbGlkZXJGb290ZXIgKCkge1xuICAgICAgICByZXR1cm4gVGV4dEZpZWxkTmFtZS5fTUFQLnNsaWRlckZvb3RlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcmltYXJ5IHRleHQgZm9yIENob2ljZVxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IG1lbnVOYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRGaWVsZE5hbWUuX01BUC5tZW51TmFtZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWNvbmRhcnkgdGV4dCBmb3IgQ2hvaWNlXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgc2Vjb25kYXJ5VGV4dCAoKSB7XG4gICAgICAgIHJldHVybiBUZXh0RmllbGROYW1lLl9NQVAuc2Vjb25kYXJ5VGV4dDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUZXJ0aWFyeSB0ZXh0IGZvciBDaG9pY2VcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCB0ZXJ0aWFyeVRleHQgKCkge1xuICAgICAgICByZXR1cm4gVGV4dEZpZWxkTmFtZS5fTUFQLnRlcnRpYXJ5VGV4dDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPcHRpb25hbCB0ZXh0IHRvIGxhYmVsIGFuIGFwcCBtZW51IGJ1dHRvbiAoZm9yIGNlcnRhaW4gdG91Y2hzY3JlZW4gcGxhdGZvcm1zKS5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBtZW51VGl0bGUgKCkge1xuICAgICAgICByZXR1cm4gVGV4dEZpZWxkTmFtZS5fTUFQLm1lbnVUaXRsZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPcHRpb25hbCBuYW1lIC8gdGl0bGUgb2YgaW50ZW5kZWQgbG9jYXRpb24gZm9yIFNlbmRMb2NhdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBsb2NhdGlvbk5hbWUgKCkge1xuICAgICAgICByZXR1cm4gVGV4dEZpZWxkTmFtZS5fTUFQLmxvY2F0aW9uTmFtZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPcHRpb25hbCBkZXNjcmlwdGlvbiBvZiBpbnRlbmRlZCBsb2NhdGlvbiAvIGVzdGFibGlzaG1lbnQgKGlmIGFwcGxpY2FibGUpIGZvciBTZW5kTG9jYXRpb24uXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgbG9jYXRpb25EZXNjcmlwdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBUZXh0RmllbGROYW1lLl9NQVAubG9jYXRpb25EZXNjcmlwdGlvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPcHRpb25hbCBsb2NhdGlvbiBhZGRyZXNzIChpZiBhcHBsaWNhYmxlKSBmb3IgU2VuZExvY2F0aW9uLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IGFkZHJlc3NMaW5lcyAoKSB7XG4gICAgICAgIHJldHVybiBUZXh0RmllbGROYW1lLl9NQVAuYWRkcmVzc0xpbmVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9wdGlvbmFsIGhvbmUgbnVtYmVyIG9mIGludGVuZGVkIGxvY2F0aW9uIC8gZXN0YWJsaXNobWVudCAoaWYgYXBwbGljYWJsZSkgZm9yIFNlbmRMb2NhdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBwaG9uZU51bWJlciAoKSB7XG4gICAgICAgIHJldHVybiBUZXh0RmllbGROYW1lLl9NQVAucGhvbmVOdW1iZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gVGV4dEZpZWxkTmFtZS5fdmFsdWVGb3JLZXkoa2V5LCBUZXh0RmllbGROYW1lLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gVGV4dEZpZWxkTmFtZS5fa2V5Rm9yVmFsdWUodmFsdWUsIFRleHRGaWVsZE5hbWUuX01BUCk7XG4gICAgfVxufVxuXG5UZXh0RmllbGROYW1lLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnbWFpbkZpZWxkMSc6ICdtYWluRmllbGQxJyxcbiAgICAnbWFpbkZpZWxkMic6ICdtYWluRmllbGQyJyxcbiAgICAnbWFpbkZpZWxkMyc6ICdtYWluRmllbGQzJyxcbiAgICAnbWFpbkZpZWxkNCc6ICdtYWluRmllbGQ0JyxcbiAgICAnc3RhdHVzQmFyJzogJ3N0YXR1c0JhcicsXG4gICAgJ21lZGlhQ2xvY2snOiAnbWVkaWFDbG9jaycsXG4gICAgJ21lZGlhVHJhY2snOiAnbWVkaWFUcmFjaycsXG4gICAgJ3RlbXBsYXRlVGl0bGUnOiAndGVtcGxhdGVUaXRsZScsXG4gICAgJ2FsZXJ0VGV4dDEnOiAnYWxlcnRUZXh0MScsXG4gICAgJ2FsZXJ0VGV4dDInOiAnYWxlcnRUZXh0MicsXG4gICAgJ2FsZXJ0VGV4dDMnOiAnYWxlcnRUZXh0MycsXG4gICAgJ3Njcm9sbGFibGVNZXNzYWdlQm9keSc6ICdzY3JvbGxhYmxlTWVzc2FnZUJvZHknLFxuICAgICdpbml0aWFsSW50ZXJhY3Rpb25UZXh0JzogJ2luaXRpYWxJbnRlcmFjdGlvblRleHQnLFxuICAgICduYXZpZ2F0aW9uVGV4dDEnOiAnbmF2aWdhdGlvblRleHQxJyxcbiAgICAnbmF2aWdhdGlvblRleHQyJzogJ25hdmlnYXRpb25UZXh0MicsXG4gICAgJ0VUQSc6ICdFVEEnLFxuICAgICd0b3RhbERpc3RhbmNlJzogJ3RvdGFsRGlzdGFuY2UnLFxuICAgICdhdWRpb1Bhc3NUaHJ1RGlzcGxheVRleHQxJzogJ2F1ZGlvUGFzc1RocnVEaXNwbGF5VGV4dDEnLFxuICAgICdhdWRpb1Bhc3NUaHJ1RGlzcGxheVRleHQyJzogJ2F1ZGlvUGFzc1RocnVEaXNwbGF5VGV4dDInLFxuICAgICdzbGlkZXJIZWFkZXInOiAnc2xpZGVySGVhZGVyJyxcbiAgICAnc2xpZGVyRm9vdGVyJzogJ3NsaWRlckZvb3RlcicsXG4gICAgJ21lbnVOYW1lJzogJ21lbnVOYW1lJyxcbiAgICAnc2Vjb25kYXJ5VGV4dCc6ICdzZWNvbmRhcnlUZXh0JyxcbiAgICAndGVydGlhcnlUZXh0JzogJ3RlcnRpYXJ5VGV4dCcsXG4gICAgJ21lbnVUaXRsZSc6ICdtZW51VGl0bGUnLFxuICAgICdsb2NhdGlvbk5hbWUnOiAnbG9jYXRpb25OYW1lJyxcbiAgICAnbG9jYXRpb25EZXNjcmlwdGlvbic6ICdsb2NhdGlvbkRlc2NyaXB0aW9uJyxcbiAgICAnYWRkcmVzc0xpbmVzJzogJ2FkZHJlc3NMaW5lcycsXG4gICAgJ3Bob25lTnVtYmVyJzogJ3Bob25lTnVtYmVyJyxcbn0pO1xuXG5leHBvcnQgeyBUZXh0RmllbGROYW1lIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogVGhlIGxpc3Qgb2YgcG90ZW50aWFsIGNoYXJhY3RlciBzZXRzXG4gKiBAdHlwZWRlZiB7RW51bX0gQ2hhcmFjdGVyU2V0XG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBDaGFyYWN0ZXJTZXQgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVFlQRTJTRVQgKCkge1xuICAgICAgICByZXR1cm4gQ2hhcmFjdGVyU2V0Ll9NQVAuVFlQRTJTRVQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVFlQRTVTRVQgKCkge1xuICAgICAgICByZXR1cm4gQ2hhcmFjdGVyU2V0Ll9NQVAuVFlQRTVTRVQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ0lEMVNFVCAoKSB7XG4gICAgICAgIHJldHVybiBDaGFyYWN0ZXJTZXQuX01BUC5DSUQxU0VUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlZVxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENJRDJTRVQgKCkge1xuICAgICAgICByZXR1cm4gQ2hhcmFjdGVyU2V0Ll9NQVAuQ0lEMlNFVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBDaGFyYWN0ZXJTZXQuX3ZhbHVlRm9yS2V5KGtleSwgQ2hhcmFjdGVyU2V0Ll9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gQ2hhcmFjdGVyU2V0Ll9rZXlGb3JWYWx1ZSh2YWx1ZSwgQ2hhcmFjdGVyU2V0Ll9NQVApO1xuICAgIH1cbn1cblxuQ2hhcmFjdGVyU2V0Ll9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnVFlQRTJTRVQnOiAnVFlQRTJTRVQnLFxuICAgICdUWVBFNVNFVCc6ICdUWVBFNVNFVCcsXG4gICAgJ0NJRDFTRVQnOiAnQ0lEMVNFVCcsXG4gICAgJ0NJRDJTRVQnOiAnQ0lEMlNFVCcsXG59KTtcblxuZXhwb3J0IHsgQ2hhcmFjdGVyU2V0IH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgVGV4dEZpZWxkTmFtZSB9IGZyb20gJy4uL2VudW1zL1RleHRGaWVsZE5hbWUuanMnO1xuaW1wb3J0IHsgQ2hhcmFjdGVyU2V0IH0gZnJvbSAnLi4vZW51bXMvQ2hhcmFjdGVyU2V0LmpzJztcbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5cbmNsYXNzIFRleHRGaWVsZCBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtUZXh0RmllbGROYW1lfSBuYW1lIC0gVGhlIG5hbWUgdGhhdCBpZGVudGlmaWVzIHRoZSBmaWVsZC4gU2VlIFRleHRGaWVsZE5hbWUuXG4gICAgICogQHJldHVybiB7VGV4dEZpZWxkfVxuICAgICAqL1xuICAgIHNldE5hbWUgKG5hbWUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVGV4dEZpZWxkTmFtZSwgbmFtZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFRleHRGaWVsZC5LRVlfTkFNRSwgbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1RleHRGaWVsZE5hbWV9XG4gICAgICovXG4gICAgZ2V0TmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChUZXh0RmllbGROYW1lLCBUZXh0RmllbGQuS0VZX05BTUUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Q2hhcmFjdGVyU2V0fSBzZXQgLSBUaGUgY2hhcmFjdGVyIHNldCB0aGF0IGlzIHN1cHBvcnRlZCBpbiB0aGlzIGZpZWxkLiBTZWUgQ2hhcmFjdGVyU2V0LlxuICAgICAqIEByZXR1cm4ge1RleHRGaWVsZH1cbiAgICAgKi9cbiAgICBzZXRDaGFyYWN0ZXJTZXQgKHNldCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShDaGFyYWN0ZXJTZXQsIHNldCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFRleHRGaWVsZC5LRVlfQ0hBUkFDVEVSX1NFVCwgc2V0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Q2hhcmFjdGVyU2V0fVxuICAgICAqL1xuICAgIGdldENoYXJhY3RlclNldCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChDaGFyYWN0ZXJTZXQsIFRleHRGaWVsZC5LRVlfQ0hBUkFDVEVSX1NFVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHdpZHRoIC0gVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGluIG9uZSByb3cgb2YgdGhpcyBmaWVsZC5cbiAgICAgKiBAcmV0dXJuIHtUZXh0RmllbGR9XG4gICAgICovXG4gICAgc2V0V2lkdGggKHdpZHRoKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFRleHRGaWVsZC5LRVlfV0lEVEgsIHdpZHRoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFdpZHRoICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFRleHRGaWVsZC5LRVlfV0lEVEgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSByb3dzIC0gVGhlIG51bWJlciBvZiByb3dzIG9mIHRoaXMgZmllbGQuXG4gICAgICogQHJldHVybiB7VGV4dEZpZWxkfVxuICAgICAqL1xuICAgIHNldFJvd3MgKHJvd3MpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVGV4dEZpZWxkLktFWV9ST1dTLCByb3dzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFJvd3MgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoVGV4dEZpZWxkLktFWV9ST1dTKTtcbiAgICB9XG59XG5cblRleHRGaWVsZC5LRVlfTkFNRSA9ICduYW1lJztcblRleHRGaWVsZC5LRVlfQ0hBUkFDVEVSX1NFVCA9ICdjaGFyYWN0ZXJTZXQnO1xuVGV4dEZpZWxkLktFWV9XSURUSCA9ICd3aWR0aCc7XG5UZXh0RmllbGQuS0VZX1JPV1MgPSAncm93cyc7XG5cbmV4cG9ydCB7IFRleHRGaWVsZCB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IE1lZGlhQ2xvY2tGb3JtYXQgfSBmcm9tICcuLi9lbnVtcy9NZWRpYUNsb2NrRm9ybWF0LmpzJztcbmltcG9ydCB7IFNjcmVlblBhcmFtcyB9IGZyb20gJy4vU2NyZWVuUGFyYW1zLmpzJztcbmltcG9ydCB7IEltYWdlRmllbGQgfSBmcm9tICcuL0ltYWdlRmllbGQuanMnO1xuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IERpc3BsYXlUeXBlIH0gZnJvbSAnLi4vZW51bXMvRGlzcGxheVR5cGUuanMnO1xuaW1wb3J0IHsgVGV4dEZpZWxkIH0gZnJvbSAnLi9UZXh0RmllbGQuanMnO1xuXG4vKipcbiAqIENvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IHRoZSBkaXNwbGF5IGNhcGFiaWxpdGllcy4gVGhpcyBzdHJ1Y3QgaXMgZGVwcmVjYXRlZDsgcGxlYXNlIHNlZSB0aGUgbmV3IFN5c3RlbUNhcGFiaWxpdHlcbiAqIERJU1BMQVlTIGFuZCBjb3JyZXNwb25kaW5nIHN0cnVjdCBEaXNwbGF5Q2FwYWJpbGl0eVxuICogQGRlcHJlY2F0ZWRcbiAqL1xuY2xhc3MgRGlzcGxheUNhcGFiaWxpdGllcyBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqIEBwYXJhbSB7RGlzcGxheVR5cGV9IHR5cGUgLSBUaGUgdHlwZSBvZiB0aGUgZGlzcGxheS4gU2VlIERpc3BsYXlUeXBlXG4gICAgICogQHJldHVybiB7RGlzcGxheUNhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXREaXNwbGF5VHlwZSAodHlwZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShEaXNwbGF5VHlwZSwgdHlwZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKERpc3BsYXlDYXBhYmlsaXRpZXMuS0VZX0RJU1BMQVlfVFlQRSwgdHlwZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICogQHJldHVybiB7RGlzcGxheVR5cGV9XG4gICAgICovXG4gICAgZ2V0RGlzcGxheVR5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoRGlzcGxheVR5cGUsIERpc3BsYXlDYXBhYmlsaXRpZXMuS0VZX0RJU1BMQVlfVFlQRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBkaXNwbGF5IHRoZSBhcHAgaXMgY29ubmVjdGVkIHRvLlxuICAgICAqIEByZXR1cm4ge0Rpc3BsYXlDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0RGlzcGxheU5hbWUgKG5hbWUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGlzcGxheUNhcGFiaWxpdGllcy5LRVlfRElTUExBWV9OQU1FLCBuYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0RGlzcGxheU5hbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoRGlzcGxheUNhcGFiaWxpdGllcy5LRVlfRElTUExBWV9OQU1FKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqIEBwYXJhbSB7VGV4dEZpZWxkW119IGZpZWxkcyAtIEEgc2V0IG9mIGFsbCBmaWVsZHMgdGhhdCBzdXBwb3J0IHRleHQgZGF0YS4gU2VlIFRleHRGaWVsZFxuICAgICAqIEByZXR1cm4ge0Rpc3BsYXlDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0VGV4dEZpZWxkcyAoZmllbGRzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFRleHRGaWVsZCwgZmllbGRzLCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGlzcGxheUNhcGFiaWxpdGllcy5LRVlfVEVYVF9GSUVMRFMsIGZpZWxkcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICogQHJldHVybiB7VGV4dEZpZWxkW119XG4gICAgICovXG4gICAgZ2V0VGV4dEZpZWxkcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChUZXh0RmllbGQsIERpc3BsYXlDYXBhYmlsaXRpZXMuS0VZX1RFWFRfRklFTERTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqIEBwYXJhbSB7SW1hZ2VGaWVsZFtdfSBmaWVsZHMgLSBBIHNldCBvZiBhbGwgZmllbGRzIHRoYXQgc3VwcG9ydCBpbWFnZXMuIFNlZSBJbWFnZUZpZWxkXG4gICAgICogQHJldHVybiB7RGlzcGxheUNhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRJbWFnZUZpZWxkcyAoZmllbGRzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEltYWdlRmllbGQsIGZpZWxkcywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKERpc3BsYXlDYXBhYmlsaXRpZXMuS0VZX0lNQUdFX0ZJRUxEUywgZmllbGRzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKiBAcmV0dXJuIHtJbWFnZUZpZWxkW119XG4gICAgICovXG4gICAgZ2V0SW1hZ2VGaWVsZHMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoSW1hZ2VGaWVsZCwgRGlzcGxheUNhcGFiaWxpdGllcy5LRVlfSU1BR0VfRklFTERTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqIEBwYXJhbSB7TWVkaWFDbG9ja0Zvcm1hdFtdfSBmb3JtYXRzIC0gQSBzZXQgb2YgYWxsIHN1cHBvcnRlZCBmb3JtYXRzIG9mIHRoZSBtZWRpYSBjbG9jay4gU2VlIE1lZGlhQ2xvY2tGb3JtYXRcbiAgICAgKiBAcmV0dXJuIHtEaXNwbGF5Q2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldE1lZGlhQ2xvY2tGb3JtYXRzIChmb3JtYXRzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKE1lZGlhQ2xvY2tGb3JtYXQsIGZvcm1hdHMsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihEaXNwbGF5Q2FwYWJpbGl0aWVzLktFWV9NRURJQV9DTE9DS19GT1JNQVRTLCBmb3JtYXRzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKiBAcmV0dXJuIHtNZWRpYUNsb2NrRm9ybWF0W119XG4gICAgICovXG4gICAgZ2V0TWVkaWFDbG9ja0Zvcm1hdHMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTWVkaWFDbG9ja0Zvcm1hdCwgRGlzcGxheUNhcGFiaWxpdGllcy5LRVlfTUVESUFfQ0xPQ0tfRk9STUFUUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHN1cHBvcnRlZCAtIFRoZSBkaXNwbGF5J3MgcGVyc2lzdGVudCBzY3JlZW4gc3VwcG9ydHMgcmVmZXJlbmNpbmcgYSBzdGF0aWMgb3IgZHluYW1pYyBpbWFnZS5cbiAgICAgKiBAcmV0dXJuIHtEaXNwbGF5Q2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldEdyYXBoaWNTdXBwb3J0ZWQgKHN1cHBvcnRlZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihEaXNwbGF5Q2FwYWJpbGl0aWVzLktFWV9HUkFQSElDX1NVUFBPUlRFRCwgc3VwcG9ydGVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEdyYXBoaWNTdXBwb3J0ZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoRGlzcGxheUNhcGFiaWxpdGllcy5LRVlfR1JBUEhJQ19TVVBQT1JURUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICogQHBhcmFtIHtTdHJpbmdbXX0gYXZhaWxhYmxlIC0gQSBzZXQgb2YgYWxsIHByZWRlZmluZWQgcGVyc2lzdGVudCBkaXNwbGF5IHRlbXBsYXRlcyBhdmFpbGFibGUgb24gaGVhZHVuaXQuIFRvIGJlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmZXJlbmNlZCBpbiBTZXREaXNwbGF5TGF5b3V0LlxuICAgICAqIEByZXR1cm4ge0Rpc3BsYXlDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0VGVtcGxhdGVzQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGlzcGxheUNhcGFiaWxpdGllcy5LRVlfVEVNUExBVEVTX0FWQUlMQUJMRSwgYXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmdbXX1cbiAgICAgKi9cbiAgICBnZXRUZW1wbGF0ZXNBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoRGlzcGxheUNhcGFiaWxpdGllcy5LRVlfVEVNUExBVEVTX0FWQUlMQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKiBAcGFyYW0ge1NjcmVlblBhcmFtc30gcGFyYW1zIC0gQSBzZXQgb2YgYWxsIHBhcmFtZXRlcnMgcmVsYXRlZCB0byBhIHByZXNjcmliZWQgc2NyZWVuIGFyZWEgKGUuZy4gZm9yIHZpZGVvIC9cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG91Y2ggaW5wdXQpLlxuICAgICAqIEByZXR1cm4ge0Rpc3BsYXlDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0U2NyZWVuUGFyYW1zIChwYXJhbXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoU2NyZWVuUGFyYW1zLCBwYXJhbXMpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihEaXNwbGF5Q2FwYWJpbGl0aWVzLktFWV9TQ1JFRU5fUEFSQU1TLCBwYXJhbXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqIEByZXR1cm4ge1NjcmVlblBhcmFtc31cbiAgICAgKi9cbiAgICBnZXRTY3JlZW5QYXJhbXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoU2NyZWVuUGFyYW1zLCBEaXNwbGF5Q2FwYWJpbGl0aWVzLktFWV9TQ1JFRU5fUEFSQU1TKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBhdmFpbGFibGUgLSBUaGUgbnVtYmVyIG9mIG9uLXNjcmVlbiBjdXN0b20gcHJlc2V0cyBhdmFpbGFibGUgKGlmIGFueSk7IG90aGVyd2lzZSBvbWl0dGVkLlxuICAgICAqIEByZXR1cm4ge0Rpc3BsYXlDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0TnVtQ3VzdG9tUHJlc2V0c0F2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKERpc3BsYXlDYXBhYmlsaXRpZXMuS0VZX05VTV9DVVNUT01fUFJFU0VUU19BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldE51bUN1c3RvbVByZXNldHNBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoRGlzcGxheUNhcGFiaWxpdGllcy5LRVlfTlVNX0NVU1RPTV9QUkVTRVRTX0FWQUlMQUJMRSk7XG4gICAgfVxufVxuXG5EaXNwbGF5Q2FwYWJpbGl0aWVzLktFWV9ESVNQTEFZX1RZUEUgPSAnZGlzcGxheVR5cGUnO1xuRGlzcGxheUNhcGFiaWxpdGllcy5LRVlfRElTUExBWV9OQU1FID0gJ2Rpc3BsYXlOYW1lJztcbkRpc3BsYXlDYXBhYmlsaXRpZXMuS0VZX1RFWFRfRklFTERTID0gJ3RleHRGaWVsZHMnO1xuRGlzcGxheUNhcGFiaWxpdGllcy5LRVlfSU1BR0VfRklFTERTID0gJ2ltYWdlRmllbGRzJztcbkRpc3BsYXlDYXBhYmlsaXRpZXMuS0VZX01FRElBX0NMT0NLX0ZPUk1BVFMgPSAnbWVkaWFDbG9ja0Zvcm1hdHMnO1xuRGlzcGxheUNhcGFiaWxpdGllcy5LRVlfR1JBUEhJQ19TVVBQT1JURUQgPSAnZ3JhcGhpY1N1cHBvcnRlZCc7XG5EaXNwbGF5Q2FwYWJpbGl0aWVzLktFWV9URU1QTEFURVNfQVZBSUxBQkxFID0gJ3RlbXBsYXRlc0F2YWlsYWJsZSc7XG5EaXNwbGF5Q2FwYWJpbGl0aWVzLktFWV9TQ1JFRU5fUEFSQU1TID0gJ3NjcmVlblBhcmFtcyc7XG5EaXNwbGF5Q2FwYWJpbGl0aWVzLktFWV9OVU1fQ1VTVE9NX1BSRVNFVFNfQVZBSUxBQkxFID0gJ251bUN1c3RvbVByZXNldHNBdmFpbGFibGUnO1xuXG5leHBvcnQgeyBEaXNwbGF5Q2FwYWJpbGl0aWVzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogRGVzY3JpYmVzIGRpZmZlcmVudCBzYW1wbGluZyBvcHRpb25zIGZvciBQZXJmb3JtQXVkaW9QYXNzVGhydS5cbiAqIEB0eXBlZGVmIHtFbnVtfSBTYW1wbGluZ1JhdGVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIFNhbXBsaW5nUmF0ZSBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTYW1wbGluZyByYXRlIG9mIDgwMDAgSHouXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU2FtcGxpbmdSYXRlXzhLSFogKCkge1xuICAgICAgICByZXR1cm4gU2FtcGxpbmdSYXRlLl9NQVAuU2FtcGxpbmdSYXRlXzhLSFo7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2FtcGxpbmcgcmF0ZSBvZiAxNjAwMCBIei5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTYW1wbGluZ1JhdGVfMTZLSFogKCkge1xuICAgICAgICByZXR1cm4gU2FtcGxpbmdSYXRlLl9NQVAuU2FtcGxpbmdSYXRlXzE2S0haO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNhbXBsaW5nIHJhdGUgb2YgMjIwNTAgSHouXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU2FtcGxpbmdSYXRlXzIyS0haICgpIHtcbiAgICAgICAgcmV0dXJuIFNhbXBsaW5nUmF0ZS5fTUFQLlNhbXBsaW5nUmF0ZV8yMktIWjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTYW1wbGluZyByYXRlIG9mIDQ0MTAwIEh6LlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNhbXBsaW5nUmF0ZV80NEtIWiAoKSB7XG4gICAgICAgIHJldHVybiBTYW1wbGluZ1JhdGUuX01BUC5TYW1wbGluZ1JhdGVfNDRLSFo7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gU2FtcGxpbmdSYXRlLl92YWx1ZUZvcktleShrZXksIFNhbXBsaW5nUmF0ZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFNhbXBsaW5nUmF0ZS5fa2V5Rm9yVmFsdWUodmFsdWUsIFNhbXBsaW5nUmF0ZS5fTUFQKTtcbiAgICB9XG59XG5cblNhbXBsaW5nUmF0ZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1NhbXBsaW5nUmF0ZV84S0haJzogJzhLSFonLFxuICAgICdTYW1wbGluZ1JhdGVfMTZLSFonOiAnMTZLSFonLFxuICAgICdTYW1wbGluZ1JhdGVfMjJLSFonOiAnMjJLSFonLFxuICAgICdTYW1wbGluZ1JhdGVfNDRLSFonOiAnNDRLSFonLFxufSk7XG5cbmV4cG9ydCB7IFNhbXBsaW5nUmF0ZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIERlc2NyaWJlcyBkaWZmZXJlbnQgcXVhbGl0eSBvcHRpb25zIGZvciBQZXJmb3JtQXVkaW9QYXNzVGhydS5cbiAqIEB0eXBlZGVmIHtFbnVtfSBCaXRzUGVyU2FtcGxlXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBCaXRzUGVyU2FtcGxlIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEF1ZGlvIHNhbXBsZSBpcyA4IGJpdHMgd2lkZSwgdW5zaWduZWQuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQml0c1BlclNhbXBsZV84X0JJVCAoKSB7XG4gICAgICAgIHJldHVybiBCaXRzUGVyU2FtcGxlLl9NQVAuQml0c1BlclNhbXBsZV84X0JJVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBdWRpbyBzYW1wbGUgaXMgMTYgYml0cyB3aWRlLCBzaWduZWQsIGFuZCBpbiBsaXR0bGUgZW5kaWFuLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEJpdHNQZXJTYW1wbGVfMTZfQklUICgpIHtcbiAgICAgICAgcmV0dXJuIEJpdHNQZXJTYW1wbGUuX01BUC5CaXRzUGVyU2FtcGxlXzE2X0JJVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBCaXRzUGVyU2FtcGxlLl92YWx1ZUZvcktleShrZXksIEJpdHNQZXJTYW1wbGUuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBCaXRzUGVyU2FtcGxlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgQml0c1BlclNhbXBsZS5fTUFQKTtcbiAgICB9XG59XG5cbkJpdHNQZXJTYW1wbGUuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdCaXRzUGVyU2FtcGxlXzhfQklUJzogJzhfQklUJyxcbiAgICAnQml0c1BlclNhbXBsZV8xNl9CSVQnOiAnMTZfQklUJyxcbn0pO1xuXG5leHBvcnQgeyBCaXRzUGVyU2FtcGxlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogRGVzY3JpYmVzIGRpZmZlcmVudCBhdWRpbyB0eXBlIG9wdGlvbnMgZm9yIFBlcmZvcm1BdWRpb1Bhc3NUaHJ1LlxuICogQHR5cGVkZWYge0VudW19IEF1ZGlvVHlwZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgQXVkaW9UeXBlIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIExpbmVhciBQQ00uXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUENNICgpIHtcbiAgICAgICAgcmV0dXJuIEF1ZGlvVHlwZS5fTUFQLlBDTTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBBdWRpb1R5cGUuX3ZhbHVlRm9yS2V5KGtleSwgQXVkaW9UeXBlLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gQXVkaW9UeXBlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgQXVkaW9UeXBlLl9NQVApO1xuICAgIH1cbn1cblxuQXVkaW9UeXBlLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnUENNJzogJ1BDTScsXG59KTtcblxuZXhwb3J0IHsgQXVkaW9UeXBlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IFNhbXBsaW5nUmF0ZSB9IGZyb20gJy4uL2VudW1zL1NhbXBsaW5nUmF0ZS5qcyc7XG5pbXBvcnQgeyBCaXRzUGVyU2FtcGxlIH0gZnJvbSAnLi4vZW51bXMvQml0c1BlclNhbXBsZS5qcyc7XG5pbXBvcnQgeyBBdWRpb1R5cGUgfSBmcm9tICcuLi9lbnVtcy9BdWRpb1R5cGUuanMnO1xuXG4vKipcbiAqIERlc2NyaWJlcyBkaWZmZXJlbnQgYXVkaW8gdHlwZSBjb25maWd1cmF0aW9ucyBmb3IgUGVyZm9ybUF1ZGlvUGFzc1RocnUuIGUuZy4gezhrSHosOC1iaXQsUENNfSBUaGUgYXVkaW8gaXMgcmVjb3JkZWRcbiAqIGluIG1vbmF1cmFsLlxuICovXG5jbGFzcyBBdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NhbXBsaW5nUmF0ZX0gcmF0ZSAtIERlc2NyaWJlcyBkaWZmZXJlbnQgc2FtcGxpbmcgb3B0aW9ucyBmb3IgUGVyZm9ybUF1ZGlvUGFzc1RocnUuXG4gICAgICogQHJldHVybiB7QXVkaW9QYXNzVGhydUNhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRTYW1wbGluZ1JhdGUgKHJhdGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoU2FtcGxpbmdSYXRlLCByYXRlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQXVkaW9QYXNzVGhydUNhcGFiaWxpdGllcy5LRVlfU0FNUExJTkdfUkFURSwgcmF0ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1NhbXBsaW5nUmF0ZX1cbiAgICAgKi9cbiAgICBnZXRTYW1wbGluZ1JhdGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoU2FtcGxpbmdSYXRlLCBBdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzLktFWV9TQU1QTElOR19SQVRFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0JpdHNQZXJTYW1wbGV9IHNhbXBsZSAtIERlc2NyaWJlcyBkaWZmZXJlbnQgcXVhbGl0eSBvcHRpb25zIGZvciBQZXJmb3JtQXVkaW9QYXNzVGhydS5cbiAgICAgKiBAcmV0dXJuIHtBdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldEJpdHNQZXJTYW1wbGUgKHNhbXBsZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShCaXRzUGVyU2FtcGxlLCBzYW1wbGUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzLktFWV9CSVRTX1BFUl9TQU1QTEUsIHNhbXBsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0JpdHNQZXJTYW1wbGV9XG4gICAgICovXG4gICAgZ2V0Qml0c1BlclNhbXBsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChCaXRzUGVyU2FtcGxlLCBBdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzLktFWV9CSVRTX1BFUl9TQU1QTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7QXVkaW9UeXBlfSB0eXBlIC0gRGVzY3JpYmVzIGRpZmZlcmVudCBhdWRpbyB0eXBlIG9wdGlvbnMgZm9yIFBlcmZvcm1BdWRpb1Bhc3NUaHJ1LlxuICAgICAqIEByZXR1cm4ge0F1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0QXVkaW9UeXBlICh0eXBlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEF1ZGlvVHlwZSwgdHlwZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEF1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXMuS0VZX0FVRElPX1RZUEUsIHR5cGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtBdWRpb1R5cGV9XG4gICAgICovXG4gICAgZ2V0QXVkaW9UeXBlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEF1ZGlvVHlwZSwgQXVkaW9QYXNzVGhydUNhcGFiaWxpdGllcy5LRVlfQVVESU9fVFlQRSk7XG4gICAgfVxufVxuXG5BdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzLktFWV9TQU1QTElOR19SQVRFID0gJ3NhbXBsaW5nUmF0ZSc7XG5BdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzLktFWV9CSVRTX1BFUl9TQU1QTEUgPSAnYml0c1BlclNhbXBsZSc7XG5BdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzLktFWV9BVURJT19UWVBFID0gJ2F1ZGlvVHlwZSc7XG5cbmV4cG9ydCB7IEF1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXMgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBDb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgVlIgY2FwYWJpbGl0aWVzLlxuICogQHR5cGVkZWYge0VudW19IFZyQ2FwYWJpbGl0aWVzXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBWckNhcGFiaWxpdGllcyBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBWUl9URVhUICgpIHtcbiAgICAgICAgcmV0dXJuIFZyQ2FwYWJpbGl0aWVzLl9NQVAuVlJfVEVYVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBWckNhcGFiaWxpdGllcy5fdmFsdWVGb3JLZXkoa2V5LCBWckNhcGFiaWxpdGllcy5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFZyQ2FwYWJpbGl0aWVzLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgVnJDYXBhYmlsaXRpZXMuX01BUCk7XG4gICAgfVxufVxuXG5WckNhcGFiaWxpdGllcy5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1ZSX1RFWFQnOiAnVEVYVCcsXG59KTtcblxuZXhwb3J0IHsgVnJDYXBhYmlsaXRpZXMgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBoYXJkIChwaHlzaWNhbCkgYW5kIHNvZnQgKHRvdWNoc2NyZWVuKSBidXR0b25zIGF2YWlsYWJsZSBmcm9tIHRoZSBtb2R1bGVcbiAqIEB0eXBlZGVmIHtFbnVtfSBCdXR0b25OYW1lXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBCdXR0b25OYW1lIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE9LICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5PSztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYnV0dG9uIG5hbWUgZm9yIHRoZSBwaHlzaWNhbCBQbGF5L1BhdXNlIHRvZ2dsZSB0aGF0IGNhbiBiZSB1c2VkIGJ5IG1lZGlhIGFwcHMuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUExBWV9QQVVTRSAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuUExBWV9QQVVTRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTRUVLTEVGVCAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuU0VFS0xFRlQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0VFS1JJR0hUICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5TRUVLUklHSFQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVFVORVVQICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5UVU5FVVA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVFVORURPV04gKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLlRVTkVET1dOO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFBSRVNFVF8wICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5QUkVTRVRfMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBQUkVTRVRfMSAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuUFJFU0VUXzE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUFJFU0VUXzIgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLlBSRVNFVF8yO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFBSRVNFVF8zICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5QUkVTRVRfMztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBQUkVTRVRfNCAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuUFJFU0VUXzQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUFJFU0VUXzUgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLlBSRVNFVF81O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFBSRVNFVF82ICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5QUkVTRVRfNjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBQUkVTRVRfNyAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuUFJFU0VUXzc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUFJFU0VUXzggKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLlBSRVNFVF84O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFBSRVNFVF85ICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5QUkVTRVRfOTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDVVNUT01fQlVUVE9OICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5DVVNUT01fQlVUVE9OO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNFQVJDSCAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuU0VBUkNIO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFDX01BWCAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuQUNfTUFYO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFDICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5BQztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSRUNJUkNVTEFURSAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuUkVDSVJDVUxBVEU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRkFOX1VQICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5GQU5fVVA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRkFOX0RPV04gKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLkZBTl9ET1dOO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFRFTVBfVVAgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLlRFTVBfVVA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVEVNUF9ET1dOICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5URU1QX0RPV047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgREVGUk9TVF9NQVggKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLkRFRlJPU1RfTUFYO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IERFRlJPU1QgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLkRFRlJPU1Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgREVGUk9TVF9SRUFSICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5ERUZST1NUX1JFQVI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVVBQRVJfVkVOVCAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuVVBQRVJfVkVOVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBMT1dFUl9WRU5UICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5MT1dFUl9WRU5UO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZPTFVNRV9VUCAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuVk9MVU1FX1VQO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZPTFVNRV9ET1dOICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5WT0xVTUVfRE9XTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFSkVDVCAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuRUpFQ1Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU09VUkNFICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5TT1VSQ0U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0hVRkZMRSAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuU0hVRkZMRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSRVBFQVQgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLlJFUEVBVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOQVZfQ0VOVEVSX0xPQ0FUSU9OICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5OQVZfQ0VOVEVSX0xPQ0FUSU9OO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5BVl9aT09NX0lOICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5OQVZfWk9PTV9JTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOQVZfWk9PTV9PVVQgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLk5BVl9aT09NX09VVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOQVZfUEFOX1VQICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5OQVZfUEFOX1VQO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5BVl9QQU5fVVBfUklHSFQgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLk5BVl9QQU5fVVBfUklHSFQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTkFWX1BBTl9SSUdIVCAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuTkFWX1BBTl9SSUdIVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOQVZfUEFOX0RPV05fUklHSFQgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLk5BVl9QQU5fRE9XTl9SSUdIVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOQVZfUEFOX0RPV04gKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLk5BVl9QQU5fRE9XTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOQVZfUEFOX0RPV05fTEVGVCAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuTkFWX1BBTl9ET1dOX0xFRlQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTkFWX1BBTl9MRUZUICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5OQVZfUEFOX0xFRlQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTkFWX1BBTl9VUF9MRUZUICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5OQVZfUEFOX1VQX0xFRlQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSWYgc3VwcG9ydGVkLCB0aGlzIHRvZ2dsZXMgYmV0d2VlbiBhIHRvcC1kb3duIHZpZXcgYW5kIGFuIGFuZ2xlZC8zRCB2aWV3LiBJZiB5b3VyIGFwcCBzdXBwb3J0cyBkaWZmZXJlbnQsIGJ1dFxuICAgICAqIHN1YnN0YW50aWFsbHkgc2ltaWxhciBvcHRpb25zLCB0aGVuIHlvdSBtYXkgaW1wbGVtZW50IHRob3NlLiBJZiB5b3UgZG9uJ3QgaW1wbGVtZW50IHRoZXNlIG9yIHNpbWlsYXIgb3B0aW9ucyxcbiAgICAgKiBkbyBub3Qgc3Vic2NyaWJlIHRvIHRoaXMgYnV0dG9uLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5BVl9USUxUX1RPR0dMRSAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9NQVAuTkFWX1RJTFRfVE9HR0xFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5BVl9ST1RBVEVfQ0xPQ0tXSVNFICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbk5hbWUuX01BUC5OQVZfUk9UQVRFX0NMT0NLV0lTRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOQVZfUk9UQVRFX0NPVU5URVJDTE9DS1dJU0UgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLk5BVl9ST1RBVEVfQ09VTlRFUkNMT0NLV0lTRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJZiBzdXBwb3J0ZWQsIHRoaXMgdG9nZ2xlcyBiZXR3ZWVuIGxvY2tpbmcgdGhlIG9yaWVudGF0aW9uIHRvIG5vcnRoIG9yIHRvIHRoZSB2ZWhpY2xlJ3MgaGVhZGluZy4gSWYgeW91ciBhcHBcbiAgICAgKiBzdXBwb3J0cyBkaWZmZXJlbnQsIGJ1dCBzdWJzdGFudGlhbGx5IHNpbWlsYXIgb3B0aW9ucywgdGhlbiB5b3UgbWF5IGltcGxlbWVudCB0aG9zZS4gSWYgeW91IGRvbid0IGltcGxlbWVudFxuICAgICAqIHRoZXNlIG9yIHNpbWlsYXIgb3B0aW9ucywgZG8gbm90IHN1YnNjcmliZSB0byB0aGlzIGJ1dHRvbi5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOQVZfSEVBRElOR19UT0dHTEUgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uTmFtZS5fTUFQLk5BVl9IRUFESU5HX1RPR0dMRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl92YWx1ZUZvcktleShrZXksIEJ1dHRvbk5hbWUuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25OYW1lLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgQnV0dG9uTmFtZS5fTUFQKTtcbiAgICB9XG59XG5cbkJ1dHRvbk5hbWUuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdPSyc6ICdPSycsXG4gICAgJ1BMQVlfUEFVU0UnOiAnUExBWV9QQVVTRScsXG4gICAgJ1NFRUtMRUZUJzogJ1NFRUtMRUZUJyxcbiAgICAnU0VFS1JJR0hUJzogJ1NFRUtSSUdIVCcsXG4gICAgJ1RVTkVVUCc6ICdUVU5FVVAnLFxuICAgICdUVU5FRE9XTic6ICdUVU5FRE9XTicsXG4gICAgJ1BSRVNFVF8wJzogJ1BSRVNFVF8wJyxcbiAgICAnUFJFU0VUXzEnOiAnUFJFU0VUXzEnLFxuICAgICdQUkVTRVRfMic6ICdQUkVTRVRfMicsXG4gICAgJ1BSRVNFVF8zJzogJ1BSRVNFVF8zJyxcbiAgICAnUFJFU0VUXzQnOiAnUFJFU0VUXzQnLFxuICAgICdQUkVTRVRfNSc6ICdQUkVTRVRfNScsXG4gICAgJ1BSRVNFVF82JzogJ1BSRVNFVF82JyxcbiAgICAnUFJFU0VUXzcnOiAnUFJFU0VUXzcnLFxuICAgICdQUkVTRVRfOCc6ICdQUkVTRVRfOCcsXG4gICAgJ1BSRVNFVF85JzogJ1BSRVNFVF85JyxcbiAgICAnQ1VTVE9NX0JVVFRPTic6ICdDVVNUT01fQlVUVE9OJyxcbiAgICAnU0VBUkNIJzogJ1NFQVJDSCcsXG4gICAgJ0FDX01BWCc6ICdBQ19NQVgnLFxuICAgICdBQyc6ICdBQycsXG4gICAgJ1JFQ0lSQ1VMQVRFJzogJ1JFQ0lSQ1VMQVRFJyxcbiAgICAnRkFOX1VQJzogJ0ZBTl9VUCcsXG4gICAgJ0ZBTl9ET1dOJzogJ0ZBTl9ET1dOJyxcbiAgICAnVEVNUF9VUCc6ICdURU1QX1VQJyxcbiAgICAnVEVNUF9ET1dOJzogJ1RFTVBfRE9XTicsXG4gICAgJ0RFRlJPU1RfTUFYJzogJ0RFRlJPU1RfTUFYJyxcbiAgICAnREVGUk9TVCc6ICdERUZST1NUJyxcbiAgICAnREVGUk9TVF9SRUFSJzogJ0RFRlJPU1RfUkVBUicsXG4gICAgJ1VQUEVSX1ZFTlQnOiAnVVBQRVJfVkVOVCcsXG4gICAgJ0xPV0VSX1ZFTlQnOiAnTE9XRVJfVkVOVCcsXG4gICAgJ1ZPTFVNRV9VUCc6ICdWT0xVTUVfVVAnLFxuICAgICdWT0xVTUVfRE9XTic6ICdWT0xVTUVfRE9XTicsXG4gICAgJ0VKRUNUJzogJ0VKRUNUJyxcbiAgICAnU09VUkNFJzogJ1NPVVJDRScsXG4gICAgJ1NIVUZGTEUnOiAnU0hVRkZMRScsXG4gICAgJ1JFUEVBVCc6ICdSRVBFQVQnLFxuICAgICdOQVZfQ0VOVEVSX0xPQ0FUSU9OJzogJ05BVl9DRU5URVJfTE9DQVRJT04nLFxuICAgICdOQVZfWk9PTV9JTic6ICdOQVZfWk9PTV9JTicsXG4gICAgJ05BVl9aT09NX09VVCc6ICdOQVZfWk9PTV9PVVQnLFxuICAgICdOQVZfUEFOX1VQJzogJ05BVl9QQU5fVVAnLFxuICAgICdOQVZfUEFOX1VQX1JJR0hUJzogJ05BVl9QQU5fVVBfUklHSFQnLFxuICAgICdOQVZfUEFOX1JJR0hUJzogJ05BVl9QQU5fUklHSFQnLFxuICAgICdOQVZfUEFOX0RPV05fUklHSFQnOiAnTkFWX1BBTl9ET1dOX1JJR0hUJyxcbiAgICAnTkFWX1BBTl9ET1dOJzogJ05BVl9QQU5fRE9XTicsXG4gICAgJ05BVl9QQU5fRE9XTl9MRUZUJzogJ05BVl9QQU5fRE9XTl9MRUZUJyxcbiAgICAnTkFWX1BBTl9MRUZUJzogJ05BVl9QQU5fTEVGVCcsXG4gICAgJ05BVl9QQU5fVVBfTEVGVCc6ICdOQVZfUEFOX1VQX0xFRlQnLFxuICAgICdOQVZfVElMVF9UT0dHTEUnOiAnTkFWX1RJTFRfVE9HR0xFJyxcbiAgICAnTkFWX1JPVEFURV9DTE9DS1dJU0UnOiAnTkFWX1JPVEFURV9DTE9DS1dJU0UnLFxuICAgICdOQVZfUk9UQVRFX0NPVU5URVJDTE9DS1dJU0UnOiAnTkFWX1JPVEFURV9DT1VOVEVSQ0xPQ0tXSVNFJyxcbiAgICAnTkFWX0hFQURJTkdfVE9HR0xFJzogJ05BVl9IRUFESU5HX1RPR0dMRScsXG59KTtcblxuZXhwb3J0IHsgQnV0dG9uTmFtZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5cbi8qKlxuICogRGVzY3JpYmVzIGEgbG9jYXRpb24gKG9yaWdpbiBjb29yZGluYXRlcyBhbmQgc3Bhbikgb2YgYSB2ZWhpY2xlIGNvbXBvbmVudC5cbiAqL1xuY2xhc3MgR3JpZCBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGNvbFxuICAgICAqIEByZXR1cm4ge0dyaWR9XG4gICAgICovXG4gICAgc2V0Q29sdW1uIChjb2wpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR3JpZC5LRVlfQ09MVU1OLCBjb2wpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0Q29sdW1uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdyaWQuS0VZX0NPTFVNTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHJvd1xuICAgICAqIEByZXR1cm4ge0dyaWR9XG4gICAgICovXG4gICAgc2V0Um93IChyb3cpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR3JpZC5LRVlfUk9XLCByb3cpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0Um93ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdyaWQuS0VZX1JPVyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGxldmVsXG4gICAgICogQHJldHVybiB7R3JpZH1cbiAgICAgKi9cbiAgICBzZXRMZXZlbCAobGV2ZWwpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR3JpZC5LRVlfTEVWRUwsIGxldmVsKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldExldmVsICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdyaWQuS0VZX0xFVkVMKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gY29sc3BhblxuICAgICAqIEByZXR1cm4ge0dyaWR9XG4gICAgICovXG4gICAgc2V0Q29sdW1uU3BhbiAoY29sc3Bhbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHcmlkLktFWV9DT0xVTU5fU1BBTiwgY29sc3Bhbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRDb2x1bW5TcGFuICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdyaWQuS0VZX0NPTFVNTl9TUEFOKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gcm93c3BhblxuICAgICAqIEByZXR1cm4ge0dyaWR9XG4gICAgICovXG4gICAgc2V0Um93U3BhbiAocm93c3Bhbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHcmlkLktFWV9ST1dfU1BBTiwgcm93c3Bhbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRSb3dTcGFuICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdyaWQuS0VZX1JPV19TUEFOKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbGV2ZWxzcGFuXG4gICAgICogQHJldHVybiB7R3JpZH1cbiAgICAgKi9cbiAgICBzZXRMZXZlbFNwYW4gKGxldmVsc3Bhbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHcmlkLktFWV9MRVZFTF9TUEFOLCBsZXZlbHNwYW4pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0TGV2ZWxTcGFuICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdyaWQuS0VZX0xFVkVMX1NQQU4pO1xuICAgIH1cbn1cblxuR3JpZC5LRVlfQ09MVU1OID0gJ2NvbCc7XG5HcmlkLktFWV9ST1cgPSAncm93JztcbkdyaWQuS0VZX0xFVkVMID0gJ2xldmVsJztcbkdyaWQuS0VZX0NPTFVNTl9TUEFOID0gJ2NvbHNwYW4nO1xuR3JpZC5LRVlfUk9XX1NQQU4gPSAncm93c3Bhbic7XG5HcmlkLktFWV9MRVZFTF9TUEFOID0gJ2xldmVsc3Bhbic7XG5cbmV4cG9ydCB7IEdyaWQgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgR3JpZCB9IGZyb20gJy4vR3JpZC5qcyc7XG5cbi8qKlxuICogSW5mb3JtYXRpb24gYWJvdXQgYSBSQyBtb2R1bGVcbiAqL1xuY2xhc3MgTW9kdWxlSW5mbyBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGlkIC0gdXVpZCBvZiBhIG1vZHVsZS4gXCJtb2R1bGVJZCArIG1vZHVsZVR5cGVcIiB1bmlxdWVseSBpZGVudGlmeSBhIG1vZHVsZS5cbiAgICAgKiBAcmV0dXJuIHtNb2R1bGVJbmZvfVxuICAgICAqL1xuICAgIHNldE1vZHVsZUlkIChpZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihNb2R1bGVJbmZvLktFWV9NT0RVTEVfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldE1vZHVsZUlkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE1vZHVsZUluZm8uS0VZX01PRFVMRV9JRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtHcmlkfSBsb2NhdGlvbiAtIExvY2F0aW9uIG9mIGEgbW9kdWxlLlxuICAgICAqIEByZXR1cm4ge01vZHVsZUluZm99XG4gICAgICovXG4gICAgc2V0TG9jYXRpb24gKGxvY2F0aW9uKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEdyaWQsIGxvY2F0aW9uKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTW9kdWxlSW5mby5LRVlfTE9DQVRJT04sIGxvY2F0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7R3JpZH1cbiAgICAgKi9cbiAgICBnZXRMb2NhdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChHcmlkLCBNb2R1bGVJbmZvLktFWV9MT0NBVElPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtHcmlkfSBhcmVhIC0gU2VydmljZSBhcmVhIG9mIGEgbW9kdWxlLlxuICAgICAqIEByZXR1cm4ge01vZHVsZUluZm99XG4gICAgICovXG4gICAgc2V0U2VydmljZUFyZWEgKGFyZWEpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoR3JpZCwgYXJlYSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE1vZHVsZUluZm8uS0VZX1NFUlZJQ0VfQVJFQSwgYXJlYSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0dyaWR9XG4gICAgICovXG4gICAgZ2V0U2VydmljZUFyZWEgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoR3JpZCwgTW9kdWxlSW5mby5LRVlfU0VSVklDRV9BUkVBKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGFjY2VzcyAtIGFsbG93IG11bHRpcGxlIHVzZXJzL2FwcHMgdG8gYWNjZXNzIHRoZSBtb2R1bGUgb3Igbm90XG4gICAgICogQHJldHVybiB7TW9kdWxlSW5mb31cbiAgICAgKi9cbiAgICBzZXRBbGxvd011bHRpcGxlQWNjZXNzIChhY2Nlc3MpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTW9kdWxlSW5mby5LRVlfQUxMT1dfTVVMVElQTEVfQUNDRVNTLCBhY2Nlc3MpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEFsbG93TXVsdGlwbGVBY2Nlc3MgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoTW9kdWxlSW5mby5LRVlfQUxMT1dfTVVMVElQTEVfQUNDRVNTKTtcbiAgICB9XG59XG5cbk1vZHVsZUluZm8uS0VZX01PRFVMRV9JRCA9ICdtb2R1bGVJZCc7XG5Nb2R1bGVJbmZvLktFWV9MT0NBVElPTiA9ICdsb2NhdGlvbic7XG5Nb2R1bGVJbmZvLktFWV9TRVJWSUNFX0FSRUEgPSAnc2VydmljZUFyZWEnO1xuTW9kdWxlSW5mby5LRVlfQUxMT1dfTVVMVElQTEVfQUNDRVNTID0gJ2FsbG93TXVsdGlwbGVBY2Nlc3MnO1xuXG5leHBvcnQgeyBNb2R1bGVJbmZvIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IEJ1dHRvbk5hbWUgfSBmcm9tICcuLi9lbnVtcy9CdXR0b25OYW1lLmpzJztcbmltcG9ydCB7IE1vZHVsZUluZm8gfSBmcm9tICcuL01vZHVsZUluZm8uanMnO1xuXG4vKipcbiAqIENvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGEgYnV0dG9uJ3MgY2FwYWJpbGl0aWVzLlxuICovXG5jbGFzcyBCdXR0b25DYXBhYmlsaXRpZXMgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7QnV0dG9uTmFtZX0gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBidXR0b24uIFNlZSBCdXR0b25OYW1lLlxuICAgICAqIEByZXR1cm4ge0J1dHRvbkNhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXROYW1lIChuYW1lKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEJ1dHRvbk5hbWUsIG5hbWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihCdXR0b25DYXBhYmlsaXRpZXMuS0VZX05BTUUsIG5hbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCdXR0b25OYW1lfVxuICAgICAqL1xuICAgIGdldE5hbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQnV0dG9uTmFtZSwgQnV0dG9uQ2FwYWJpbGl0aWVzLktFWV9OQU1FKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge01vZHVsZUluZm99IGluZm8gLSBJbmZvcm1hdGlvbiBhYm91dCBhIFJDIG1vZHVsZSwgaW5jbHVkaW5nIGl0cyBpZC5cbiAgICAgKiBAcmV0dXJuIHtCdXR0b25DYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0TW9kdWxlSW5mbyAoaW5mbykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShNb2R1bGVJbmZvLCBpbmZvKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQnV0dG9uQ2FwYWJpbGl0aWVzLktFWV9NT0RVTEVfSU5GTywgaW5mbyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge01vZHVsZUluZm99XG4gICAgICovXG4gICAgZ2V0TW9kdWxlSW5mbyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChNb2R1bGVJbmZvLCBCdXR0b25DYXBhYmlsaXRpZXMuS0VZX01PRFVMRV9JTkZPKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGF2YWlsYWJsZSAtIFRoZSBidXR0b24gc3VwcG9ydHMgYSBzaG9ydCBwcmVzcy4gV2hlbmV2ZXIgdGhlIGJ1dHRvbiBpcyBwcmVzc2VkIHNob3J0LFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25CdXR0b25QcmVzc2VkKCBTSE9SVCkgd2lsbCBiZSBpbnZva2VkLlxuICAgICAqIEByZXR1cm4ge0J1dHRvbkNhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRTaG9ydFByZXNzQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQnV0dG9uQ2FwYWJpbGl0aWVzLktFWV9TSE9SVF9QUkVTU19BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0U2hvcnRQcmVzc0F2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihCdXR0b25DYXBhYmlsaXRpZXMuS0VZX1NIT1JUX1BSRVNTX0FWQUlMQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhdmFpbGFibGUgLSBUaGUgYnV0dG9uIHN1cHBvcnRzIGEgTE9ORyBwcmVzcy4gV2hlbmV2ZXIgdGhlIGJ1dHRvbiBpcyBwcmVzc2VkIGxvbmcsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkJ1dHRvblByZXNzZWQoIExPTkcpIHdpbGwgYmUgaW52b2tlZC5cbiAgICAgKiBAcmV0dXJuIHtCdXR0b25DYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0TG9uZ1ByZXNzQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQnV0dG9uQ2FwYWJpbGl0aWVzLktFWV9MT05HX1BSRVNTX0FWQUlMQUJMRSwgYXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRMb25nUHJlc3NBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQnV0dG9uQ2FwYWJpbGl0aWVzLktFWV9MT05HX1BSRVNTX0FWQUlMQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhdmFpbGFibGUgLSBUaGUgYnV0dG9uIHN1cHBvcnRzIFwiYnV0dG9uIGRvd25cIiBhbmQgXCJidXR0b24gdXBcIi4gV2hlbmV2ZXIgdGhlIGJ1dHRvbiBpcyBwcmVzc2VkLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25CdXR0b25FdmVudCggRE9XTikgd2lsbCBiZSBpbnZva2VkLiBXaGVuZXZlciB0aGUgYnV0dG9uIGlzIHJlbGVhc2VkLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25CdXR0b25FdmVudCggVVApIHdpbGwgYmUgaW52b2tlZC5cbiAgICAgKiBAcmV0dXJuIHtCdXR0b25DYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0VXBEb3duQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQnV0dG9uQ2FwYWJpbGl0aWVzLktFWV9VUF9ET1dOX0FWQUlMQUJMRSwgYXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRVcERvd25BdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQnV0dG9uQ2FwYWJpbGl0aWVzLktFWV9VUF9ET1dOX0FWQUlMQUJMRSk7XG4gICAgfVxufVxuXG5CdXR0b25DYXBhYmlsaXRpZXMuS0VZX05BTUUgPSAnbmFtZSc7XG5CdXR0b25DYXBhYmlsaXRpZXMuS0VZX01PRFVMRV9JTkZPID0gJ21vZHVsZUluZm8nO1xuQnV0dG9uQ2FwYWJpbGl0aWVzLktFWV9TSE9SVF9QUkVTU19BVkFJTEFCTEUgPSAnc2hvcnRQcmVzc0F2YWlsYWJsZSc7XG5CdXR0b25DYXBhYmlsaXRpZXMuS0VZX0xPTkdfUFJFU1NfQVZBSUxBQkxFID0gJ2xvbmdQcmVzc0F2YWlsYWJsZSc7XG5CdXR0b25DYXBhYmlsaXRpZXMuS0VZX1VQX0RPV05fQVZBSUxBQkxFID0gJ3VwRG93bkF2YWlsYWJsZSc7XG5cbmV4cG9ydCB7IEJ1dHRvbkNhcGFiaWxpdGllcyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5cbmNsYXNzIEhNSUNhcGFiaWxpdGllcyBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBuYXZpZ2F0aW9uIC0gQXZhaWxhYmlsaXR5IG9mIGJ1aWxkIGluIE5hdi4gVHJ1ZTogQXZhaWxhYmxlLCBGYWxzZTogTm90IEF2YWlsYWJsZVxuICAgICAqIEByZXR1cm4ge0hNSUNhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXROYXZpZ2F0aW9uIChuYXZpZ2F0aW9uKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEhNSUNhcGFiaWxpdGllcy5LRVlfTkFWSUdBVElPTiwgbmF2aWdhdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0TmF2aWdhdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihITUlDYXBhYmlsaXRpZXMuS0VZX05BVklHQVRJT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gY2FsbCAtIEF2YWlsYWJpbGl0eSBvZiBidWlsZCBpbiBwaG9uZS4gVHJ1ZTogQXZhaWxhYmxlLCBGYWxzZTogTm90IEF2YWlsYWJsZVxuICAgICAqIEByZXR1cm4ge0hNSUNhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRQaG9uZUNhbGwgKGNhbGwpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoSE1JQ2FwYWJpbGl0aWVzLktFWV9QSE9ORV9DQUxMLCBjYWxsKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRQaG9uZUNhbGwgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoSE1JQ2FwYWJpbGl0aWVzLktFWV9QSE9ORV9DQUxMKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHN0cmVhbWluZyAtIEF2YWlsYWJpbGl0eSBvZiB2aWRlbyBzdHJlYW1pbmcuXG4gICAgICogQHJldHVybiB7SE1JQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldFZpZGVvU3RyZWFtaW5nIChzdHJlYW1pbmcpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoSE1JQ2FwYWJpbGl0aWVzLktFWV9WSURFT19TVFJFQU1JTkcsIHN0cmVhbWluZyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0VmlkZW9TdHJlYW1pbmcgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoSE1JQ2FwYWJpbGl0aWVzLktFWV9WSURFT19TVFJFQU1JTkcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gY29udHJvbCAtIEF2YWlsYWJpbGl0eSBvZiByZW1vdGUgY29udHJvbCBmZWF0dXJlLiBUcnVlOiBBdmFpbGFibGUsIEZhbHNlOiBOb3QgQXZhaWxhYmxlXG4gICAgICogQHJldHVybiB7SE1JQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldFJlbW90ZUNvbnRyb2wgKGNvbnRyb2wpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoSE1JQ2FwYWJpbGl0aWVzLktFWV9SRU1PVEVfQ09OVFJPTCwgY29udHJvbCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0UmVtb3RlQ29udHJvbCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihITUlDYXBhYmlsaXRpZXMuS0VZX1JFTU9URV9DT05UUk9MKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHNlcnZpY2VzIC0gQXZhaWxhYmlsaXR5IG9mIEFwcCBTZXJ2aWNlcyBmdW5jdGlvbmFsaXR5LiBUcnVlOiBBdmFpbGFibGUsIEZhbHNlOiBOb3QgQXZhaWxhYmxlXG4gICAgICogQHJldHVybiB7SE1JQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldEFwcFNlcnZpY2VzIChzZXJ2aWNlcykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihITUlDYXBhYmlsaXRpZXMuS0VZX0FQUF9TRVJWSUNFUywgc2VydmljZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEFwcFNlcnZpY2VzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEhNSUNhcGFiaWxpdGllcy5LRVlfQVBQX1NFUlZJQ0VTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGRpc3BsYXlzIC0gQXZhaWxhYmlsaXR5IG9mIGRpc3BsYXlzIGNhcGFiaWxpdHkuIFRydWU6IEF2YWlsYWJsZSwgRmFsc2U6IE5vdCBBdmFpbGFibGVcbiAgICAgKiBAcmV0dXJuIHtITUlDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0RGlzcGxheXMgKGRpc3BsYXlzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEhNSUNhcGFiaWxpdGllcy5LRVlfRElTUExBWVMsIGRpc3BsYXlzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXREaXNwbGF5cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihITUlDYXBhYmlsaXRpZXMuS0VZX0RJU1BMQVlTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGxvY2F0aW9uIC0gQXZhaWxhYmlsaXR5IG9mIHNlYXQgbG9jYXRpb24gZmVhdHVyZS4gVHJ1ZTogQXZhaWxhYmxlLCBGYWxzZTogTm90IEF2YWlsYWJsZVxuICAgICAqIEByZXR1cm4ge0hNSUNhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRTZWF0TG9jYXRpb24gKGxvY2F0aW9uKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEhNSUNhcGFiaWxpdGllcy5LRVlfU0VBVF9MT0NBVElPTiwgbG9jYXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFNlYXRMb2NhdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihITUlDYXBhYmlsaXRpZXMuS0VZX1NFQVRfTE9DQVRJT04pO1xuICAgIH1cbn1cblxuSE1JQ2FwYWJpbGl0aWVzLktFWV9OQVZJR0FUSU9OID0gJ25hdmlnYXRpb24nO1xuSE1JQ2FwYWJpbGl0aWVzLktFWV9QSE9ORV9DQUxMID0gJ3Bob25lQ2FsbCc7XG5ITUlDYXBhYmlsaXRpZXMuS0VZX1ZJREVPX1NUUkVBTUlORyA9ICd2aWRlb1N0cmVhbWluZyc7XG5ITUlDYXBhYmlsaXRpZXMuS0VZX1JFTU9URV9DT05UUk9MID0gJ3JlbW90ZUNvbnRyb2wnO1xuSE1JQ2FwYWJpbGl0aWVzLktFWV9BUFBfU0VSVklDRVMgPSAnYXBwU2VydmljZXMnO1xuSE1JQ2FwYWJpbGl0aWVzLktFWV9ESVNQTEFZUyA9ICdkaXNwbGF5cyc7XG5ITUlDYXBhYmlsaXRpZXMuS0VZX1NFQVRfTE9DQVRJT04gPSAnc2VhdExvY2F0aW9uJztcblxuZXhwb3J0IHsgSE1JQ2FwYWJpbGl0aWVzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgU29mdEJ1dHRvbkNhcGFiaWxpdGllcyB9IGZyb20gJy4uL3N0cnVjdHMvU29mdEJ1dHRvbkNhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBScGNSZXNwb25zZSB9IGZyb20gJy4uL1JwY1Jlc3BvbnNlLmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFNkbE1zZ1ZlcnNpb24gfSBmcm9tICcuLi9zdHJ1Y3RzL1NkbE1zZ1ZlcnNpb24uanMnO1xuaW1wb3J0IHsgUHJlcmVjb3JkZWRTcGVlY2ggfSBmcm9tICcuLi9lbnVtcy9QcmVyZWNvcmRlZFNwZWVjaC5qcyc7XG5pbXBvcnQgeyBTcGVlY2hDYXBhYmlsaXRpZXMgfSBmcm9tICcuLi9lbnVtcy9TcGVlY2hDYXBhYmlsaXRpZXMuanMnO1xuaW1wb3J0IHsgUHJlc2V0QmFua0NhcGFiaWxpdGllcyB9IGZyb20gJy4uL3N0cnVjdHMvUHJlc2V0QmFua0NhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBWZWhpY2xlVHlwZSB9IGZyb20gJy4uL3N0cnVjdHMvVmVoaWNsZVR5cGUuanMnO1xuaW1wb3J0IHsgSG1pWm9uZUNhcGFiaWxpdGllcyB9IGZyb20gJy4uL2VudW1zL0htaVpvbmVDYXBhYmlsaXRpZXMuanMnO1xuaW1wb3J0IHsgRGlzcGxheUNhcGFiaWxpdGllcyB9IGZyb20gJy4uL3N0cnVjdHMvRGlzcGxheUNhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBMYW5ndWFnZSB9IGZyb20gJy4uL2VudW1zL0xhbmd1YWdlLmpzJztcbmltcG9ydCB7IEF1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXMgfSBmcm9tICcuLi9zdHJ1Y3RzL0F1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXMuanMnO1xuaW1wb3J0IHsgVnJDYXBhYmlsaXRpZXMgfSBmcm9tICcuLi9lbnVtcy9WckNhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBCdXR0b25DYXBhYmlsaXRpZXMgfSBmcm9tICcuLi9zdHJ1Y3RzL0J1dHRvbkNhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBITUlDYXBhYmlsaXRpZXMgfSBmcm9tICcuLi9zdHJ1Y3RzL0hNSUNhcGFiaWxpdGllcy5qcyc7XG5cbi8qKlxuICogVGhlIHJlc3BvbnNlIHRvIHJlZ2lzdGVyQXBwSW50ZXJmYWNlXG4gKi9cbmNsYXNzIFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UgZXh0ZW5kcyBScGNSZXNwb25zZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5SZWdpc3RlckFwcEludGVyZmFjZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTZGxNc2dWZXJzaW9ufSB2ZXJzaW9uIC0gU2VlIFN5bmNNc2dWZXJzaW9uXG4gICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRTZGxNc2dWZXJzaW9uICh2ZXJzaW9uKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFNkbE1zZ1ZlcnNpb24sIHZlcnNpb24pO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9TRExfTVNHX1ZFUlNJT04sIHZlcnNpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTZGxNc2dWZXJzaW9ufVxuICAgICAqL1xuICAgIGdldFNkbE1zZ1ZlcnNpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoU2RsTXNnVmVyc2lvbiwgUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfU0RMX01TR19WRVJTSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0xhbmd1YWdlfSBsYW5ndWFnZSAtIFRoZSBjdXJyZW50bHkgYWN0aXZlIFZSK1RUUyBsYW5ndWFnZSBvbiB0aGUgbW9kdWxlLiBTZWUgXCJMYW5ndWFnZVwiIGZvciBvcHRpb25zLlxuICAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0TGFuZ3VhZ2UgKGxhbmd1YWdlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKExhbmd1YWdlLCBsYW5ndWFnZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX0xBTkdVQUdFLCBsYW5ndWFnZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0xhbmd1YWdlfVxuICAgICAqL1xuICAgIGdldExhbmd1YWdlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KExhbmd1YWdlLCBSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9MQU5HVUFHRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBUaGUgY3VycmVudGx5IGFjdGl2ZSBkaXNwbGF5IGxhbmd1YWdlIG9uIHRoZSBtb2R1bGUuIFNlZSBcIkxhbmd1YWdlXCIgZm9yIG9wdGlvbnMuXG4gICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRIbWlEaXNwbGF5TGFuZ3VhZ2UgKGxhbmd1YWdlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKExhbmd1YWdlLCBsYW5ndWFnZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX0hNSV9ESVNQTEFZX0xBTkdVQUdFLCBsYW5ndWFnZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0xhbmd1YWdlfVxuICAgICAqL1xuICAgIGdldEhtaURpc3BsYXlMYW5ndWFnZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChMYW5ndWFnZSwgUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfSE1JX0RJU1BMQVlfTEFOR1VBR0UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RGlzcGxheUNhcGFiaWxpdGllc30gY2FwYWJpbGl0aWVzIC0gU2VlIERpc3BsYXlDYXBhYmlsaXRpZXMuIFRoaXMgcGFyYW1ldGVyIGlzIGRlcHJlY2F0ZWQgYW5kIHJlcGxhY2VkIGJ5XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW1DYXBhYmlsaXR5IHVzaW5nIERJU1BMQVlTLlxuICAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0RGlzcGxheUNhcGFiaWxpdGllcyAoY2FwYWJpbGl0aWVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKERpc3BsYXlDYXBhYmlsaXRpZXMsIGNhcGFiaWxpdGllcyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX0RJU1BMQVlfQ0FQQUJJTElUSUVTLCBjYXBhYmlsaXRpZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtEaXNwbGF5Q2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIGdldERpc3BsYXlDYXBhYmlsaXRpZXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoRGlzcGxheUNhcGFiaWxpdGllcywgUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfRElTUExBWV9DQVBBQklMSVRJRVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7QnV0dG9uQ2FwYWJpbGl0aWVzW119IGNhcGFiaWxpdGllcyAtIFNlZSBCdXR0b25DYXBhYmlsaXRpZXMuIFRoaXMgcGFyYW1ldGVyIGlzIGRlcHJlY2F0ZWQgYW5kIHJlcGxhY2VkIGJ5XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtQ2FwYWJpbGl0eSB1c2luZyBESVNQTEFZUy5cbiAgICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldEJ1dHRvbkNhcGFiaWxpdGllcyAoY2FwYWJpbGl0aWVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEJ1dHRvbkNhcGFiaWxpdGllcywgY2FwYWJpbGl0aWVzLCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfQlVUVE9OX0NBUEFCSUxJVElFUywgY2FwYWJpbGl0aWVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7QnV0dG9uQ2FwYWJpbGl0aWVzW119XG4gICAgICovXG4gICAgZ2V0QnV0dG9uQ2FwYWJpbGl0aWVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEJ1dHRvbkNhcGFiaWxpdGllcywgUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfQlVUVE9OX0NBUEFCSUxJVElFUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzW119IGNhcGFiaWxpdGllcyAtIElmIHJldHVybmVkLCB0aGUgcGxhdGZvcm0gc3VwcG9ydHMgb24tc2NyZWVuIFNvZnRCdXR0b25zOyBzZWVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU29mdEJ1dHRvbkNhcGFiaWxpdGllcy4gVGhpcyBwYXJhbWV0ZXIgaXMgZGVwcmVjYXRlZCBhbmRcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZWQgYnkgU3lzdGVtQ2FwYWJpbGl0eSB1c2luZyBESVNQTEFZUy5cbiAgICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldFNvZnRCdXR0b25DYXBhYmlsaXRpZXMgKGNhcGFiaWxpdGllcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShTb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzLCBjYXBhYmlsaXRpZXMsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9TT0ZUX0JVVFRPTl9DQVBBQklMSVRJRVMsIGNhcGFiaWxpdGllcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1NvZnRCdXR0b25DYXBhYmlsaXRpZXNbXX1cbiAgICAgKi9cbiAgICBnZXRTb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFNvZnRCdXR0b25DYXBhYmlsaXRpZXMsIFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1NPRlRfQlVUVE9OX0NBUEFCSUxJVElFUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtQcmVzZXRCYW5rQ2FwYWJpbGl0aWVzfSBjYXBhYmlsaXRpZXMgLSBJZiByZXR1cm5lZCwgdGhlIHBsYXRmb3JtIHN1cHBvcnRzIGN1c3RvbSBvbi1zY3JlZW4gUHJlc2V0czsgc2VlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmVzZXRCYW5rQ2FwYWJpbGl0aWVzLiBUaGlzIHBhcmFtZXRlciBpcyBkZXByZWNhdGVkIGFuZCByZXBsYWNlZFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnkgU3lzdGVtQ2FwYWJpbGl0eSB1c2luZyBESVNQTEFZUy5cbiAgICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldFByZXNldEJhbmtDYXBhYmlsaXRpZXMgKGNhcGFiaWxpdGllcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShQcmVzZXRCYW5rQ2FwYWJpbGl0aWVzLCBjYXBhYmlsaXRpZXMpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9QUkVTRVRfQkFOS19DQVBBQklMSVRJRVMsIGNhcGFiaWxpdGllcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ByZXNldEJhbmtDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgZ2V0UHJlc2V0QmFua0NhcGFiaWxpdGllcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChQcmVzZXRCYW5rQ2FwYWJpbGl0aWVzLCBSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9QUkVTRVRfQkFOS19DQVBBQklMSVRJRVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7SG1pWm9uZUNhcGFiaWxpdGllc1tdfSBjYXBhYmlsaXRpZXMgLSBTZWUgSG1pWm9uZUNhcGFiaWxpdGllc1xuICAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0SG1pWm9uZUNhcGFiaWxpdGllcyAoY2FwYWJpbGl0aWVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEhtaVpvbmVDYXBhYmlsaXRpZXMsIGNhcGFiaWxpdGllcywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX0hNSV9aT05FX0NBUEFCSUxJVElFUywgY2FwYWJpbGl0aWVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7SG1pWm9uZUNhcGFiaWxpdGllc1tdfVxuICAgICAqL1xuICAgIGdldEhtaVpvbmVDYXBhYmlsaXRpZXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoSG1pWm9uZUNhcGFiaWxpdGllcywgUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfSE1JX1pPTkVfQ0FQQUJJTElUSUVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NwZWVjaENhcGFiaWxpdGllc1tdfSBjYXBhYmlsaXRpZXMgLSBTZWUgU3BlZWNoQ2FwYWJpbGl0aWVzXG4gICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRTcGVlY2hDYXBhYmlsaXRpZXMgKGNhcGFiaWxpdGllcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShTcGVlY2hDYXBhYmlsaXRpZXMsIGNhcGFiaWxpdGllcywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1NQRUVDSF9DQVBBQklMSVRJRVMsIGNhcGFiaWxpdGllcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1NwZWVjaENhcGFiaWxpdGllc1tdfVxuICAgICAqL1xuICAgIGdldFNwZWVjaENhcGFiaWxpdGllcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChTcGVlY2hDYXBhYmlsaXRpZXMsIFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1NQRUVDSF9DQVBBQklMSVRJRVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7UHJlcmVjb3JkZWRTcGVlY2hbXX0gc3BlZWNoIC0gU2VlIFByZXJlY29yZGVkU3BlZWNoXG4gICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRQcmVyZWNvcmRlZFNwZWVjaCAoc3BlZWNoKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFByZXJlY29yZGVkU3BlZWNoLCBzcGVlY2gsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9QUkVSRUNPUkRFRF9TUEVFQ0gsIHNwZWVjaCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ByZXJlY29yZGVkU3BlZWNoW119XG4gICAgICovXG4gICAgZ2V0UHJlcmVjb3JkZWRTcGVlY2ggKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoUHJlcmVjb3JkZWRTcGVlY2gsIFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1BSRVJFQ09SREVEX1NQRUVDSCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWckNhcGFiaWxpdGllc1tdfSBjYXBhYmlsaXRpZXMgLSBTZWUgVnJDYXBhYmlsaXRpZXNcbiAgICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldFZyQ2FwYWJpbGl0aWVzIChjYXBhYmlsaXRpZXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVnJDYXBhYmlsaXRpZXMsIGNhcGFiaWxpdGllcywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1ZSX0NBUEFCSUxJVElFUywgY2FwYWJpbGl0aWVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VnJDYXBhYmlsaXRpZXNbXX1cbiAgICAgKi9cbiAgICBnZXRWckNhcGFiaWxpdGllcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWckNhcGFiaWxpdGllcywgUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfVlJfQ0FQQUJJTElUSUVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0F1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXNbXX0gY2FwYWJpbGl0aWVzIC0gU2VlIEF1ZGlvUGFzc1RocnVDYXBhYmlsaXR5XG4gICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRBdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzIChjYXBhYmlsaXRpZXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQXVkaW9QYXNzVGhydUNhcGFiaWxpdGllcywgY2FwYWJpbGl0aWVzLCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfQVVESU9fUEFTU19USFJVX0NBUEFCSUxJVElFUywgY2FwYWJpbGl0aWVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7QXVkaW9QYXNzVGhydUNhcGFiaWxpdGllc1tdfVxuICAgICAqL1xuICAgIGdldEF1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQXVkaW9QYXNzVGhydUNhcGFiaWxpdGllcywgUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfQVVESU9fUEFTU19USFJVX0NBUEFCSUxJVElFUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtBdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzfSBjYXBhYmlsaXRpZXMgLSBTZWUgQXVkaW9QYXNzVGhydUNhcGFiaWxpdHlcbiAgICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldFBjbVN0cmVhbUNhcGFiaWxpdGllcyAoY2FwYWJpbGl0aWVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEF1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXMsIGNhcGFiaWxpdGllcyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1BDTV9TVFJFQU1fQ0FQQUJJTElUSUVTLCBjYXBhYmlsaXRpZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtBdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIGdldFBjbVN0cmVhbUNhcGFiaWxpdGllcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChBdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzLCBSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9QQ01fU1RSRUFNX0NBUEFCSUxJVElFUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlVHlwZX0gdHlwZSAtIFNwZWNpZmllcyB0aGUgdmVoaWNsZSdzIHR5cGUuIFNlZSBWZWhpY2xlVHlwZS5cbiAgICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldFZlaGljbGVUeXBlICh0eXBlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVUeXBlLCB0eXBlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfVkVISUNMRV9UWVBFLCB0eXBlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZVR5cGV9XG4gICAgICovXG4gICAgZ2V0VmVoaWNsZVR5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZVR5cGUsIFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1ZFSElDTEVfVFlQRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJbXX0gbW9kZXMgLSBTcGVjaWZpZXMgdGhlIHdoaXRlLWxpc3Qgb2Ygc3VwcG9ydGVkIGRpYWdub3N0aWMgbW9kZXMgKDB4MDAtMHhGRikgY2FwYWJsZSBmb3JcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIERpYWdub3N0aWNNZXNzYWdlIHJlcXVlc3RzLiBJZiBhIG1vZGUgb3V0c2lkZSB0aGlzIGxpc3QgaXMgcmVxdWVzdGVkLCBpdCB3aWxsIGJlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3RlZC5cbiAgICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldFN1cHBvcnRlZERpYWdNb2RlcyAobW9kZXMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfU1VQUE9SVEVEX0RJQUdfTU9ERVMsIG1vZGVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyW119XG4gICAgICovXG4gICAgZ2V0U3VwcG9ydGVkRGlhZ01vZGVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1NVUFBPUlRFRF9ESUFHX01PREVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0hNSUNhcGFiaWxpdGllc30gY2FwYWJpbGl0aWVzIC0gU3BlY2lmaWVzIHRoZSBITUkncyBjYXBhYmlsaXRpZXMuIFNlZSBITUlDYXBhYmlsaXRpZXMuXG4gICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRIbWlDYXBhYmlsaXRpZXMgKGNhcGFiaWxpdGllcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShITUlDYXBhYmlsaXRpZXMsIGNhcGFiaWxpdGllcyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX0hNSV9DQVBBQklMSVRJRVMsIGNhcGFiaWxpdGllcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0hNSUNhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBnZXRIbWlDYXBhYmlsaXRpZXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoSE1JQ2FwYWJpbGl0aWVzLCBSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9ITUlfQ0FQQUJJTElUSUVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdmVyc2lvbiAtIFRoZSBTbWFydERldmljZUxpbmsgdmVyc2lvbi5cbiAgICAgKiBAcmV0dXJuIHtSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldFNkbFZlcnNpb24gKHZlcnNpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfU0RMX1ZFUlNJT04sIHZlcnNpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0U2RsVmVyc2lvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9TRExfVkVSU0lPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHZlcnNpb24gLSBUaGUgc29mdHdhcmUgdmVyc2lvbiBvZiB0aGUgc3lzdGVtIHRoYXQgaW1wbGVtZW50cyB0aGUgU21hcnREZXZpY2VMaW5rIGNvcmUuXG4gICAgICogQHJldHVybiB7UmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRTeXN0ZW1Tb2Z0d2FyZVZlcnNpb24gKHZlcnNpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfU1lTVEVNX1NPRlRXQVJFX1ZFUlNJT04sIHZlcnNpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0U3lzdGVtU29mdHdhcmVWZXJzaW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1NZU1RFTV9TT0ZUV0FSRV9WRVJTSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHJlc3VtZWQgLSBFeGlzdGVuY2Ugb2YgYXBwcyBpY29uIGF0IHN5c3RlbS4gSWYgdHJ1ZSwgYXBwcyBpY29uIHdhcyByZXN1bWVkIGF0IHN5c3RlbS4gSWYgZmFsc2UsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwcyBpY29uIGlzIG5vdCByZXN1bWVkIGF0IHN5c3RlbVxuICAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0SWNvblJlc3VtZWQgKHJlc3VtZWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfSUNPTl9SRVNVTUVELCByZXN1bWVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRJY29uUmVzdW1lZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9JQ09OX1JFU1VNRUQpO1xuICAgIH1cbn1cblxuUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfU0RMX01TR19WRVJTSU9OID0gJ3N5bmNNc2dWZXJzaW9uJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX0xBTkdVQUdFID0gJ2xhbmd1YWdlJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX0hNSV9ESVNQTEFZX0xBTkdVQUdFID0gJ2htaURpc3BsYXlMYW5ndWFnZSc7XG5SZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9ESVNQTEFZX0NBUEFCSUxJVElFUyA9ICdkaXNwbGF5Q2FwYWJpbGl0aWVzJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX0JVVFRPTl9DQVBBQklMSVRJRVMgPSAnYnV0dG9uQ2FwYWJpbGl0aWVzJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1NPRlRfQlVUVE9OX0NBUEFCSUxJVElFUyA9ICdzb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1BSRVNFVF9CQU5LX0NBUEFCSUxJVElFUyA9ICdwcmVzZXRCYW5rQ2FwYWJpbGl0aWVzJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX0hNSV9aT05FX0NBUEFCSUxJVElFUyA9ICdobWlab25lQ2FwYWJpbGl0aWVzJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1NQRUVDSF9DQVBBQklMSVRJRVMgPSAnc3BlZWNoQ2FwYWJpbGl0aWVzJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1BSRVJFQ09SREVEX1NQRUVDSCA9ICdwcmVyZWNvcmRlZFNwZWVjaCc7XG5SZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9WUl9DQVBBQklMSVRJRVMgPSAndnJDYXBhYmlsaXRpZXMnO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfQVVESU9fUEFTU19USFJVX0NBUEFCSUxJVElFUyA9ICdhdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1BDTV9TVFJFQU1fQ0FQQUJJTElUSUVTID0gJ3BjbVN0cmVhbUNhcGFiaWxpdGllcyc7XG5SZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLktFWV9WRUhJQ0xFX1RZUEUgPSAndmVoaWNsZVR5cGUnO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfU1VQUE9SVEVEX0RJQUdfTU9ERVMgPSAnc3VwcG9ydGVkRGlhZ01vZGVzJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX0hNSV9DQVBBQklMSVRJRVMgPSAnaG1pQ2FwYWJpbGl0aWVzJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX1NETF9WRVJTSU9OID0gJ3NkbFZlcnNpb24nO1xuUmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5LRVlfU1lTVEVNX1NPRlRXQVJFX1ZFUlNJT04gPSAnc3lzdGVtU29mdHdhcmVWZXJzaW9uJztcblJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuS0VZX0lDT05fUkVTVU1FRCA9ICdpY29uUmVzdW1lZCc7XG5cbmV4cG9ydCB7IFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5cbi8qKlxuICogQ2xvc2VzIGFuIGludGVyZmFjZSBmcm9tIGEgbW9iaWxlIGFwcGxpY2F0aW9uLiBBZnRlciB1bnJlZ2lzdGVyQXBwSW50ZXJmYWNlLCBubyBjb21tYW5kcyBvdGhlciB0aGFuXG4gKiByZWdpc3RlckFwcEludGVyZmFjZSB3aWxsIGJlIGFjY2VwdGVkL2V4ZWN1dGVkLiBXaWxsIGZhaWwsIGlmIG5vIHJlZ2lzdGVyQXBwSW50ZXJmYWNlIHdhcyBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5XG4gKiBiZWZvcmUuXG4gKi9cbmNsYXNzIFVucmVnaXN0ZXJBcHBJbnRlcmZhY2UgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlVucmVnaXN0ZXJBcHBJbnRlcmZhY2UpO1xuICAgIH1cbn1cblxuXG5leHBvcnQgeyBVbnJlZ2lzdGVyQXBwSW50ZXJmYWNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbmNsYXNzIFVucmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlVucmVnaXN0ZXJBcHBJbnRlcmZhY2UpO1xuICAgIH1cbn1cblxuXG5leHBvcnQgeyBVbnJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gV2luZG93VHlwZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgV2luZG93VHlwZSBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIHdpbmRvdyB0eXBlIGRlc2NyaWJlcyB0aGUgbWFpbiB3aW5kb3cgb24gYSBkaXNwbGF5LlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE1BSU4gKCkge1xuICAgICAgICByZXR1cm4gV2luZG93VHlwZS5fTUFQLk1BSU47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSB3aWRnZXQgaXMgYSBzbWFsbCB3aW5kb3cgdGhhdCB0aGUgYXBwIGNhbiBjcmVhdGUgdG8gcHJvdmlkZSBpbmZvcm1hdGlvbiBhbmQgc29mdCBidXR0b25zIGZvciBxdWljayBhcHBcbiAgICAgKiBjb250cm9sLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFdJREdFVCAoKSB7XG4gICAgICAgIHJldHVybiBXaW5kb3dUeXBlLl9NQVAuV0lER0VUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFdpbmRvd1R5cGUuX3ZhbHVlRm9yS2V5KGtleSwgV2luZG93VHlwZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFdpbmRvd1R5cGUuX2tleUZvclZhbHVlKHZhbHVlLCBXaW5kb3dUeXBlLl9NQVApO1xuICAgIH1cbn1cblxuV2luZG93VHlwZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ01BSU4nOiAnTUFJTicsXG4gICAgJ1dJREdFVCc6ICdXSURHRVQnLFxufSk7XG5cbmV4cG9ydCB7IFdpbmRvd1R5cGUgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBXaW5kb3dUeXBlIH0gZnJvbSAnLi4vZW51bXMvV2luZG93VHlwZS5qcyc7XG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5cbi8qKlxuICogQ3JlYXRlIGEgbmV3IHdpbmRvdyBvbiB0aGUgZGlzcGxheSB3aXRoIHRoZSBzcGVjaWZpZWQgd2luZG93IHR5cGUuXG4gKi9cbmNsYXNzIENyZWF0ZVdpbmRvdyBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuQ3JlYXRlV2luZG93KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaWQgLSBBIHVuaXF1ZSBJRCB0byBpZGVudGlmeSB0aGUgd2luZG93LiBUaGUgdmFsdWUgb2YgJzAnIHdpbGwgYWx3YXlzIGJlIHRoZSBkZWZhdWx0IG1haW4gd2luZG93XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgb24gdGhlIG1haW4gZGlzcGxheSBhbmQgc2hvdWxkIG5vdCBiZSB1c2VkIGluIHRoaXMgY29udGV4dCBhcyBpdCB3aWxsIGFscmVhZHkgYmUgY3JlYXRlZCBmb3JcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICB0aGUgYXBwLiBTZWUgUHJlZGVmaW5lZFdpbmRvd3MgZW51bS4gQ3JlYXRpbmcgYSB3aW5kb3cgd2l0aCBhbiBJRCB0aGF0IGlzIGFscmVhZHkgaW4gdXNlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgd2lsbCBiZSByZWplY3RlZCB3aXRoIGBJTlZBTElEX0lEYC5cbiAgICAgKiBAcmV0dXJuIHtDcmVhdGVXaW5kb3d9XG4gICAgICovXG4gICAgc2V0V2luZG93SUQgKGlkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENyZWF0ZVdpbmRvdy5LRVlfV0lORE9XX0lELCBpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRXaW5kb3dJRCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihDcmVhdGVXaW5kb3cuS0VZX1dJTkRPV19JRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBUaGUgd2luZG93IG5hbWUgdG8gYmUgdXNlZCBieSB0aGUgSE1JLiBUaGUgbmFtZSBvZiB0aGUgcHJlLWNyZWF0ZWQgZGVmYXVsdCB3aW5kb3cgd2lsbFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2ggdGhlIGFwcCBuYW1lLiBNdWx0aXBsZSBhcHBzIGNhbiBzaGFyZSB0aGUgc2FtZSB3aW5kb3cgbmFtZSBleGNlcHQgZm9yIHRoZSBkZWZhdWx0XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICBtYWluIHdpbmRvdy4gQ3JlYXRpbmcgYSB3aW5kb3cgd2l0aCBhIG5hbWUgd2hpY2ggaXMgYWxyZWFkeSBpbiB1c2UgYnkgdGhlIGFwcCB3aWxsIHJlc3VsdFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgaW4gYERVUExJQ0FURV9OQU1FYC5cbiAgICAgKiBAcmV0dXJuIHtDcmVhdGVXaW5kb3d9XG4gICAgICovXG4gICAgc2V0V2luZG93TmFtZSAobmFtZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihDcmVhdGVXaW5kb3cuS0VZX1dJTkRPV19OQU1FLCBuYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldFdpbmRvd05hbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQ3JlYXRlV2luZG93LktFWV9XSU5ET1dfTkFNRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtXaW5kb3dUeXBlfSB0eXBlIC0gVGhlIHR5cGUgb2YgdGhlIHdpbmRvdyB0byBiZSBjcmVhdGVkLiBNYWluIHdpbmRvdyBvciB3aWRnZXQuXG4gICAgICogQHJldHVybiB7Q3JlYXRlV2luZG93fVxuICAgICAqL1xuICAgIHNldFR5cGUgKHR5cGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoV2luZG93VHlwZSwgdHlwZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENyZWF0ZVdpbmRvdy5LRVlfVFlQRSwgdHlwZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1dpbmRvd1R5cGV9XG4gICAgICovXG4gICAgZ2V0VHlwZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChXaW5kb3dUeXBlLCBDcmVhdGVXaW5kb3cuS0VZX1RZUEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIC0gQWxsb3dzIGFuIGFwcCB0byBjcmVhdGUgYSB3aWRnZXQgcmVsYXRlZCB0byBhIHNwZWNpZmljIHNlcnZpY2UgdHlwZS4gQXMgYW4gZXhhbXBsZSBpZiBhXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICBgTUVESUFgIGFwcCBiZWNvbWVzIGFjdGl2ZSwgdGhpcyBhcHAgYmVjb21lcyBhdWRpYmxlIGFuZCBpcyBhbGxvd2VkIHRvIHBsYXkgYXVkaW8uIEFjdGlvbnNcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2ggYXMgc2tpcCBvciBwbGF5L3BhdXNlIHdpbGwgYmUgZGlyZWN0ZWQgdG8gdGhpcyBhY3RpdmUgbWVkaWEgYXBwLiBJbiBjYXNlIG9mIHdpZGdldHMsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICB0aGUgc3lzdGVtIGNhbiBwcm92aWRlIGEgc2luZ2xlIFwibWVkaWFcIiB3aWRnZXQgd2hpY2ggd2lsbCBhY3QgYXMgYSBwbGFjZWhvbGRlciBmb3IgdGhlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICBhY3RpdmUgbWVkaWEgYXBwLiBJdCBpcyBvbmx5IGFsbG93ZWQgdG8gaGF2ZSBvbmUgd2luZG93IHBlciBzZXJ2aWNlIHR5cGUuIFRoaXMgbWVhbnMgdGhhdFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgYSBtZWRpYSBhcHAgY2FuIG9ubHkgaGF2ZSBhIHNpbmdsZSBNRURJQSB3aWRnZXQuIFN0aWxsIHRoZSBhcHAgY2FuIGNyZWF0ZSB3aWRnZXRzIG9taXR0aW5nXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICB0aGlzIHBhcmFtZXRlci4gVGhvc2Ugd2lkZ2V0cyB3b3VsZCBiZSBhdmFpbGFibGUgYXMgYXBwIHNwZWNpZmljIHdpZGdldHMgdGhhdCBhcmVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHBlcm1hbmVudGx5IGluY2x1ZGVkIGluIHRoZSBITUkuIFRoaXMgcGFyYW1ldGVyIGlzIHJlbGF0ZWQgdG8gd2lkZ2V0cyBvbmx5LiBUaGUgZGVmYXVsdFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgbWFpbiB3aW5kb3csIHdoaWNoIGlzIHByZS1jcmVhdGVkIGR1cmluZyBhcHAgcmVnaXN0cmF0aW9uLCB3aWxsIGJlIGNyZWF0ZWQgYmFzZWQgb24gdGhlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICBITUkgdHlwZXMgc3BlY2lmaWVkIGluIHRoZSBhcHAgcmVnaXN0cmF0aW9uIHJlcXVlc3QuXG4gICAgICogQHJldHVybiB7Q3JlYXRlV2luZG93fVxuICAgICAqL1xuICAgIHNldEFzc29jaWF0ZWRTZXJ2aWNlVHlwZSAodHlwZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihDcmVhdGVXaW5kb3cuS0VZX0FTU09DSUFURURfU0VSVklDRV9UWVBFLCB0eXBlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldEFzc29jaWF0ZWRTZXJ2aWNlVHlwZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihDcmVhdGVXaW5kb3cuS0VZX0FTU09DSUFURURfU0VSVklDRV9UWVBFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaWQgLSBPcHRpb25hbCBwYXJhbWV0ZXIuIFNwZWNpZnkgd2hldGhlciB0aGUgY29udGVudCBzZW50IHRvIGFuIGV4aXN0aW5nIHdpbmRvdyBzaG91bGQgYmVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBkdXBsaWNhdGVkIHRvIHRoZSBjcmVhdGVkIHdpbmRvdy4gSWYgdGhlcmUgaXNuJ3QgYSB3aW5kb3cgd2l0aCB0aGUgSUQsIHRoZSByZXF1ZXN0IHdpbGwgYmVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICByZWplY3RlZCB3aXRoIGBJTlZBTElEX0RBVEFgLlxuICAgICAqIEByZXR1cm4ge0NyZWF0ZVdpbmRvd31cbiAgICAgKi9cbiAgICBzZXREdXBsaWNhdGVVcGRhdGVzRnJvbVdpbmRvd0lEIChpZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihDcmVhdGVXaW5kb3cuS0VZX0RVUExJQ0FURV9VUERBVEVTX0ZST01fV0lORE9XX0lELCBpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXREdXBsaWNhdGVVcGRhdGVzRnJvbVdpbmRvd0lEICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKENyZWF0ZVdpbmRvdy5LRVlfRFVQTElDQVRFX1VQREFURVNfRlJPTV9XSU5ET1dfSUQpO1xuICAgIH1cbn1cblxuQ3JlYXRlV2luZG93LktFWV9XSU5ET1dfSUQgPSAnd2luZG93SUQnO1xuQ3JlYXRlV2luZG93LktFWV9XSU5ET1dfTkFNRSA9ICd3aW5kb3dOYW1lJztcbkNyZWF0ZVdpbmRvdy5LRVlfVFlQRSA9ICd0eXBlJztcbkNyZWF0ZVdpbmRvdy5LRVlfQVNTT0NJQVRFRF9TRVJWSUNFX1RZUEUgPSAnYXNzb2NpYXRlZFNlcnZpY2VUeXBlJztcbkNyZWF0ZVdpbmRvdy5LRVlfRFVQTElDQVRFX1VQREFURVNfRlJPTV9XSU5ET1dfSUQgPSAnZHVwbGljYXRlVXBkYXRlc0Zyb21XaW5kb3dJRCc7XG5cbmV4cG9ydCB7IENyZWF0ZVdpbmRvdyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG5jbGFzcyBDcmVhdGVXaW5kb3dSZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkNyZWF0ZVdpbmRvdyk7XG4gICAgfVxufVxuXG5cbmV4cG9ydCB7IENyZWF0ZVdpbmRvd1Jlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG4vKipcbiAqIERlbGV0ZXMgcHJldmlvdXNseSBjcmVhdGVkIHdpbmRvdyBvZiB0aGUgU0RMIGFwcGxpY2F0aW9uLlxuICovXG5jbGFzcyBEZWxldGVXaW5kb3cgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkRlbGV0ZVdpbmRvdyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGlkIC0gQSB1bmlxdWUgSUQgdG8gaWRlbnRpZnkgdGhlIHdpbmRvdy4gVGhlIHZhbHVlIG9mICcwJyB3aWxsIGFsd2F5cyBiZSB0aGUgZGVmYXVsdCBtYWluIHdpbmRvd1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgIG9uIHRoZSBtYWluIGRpc3BsYXkgYW5kIGNhbm5vdCBiZSBkZWxldGVkLiBTZWUgUHJlZGVmaW5lZFdpbmRvd3MgZW51bS5cbiAgICAgKiBAcmV0dXJuIHtEZWxldGVXaW5kb3d9XG4gICAgICovXG4gICAgc2V0V2luZG93SUQgKGlkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKERlbGV0ZVdpbmRvdy5LRVlfV0lORE9XX0lELCBpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRXaW5kb3dJRCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihEZWxldGVXaW5kb3cuS0VZX1dJTkRPV19JRCk7XG4gICAgfVxufVxuXG5EZWxldGVXaW5kb3cuS0VZX1dJTkRPV19JRCA9ICd3aW5kb3dJRCc7XG5cbmV4cG9ydCB7IERlbGV0ZVdpbmRvdyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG5jbGFzcyBEZWxldGVXaW5kb3dSZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkRlbGV0ZVdpbmRvdyk7XG4gICAgfVxufVxuXG5cbmV4cG9ydCB7IERlbGV0ZVdpbmRvd1Jlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogQ29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHR5cGUgb2YgaW1hZ2UuXG4gKiBAdHlwZWRlZiB7RW51bX0gSW1hZ2VUeXBlXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBJbWFnZVR5cGUgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU1RBVElDICgpIHtcbiAgICAgICAgcmV0dXJuIEltYWdlVHlwZS5fTUFQLlNUQVRJQztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBEWU5BTUlDICgpIHtcbiAgICAgICAgcmV0dXJuIEltYWdlVHlwZS5fTUFQLkRZTkFNSUM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gSW1hZ2VUeXBlLl92YWx1ZUZvcktleShrZXksIEltYWdlVHlwZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIEltYWdlVHlwZS5fa2V5Rm9yVmFsdWUodmFsdWUsIEltYWdlVHlwZS5fTUFQKTtcbiAgICB9XG59XG5cbkltYWdlVHlwZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1NUQVRJQyc6ICdTVEFUSUMnLFxuICAgICdEWU5BTUlDJzogJ0RZTkFNSUMnLFxufSk7XG5cbmV4cG9ydCB7IEltYWdlVHlwZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBJbWFnZVR5cGUgfSBmcm9tICcuLi9lbnVtcy9JbWFnZVR5cGUuanMnO1xuXG5jbGFzcyBJbWFnZSBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlIC0gRWl0aGVyIHRoZSBzdGF0aWMgaGV4IGljb24gdmFsdWUgb3IgdGhlIGJpbmFyeSBpbWFnZSBmaWxlIG5hbWUgaWRlbnRpZmllciAoc2VudCBieVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIFB1dEZpbGUpLlxuICAgICAqIEByZXR1cm4ge0ltYWdlfVxuICAgICAqL1xuICAgIHNldFZhbHVlICh2YWx1ZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihJbWFnZS5LRVlfVkFMVUUsIHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldFZhbHVlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEltYWdlLktFWV9WQUxVRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtJbWFnZVR5cGV9IHR5cGUgLSBEZXNjcmliZXMsIHdoZXRoZXIgaXQgaXMgYSBzdGF0aWMgb3IgZHluYW1pYyBpbWFnZS5cbiAgICAgKiBAcmV0dXJuIHtJbWFnZX1cbiAgICAgKi9cbiAgICBzZXRJbWFnZVR5cGUgKHR5cGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoSW1hZ2VUeXBlLCB0eXBlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoSW1hZ2UuS0VZX0lNQUdFX1RZUEUsIHR5cGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtJbWFnZVR5cGV9XG4gICAgICovXG4gICAgZ2V0SW1hZ2VUeXBlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEltYWdlVHlwZSwgSW1hZ2UuS0VZX0lNQUdFX1RZUEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gdGVtcGxhdGUgLSBJZiB0cnVlLCB0aGUgaW1hZ2UgaXMgYSB0ZW1wbGF0ZSBpbWFnZSBhbmQgY2FuIGJlIHJlY29sb3JlZCBieSB0aGUgSE1JXG4gICAgICogQHJldHVybiB7SW1hZ2V9XG4gICAgICovXG4gICAgc2V0SXNUZW1wbGF0ZSAodGVtcGxhdGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoSW1hZ2UuS0VZX0lTX1RFTVBMQVRFLCB0ZW1wbGF0ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0SXNUZW1wbGF0ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihJbWFnZS5LRVlfSVNfVEVNUExBVEUpO1xuICAgIH1cbn1cblxuSW1hZ2UuS0VZX1ZBTFVFID0gJ3ZhbHVlJztcbkltYWdlLktFWV9JTUFHRV9UWVBFID0gJ2ltYWdlVHlwZSc7XG5JbWFnZS5LRVlfSVNfVEVNUExBVEUgPSAnaXNUZW1wbGF0ZSc7XG5cbmV4cG9ydCB7IEltYWdlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IEltYWdlIH0gZnJvbSAnLi9JbWFnZS5qcyc7XG5cbmNsYXNzIFZySGVscEl0ZW0gZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0IC0gVGV4dCB0byBkaXNwbGF5IGZvciBWUiBIZWxwIGl0ZW1cbiAgICAgKiBAcmV0dXJuIHtWckhlbHBJdGVtfVxuICAgICAqL1xuICAgIHNldFRleHQgKHRleHQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVnJIZWxwSXRlbS5LRVlfVEVYVCwgdGV4dCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRUZXh0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFZySGVscEl0ZW0uS0VZX1RFWFQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7SW1hZ2V9IGltYWdlIC0gSW1hZ2Ugc3RydWN0IGZvciBWUiBIZWxwIGl0ZW1cbiAgICAgKiBAcmV0dXJuIHtWckhlbHBJdGVtfVxuICAgICAqL1xuICAgIHNldEltYWdlIChpbWFnZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShJbWFnZSwgaW1hZ2UpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihWckhlbHBJdGVtLktFWV9JTUFHRSwgaW1hZ2UpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtJbWFnZX1cbiAgICAgKi9cbiAgICBnZXRJbWFnZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChJbWFnZSwgVnJIZWxwSXRlbS5LRVlfSU1BR0UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBwb3NpdGlvbiAtIFBvc2l0aW9uIHRvIGRpc3BsYXkgaXRlbSBpbiBWUiBIZWxwIGxpc3RcbiAgICAgKiBAcmV0dXJuIHtWckhlbHBJdGVtfVxuICAgICAqL1xuICAgIHNldFBvc2l0aW9uIChwb3NpdGlvbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihWckhlbHBJdGVtLktFWV9QT1NJVElPTiwgcG9zaXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0UG9zaXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoVnJIZWxwSXRlbS5LRVlfUE9TSVRJT04pO1xuICAgIH1cbn1cblxuVnJIZWxwSXRlbS5LRVlfVEVYVCA9ICd0ZXh0JztcblZySGVscEl0ZW0uS0VZX0lNQUdFID0gJ2ltYWdlJztcblZySGVscEl0ZW0uS0VZX1BPU0lUSU9OID0gJ3Bvc2l0aW9uJztcblxuZXhwb3J0IHsgVnJIZWxwSXRlbSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBHcmlkIH0gZnJvbSAnLi9HcmlkLmpzJztcblxuLyoqXG4gKiBEZXNjcmliZXMgdGhlIGxvY2F0aW9uIG9mIGEgc2VhdC5cbiAqL1xuY2xhc3MgU2VhdExvY2F0aW9uIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0dyaWR9IGdyaWQgLSBEZXNjcmliZXMgYSBsb2NhdGlvbiAob3JpZ2luIGNvb3JkaW5hdGVzIGFuZCBzcGFuKSBvZiBhIHZlaGljbGUgY29tcG9uZW50LlxuICAgICAqIEByZXR1cm4ge1NlYXRMb2NhdGlvbn1cbiAgICAgKi9cbiAgICBzZXRHcmlkIChncmlkKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEdyaWQsIGdyaWQpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZWF0TG9jYXRpb24uS0VZX0dSSUQsIGdyaWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtHcmlkfVxuICAgICAqL1xuICAgIGdldEdyaWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoR3JpZCwgU2VhdExvY2F0aW9uLktFWV9HUklEKTtcbiAgICB9XG59XG5cblNlYXRMb2NhdGlvbi5LRVlfR1JJRCA9ICdncmlkJztcblxuZXhwb3J0IHsgU2VhdExvY2F0aW9uIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogSG93IHRoZSBtYWluIG1lbnUgb3Igc3VibWVudSBpcyBsYWlkIG91dCBvbiBzY3JlZW5cbiAqIEB0eXBlZGVmIHtFbnVtfSBNZW51TGF5b3V0XG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBNZW51TGF5b3V0IGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IExJU1QgKCkge1xuICAgICAgICByZXR1cm4gTWVudUxheW91dC5fTUFQLkxJU1Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVElMRVMgKCkge1xuICAgICAgICByZXR1cm4gTWVudUxheW91dC5fTUFQLlRJTEVTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIE1lbnVMYXlvdXQuX3ZhbHVlRm9yS2V5KGtleSwgTWVudUxheW91dC5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIE1lbnVMYXlvdXQuX2tleUZvclZhbHVlKHZhbHVlLCBNZW51TGF5b3V0Ll9NQVApO1xuICAgIH1cbn1cblxuTWVudUxheW91dC5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0xJU1QnOiAnTElTVCcsXG4gICAgJ1RJTEVTJzogJ1RJTEVTJyxcbn0pO1xuXG5leHBvcnQgeyBNZW51TGF5b3V0IH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogRW51bWVyYXRpb24gbGlzdGluZyBwb3NzaWJsZSBrZXlib2FyZCBsYXlvdXRzLlxuICogQHR5cGVkZWYge0VudW19IEtleWJvYXJkTGF5b3V0XG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBLZXlib2FyZExheW91dCBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBRV0VSVFkgKCkge1xuICAgICAgICByZXR1cm4gS2V5Ym9hcmRMYXlvdXQuX01BUC5RV0VSVFk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUVdFUlRaICgpIHtcbiAgICAgICAgcmV0dXJuIEtleWJvYXJkTGF5b3V0Ll9NQVAuUVdFUlRaO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFaRVJUWSAoKSB7XG4gICAgICAgIHJldHVybiBLZXlib2FyZExheW91dC5fTUFQLkFaRVJUWTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBLZXlib2FyZExheW91dC5fdmFsdWVGb3JLZXkoa2V5LCBLZXlib2FyZExheW91dC5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIEtleWJvYXJkTGF5b3V0Ll9rZXlGb3JWYWx1ZSh2YWx1ZSwgS2V5Ym9hcmRMYXlvdXQuX01BUCk7XG4gICAgfVxufVxuXG5LZXlib2FyZExheW91dC5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1FXRVJUWSc6ICdRV0VSVFknLFxuICAgICdRV0VSVFonOiAnUVdFUlRaJyxcbiAgICAnQVpFUlRZJzogJ0FaRVJUWScsXG59KTtcblxuZXhwb3J0IHsgS2V5Ym9hcmRMYXlvdXQgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBFbnVtZXJhdGlvbiBsaXN0aW5nIHBvc3NpYmxlIGtleWJvYXJkIGV2ZW50cy5cbiAqIEB0eXBlZGVmIHtFbnVtfSBLZXlwcmVzc01vZGVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIEtleXByZXNzTW9kZSBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFYWNoIGtleXByZXNzIGlzIGluZGl2aWR1YWxseSBzZW50IGFzIHRoZSB1c2VyIHByZXNzZXMgdGhlIGtleWJvYXJkIGtleXMuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0lOR0xFX0tFWVBSRVNTICgpIHtcbiAgICAgICAgcmV0dXJuIEtleXByZXNzTW9kZS5fTUFQLlNJTkdMRV9LRVlQUkVTUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUga2V5cHJlc3NlcyBhcmUgcXVldWVkIGFuZCBhIHN0cmluZyBpcyBldmVudHVhbGx5IHNlbnQgb25jZSB0aGUgdXNlciBjaG9vc2VzIHRvIHN1Ym1pdCB0aGVpciBlbnRyeS5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBRVUVVRV9LRVlQUkVTU0VTICgpIHtcbiAgICAgICAgcmV0dXJuIEtleXByZXNzTW9kZS5fTUFQLlFVRVVFX0tFWVBSRVNTRVM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGtleXByZXNzZXMgYXJlIHF1ZXVlIGFuZCBhIHN0cmluZyBpcyBzZW50IGVhY2ggdGltZSB0aGUgdXNlciBwcmVzc2VzIGEga2V5Ym9hcmQga2V5OyB0aGUgc3RyaW5nIGNvbnRhaW5zXG4gICAgICogdGhlIGVudGlyZSBjdXJyZW50IGVudHJ5LlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJFU0VORF9DVVJSRU5UX0VOVFJZICgpIHtcbiAgICAgICAgcmV0dXJuIEtleXByZXNzTW9kZS5fTUFQLlJFU0VORF9DVVJSRU5UX0VOVFJZO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIEtleXByZXNzTW9kZS5fdmFsdWVGb3JLZXkoa2V5LCBLZXlwcmVzc01vZGUuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBLZXlwcmVzc01vZGUuX2tleUZvclZhbHVlKHZhbHVlLCBLZXlwcmVzc01vZGUuX01BUCk7XG4gICAgfVxufVxuXG5LZXlwcmVzc01vZGUuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdTSU5HTEVfS0VZUFJFU1MnOiAnU0lOR0xFX0tFWVBSRVNTJyxcbiAgICAnUVVFVUVfS0VZUFJFU1NFUyc6ICdRVUVVRV9LRVlQUkVTU0VTJyxcbiAgICAnUkVTRU5EX0NVUlJFTlRfRU5UUlknOiAnUkVTRU5EX0NVUlJFTlRfRU5UUlknLFxufSk7XG5cbmV4cG9ydCB7IEtleXByZXNzTW9kZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBLZXlib2FyZExheW91dCB9IGZyb20gJy4uL2VudW1zL0tleWJvYXJkTGF5b3V0LmpzJztcbmltcG9ydCB7IExhbmd1YWdlIH0gZnJvbSAnLi4vZW51bXMvTGFuZ3VhZ2UuanMnO1xuaW1wb3J0IHsgS2V5cHJlc3NNb2RlIH0gZnJvbSAnLi4vZW51bXMvS2V5cHJlc3NNb2RlLmpzJztcblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIG9mIG9uLXNjcmVlbiBrZXlib2FyZCAoaWYgYXZhaWxhYmxlKS5cbiAqL1xuY2xhc3MgS2V5Ym9hcmRQcm9wZXJ0aWVzIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0xhbmd1YWdlfSBsYW5ndWFnZSAtIFRoZSBrZXlib2FyZCBsYW5ndWFnZS5cbiAgICAgKiBAcmV0dXJuIHtLZXlib2FyZFByb3BlcnRpZXN9XG4gICAgICovXG4gICAgc2V0TGFuZ3VhZ2UgKGxhbmd1YWdlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKExhbmd1YWdlLCBsYW5ndWFnZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEtleWJvYXJkUHJvcGVydGllcy5LRVlfTEFOR1VBR0UsIGxhbmd1YWdlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TGFuZ3VhZ2V9XG4gICAgICovXG4gICAgZ2V0TGFuZ3VhZ2UgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTGFuZ3VhZ2UsIEtleWJvYXJkUHJvcGVydGllcy5LRVlfTEFOR1VBR0UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7S2V5Ym9hcmRMYXlvdXR9IGxheW91dCAtIERlc2lyZWQga2V5Ym9hcmQgbGF5b3V0LlxuICAgICAqIEByZXR1cm4ge0tleWJvYXJkUHJvcGVydGllc31cbiAgICAgKi9cbiAgICBzZXRLZXlib2FyZExheW91dCAobGF5b3V0KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEtleWJvYXJkTGF5b3V0LCBsYXlvdXQpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihLZXlib2FyZFByb3BlcnRpZXMuS0VZX0tFWUJPQVJEX0xBWU9VVCwgbGF5b3V0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7S2V5Ym9hcmRMYXlvdXR9XG4gICAgICovXG4gICAgZ2V0S2V5Ym9hcmRMYXlvdXQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoS2V5Ym9hcmRMYXlvdXQsIEtleWJvYXJkUHJvcGVydGllcy5LRVlfS0VZQk9BUkRfTEFZT1VUKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0tleXByZXNzTW9kZX0gbW9kZSAtIERlc2lyZWQga2V5cHJlc3MgbW9kZS4gSWYgb21pdHRlZCwgdGhpcyB2YWx1ZSB3aWxsIGJlIHNldCB0byBSRVNFTkRfQ1VSUkVOVF9FTlRSWS5cbiAgICAgKiBAcmV0dXJuIHtLZXlib2FyZFByb3BlcnRpZXN9XG4gICAgICovXG4gICAgc2V0S2V5cHJlc3NNb2RlIChtb2RlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEtleXByZXNzTW9kZSwgbW9kZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEtleWJvYXJkUHJvcGVydGllcy5LRVlfS0VZUFJFU1NfTU9ERSwgbW9kZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0tleXByZXNzTW9kZX1cbiAgICAgKi9cbiAgICBnZXRLZXlwcmVzc01vZGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoS2V5cHJlc3NNb2RlLCBLZXlib2FyZFByb3BlcnRpZXMuS0VZX0tFWVBSRVNTX01PREUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nW119IGxpc3QgLSBBcnJheSBvZiBrZXlib2FyZCBjaGFyYWN0ZXJzIHRvIGVuYWJsZS4gQWxsIG9taXR0ZWQgY2hhcmFjdGVycyB3aWxsIGJlIGdyZXllZCBvdXRcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgKGRpc2FibGVkKSBvbiB0aGUga2V5Ym9hcmQuIElmIG9taXR0ZWQsIHRoZSBlbnRpcmUga2V5Ym9hcmQgd2lsbCBiZSBlbmFibGVkLlxuICAgICAqIEByZXR1cm4ge0tleWJvYXJkUHJvcGVydGllc31cbiAgICAgKi9cbiAgICBzZXRMaW1pdGVkQ2hhcmFjdGVyTGlzdCAobGlzdCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihLZXlib2FyZFByb3BlcnRpZXMuS0VZX0xJTUlURURfQ0hBUkFDVEVSX0xJU1QsIGxpc3QpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmdbXX1cbiAgICAgKi9cbiAgICBnZXRMaW1pdGVkQ2hhcmFjdGVyTGlzdCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihLZXlib2FyZFByb3BlcnRpZXMuS0VZX0xJTUlURURfQ0hBUkFDVEVSX0xJU1QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0IC0gRGVwcmVjYXRlZCwgdXNlIGF1dG9Db21wbGV0ZUxpc3QgaW5zdGVhZC5cbiAgICAgKiBAcmV0dXJuIHtLZXlib2FyZFByb3BlcnRpZXN9XG4gICAgICovXG4gICAgc2V0QXV0b0NvbXBsZXRlVGV4dCAodGV4dCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihLZXlib2FyZFByb3BlcnRpZXMuS0VZX0FVVE9fQ09NUExFVEVfVEVYVCwgdGV4dCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRBdXRvQ29tcGxldGVUZXh0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEtleWJvYXJkUHJvcGVydGllcy5LRVlfQVVUT19DT01QTEVURV9URVhUKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ1tdfSBsaXN0IC0gQWxsb3dzIGFuIGFwcCB0byBwcmVwb3B1bGF0ZSB0aGUgdGV4dCBmaWVsZCB3aXRoIGEgbGlzdCBvZiBzdWdnZXN0ZWQgb3IgY29tcGxldGVkXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGVudHJpZXMgYXMgdGhlIHVzZXIgdHlwZXMuIElmIGVtcHR5LCB0aGUgYXV0by1jb21wbGV0ZSBsaXN0IHdpbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JlZW4uXG4gICAgICogQHJldHVybiB7S2V5Ym9hcmRQcm9wZXJ0aWVzfVxuICAgICAqL1xuICAgIHNldEF1dG9Db21wbGV0ZUxpc3QgKGxpc3QpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoS2V5Ym9hcmRQcm9wZXJ0aWVzLktFWV9BVVRPX0NPTVBMRVRFX0xJU1QsIGxpc3QpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmdbXX1cbiAgICAgKi9cbiAgICBnZXRBdXRvQ29tcGxldGVMaXN0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEtleWJvYXJkUHJvcGVydGllcy5LRVlfQVVUT19DT01QTEVURV9MSVNUKTtcbiAgICB9XG59XG5cbktleWJvYXJkUHJvcGVydGllcy5LRVlfTEFOR1VBR0UgPSAnbGFuZ3VhZ2UnO1xuS2V5Ym9hcmRQcm9wZXJ0aWVzLktFWV9LRVlCT0FSRF9MQVlPVVQgPSAna2V5Ym9hcmRMYXlvdXQnO1xuS2V5Ym9hcmRQcm9wZXJ0aWVzLktFWV9LRVlQUkVTU19NT0RFID0gJ2tleXByZXNzTW9kZSc7XG5LZXlib2FyZFByb3BlcnRpZXMuS0VZX0xJTUlURURfQ0hBUkFDVEVSX0xJU1QgPSAnbGltaXRlZENoYXJhY3Rlckxpc3QnO1xuS2V5Ym9hcmRQcm9wZXJ0aWVzLktFWV9BVVRPX0NPTVBMRVRFX1RFWFQgPSAnYXV0b0NvbXBsZXRlVGV4dCc7XG5LZXlib2FyZFByb3BlcnRpZXMuS0VZX0FVVE9fQ09NUExFVEVfTElTVCA9ICdhdXRvQ29tcGxldGVMaXN0JztcblxuZXhwb3J0IHsgS2V5Ym9hcmRQcm9wZXJ0aWVzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgVnJIZWxwSXRlbSB9IGZyb20gJy4uL3N0cnVjdHMvVnJIZWxwSXRlbS5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBTZWF0TG9jYXRpb24gfSBmcm9tICcuLi9zdHJ1Y3RzL1NlYXRMb2NhdGlvbi5qcyc7XG5pbXBvcnQgeyBUVFNDaHVuayB9IGZyb20gJy4uL3N0cnVjdHMvVFRTQ2h1bmsuanMnO1xuaW1wb3J0IHsgTWVudUxheW91dCB9IGZyb20gJy4uL2VudW1zL01lbnVMYXlvdXQuanMnO1xuaW1wb3J0IHsgS2V5Ym9hcmRQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vc3RydWN0cy9LZXlib2FyZFByb3BlcnRpZXMuanMnO1xuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgSW1hZ2UgfSBmcm9tICcuLi9zdHJ1Y3RzL0ltYWdlLmpzJztcblxuLyoqXG4gKiBBbGxvd3Mgc2V0dGluZyBnbG9iYWwgcHJvcGVydGllcy5cbiAqL1xuY2xhc3MgU2V0R2xvYmFsUHJvcGVydGllcyBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuU2V0R2xvYmFsUHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTZWF0TG9jYXRpb259IGxvY2F0aW9uIC0gTG9jYXRpb24gb2YgdGhlIHVzZXIncyBzZWF0LiBEZWZhdWx0IGlzIGRyaXZlcidzIHNlYXQgbG9jYXRpb24gaWYgaXQgaXMgbm90IHNldFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlldC5cbiAgICAgKiBAcmV0dXJuIHtTZXRHbG9iYWxQcm9wZXJ0aWVzfVxuICAgICAqL1xuICAgIHNldFVzZXJMb2NhdGlvbiAobG9jYXRpb24pIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoU2VhdExvY2F0aW9uLCBsb2NhdGlvbik7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNldEdsb2JhbFByb3BlcnRpZXMuS0VZX1VTRVJfTE9DQVRJT04sIGxvY2F0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U2VhdExvY2F0aW9ufVxuICAgICAqL1xuICAgIGdldFVzZXJMb2NhdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChTZWF0TG9jYXRpb24sIFNldEdsb2JhbFByb3BlcnRpZXMuS0VZX1VTRVJfTE9DQVRJT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VFRTQ2h1bmtbXX0gcHJvbXB0IC0gVGhlIGhlbHAgcHJvbXB0LiBBbiBhcnJheSBvZiB0ZXh0IGNodW5rcyBvZiB0eXBlIFRUU0NodW5rLiBTZWUgVFRTQ2h1bmsuIFRoZSBhcnJheVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXVzdCBoYXZlIGF0IGxlYXN0IG9uZSBpdGVtLlxuICAgICAqIEByZXR1cm4ge1NldEdsb2JhbFByb3BlcnRpZXN9XG4gICAgICovXG4gICAgc2V0SGVscFByb21wdCAocHJvbXB0KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFRUU0NodW5rLCBwcm9tcHQsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZXRHbG9iYWxQcm9wZXJ0aWVzLktFWV9IRUxQX1BST01QVCwgcHJvbXB0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VFRTQ2h1bmtbXX1cbiAgICAgKi9cbiAgICBnZXRIZWxwUHJvbXB0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFRUU0NodW5rLCBTZXRHbG9iYWxQcm9wZXJ0aWVzLktFWV9IRUxQX1BST01QVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtUVFNDaHVua1tdfSBwcm9tcHQgLSBIZWxwIHRleHQgZm9yIGEgd2FpdCB0aW1lb3V0LiBBbiBhcnJheSBvZiB0ZXh0IGNodW5rcyBvZiB0eXBlIFRUU0NodW5rLiBTZWVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRUU0NodW5rLiBUaGUgYXJyYXkgbXVzdCBoYXZlIGF0IGxlYXN0IG9uZSBpdGVtLlxuICAgICAqIEByZXR1cm4ge1NldEdsb2JhbFByb3BlcnRpZXN9XG4gICAgICovXG4gICAgc2V0VGltZW91dFByb21wdCAocHJvbXB0KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFRUU0NodW5rLCBwcm9tcHQsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZXRHbG9iYWxQcm9wZXJ0aWVzLktFWV9USU1FT1VUX1BST01QVCwgcHJvbXB0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VFRTQ2h1bmtbXX1cbiAgICAgKi9cbiAgICBnZXRUaW1lb3V0UHJvbXB0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFRUU0NodW5rLCBTZXRHbG9iYWxQcm9wZXJ0aWVzLktFWV9USU1FT1VUX1BST01QVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHRpdGxlIC0gVlIgSGVscCBUaXRsZSB0ZXh0LiBJZiBvbWl0dGVkIG9uIHN1cHBvcnRlZCBkaXNwbGF5cywgdGhlIGRlZmF1bHQgbW9kdWxlIGhlbHAgdGl0bGUgc2hhbGxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBiZSB1c2VkLiBJZiBvbWl0dGVkIGFuZCBvbmUgb3IgbW9yZSB2ckhlbHAgaXRlbXMgYXJlIHByb3ZpZGVkLCB0aGUgcmVxdWVzdCB3aWxsIGJlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0ZWQuXG4gICAgICogQHJldHVybiB7U2V0R2xvYmFsUHJvcGVydGllc31cbiAgICAgKi9cbiAgICBzZXRWckhlbHBUaXRsZSAodGl0bGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2V0R2xvYmFsUHJvcGVydGllcy5LRVlfVlJfSEVMUF9USVRMRSwgdGl0bGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0VnJIZWxwVGl0bGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2V0R2xvYmFsUHJvcGVydGllcy5LRVlfVlJfSEVMUF9USVRMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWckhlbHBJdGVtW119IGhlbHAgLSBWUiBIZWxwIEl0ZW1zLiBJZiBvbWl0dGVkIG9uIHN1cHBvcnRlZCBkaXNwbGF5cywgdGhlIGRlZmF1bHQgU21hcnREZXZpY2VMaW5rIFZSIGhlbHBcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8gV2hhdCBDYW4gSSBTYXk/IHNjcmVlbiBzaGFsbCBiZSB1c2VkLiBJZiB0aGUgbGlzdCBvZiBWUiBIZWxwIEl0ZW1zIGNvbnRhaW5zXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub25zZXF1ZW50aWFsIHBvc2l0aW9ucyAoZS5nLiBbMSwyLDRdKSwgdGhlIFJQQyBzaGFsbCBiZSByZWplY3RlZC4gSWYgb21pdHRlZCBhbmQgYVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdnJIZWxwVGl0bGUgaXMgcHJvdmlkZWQsIHRoZSByZXF1ZXN0IHdpbGwgYmUgcmVqZWN0ZWQuXG4gICAgICogQHJldHVybiB7U2V0R2xvYmFsUHJvcGVydGllc31cbiAgICAgKi9cbiAgICBzZXRWckhlbHAgKGhlbHApIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVnJIZWxwSXRlbSwgaGVscCwgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNldEdsb2JhbFByb3BlcnRpZXMuS0VZX1ZSX0hFTFAsIGhlbHApO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWckhlbHBJdGVtW119XG4gICAgICovXG4gICAgZ2V0VnJIZWxwICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZySGVscEl0ZW0sIFNldEdsb2JhbFByb3BlcnRpZXMuS0VZX1ZSX0hFTFApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0aXRsZSAtIE9wdGlvbmFsIHRleHQgdG8gbGFiZWwgYW4gYXBwIG1lbnUgYnV0dG9uIChmb3IgY2VydGFpbiB0b3VjaHNjcmVlbiBwbGF0Zm9ybXMpLlxuICAgICAqIEByZXR1cm4ge1NldEdsb2JhbFByb3BlcnRpZXN9XG4gICAgICovXG4gICAgc2V0TWVudVRpdGxlICh0aXRsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZXRHbG9iYWxQcm9wZXJ0aWVzLktFWV9NRU5VX1RJVExFLCB0aXRsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRNZW51VGl0bGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2V0R2xvYmFsUHJvcGVydGllcy5LRVlfTUVOVV9USVRMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtJbWFnZX0gaWNvbiAtIE9wdGlvbmFsIGljb24gdG8gZHJhdyBvbiBhbiBhcHAgbWVudSBidXR0b24gKGZvciBjZXJ0YWluIHRvdWNoc2NyZWVuIHBsYXRmb3JtcykuXG4gICAgICogQHJldHVybiB7U2V0R2xvYmFsUHJvcGVydGllc31cbiAgICAgKi9cbiAgICBzZXRNZW51SWNvbiAoaWNvbikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShJbWFnZSwgaWNvbik7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNldEdsb2JhbFByb3BlcnRpZXMuS0VZX01FTlVfSUNPTiwgaWNvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0ltYWdlfVxuICAgICAqL1xuICAgIGdldE1lbnVJY29uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEltYWdlLCBTZXRHbG9iYWxQcm9wZXJ0aWVzLktFWV9NRU5VX0lDT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7S2V5Ym9hcmRQcm9wZXJ0aWVzfSBwcm9wZXJ0aWVzIC0gT24tc2NyZWVuIGtleWJvYXJkIGNvbmZpZ3VyYXRpb24gKGlmIGF2YWlsYWJsZSkuXG4gICAgICogQHJldHVybiB7U2V0R2xvYmFsUHJvcGVydGllc31cbiAgICAgKi9cbiAgICBzZXRLZXlib2FyZFByb3BlcnRpZXMgKHByb3BlcnRpZXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoS2V5Ym9hcmRQcm9wZXJ0aWVzLCBwcm9wZXJ0aWVzKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2V0R2xvYmFsUHJvcGVydGllcy5LRVlfS0VZQk9BUkRfUFJPUEVSVElFUywgcHJvcGVydGllcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0tleWJvYXJkUHJvcGVydGllc31cbiAgICAgKi9cbiAgICBnZXRLZXlib2FyZFByb3BlcnRpZXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoS2V5Ym9hcmRQcm9wZXJ0aWVzLCBTZXRHbG9iYWxQcm9wZXJ0aWVzLktFWV9LRVlCT0FSRF9QUk9QRVJUSUVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge01lbnVMYXlvdXR9IGxheW91dCAtIFNldHMgdGhlIGxheW91dCBvZiB0aGUgbWFpbiBtZW51IHNjcmVlbi4gSWYgdGhpcyBpcyBzZW50IHdoaWxlIGEgbWVudSBpcyBhbHJlYWR5IG9uLVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NyZWVuLCB0aGUgaGVhZCB1bml0IHdpbGwgY2hhbmdlIHRoZSBkaXNwbGF5IHRvIHRoZSBuZXcgbGF5b3V0IHR5cGUuXG4gICAgICogQHJldHVybiB7U2V0R2xvYmFsUHJvcGVydGllc31cbiAgICAgKi9cbiAgICBzZXRNZW51TGF5b3V0IChsYXlvdXQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTWVudUxheW91dCwgbGF5b3V0KTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2V0R2xvYmFsUHJvcGVydGllcy5LRVlfTUVOVV9MQVlPVVQsIGxheW91dCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge01lbnVMYXlvdXR9XG4gICAgICovXG4gICAgZ2V0TWVudUxheW91dCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChNZW51TGF5b3V0LCBTZXRHbG9iYWxQcm9wZXJ0aWVzLktFWV9NRU5VX0xBWU9VVCk7XG4gICAgfVxufVxuXG5TZXRHbG9iYWxQcm9wZXJ0aWVzLktFWV9VU0VSX0xPQ0FUSU9OID0gJ3VzZXJMb2NhdGlvbic7XG5TZXRHbG9iYWxQcm9wZXJ0aWVzLktFWV9IRUxQX1BST01QVCA9ICdoZWxwUHJvbXB0JztcblNldEdsb2JhbFByb3BlcnRpZXMuS0VZX1RJTUVPVVRfUFJPTVBUID0gJ3RpbWVvdXRQcm9tcHQnO1xuU2V0R2xvYmFsUHJvcGVydGllcy5LRVlfVlJfSEVMUF9USVRMRSA9ICd2ckhlbHBUaXRsZSc7XG5TZXRHbG9iYWxQcm9wZXJ0aWVzLktFWV9WUl9IRUxQID0gJ3ZySGVscCc7XG5TZXRHbG9iYWxQcm9wZXJ0aWVzLktFWV9NRU5VX1RJVExFID0gJ21lbnVUaXRsZSc7XG5TZXRHbG9iYWxQcm9wZXJ0aWVzLktFWV9NRU5VX0lDT04gPSAnbWVudUljb24nO1xuU2V0R2xvYmFsUHJvcGVydGllcy5LRVlfS0VZQk9BUkRfUFJPUEVSVElFUyA9ICdrZXlib2FyZFByb3BlcnRpZXMnO1xuU2V0R2xvYmFsUHJvcGVydGllcy5LRVlfTUVOVV9MQVlPVVQgPSAnbWVudUxheW91dCc7XG5cbmV4cG9ydCB7IFNldEdsb2JhbFByb3BlcnRpZXMgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBScGNSZXNwb25zZSB9IGZyb20gJy4uL1JwY1Jlc3BvbnNlLmpzJztcblxuY2xhc3MgU2V0R2xvYmFsUHJvcGVydGllc1Jlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuU2V0R2xvYmFsUHJvcGVydGllcyk7XG4gICAgfVxufVxuXG5cbmV4cG9ydCB7IFNldEdsb2JhbFByb3BlcnRpZXNSZXNwb25zZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIFRoZSBkaWZmZXJlbnQgZ2xvYmFsIHByb3BlcnRpZXMuXG4gKiBAdHlwZWRlZiB7RW51bX0gR2xvYmFsUHJvcGVydHlcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIEdsb2JhbFByb3BlcnR5IGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIExvY2F0aW9uIG9mIHRoZSB1c2VyJ3Mgc2VhdCBvZiBzZXRHbG9iYWxQcm9wZXJ0aWVzXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVVNFUl9MT0NBVElPTiAoKSB7XG4gICAgICAgIHJldHVybiBHbG9iYWxQcm9wZXJ0eS5fTUFQLlVTRVJfTE9DQVRJT047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIHByb3BlcnR5IGhlbHBQcm9tcHQgb2Ygc2V0R2xvYmFsUHJvcGVydGllc1xuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEhFTFBQUk9NUFQgKCkge1xuICAgICAgICByZXR1cm4gR2xvYmFsUHJvcGVydHkuX01BUC5IRUxQUFJPTVBUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBwcm9wZXJ0eSB0aW1lb3V0UHJvbXB0IG9mIHNldEdsb2JhbFByb3BlcnRpZXNcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBUSU1FT1VUUFJPTVBUICgpIHtcbiAgICAgICAgcmV0dXJuIEdsb2JhbFByb3BlcnR5Ll9NQVAuVElNRU9VVFBST01QVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcHJvcGVydHkgdnJIZWxwVGl0bGUgb2Ygc2V0R2xvYmFsUHJvcGVydGllc1xuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZSSEVMUFRJVExFICgpIHtcbiAgICAgICAgcmV0dXJuIEdsb2JhbFByb3BlcnR5Ll9NQVAuVlJIRUxQVElUTEU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIHByb3BlcnR5IGFycmF5IG9mIHZySGVscCBvZiBzZXRHbG9iYWxQcm9wZXJ0aWVzXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVlJIRUxQSVRFTVMgKCkge1xuICAgICAgICByZXR1cm4gR2xvYmFsUHJvcGVydHkuX01BUC5WUkhFTFBJVEVNUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcHJvcGVydHkgaW4tYXBwIG1lbnUgbmFtZSBvZiBzZXRHbG9iYWxQcm9wZXJ0aWVzXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTUVOVU5BTUUgKCkge1xuICAgICAgICByZXR1cm4gR2xvYmFsUHJvcGVydHkuX01BUC5NRU5VTkFNRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcHJvcGVydHkgaW4tYXBwIG1lbnUgaWNvbiBvZiBzZXRHbG9iYWxQcm9wZXJ0aWVzXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTUVOVUlDT04gKCkge1xuICAgICAgICByZXR1cm4gR2xvYmFsUHJvcGVydHkuX01BUC5NRU5VSUNPTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb24tc2NyZWVuIGtleWJvYXJkIGNvbmZpZ3VyYXRpb24gb2Ygc2V0R2xvYmFsUHJvcGVydGllc1xuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEtFWUJPQVJEUFJPUEVSVElFUyAoKSB7XG4gICAgICAgIHJldHVybiBHbG9iYWxQcm9wZXJ0eS5fTUFQLktFWUJPQVJEUFJPUEVSVElFUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBHbG9iYWxQcm9wZXJ0eS5fdmFsdWVGb3JLZXkoa2V5LCBHbG9iYWxQcm9wZXJ0eS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIEdsb2JhbFByb3BlcnR5Ll9rZXlGb3JWYWx1ZSh2YWx1ZSwgR2xvYmFsUHJvcGVydHkuX01BUCk7XG4gICAgfVxufVxuXG5HbG9iYWxQcm9wZXJ0eS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1VTRVJfTE9DQVRJT04nOiAnVVNFUl9MT0NBVElPTicsXG4gICAgJ0hFTFBQUk9NUFQnOiAnSEVMUFBST01QVCcsXG4gICAgJ1RJTUVPVVRQUk9NUFQnOiAnVElNRU9VVFBST01QVCcsXG4gICAgJ1ZSSEVMUFRJVExFJzogJ1ZSSEVMUFRJVExFJyxcbiAgICAnVlJIRUxQSVRFTVMnOiAnVlJIRUxQSVRFTVMnLFxuICAgICdNRU5VTkFNRSc6ICdNRU5VTkFNRScsXG4gICAgJ01FTlVJQ09OJzogJ01FTlVJQ09OJyxcbiAgICAnS0VZQk9BUkRQUk9QRVJUSUVTJzogJ0tFWUJPQVJEUFJPUEVSVElFUycsXG59KTtcblxuZXhwb3J0IHsgR2xvYmFsUHJvcGVydHkgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBHbG9iYWxQcm9wZXJ0eSB9IGZyb20gJy4uL2VudW1zL0dsb2JhbFByb3BlcnR5LmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcblxuLyoqXG4gKiBBbGxvd3MgcmVzZXR0aW5nIGdsb2JhbCBwcm9wZXJ0aWVzLlxuICovXG5jbGFzcyBSZXNldEdsb2JhbFByb3BlcnRpZXMgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlJlc2V0R2xvYmFsUHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtHbG9iYWxQcm9wZXJ0eVtdfSBwcm9wZXJ0aWVzIC0gQ29udGFpbnMgdGhlIG5hbWVzIG9mIGFsbCBnbG9iYWwgcHJvcGVydGllcyAobGlrZSB0aW1lb3V0UHJvbXB0KSB0aGF0XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvdWxkIGJlIHVuc2V0LiBSZXNldHRpbmcgbWVhbnMsIHRoYXQgdGhleSBoYXZlIHRoZSBzYW1lIHZhbHVlIGFzIGF0XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnQgdXAgKGRlZmF1bHQpXG4gICAgICogQHJldHVybiB7UmVzZXRHbG9iYWxQcm9wZXJ0aWVzfVxuICAgICAqL1xuICAgIHNldFByb3BlcnRpZXMgKHByb3BlcnRpZXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoR2xvYmFsUHJvcGVydHksIHByb3BlcnRpZXMsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZXNldEdsb2JhbFByb3BlcnRpZXMuS0VZX1BST1BFUlRJRVMsIHByb3BlcnRpZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtHbG9iYWxQcm9wZXJ0eVtdfVxuICAgICAqL1xuICAgIGdldFByb3BlcnRpZXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoR2xvYmFsUHJvcGVydHksIFJlc2V0R2xvYmFsUHJvcGVydGllcy5LRVlfUFJPUEVSVElFUyk7XG4gICAgfVxufVxuXG5SZXNldEdsb2JhbFByb3BlcnRpZXMuS0VZX1BST1BFUlRJRVMgPSAncHJvcGVydGllcyc7XG5cbmV4cG9ydCB7IFJlc2V0R2xvYmFsUHJvcGVydGllcyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG5jbGFzcyBSZXNldEdsb2JhbFByb3BlcnRpZXNSZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlJlc2V0R2xvYmFsUHJvcGVydGllcyk7XG4gICAgfVxufVxuXG5cbmV4cG9ydCB7IFJlc2V0R2xvYmFsUHJvcGVydGllc1Jlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcblxuY2xhc3MgTWVudVBhcmFtcyBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGlkIC0gdW5pcXVlIElEIG9mIHRoZSBzdWIgbWVudSwgdGhlIGNvbW1hbmQgd2lsbCBiZSBhZGRlZCB0by4gSWYgbm90IHByb3ZpZGVkLCBpdCB3aWxsIGJlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgcHJvdmlkZWQgdG8gdGhlIHRvcCBsZXZlbCBvZiB0aGUgaW4gYXBwbGljYXRpb24gbWVudS5cbiAgICAgKiBAcmV0dXJuIHtNZW51UGFyYW1zfVxuICAgICAqL1xuICAgIHNldFBhcmVudElEIChpZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihNZW51UGFyYW1zLktFWV9QQVJFTlRfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFBhcmVudElEICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE1lbnVQYXJhbXMuS0VZX1BBUkVOVF9JRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHBvc2l0aW9uIC0gUG9zaXRpb24gd2l0aGluIHRoZSBpdGVtcyB0aGF0IGFyZSBhcmUgYXQgdG9wIGxldmVsIG9mIHRoZSBpbiBhcHBsaWNhdGlvbiBtZW51LiAwIHdpbGxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnNlcnQgYXQgdGhlIGZyb250LiAxIHdpbGwgaW5zZXJ0IGF0IHRoZSBzZWNvbmQgcG9zaXRpb24uIGlmIHBvc2l0aW9uIGlzIGdyZWF0ZXIgb3JcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcXVhbCB0aGFuIHRoZSBudW1iZXIgb2YgaXRlbXMgb24gdG9wIGxldmVsLCB0aGUgc3ViIG1lbnUgd2lsbCBiZSBhcHBlbmRlZCB0byB0aGUgZW5kLlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmIHRoaXMgcGFyYW0gd2FzIG9taXR0ZWQgdGhlIGVudHJ5IHdpbGwgYmUgYWRkZWQgYXQgdGhlIGVuZC5cbiAgICAgKiBAcmV0dXJuIHtNZW51UGFyYW1zfVxuICAgICAqL1xuICAgIHNldFBvc2l0aW9uIChwb3NpdGlvbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihNZW51UGFyYW1zLktFWV9QT1NJVElPTiwgcG9zaXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0UG9zaXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoTWVudVBhcmFtcy5LRVlfUE9TSVRJT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIC0gVGV4dCB0byBzaG93IGluIHRoZSBtZW51IGZvciB0aGlzIHN1YiBtZW51LlxuICAgICAqIEByZXR1cm4ge01lbnVQYXJhbXN9XG4gICAgICovXG4gICAgc2V0TWVudU5hbWUgKG5hbWUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTWVudVBhcmFtcy5LRVlfTUVOVV9OQU1FLCBuYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldE1lbnVOYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE1lbnVQYXJhbXMuS0VZX01FTlVfTkFNRSk7XG4gICAgfVxufVxuXG5NZW51UGFyYW1zLktFWV9QQVJFTlRfSUQgPSAncGFyZW50SUQnO1xuTWVudVBhcmFtcy5LRVlfUE9TSVRJT04gPSAncG9zaXRpb24nO1xuTWVudVBhcmFtcy5LRVlfTUVOVV9OQU1FID0gJ21lbnVOYW1lJztcblxuZXhwb3J0IHsgTWVudVBhcmFtcyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1JlcXVlc3QgfSBmcm9tICcuLi9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IE1lbnVQYXJhbXMgfSBmcm9tICcuLi9zdHJ1Y3RzL01lbnVQYXJhbXMuanMnO1xuaW1wb3J0IHsgSW1hZ2UgfSBmcm9tICcuLi9zdHJ1Y3RzL0ltYWdlLmpzJztcblxuLyoqXG4gKiBBZGRzIGEgY29tbWFuZCB0byB0aGUgaW4gYXBwbGljYXRpb24gbWVudS4gRWl0aGVyIG1lbnVQYXJhbXMgb3IgdnJDb21tYW5kcyBtdXN0IGJlIHByb3ZpZGVkLlxuICovXG5jbGFzcyBBZGRDb21tYW5kIGV4dGVuZHMgUnBjUmVxdWVzdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5BZGRDb21tYW5kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaWQgLSB1bmlxdWUgSUQgb2YgdGhlIGNvbW1hbmQgdG8gYWRkLlxuICAgICAqIEByZXR1cm4ge0FkZENvbW1hbmR9XG4gICAgICovXG4gICAgc2V0Q21kSUQgKGlkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEFkZENvbW1hbmQuS0VZX0NNRF9JRCwgaWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0Q21kSUQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQWRkQ29tbWFuZC5LRVlfQ01EX0lEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge01lbnVQYXJhbXN9IHBhcmFtcyAtIE9wdGlvbmFsIHN1YiB2YWx1ZSBjb250YWluaW5nIG1lbnUgcGFyYW1ldGVyc1xuICAgICAqIEByZXR1cm4ge0FkZENvbW1hbmR9XG4gICAgICovXG4gICAgc2V0TWVudVBhcmFtcyAocGFyYW1zKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKE1lbnVQYXJhbXMsIHBhcmFtcyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEFkZENvbW1hbmQuS0VZX01FTlVfUEFSQU1TLCBwYXJhbXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtNZW51UGFyYW1zfVxuICAgICAqL1xuICAgIGdldE1lbnVQYXJhbXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTWVudVBhcmFtcywgQWRkQ29tbWFuZC5LRVlfTUVOVV9QQVJBTVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nW119IGNvbW1hbmRzIC0gQW4gYXJyYXkgb2Ygc3RyaW5ncyB0byBiZSB1c2VkIGFzIFZSIHN5bm9ueW1zIGZvciB0aGlzIGNvbW1hbmQuIElmIHRoaXMgYXJyYXkgaXNcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3ZpZGVkLCBpdCBtYXkgbm90IGJlIGVtcHR5LlxuICAgICAqIEByZXR1cm4ge0FkZENvbW1hbmR9XG4gICAgICovXG4gICAgc2V0VnJDb21tYW5kcyAoY29tbWFuZHMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQWRkQ29tbWFuZC5LRVlfVlJfQ09NTUFORFMsIGNvbW1hbmRzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nW119XG4gICAgICovXG4gICAgZ2V0VnJDb21tYW5kcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihBZGRDb21tYW5kLktFWV9WUl9DT01NQU5EUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtJbWFnZX0gaWNvbiAtIEltYWdlIHN0cnVjdCBkZXRlcm1pbmluZyB3aGV0aGVyIHN0YXRpYyBvciBkeW5hbWljIGljb24uIElmIG9taXR0ZWQgb24gc3VwcG9ydGVkIGRpc3BsYXlzLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICBubyAob3IgdGhlIGRlZmF1bHQgaWYgYXBwbGljYWJsZSkgaWNvbiBzaGFsbCBiZSBkaXNwbGF5ZWQuXG4gICAgICogQHJldHVybiB7QWRkQ29tbWFuZH1cbiAgICAgKi9cbiAgICBzZXRDbWRJY29uIChpY29uKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEltYWdlLCBpY29uKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQWRkQ29tbWFuZC5LRVlfQ01EX0lDT04sIGljb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtJbWFnZX1cbiAgICAgKi9cbiAgICBnZXRDbWRJY29uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEltYWdlLCBBZGRDb21tYW5kLktFWV9DTURfSUNPTik7XG4gICAgfVxufVxuXG5BZGRDb21tYW5kLktFWV9DTURfSUQgPSAnY21kSUQnO1xuQWRkQ29tbWFuZC5LRVlfTUVOVV9QQVJBTVMgPSAnbWVudVBhcmFtcyc7XG5BZGRDb21tYW5kLktFWV9WUl9DT01NQU5EUyA9ICd2ckNvbW1hbmRzJztcbkFkZENvbW1hbmQuS0VZX0NNRF9JQ09OID0gJ2NtZEljb24nO1xuXG5leHBvcnQgeyBBZGRDb21tYW5kIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbmNsYXNzIEFkZENvbW1hbmRSZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkFkZENvbW1hbmQpO1xuICAgIH1cbn1cblxuXG5leHBvcnQgeyBBZGRDb21tYW5kUmVzcG9uc2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5cbi8qKlxuICogRGVsZXRlcyBhbGwgY29tbWFuZHMgZnJvbSB0aGUgaW4tYXBwbGljYXRpb24gbWVudSB3aXRoIHRoZSBzcGVjaWZpZWQgY29tbWFuZCBpZC5cbiAqL1xuY2xhc3MgRGVsZXRlQ29tbWFuZCBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuRGVsZXRlQ29tbWFuZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGlkIC0gSUQgb2YgdGhlIGNvbW1hbmQocykgdG8gZGVsZXRlLlxuICAgICAqIEByZXR1cm4ge0RlbGV0ZUNvbW1hbmR9XG4gICAgICovXG4gICAgc2V0Q21kSUQgKGlkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKERlbGV0ZUNvbW1hbmQuS0VZX0NNRF9JRCwgaWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0Q21kSUQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoRGVsZXRlQ29tbWFuZC5LRVlfQ01EX0lEKTtcbiAgICB9XG59XG5cbkRlbGV0ZUNvbW1hbmQuS0VZX0NNRF9JRCA9ICdjbWRJRCc7XG5cbmV4cG9ydCB7IERlbGV0ZUNvbW1hbmQgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBScGNSZXNwb25zZSB9IGZyb20gJy4uL1JwY1Jlc3BvbnNlLmpzJztcblxuY2xhc3MgRGVsZXRlQ29tbWFuZFJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuRGVsZXRlQ29tbWFuZCk7XG4gICAgfVxufVxuXG5cbmV4cG9ydCB7IERlbGV0ZUNvbW1hbmRSZXNwb25zZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1JlcXVlc3QgfSBmcm9tICcuLi9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IE1lbnVMYXlvdXQgfSBmcm9tICcuLi9lbnVtcy9NZW51TGF5b3V0LmpzJztcbmltcG9ydCB7IEltYWdlIH0gZnJvbSAnLi4vc3RydWN0cy9JbWFnZS5qcyc7XG5cbi8qKlxuICogQWRkcyBhIHN1YiBtZW51IHRvIHRoZSBpbi1hcHBsaWNhdGlvbiBtZW51LlxuICovXG5jbGFzcyBBZGRTdWJNZW51IGV4dGVuZHMgUnBjUmVxdWVzdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5BZGRTdWJNZW51KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaWQgLSB1bmlxdWUgSUQgb2YgdGhlIHN1YiBtZW51IHRvIGFkZC5cbiAgICAgKiBAcmV0dXJuIHtBZGRTdWJNZW51fVxuICAgICAqL1xuICAgIHNldE1lbnVJRCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQWRkU3ViTWVudS5LRVlfTUVOVV9JRCwgaWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0TWVudUlEICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEFkZFN1Yk1lbnUuS0VZX01FTlVfSUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBwb3NpdGlvbiAtIFBvc2l0aW9uIHdpdGhpbiB0aGUgaXRlbXMgdGhhdCBhcmUgYXJlIGF0IHRvcCBsZXZlbCBvZiB0aGUgaW4gYXBwbGljYXRpb24gbWVudS4gMCB3aWxsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zZXJ0IGF0IHRoZSBmcm9udC4gMSB3aWxsIGluc2VydCBhdCB0aGUgc2Vjb25kIHBvc2l0aW9uLiBJZiBwb3NpdGlvbiBpcyBncmVhdGVyIG9yXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXF1YWwgdGhhbiB0aGUgbnVtYmVyIG9mIGl0ZW1zIG9uIHRvcCBsZXZlbCwgdGhlIHN1YiBtZW51IHdpbGwgYmUgYXBwZW5kZWQgdG8gdGhlIGVuZC5cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQb3NpdGlvbiBvZiBhbnkgc3VibWVudSB3aWxsIGFsd2F5cyBiZSBsb2NhdGVkIGJlZm9yZSB0aGUgcmV0dXJuIGFuZCBleGl0IG9wdGlvbnMgSWZcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIHBhcmFtIHdhcyBvbWl0dGVkIHRoZSBlbnRyeSB3aWxsIGJlIGFkZGVkIGF0IHRoZSBlbmQuXG4gICAgICogQHJldHVybiB7QWRkU3ViTWVudX1cbiAgICAgKi9cbiAgICBzZXRQb3NpdGlvbiAocG9zaXRpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQWRkU3ViTWVudS5LRVlfUE9TSVRJT04sIHBvc2l0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFBvc2l0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEFkZFN1Yk1lbnUuS0VZX1BPU0lUSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSAtIFRleHQgdG8gc2hvdyBpbiB0aGUgbWVudSBmb3IgdGhpcyBzdWIgbWVudS5cbiAgICAgKiBAcmV0dXJuIHtBZGRTdWJNZW51fVxuICAgICAqL1xuICAgIHNldE1lbnVOYW1lIChuYW1lKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEFkZFN1Yk1lbnUuS0VZX01FTlVfTkFNRSwgbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRNZW51TmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihBZGRTdWJNZW51LktFWV9NRU5VX05BTUUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7SW1hZ2V9IGljb24gLSBUaGUgaW1hZ2UgZmllbGQgZm9yIEFkZFN1Yk1lbnVcbiAgICAgKiBAcmV0dXJuIHtBZGRTdWJNZW51fVxuICAgICAqL1xuICAgIHNldE1lbnVJY29uIChpY29uKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEltYWdlLCBpY29uKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQWRkU3ViTWVudS5LRVlfTUVOVV9JQ09OLCBpY29uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7SW1hZ2V9XG4gICAgICovXG4gICAgZ2V0TWVudUljb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoSW1hZ2UsIEFkZFN1Yk1lbnUuS0VZX01FTlVfSUNPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtNZW51TGF5b3V0fSBsYXlvdXQgLSBTZXRzIHRoZSBsYXlvdXQgb2YgdGhlIHN1Ym1lbnUgc2NyZWVuLlxuICAgICAqIEByZXR1cm4ge0FkZFN1Yk1lbnV9XG4gICAgICovXG4gICAgc2V0TWVudUxheW91dCAobGF5b3V0KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKE1lbnVMYXlvdXQsIGxheW91dCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEFkZFN1Yk1lbnUuS0VZX01FTlVfTEFZT1VULCBsYXlvdXQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtNZW51TGF5b3V0fVxuICAgICAqL1xuICAgIGdldE1lbnVMYXlvdXQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTWVudUxheW91dCwgQWRkU3ViTWVudS5LRVlfTUVOVV9MQVlPVVQpO1xuICAgIH1cbn1cblxuQWRkU3ViTWVudS5LRVlfTUVOVV9JRCA9ICdtZW51SUQnO1xuQWRkU3ViTWVudS5LRVlfUE9TSVRJT04gPSAncG9zaXRpb24nO1xuQWRkU3ViTWVudS5LRVlfTUVOVV9OQU1FID0gJ21lbnVOYW1lJztcbkFkZFN1Yk1lbnUuS0VZX01FTlVfSUNPTiA9ICdtZW51SWNvbic7XG5BZGRTdWJNZW51LktFWV9NRU5VX0xBWU9VVCA9ICdtZW51TGF5b3V0JztcblxuZXhwb3J0IHsgQWRkU3ViTWVudSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG5jbGFzcyBBZGRTdWJNZW51UmVzcG9uc2UgZXh0ZW5kcyBScGNSZXNwb25zZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5BZGRTdWJNZW51KTtcbiAgICB9XG59XG5cblxuZXhwb3J0IHsgQWRkU3ViTWVudVJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG4vKipcbiAqIERlbGV0ZXMgYSBzdWJtZW51IGZyb20gdGhlIGluLWFwcGxpY2F0aW9uIG1lbnUuXG4gKi9cbmNsYXNzIERlbGV0ZVN1Yk1lbnUgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkRlbGV0ZVN1Yk1lbnUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBpZCAtIFRoZSBcIm1lbnVJRFwiIG9mIHRoZSBzdWJtZW51IHRvIGRlbGV0ZS4gKFNlZSBhZGRTdWJNZW51Lm1lbnVJRClcbiAgICAgKiBAcmV0dXJuIHtEZWxldGVTdWJNZW51fVxuICAgICAqL1xuICAgIHNldE1lbnVJRCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGVsZXRlU3ViTWVudS5LRVlfTUVOVV9JRCwgaWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0TWVudUlEICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKERlbGV0ZVN1Yk1lbnUuS0VZX01FTlVfSUQpO1xuICAgIH1cbn1cblxuRGVsZXRlU3ViTWVudS5LRVlfTUVOVV9JRCA9ICdtZW51SUQnO1xuXG5leHBvcnQgeyBEZWxldGVTdWJNZW51IH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbmNsYXNzIERlbGV0ZVN1Yk1lbnVSZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkRlbGV0ZVN1Yk1lbnUpO1xuICAgIH1cbn1cblxuXG5leHBvcnQgeyBEZWxldGVTdWJNZW51UmVzcG9uc2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5cbi8qKlxuICogU2hvd3MgdGhlIGJ1aWx0IGluIG1lbnUgdmlld1xuICovXG5jbGFzcyBTaG93QXBwTWVudSBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuU2hvd0FwcE1lbnUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBpZCAtIElmIG9taXR0ZWQgdGhlIEhNSSBvcGVucyB0aGUgYXBwJ3MgbWVudS4gSWYgc2V0IHRvIGEgc3ViLW1lbnUgSUQgdGhlIEhNSSBvcGVucyB0aGVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBjb3JyZXNwb25kaW5nIHN1Yi1tZW51IHByZXZpb3VzbHkgYWRkZWQgdXNpbmcgYEFkZFN1Yk1lbnVgLlxuICAgICAqIEByZXR1cm4ge1Nob3dBcHBNZW51fVxuICAgICAqL1xuICAgIHNldE1lbnVJRCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2hvd0FwcE1lbnUuS0VZX01FTlVfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldE1lbnVJRCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTaG93QXBwTWVudS5LRVlfTUVOVV9JRCk7XG4gICAgfVxufVxuXG5TaG93QXBwTWVudS5LRVlfTUVOVV9JRCA9ICdtZW51SUQnO1xuXG5leHBvcnQgeyBTaG93QXBwTWVudSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG5jbGFzcyBTaG93QXBwTWVudVJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuU2hvd0FwcE1lbnUpO1xuICAgIH1cbn1cblxuXG5leHBvcnQgeyBTaG93QXBwTWVudVJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IEltYWdlIH0gZnJvbSAnLi9JbWFnZS5qcyc7XG5cbi8qKlxuICogQSBjaG9pY2UgaXMgYW4gb3B0aW9uIGdpdmVuIHRvIHRoZSB1c2VyLCB3aGljaCBjYW4gYmUgc2VsZWN0ZWQgZWl0aGVyIGJ5IG1lbnUsIG9yIHRocm91Z2ggdm9pY2UgcmVjb2duaXRpb24gc3lzdGVtLlxuICovXG5jbGFzcyBDaG9pY2UgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBpZFxuICAgICAqIEByZXR1cm4ge0Nob2ljZX1cbiAgICAgKi9cbiAgICBzZXRDaG9pY2VJRCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2hvaWNlLktFWV9DSE9JQ0VfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldENob2ljZUlEICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKENob2ljZS5LRVlfQ0hPSUNFX0lEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICAgICAqIEByZXR1cm4ge0Nob2ljZX1cbiAgICAgKi9cbiAgICBzZXRNZW51TmFtZSAobmFtZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihDaG9pY2UuS0VZX01FTlVfTkFNRSwgbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRNZW51TmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihDaG9pY2UuS0VZX01FTlVfTkFNRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmdbXX0gY29tbWFuZHNcbiAgICAgKiBAcmV0dXJuIHtDaG9pY2V9XG4gICAgICovXG4gICAgc2V0VnJDb21tYW5kcyAoY29tbWFuZHMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2hvaWNlLktFWV9WUl9DT01NQU5EUywgY29tbWFuZHMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmdbXX1cbiAgICAgKi9cbiAgICBnZXRWckNvbW1hbmRzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKENob2ljZS5LRVlfVlJfQ09NTUFORFMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7SW1hZ2V9IGltYWdlXG4gICAgICogQHJldHVybiB7Q2hvaWNlfVxuICAgICAqL1xuICAgIHNldEltYWdlIChpbWFnZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShJbWFnZSwgaW1hZ2UpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihDaG9pY2UuS0VZX0lNQUdFLCBpbWFnZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0ltYWdlfVxuICAgICAqL1xuICAgIGdldEltYWdlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEltYWdlLCBDaG9pY2UuS0VZX0lNQUdFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdGV4dCAtIE9wdGlvbmFsIHNlY29uZGFyeSB0ZXh0IHRvIGRpc3BsYXk7IGUuZy4gYWRkcmVzcyBvZiBQT0kgaW4gYSBzZWFyY2ggcmVzdWx0IGVudHJ5XG4gICAgICogQHJldHVybiB7Q2hvaWNlfVxuICAgICAqL1xuICAgIHNldFNlY29uZGFyeVRleHQgKHRleHQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2hvaWNlLktFWV9TRUNPTkRBUllfVEVYVCwgdGV4dCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRTZWNvbmRhcnlUZXh0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKENob2ljZS5LRVlfU0VDT05EQVJZX1RFWFQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0IC0gT3B0aW9uYWwgdGVydGlhcnkgdGV4dCB0byBkaXNwbGF5OyBlLmcuIGRpc3RhbmNlIHRvIFBPSSBmb3IgYSBzZWFyY2ggcmVzdWx0IGVudHJ5XG4gICAgICogQHJldHVybiB7Q2hvaWNlfVxuICAgICAqL1xuICAgIHNldFRlcnRpYXJ5VGV4dCAodGV4dCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihDaG9pY2UuS0VZX1RFUlRJQVJZX1RFWFQsIHRleHQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0VGVydGlhcnlUZXh0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKENob2ljZS5LRVlfVEVSVElBUllfVEVYVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtJbWFnZX0gaW1hZ2UgLSBPcHRpb25hbCBzZWNvbmRhcnkgaW1hZ2Ugc3RydWN0IGZvciBjaG9pY2VcbiAgICAgKiBAcmV0dXJuIHtDaG9pY2V9XG4gICAgICovXG4gICAgc2V0U2Vjb25kYXJ5SW1hZ2UgKGltYWdlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEltYWdlLCBpbWFnZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENob2ljZS5LRVlfU0VDT05EQVJZX0lNQUdFLCBpbWFnZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0ltYWdlfVxuICAgICAqL1xuICAgIGdldFNlY29uZGFyeUltYWdlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEltYWdlLCBDaG9pY2UuS0VZX1NFQ09OREFSWV9JTUFHRSk7XG4gICAgfVxufVxuXG5DaG9pY2UuS0VZX0NIT0lDRV9JRCA9ICdjaG9pY2VJRCc7XG5DaG9pY2UuS0VZX01FTlVfTkFNRSA9ICdtZW51TmFtZSc7XG5DaG9pY2UuS0VZX1ZSX0NPTU1BTkRTID0gJ3ZyQ29tbWFuZHMnO1xuQ2hvaWNlLktFWV9JTUFHRSA9ICdpbWFnZSc7XG5DaG9pY2UuS0VZX1NFQ09OREFSWV9URVhUID0gJ3NlY29uZGFyeVRleHQnO1xuQ2hvaWNlLktFWV9URVJUSUFSWV9URVhUID0gJ3RlcnRpYXJ5VGV4dCc7XG5DaG9pY2UuS0VZX1NFQ09OREFSWV9JTUFHRSA9ICdzZWNvbmRhcnlJbWFnZSc7XG5cbmV4cG9ydCB7IENob2ljZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1JlcXVlc3QgfSBmcm9tICcuLi9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IENob2ljZSB9IGZyb20gJy4uL3N0cnVjdHMvQ2hvaWNlLmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcblxuLyoqXG4gKiBjcmVhdGVzIGludGVyYWN0aW9uIGNob2ljZSBzZXQgdG8gYmUgdXNlZCBsYXRlciBieSBwZXJmb3JtSW50ZXJhY3Rpb25cbiAqL1xuY2xhc3MgQ3JlYXRlSW50ZXJhY3Rpb25DaG9pY2VTZXQgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkNyZWF0ZUludGVyYWN0aW9uQ2hvaWNlU2V0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaWQgLSBVbmlxdWUgSUQgdXNlZCBmb3IgdGhpcyBpbnRlcmFjdGlvbiBjaG9pY2Ugc2V0LlxuICAgICAqIEByZXR1cm4ge0NyZWF0ZUludGVyYWN0aW9uQ2hvaWNlU2V0fVxuICAgICAqL1xuICAgIHNldEludGVyYWN0aW9uQ2hvaWNlU2V0SUQgKGlkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENyZWF0ZUludGVyYWN0aW9uQ2hvaWNlU2V0LktFWV9JTlRFUkFDVElPTl9DSE9JQ0VfU0VUX0lELCBpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRJbnRlcmFjdGlvbkNob2ljZVNldElEICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKENyZWF0ZUludGVyYWN0aW9uQ2hvaWNlU2V0LktFWV9JTlRFUkFDVElPTl9DSE9JQ0VfU0VUX0lEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Nob2ljZVtdfSBzZXQgLSBBIGNob2ljZSBpcyBhbiBvcHRpb24gZ2l2ZW4gdG8gdGhlIHVzZXIsIHdoaWNoIGNhbiBiZSBzZWxlY3RlZCBlaXRoZXIgYnkgbWVudSwgb3IgdGhyb3VnaFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWNlIHJlY29nbml0aW9uIHN5c3RlbS5cbiAgICAgKiBAcmV0dXJuIHtDcmVhdGVJbnRlcmFjdGlvbkNob2ljZVNldH1cbiAgICAgKi9cbiAgICBzZXRDaG9pY2VTZXQgKHNldCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShDaG9pY2UsIHNldCwgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENyZWF0ZUludGVyYWN0aW9uQ2hvaWNlU2V0LktFWV9DSE9JQ0VfU0VULCBzZXQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtDaG9pY2VbXX1cbiAgICAgKi9cbiAgICBnZXRDaG9pY2VTZXQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQ2hvaWNlLCBDcmVhdGVJbnRlcmFjdGlvbkNob2ljZVNldC5LRVlfQ0hPSUNFX1NFVCk7XG4gICAgfVxufVxuXG5DcmVhdGVJbnRlcmFjdGlvbkNob2ljZVNldC5LRVlfSU5URVJBQ1RJT05fQ0hPSUNFX1NFVF9JRCA9ICdpbnRlcmFjdGlvbkNob2ljZVNldElEJztcbkNyZWF0ZUludGVyYWN0aW9uQ2hvaWNlU2V0LktFWV9DSE9JQ0VfU0VUID0gJ2Nob2ljZVNldCc7XG5cbmV4cG9ydCB7IENyZWF0ZUludGVyYWN0aW9uQ2hvaWNlU2V0IH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbmNsYXNzIENyZWF0ZUludGVyYWN0aW9uQ2hvaWNlU2V0UmVzcG9uc2UgZXh0ZW5kcyBScGNSZXNwb25zZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5DcmVhdGVJbnRlcmFjdGlvbkNob2ljZVNldCk7XG4gICAgfVxufVxuXG5cbmV4cG9ydCB7IENyZWF0ZUludGVyYWN0aW9uQ2hvaWNlU2V0UmVzcG9uc2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBGb3IgdG91Y2hzY3JlZW4gaW50ZXJhY3Rpb25zLCB0aGUgbW9kZSBvZiBob3cgdGhlIGNob2ljZXMgYXJlIHByZXNlbnRlZC5cbiAqIEB0eXBlZGVmIHtFbnVtfSBMYXlvdXRNb2RlXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBMYXlvdXRNb2RlIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbW9kZSBjYXVzZXMgdGhlIGludGVyYWN0aW9uIHRvIGRpc3BsYXkgdGhlIHByZXZpb3VzIHNldCBvZiBjaG9pY2VzIGFzIGljb25zLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IElDT05fT05MWSAoKSB7XG4gICAgICAgIHJldHVybiBMYXlvdXRNb2RlLl9NQVAuSUNPTl9PTkxZO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbW9kZSBjYXVzZXMgdGhlIGludGVyYWN0aW9uIHRvIGRpc3BsYXkgdGhlIHByZXZpb3VzIHNldCBvZiBjaG9pY2VzIGFzIGljb25zIGFsb25nIHdpdGggYSBzZWFyY2ggZmllbGQgaW5cbiAgICAgKiB0aGUgSE1JLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IElDT05fV0lUSF9TRUFSQ0ggKCkge1xuICAgICAgICByZXR1cm4gTGF5b3V0TW9kZS5fTUFQLklDT05fV0lUSF9TRUFSQ0g7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtb2RlIGNhdXNlcyB0aGUgaW50ZXJhY3Rpb24gdG8gZGlzcGxheSB0aGUgcHJldmlvdXMgc2V0IG9mIGNob2ljZXMgYXMgYSBsaXN0LlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IExJU1RfT05MWSAoKSB7XG4gICAgICAgIHJldHVybiBMYXlvdXRNb2RlLl9NQVAuTElTVF9PTkxZO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbW9kZSBjYXVzZXMgdGhlIGludGVyYWN0aW9uIHRvIGRpc3BsYXkgdGhlIHByZXZpb3VzIHNldCBvZiBjaG9pY2VzIGFzIGEgbGlzdCBhbG9uZyB3aXRoIGEgc2VhcmNoIGZpZWxkIGluXG4gICAgICogdGhlIEhNSS5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBMSVNUX1dJVEhfU0VBUkNIICgpIHtcbiAgICAgICAgcmV0dXJuIExheW91dE1vZGUuX01BUC5MSVNUX1dJVEhfU0VBUkNIO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbW9kZSBjYXVzZXMgdGhlIGludGVyYWN0aW9uIHRvIGltbWVkaWF0ZWx5IGRpc3BsYXkgYSBrZXlib2FyZCBlbnRyeSB0aHJvdWdoIHRoZSBITUkuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgS0VZQk9BUkQgKCkge1xuICAgICAgICByZXR1cm4gTGF5b3V0TW9kZS5fTUFQLktFWUJPQVJEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIExheW91dE1vZGUuX3ZhbHVlRm9yS2V5KGtleSwgTGF5b3V0TW9kZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIExheW91dE1vZGUuX2tleUZvclZhbHVlKHZhbHVlLCBMYXlvdXRNb2RlLl9NQVApO1xuICAgIH1cbn1cblxuTGF5b3V0TW9kZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0lDT05fT05MWSc6ICdJQ09OX09OTFknLFxuICAgICdJQ09OX1dJVEhfU0VBUkNIJzogJ0lDT05fV0lUSF9TRUFSQ0gnLFxuICAgICdMSVNUX09OTFknOiAnTElTVF9PTkxZJyxcbiAgICAnTElTVF9XSVRIX1NFQVJDSCc6ICdMSVNUX1dJVEhfU0VBUkNIJyxcbiAgICAnS0VZQk9BUkQnOiAnS0VZQk9BUkQnLFxufSk7XG5cbmV4cG9ydCB7IExheW91dE1vZGUgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBGb3IgYXBwbGljYXRpb24tcmVxdWVzdGVkIGludGVyYWN0aW9ucywgdGhpcyBtb2RlIGluZGljYXRlcyB0aGUgbWV0aG9kIGluIHdoaWNoIHRoZSB1c2VyIGlzIG5vdGlmaWVkIGFuZCB1c2VzIHRoZVxuICogaW50ZXJhY3Rpb24uXG4gKiBAdHlwZWRlZiB7RW51bX0gSW50ZXJhY3Rpb25Nb2RlXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBJbnRlcmFjdGlvbk1vZGUgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtb2RlIGNhdXNlcyB0aGUgaW50ZXJhY3Rpb24gdG8gb25seSBvY2N1ciBvbiB0aGUgZGlzcGxheSwgbWVhbmluZyB0aGUgY2hvaWNlcyBhcmUgcHJvdmlkZWQgb25seSB2aWEgdGhlXG4gICAgICogZGlzcGxheS4gTm8gVm9pY2UgSW50ZXJhY3Rpb24uXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTUFOVUFMX09OTFkgKCkge1xuICAgICAgICByZXR1cm4gSW50ZXJhY3Rpb25Nb2RlLl9NQVAuTUFOVUFMX09OTFk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtb2RlIGNhdXNlcyB0aGUgaW50ZXJhY3Rpb24gdG8gb25seSBvY2N1ciB1c2luZyB0aGUgaGVhZHVuaXRzIFZSIHN5c3RlbS4gU2VsZWN0aW9ucyBhcmUgbWFkZSBieSBzYXlpbmcgdGhlXG4gICAgICogY29tbWFuZC5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBWUl9PTkxZICgpIHtcbiAgICAgICAgcmV0dXJuIEludGVyYWN0aW9uTW9kZS5fTUFQLlZSX09OTFk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtb2RlIGNhdXNlcyBib3RoIGEgVlIgYW5kIGRpc3BsYXkgc2VsZWN0aW9uIG9wdGlvbiBmb3IgYW4gaW50ZXJhY3Rpb24uIFRoZSB1c2VyIHdpbGwgZmlyc3QgYmUgYXNrZWQgdmlhXG4gICAgICogVm9pY2UgSW50ZXJhY3Rpb24gKGlmIGF2YWlsYWJsZSkuIElmIHRoaXMgaXMgdW5zdWNjZXNzZnVsLCB0aGUgc3lzdGVtIHdpbGwgc3dpdGNoIHRvIG1hbnVhbCBpbnB1dC5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBCT1RIICgpIHtcbiAgICAgICAgcmV0dXJuIEludGVyYWN0aW9uTW9kZS5fTUFQLkJPVEg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gSW50ZXJhY3Rpb25Nb2RlLl92YWx1ZUZvcktleShrZXksIEludGVyYWN0aW9uTW9kZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIEludGVyYWN0aW9uTW9kZS5fa2V5Rm9yVmFsdWUodmFsdWUsIEludGVyYWN0aW9uTW9kZS5fTUFQKTtcbiAgICB9XG59XG5cbkludGVyYWN0aW9uTW9kZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ01BTlVBTF9PTkxZJzogJ01BTlVBTF9PTkxZJyxcbiAgICAnVlJfT05MWSc6ICdWUl9PTkxZJyxcbiAgICAnQk9USCc6ICdCT1RIJyxcbn0pO1xuXG5leHBvcnQgeyBJbnRlcmFjdGlvbk1vZGUgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBWckhlbHBJdGVtIH0gZnJvbSAnLi4vc3RydWN0cy9WckhlbHBJdGVtLmpzJztcbmltcG9ydCB7IExheW91dE1vZGUgfSBmcm9tICcuLi9lbnVtcy9MYXlvdXRNb2RlLmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFRUU0NodW5rIH0gZnJvbSAnLi4vc3RydWN0cy9UVFNDaHVuay5qcyc7XG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBJbnRlcmFjdGlvbk1vZGUgfSBmcm9tICcuLi9lbnVtcy9JbnRlcmFjdGlvbk1vZGUuanMnO1xuXG4vKipcbiAqIFRyaWdnZXJzIGFuIGludGVyYWN0aW9uIChlLmcuIFwiUGVybWl0IEdQUz9cIiAtIFllcywgbm8sIEFsd2F5cyBBbGxvdykuXG4gKi9cbmNsYXNzIFBlcmZvcm1JbnRlcmFjdGlvbiBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuUGVyZm9ybUludGVyYWN0aW9uKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdGV4dCAtIFRleHQgdG8gYmUgZGlzcGxheWVkIGZpcnN0LlxuICAgICAqIEByZXR1cm4ge1BlcmZvcm1JbnRlcmFjdGlvbn1cbiAgICAgKi9cbiAgICBzZXRJbml0aWFsVGV4dCAodGV4dCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihQZXJmb3JtSW50ZXJhY3Rpb24uS0VZX0lOSVRJQUxfVEVYVCwgdGV4dCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRJbml0aWFsVGV4dCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihQZXJmb3JtSW50ZXJhY3Rpb24uS0VZX0lOSVRJQUxfVEVYVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtUVFNDaHVua1tdfSBwcm9tcHQgLSBUaGlzIGlzIHRoZSBpbml0aWFsIHByb21wdCBzcG9rZW4gdG8gdGhlIHVzZXIgYXQgdGhlIHN0YXJ0IG9mIGFuIGludGVyYWN0aW9uLiBBblxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXkgb2YgdGV4dCBjaHVua3Mgb2YgdHlwZSBUVFNDaHVuay4gU2VlIFRUU0NodW5rLiBUaGUgYXJyYXkgbXVzdCBoYXZlIGF0IGxlYXN0XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmUgaXRlbS5cbiAgICAgKiBAcmV0dXJuIHtQZXJmb3JtSW50ZXJhY3Rpb259XG4gICAgICovXG4gICAgc2V0SW5pdGlhbFByb21wdCAocHJvbXB0KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFRUU0NodW5rLCBwcm9tcHQsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihQZXJmb3JtSW50ZXJhY3Rpb24uS0VZX0lOSVRJQUxfUFJPTVBULCBwcm9tcHQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtUVFNDaHVua1tdfVxuICAgICAqL1xuICAgIGdldEluaXRpYWxQcm9tcHQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVFRTQ2h1bmssIFBlcmZvcm1JbnRlcmFjdGlvbi5LRVlfSU5JVElBTF9QUk9NUFQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7SW50ZXJhY3Rpb25Nb2RlfSBtb2RlIC0gU2VlIEludGVyYWN0aW9uTW9kZS5cbiAgICAgKiBAcmV0dXJuIHtQZXJmb3JtSW50ZXJhY3Rpb259XG4gICAgICovXG4gICAgc2V0SW50ZXJhY3Rpb25Nb2RlIChtb2RlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEludGVyYWN0aW9uTW9kZSwgbW9kZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFBlcmZvcm1JbnRlcmFjdGlvbi5LRVlfSU5URVJBQ1RJT05fTU9ERSwgbW9kZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0ludGVyYWN0aW9uTW9kZX1cbiAgICAgKi9cbiAgICBnZXRJbnRlcmFjdGlvbk1vZGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoSW50ZXJhY3Rpb25Nb2RlLCBQZXJmb3JtSW50ZXJhY3Rpb24uS0VZX0lOVEVSQUNUSU9OX01PREUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyW119IGxpc3QgLSBMaXN0IG9mIGludGVyYWN0aW9uIGNob2ljZSBzZXQgSURzIHRvIHVzZSB3aXRoIGFuIGludGVyYWN0aW9uLlxuICAgICAqIEByZXR1cm4ge1BlcmZvcm1JbnRlcmFjdGlvbn1cbiAgICAgKi9cbiAgICBzZXRJbnRlcmFjdGlvbkNob2ljZVNldElETGlzdCAobGlzdCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihQZXJmb3JtSW50ZXJhY3Rpb24uS0VZX0lOVEVSQUNUSU9OX0NIT0lDRV9TRVRfSURMSVNULCBsaXN0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyW119XG4gICAgICovXG4gICAgZ2V0SW50ZXJhY3Rpb25DaG9pY2VTZXRJRExpc3QgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUGVyZm9ybUludGVyYWN0aW9uLktFWV9JTlRFUkFDVElPTl9DSE9JQ0VfU0VUX0lETElTVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtUVFNDaHVua1tdfSBwcm9tcHQgLSBIZWxwIHRleHQuIFRoaXMgaXMgdGhlIHNwb2tlbiBzdHJpbmcgd2hlbiBhIHVzZXIgc3BlYWtzIFwiaGVscFwiIHdoZW4gdGhlIGludGVyYWN0aW9uXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcyBvY2N1cnJpbmcuIEFuIGFycmF5IG9mIHRleHQgY2h1bmtzIG9mIHR5cGUgVFRTQ2h1bmsuIFNlZSBUVFNDaHVuay4gVGhlIGFycmF5IG11c3RcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhdmUgYXQgbGVhc3Qgb25lIGl0ZW0uXG4gICAgICogQHJldHVybiB7UGVyZm9ybUludGVyYWN0aW9ufVxuICAgICAqL1xuICAgIHNldEhlbHBQcm9tcHQgKHByb21wdCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShUVFNDaHVuaywgcHJvbXB0LCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUGVyZm9ybUludGVyYWN0aW9uLktFWV9IRUxQX1BST01QVCwgcHJvbXB0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VFRTQ2h1bmtbXX1cbiAgICAgKi9cbiAgICBnZXRIZWxwUHJvbXB0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFRUU0NodW5rLCBQZXJmb3JtSW50ZXJhY3Rpb24uS0VZX0hFTFBfUFJPTVBUKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1RUU0NodW5rW119IHByb21wdCAtIFRpbWVvdXQgdGV4dC4gVGhpcyB0ZXh0IGlzIHNwb2tlbiB3aGVuIGEgVlIgaW50ZXJhY3Rpb24gdGltZXMgb3V0LiBBbiBhcnJheSBvZiB0ZXh0XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaHVua3Mgb2YgdHlwZSBUVFNDaHVuay4gU2VlIFRUU0NodW5rLiBUaGUgYXJyYXkgbXVzdCBoYXZlIGF0IGxlYXN0IG9uZSBpdGVtLlxuICAgICAqIEByZXR1cm4ge1BlcmZvcm1JbnRlcmFjdGlvbn1cbiAgICAgKi9cbiAgICBzZXRUaW1lb3V0UHJvbXB0IChwcm9tcHQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVFRTQ2h1bmssIHByb21wdCwgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFBlcmZvcm1JbnRlcmFjdGlvbi5LRVlfVElNRU9VVF9QUk9NUFQsIHByb21wdCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1RUU0NodW5rW119XG4gICAgICovXG4gICAgZ2V0VGltZW91dFByb21wdCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChUVFNDaHVuaywgUGVyZm9ybUludGVyYWN0aW9uLktFWV9USU1FT1VUX1BST01QVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHRpbWVvdXQgLSBUaW1lb3V0IGluIG1pbGxpc2Vjb25kcy4gSWYgb21pdHRlZCBhIHN0YW5kYXJkIHZhbHVlIG9mIDEwMDAwIG1pbGxpc2Vjb25kcyBpcyB1c2VkLlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgQXBwbGllcyBvbmx5IHRvIHRoZSBtZW51IHBvcnRpb24gb2YgdGhlIGludGVyYWN0aW9uLiBUaGUgVlIgdGltZW91dCB3aWxsIGJlIGhhbmRsZWQgYnlcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBwbGF0Zm9ybS5cbiAgICAgKiBAcmV0dXJuIHtQZXJmb3JtSW50ZXJhY3Rpb259XG4gICAgICovXG4gICAgc2V0VGltZW91dCAodGltZW91dCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihQZXJmb3JtSW50ZXJhY3Rpb24uS0VZX1RJTUVPVVQsIHRpbWVvdXQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0VGltZW91dCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihQZXJmb3JtSW50ZXJhY3Rpb24uS0VZX1RJTUVPVVQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VnJIZWxwSXRlbVtdfSBoZWxwIC0gQWJpbGl0eSB0byBzZW5kIHN1Z2dlc3RlZCBWUiBIZWxwIEl0ZW1zIHRvIGRpc3BsYXkgb24tc2NyZWVuIGR1cmluZyBQZXJmb3JtXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlcmFjdGlvbi4gSWYgb21pdHRlZCBvbiBzdXBwb3J0ZWQgZGlzcGxheXMsIHRoZSBkZWZhdWx0IGdlbmVyYXRlZCBsaXN0IG9mXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWdnZXN0ZWQgY2hvaWNlcyBzaGFsbCBiZSBkaXNwbGF5ZWQuXG4gICAgICogQHJldHVybiB7UGVyZm9ybUludGVyYWN0aW9ufVxuICAgICAqL1xuICAgIHNldFZySGVscCAoaGVscCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWckhlbHBJdGVtLCBoZWxwLCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUGVyZm9ybUludGVyYWN0aW9uLktFWV9WUl9IRUxQLCBoZWxwKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VnJIZWxwSXRlbVtdfVxuICAgICAqL1xuICAgIGdldFZySGVscCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWckhlbHBJdGVtLCBQZXJmb3JtSW50ZXJhY3Rpb24uS0VZX1ZSX0hFTFApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TGF5b3V0TW9kZX0gbGF5b3V0IC0gU2VlIExheW91dE1vZGUuXG4gICAgICogQHJldHVybiB7UGVyZm9ybUludGVyYWN0aW9ufVxuICAgICAqL1xuICAgIHNldEludGVyYWN0aW9uTGF5b3V0IChsYXlvdXQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTGF5b3V0TW9kZSwgbGF5b3V0KTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUGVyZm9ybUludGVyYWN0aW9uLktFWV9JTlRFUkFDVElPTl9MQVlPVVQsIGxheW91dCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0xheW91dE1vZGV9XG4gICAgICovXG4gICAgZ2V0SW50ZXJhY3Rpb25MYXlvdXQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTGF5b3V0TW9kZSwgUGVyZm9ybUludGVyYWN0aW9uLktFWV9JTlRFUkFDVElPTl9MQVlPVVQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBpZCAtIEFuIElEIGZvciB0aGlzIHNwZWNpZmljIFBlcmZvcm1JbnRlcmFjdGlvbiB0byBhbGxvdyBjYW5jZWxsYXRpb24gdGhyb3VnaCB0aGVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBgQ2FuY2VsSW50ZXJhY3Rpb25gIFJQQy5cbiAgICAgKiBAcmV0dXJuIHtQZXJmb3JtSW50ZXJhY3Rpb259XG4gICAgICovXG4gICAgc2V0Q2FuY2VsSUQgKGlkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFBlcmZvcm1JbnRlcmFjdGlvbi5LRVlfQ0FOQ0VMX0lELCBpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRDYW5jZWxJRCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihQZXJmb3JtSW50ZXJhY3Rpb24uS0VZX0NBTkNFTF9JRCk7XG4gICAgfVxufVxuXG5QZXJmb3JtSW50ZXJhY3Rpb24uS0VZX0lOSVRJQUxfVEVYVCA9ICdpbml0aWFsVGV4dCc7XG5QZXJmb3JtSW50ZXJhY3Rpb24uS0VZX0lOSVRJQUxfUFJPTVBUID0gJ2luaXRpYWxQcm9tcHQnO1xuUGVyZm9ybUludGVyYWN0aW9uLktFWV9JTlRFUkFDVElPTl9NT0RFID0gJ2ludGVyYWN0aW9uTW9kZSc7XG5QZXJmb3JtSW50ZXJhY3Rpb24uS0VZX0lOVEVSQUNUSU9OX0NIT0lDRV9TRVRfSURMSVNUID0gJ2ludGVyYWN0aW9uQ2hvaWNlU2V0SURMaXN0JztcblBlcmZvcm1JbnRlcmFjdGlvbi5LRVlfSEVMUF9QUk9NUFQgPSAnaGVscFByb21wdCc7XG5QZXJmb3JtSW50ZXJhY3Rpb24uS0VZX1RJTUVPVVRfUFJPTVBUID0gJ3RpbWVvdXRQcm9tcHQnO1xuUGVyZm9ybUludGVyYWN0aW9uLktFWV9USU1FT1VUID0gJ3RpbWVvdXQnO1xuUGVyZm9ybUludGVyYWN0aW9uLktFWV9WUl9IRUxQID0gJ3ZySGVscCc7XG5QZXJmb3JtSW50ZXJhY3Rpb24uS0VZX0lOVEVSQUNUSU9OX0xBWU9VVCA9ICdpbnRlcmFjdGlvbkxheW91dCc7XG5QZXJmb3JtSW50ZXJhY3Rpb24uS0VZX0NBTkNFTF9JRCA9ICdjYW5jZWxJRCc7XG5cbmV4cG9ydCB7IFBlcmZvcm1JbnRlcmFjdGlvbiB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEluZGljYXRlcyB0aGUgc291cmNlIGZyb20gd2hlcmUgdGhlIGNvbW1hbmQgd2FzIHRyaWdnZXJlZC5cbiAqIEB0eXBlZGVmIHtFbnVtfSBUcmlnZ2VyU291cmNlXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBUcmlnZ2VyU291cmNlIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFRTX01FTlUgKCkge1xuICAgICAgICByZXR1cm4gVHJpZ2dlclNvdXJjZS5fTUFQLlRTX01FTlU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVFNfVlIgKCkge1xuICAgICAgICByZXR1cm4gVHJpZ2dlclNvdXJjZS5fTUFQLlRTX1ZSO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFRTX0tFWUJPQVJEICgpIHtcbiAgICAgICAgcmV0dXJuIFRyaWdnZXJTb3VyY2UuX01BUC5UU19LRVlCT0FSRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBUcmlnZ2VyU291cmNlLl92YWx1ZUZvcktleShrZXksIFRyaWdnZXJTb3VyY2UuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBUcmlnZ2VyU291cmNlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgVHJpZ2dlclNvdXJjZS5fTUFQKTtcbiAgICB9XG59XG5cblRyaWdnZXJTb3VyY2UuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdUU19NRU5VJzogJ01FTlUnLFxuICAgICdUU19WUic6ICdWUicsXG4gICAgJ1RTX0tFWUJPQVJEJzogJ0tFWUJPQVJEJyxcbn0pO1xuXG5leHBvcnQgeyBUcmlnZ2VyU291cmNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgVHJpZ2dlclNvdXJjZSB9IGZyb20gJy4uL2VudW1zL1RyaWdnZXJTb3VyY2UuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbmNsYXNzIFBlcmZvcm1JbnRlcmFjdGlvblJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuUGVyZm9ybUludGVyYWN0aW9uKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaWQgLSBJRCBvZiB0aGUgY2hvaWNlIHRoYXQgd2FzIHNlbGVjdGVkIGluIHJlc3BvbnNlIHRvIFBlcmZvcm1JbnRlcmFjdGlvbi4gT25seSBpcyB2YWxpZCBpZlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIGdlbmVyYWwgcmVzdWx0IGlzIFwic3VjY2Vzczp0cnVlXCIuXG4gICAgICogQHJldHVybiB7UGVyZm9ybUludGVyYWN0aW9uUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0Q2hvaWNlSUQgKGlkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFBlcmZvcm1JbnRlcmFjdGlvblJlc3BvbnNlLktFWV9DSE9JQ0VfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldENob2ljZUlEICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFBlcmZvcm1JbnRlcmFjdGlvblJlc3BvbnNlLktFWV9DSE9JQ0VfSUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBlbnRyeSAtIE1hbnVhbGx5IGVudGVyZWQgdGV4dCBzZWxlY3Rpb24sIGUuZy4gdGhyb3VnaCBrZXlib2FyZCBDYW4gYmUgcmV0dXJuZWQgaW4gbGlldSBvZlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGNob2ljZUlELCBkZXBlbmRpbmcgb24gdHJpZ2dlciBzb3VyY2VcbiAgICAgKiBAcmV0dXJuIHtQZXJmb3JtSW50ZXJhY3Rpb25SZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRNYW51YWxUZXh0RW50cnkgKGVudHJ5KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFBlcmZvcm1JbnRlcmFjdGlvblJlc3BvbnNlLktFWV9NQU5VQUxfVEVYVF9FTlRSWSwgZW50cnkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0TWFudWFsVGV4dEVudHJ5ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFBlcmZvcm1JbnRlcmFjdGlvblJlc3BvbnNlLktFWV9NQU5VQUxfVEVYVF9FTlRSWSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtUcmlnZ2VyU291cmNlfSBzb3VyY2UgLSBTZWUgVHJpZ2dlclNvdXJjZSBPbmx5IGlzIHZhbGlkIGlmIHJlc3VsdENvZGUgaXMgU1VDQ0VTUy5cbiAgICAgKiBAcmV0dXJuIHtQZXJmb3JtSW50ZXJhY3Rpb25SZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRUcmlnZ2VyU291cmNlIChzb3VyY2UpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVHJpZ2dlclNvdXJjZSwgc291cmNlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUGVyZm9ybUludGVyYWN0aW9uUmVzcG9uc2UuS0VZX1RSSUdHRVJfU09VUkNFLCBzb3VyY2UpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtUcmlnZ2VyU291cmNlfVxuICAgICAqL1xuICAgIGdldFRyaWdnZXJTb3VyY2UgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVHJpZ2dlclNvdXJjZSwgUGVyZm9ybUludGVyYWN0aW9uUmVzcG9uc2UuS0VZX1RSSUdHRVJfU09VUkNFKTtcbiAgICB9XG59XG5cblBlcmZvcm1JbnRlcmFjdGlvblJlc3BvbnNlLktFWV9DSE9JQ0VfSUQgPSAnY2hvaWNlSUQnO1xuUGVyZm9ybUludGVyYWN0aW9uUmVzcG9uc2UuS0VZX01BTlVBTF9URVhUX0VOVFJZID0gJ21hbnVhbFRleHRFbnRyeSc7XG5QZXJmb3JtSW50ZXJhY3Rpb25SZXNwb25zZS5LRVlfVFJJR0dFUl9TT1VSQ0UgPSAndHJpZ2dlclNvdXJjZSc7XG5cbmV4cG9ydCB7IFBlcmZvcm1JbnRlcmFjdGlvblJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG4vKipcbiAqIERlbGV0ZXMgaW50ZXJhY3Rpb24gY2hvaWNlIHNldCB0aGF0IGhhcyBiZWVuIGNyZWF0ZWQgd2l0aCBcIkNyZWF0ZUludGVyYWN0aW9uQ2hvaWNlU2V0XCIuIFRoZSBpbnRlcmFjdGlvbiBtYXkgb25seSBiZVxuICogZGVsZXRlZCB3aGVuIG5vdCBjdXJyZW50bHkgaW4gdXNlIGJ5IGEgXCJwZXJmb3JtSW50ZXJhY3Rpb25cIi5cbiAqL1xuY2xhc3MgRGVsZXRlSW50ZXJhY3Rpb25DaG9pY2VTZXQgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkRlbGV0ZUludGVyYWN0aW9uQ2hvaWNlU2V0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaWQgLSBJRCBvZiB0aGUgaW50ZXJhY3Rpb24gY2hvaWNlIHNldCB0byBkZWxldGUuXG4gICAgICogQHJldHVybiB7RGVsZXRlSW50ZXJhY3Rpb25DaG9pY2VTZXR9XG4gICAgICovXG4gICAgc2V0SW50ZXJhY3Rpb25DaG9pY2VTZXRJRCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGVsZXRlSW50ZXJhY3Rpb25DaG9pY2VTZXQuS0VZX0lOVEVSQUNUSU9OX0NIT0lDRV9TRVRfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldEludGVyYWN0aW9uQ2hvaWNlU2V0SUQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoRGVsZXRlSW50ZXJhY3Rpb25DaG9pY2VTZXQuS0VZX0lOVEVSQUNUSU9OX0NIT0lDRV9TRVRfSUQpO1xuICAgIH1cbn1cblxuRGVsZXRlSW50ZXJhY3Rpb25DaG9pY2VTZXQuS0VZX0lOVEVSQUNUSU9OX0NIT0lDRV9TRVRfSUQgPSAnaW50ZXJhY3Rpb25DaG9pY2VTZXRJRCc7XG5cbmV4cG9ydCB7IERlbGV0ZUludGVyYWN0aW9uQ2hvaWNlU2V0IH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbmNsYXNzIERlbGV0ZUludGVyYWN0aW9uQ2hvaWNlU2V0UmVzcG9uc2UgZXh0ZW5kcyBScGNSZXNwb25zZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5EZWxldGVJbnRlcmFjdGlvbkNob2ljZVNldCk7XG4gICAgfVxufVxuXG5cbmV4cG9ydCB7IERlbGV0ZUludGVyYWN0aW9uQ2hvaWNlU2V0UmVzcG9uc2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBDb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgU29mdEJ1dHRvbiBjYXBhYmlsaXRpZXMuXG4gKiBAdHlwZWRlZiB7RW51bX0gU29mdEJ1dHRvblR5cGVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIFNvZnRCdXR0b25UeXBlIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNCVF9URVhUICgpIHtcbiAgICAgICAgcmV0dXJuIFNvZnRCdXR0b25UeXBlLl9NQVAuU0JUX1RFWFQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0JUX0lNQUdFICgpIHtcbiAgICAgICAgcmV0dXJuIFNvZnRCdXR0b25UeXBlLl9NQVAuU0JUX0lNQUdFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNCVF9CT1RIICgpIHtcbiAgICAgICAgcmV0dXJuIFNvZnRCdXR0b25UeXBlLl9NQVAuU0JUX0JPVEg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gU29mdEJ1dHRvblR5cGUuX3ZhbHVlRm9yS2V5KGtleSwgU29mdEJ1dHRvblR5cGUuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBTb2Z0QnV0dG9uVHlwZS5fa2V5Rm9yVmFsdWUodmFsdWUsIFNvZnRCdXR0b25UeXBlLl9NQVApO1xuICAgIH1cbn1cblxuU29mdEJ1dHRvblR5cGUuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdTQlRfVEVYVCc6ICdURVhUJyxcbiAgICAnU0JUX0lNQUdFJzogJ0lNQUdFJyxcbiAgICAnU0JUX0JPVEgnOiAnQk9USCcsXG59KTtcblxuZXhwb3J0IHsgU29mdEJ1dHRvblR5cGUgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBFbnVtZXJhdGlvbiB0aGF0IGRlc2NyaWJlcyBzeXN0ZW0gYWN0aW9ucyB0aGF0IGNhbiBiZSB0cmlnZ2VyZWQuXG4gKiBAdHlwZWRlZiB7RW51bX0gU3lzdGVtQWN0aW9uXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBTeXN0ZW1BY3Rpb24gZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVmYXVsdCBhY3Rpb24gb2NjdXJzLiBTdGFuZGFyZCBiZWhhdmlvciAoZS5nLiBTb2Z0QnV0dG9uIGNsZWFycyBvdmVybGF5KS5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBERUZBVUxUX0FDVElPTiAoKSB7XG4gICAgICAgIHJldHVybiBTeXN0ZW1BY3Rpb24uX01BUC5ERUZBVUxUX0FDVElPTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBcHAgaXMgYnJvdWdodCBpbnRvIEhNSV9GVUxMLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNURUFMX0ZPQ1VTICgpIHtcbiAgICAgICAgcmV0dXJuIFN5c3RlbUFjdGlvbi5fTUFQLlNURUFMX0ZPQ1VTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEN1cnJlbnQgc3lzdGVtIGNvbnRleHQgaXMgbWFpbnRhaW5lZC4gQW4gb3ZlcmxheSBpcyBwZXJzaXN0ZWQgZXZlbiB0aG91Z2ggYSBTb2Z0QnV0dG9uIGhhcyBiZWVuIHByZXNzZWQgYW5kIHRoZVxuICAgICAqIG5vdGlmaWNhdGlvbiBzZW50LlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEtFRVBfQ09OVEVYVCAoKSB7XG4gICAgICAgIHJldHVybiBTeXN0ZW1BY3Rpb24uX01BUC5LRUVQX0NPTlRFWFQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gU3lzdGVtQWN0aW9uLl92YWx1ZUZvcktleShrZXksIFN5c3RlbUFjdGlvbi5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFN5c3RlbUFjdGlvbi5fa2V5Rm9yVmFsdWUodmFsdWUsIFN5c3RlbUFjdGlvbi5fTUFQKTtcbiAgICB9XG59XG5cblN5c3RlbUFjdGlvbi5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0RFRkFVTFRfQUNUSU9OJzogJ0RFRkFVTFRfQUNUSU9OJyxcbiAgICAnU1RFQUxfRk9DVVMnOiAnU1RFQUxfRk9DVVMnLFxuICAgICdLRUVQX0NPTlRFWFQnOiAnS0VFUF9DT05URVhUJyxcbn0pO1xuXG5leHBvcnQgeyBTeXN0ZW1BY3Rpb24gfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgU29mdEJ1dHRvblR5cGUgfSBmcm9tICcuLi9lbnVtcy9Tb2Z0QnV0dG9uVHlwZS5qcyc7XG5pbXBvcnQgeyBJbWFnZSB9IGZyb20gJy4vSW1hZ2UuanMnO1xuaW1wb3J0IHsgU3lzdGVtQWN0aW9uIH0gZnJvbSAnLi4vZW51bXMvU3lzdGVtQWN0aW9uLmpzJztcblxuY2xhc3MgU29mdEJ1dHRvbiBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTb2Z0QnV0dG9uVHlwZX0gdHlwZSAtIERlc2NyaWJlcywgd2hldGhlciBpdCBpcyB0ZXh0LCBoaWdobGlnaHRlZCB0ZXh0LCBpY29uLCBvciBkeW5hbWljIGltYWdlLiBTZWVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc29mdEJ1dHRvblR5cGVcbiAgICAgKiBAcmV0dXJuIHtTb2Z0QnV0dG9ufVxuICAgICAqL1xuICAgIHNldFR5cGUgKHR5cGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoU29mdEJ1dHRvblR5cGUsIHR5cGUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTb2Z0QnV0dG9uLktFWV9UWVBFLCB0eXBlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U29mdEJ1dHRvblR5cGV9XG4gICAgICovXG4gICAgZ2V0VHlwZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChTb2Z0QnV0dG9uVHlwZSwgU29mdEJ1dHRvbi5LRVlfVFlQRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHRleHQgLSBPcHRpb25hbCB0ZXh0IHRvIGRpc3BsYXkgKGlmIGRlZmluZWQgYXMgVEVYVCBvciBCT1RIKVxuICAgICAqIEByZXR1cm4ge1NvZnRCdXR0b259XG4gICAgICovXG4gICAgc2V0VGV4dCAodGV4dCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTb2Z0QnV0dG9uLktFWV9URVhULCB0ZXh0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldFRleHQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU29mdEJ1dHRvbi5LRVlfVEVYVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtJbWFnZX0gaW1hZ2UgLSBPcHRpb25hbCBpbWFnZSBzdHJ1Y3QgZm9yIFNvZnRCdXR0b24gKGlmIGRlZmluZWQgYXMgSU1BR0Ugb3IgQk9USClcbiAgICAgKiBAcmV0dXJuIHtTb2Z0QnV0dG9ufVxuICAgICAqL1xuICAgIHNldEltYWdlIChpbWFnZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShJbWFnZSwgaW1hZ2UpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTb2Z0QnV0dG9uLktFWV9JTUFHRSwgaW1hZ2UpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtJbWFnZX1cbiAgICAgKi9cbiAgICBnZXRJbWFnZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChJbWFnZSwgU29mdEJ1dHRvbi5LRVlfSU1BR0UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gaGlnaGxpZ2h0ZWQgLSBUcnVlLCBpZiBoaWdobGlnaHRlZCBGYWxzZSwgaWYgbm90IGhpZ2hsaWdodGVkXG4gICAgICogQHJldHVybiB7U29mdEJ1dHRvbn1cbiAgICAgKi9cbiAgICBzZXRJc0hpZ2hsaWdodGVkIChoaWdobGlnaHRlZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTb2Z0QnV0dG9uLktFWV9JU19ISUdITElHSFRFRCwgaGlnaGxpZ2h0ZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldElzSGlnaGxpZ2h0ZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU29mdEJ1dHRvbi5LRVlfSVNfSElHSExJR0hURUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBpZCAtIFZhbHVlIHdoaWNoIGlzIHJldHVybmVkIHZpYSBPbkJ1dHRvblByZXNzIC8gT25CdXR0b25FdmVudFxuICAgICAqIEByZXR1cm4ge1NvZnRCdXR0b259XG4gICAgICovXG4gICAgc2V0U29mdEJ1dHRvbklEIChpZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTb2Z0QnV0dG9uLktFWV9TT0ZUX0JVVFRPTl9JRCwgaWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0U29mdEJ1dHRvbklEICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNvZnRCdXR0b24uS0VZX1NPRlRfQlVUVE9OX0lEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N5c3RlbUFjdGlvbn0gYWN0aW9uIC0gUGFyYW1ldGVyIGluZGljYXRpbmcgd2hldGhlciBzZWxlY3RpbmcgYSBTb2Z0QnV0dG9uIHNoYWxsIGNhbGwgYSBzcGVjaWZpYyBzeXN0ZW1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uLiBUaGlzIGlzIGludGVuZGVkIHRvIGFsbG93IE5vdGlmaWNhdGlvbnMgdG8gYnJpbmcgdGhlIGNhbGxlZSBpbnRvIGZ1bGwgL1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb2N1czsgb3IgaW4gdGhlIGNhc2Ugb2YgcGVyc2lzdGVudCBvdmVybGF5cywgdGhlIG92ZXJsYXkgY2FuIHBlcnNpc3Qgd2hlbiBhXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvZnRCdXR0b24gaXMgcHJlc3NlZC5cbiAgICAgKiBAcmV0dXJuIHtTb2Z0QnV0dG9ufVxuICAgICAqL1xuICAgIHNldFN5c3RlbUFjdGlvbiAoYWN0aW9uKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFN5c3RlbUFjdGlvbiwgYWN0aW9uKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU29mdEJ1dHRvbi5LRVlfU1lTVEVNX0FDVElPTiwgYWN0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3lzdGVtQWN0aW9ufVxuICAgICAqL1xuICAgIGdldFN5c3RlbUFjdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChTeXN0ZW1BY3Rpb24sIFNvZnRCdXR0b24uS0VZX1NZU1RFTV9BQ1RJT04pO1xuICAgIH1cbn1cblxuU29mdEJ1dHRvbi5LRVlfVFlQRSA9ICd0eXBlJztcblNvZnRCdXR0b24uS0VZX1RFWFQgPSAndGV4dCc7XG5Tb2Z0QnV0dG9uLktFWV9JTUFHRSA9ICdpbWFnZSc7XG5Tb2Z0QnV0dG9uLktFWV9JU19ISUdITElHSFRFRCA9ICdpc0hpZ2hsaWdodGVkJztcblNvZnRCdXR0b24uS0VZX1NPRlRfQlVUVE9OX0lEID0gJ3NvZnRCdXR0b25JRCc7XG5Tb2Z0QnV0dG9uLktFWV9TWVNURU1fQUNUSU9OID0gJ3N5c3RlbUFjdGlvbic7XG5cbmV4cG9ydCB7IFNvZnRCdXR0b24gfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBUVFNDaHVuayB9IGZyb20gJy4uL3N0cnVjdHMvVFRTQ2h1bmsuanMnO1xuaW1wb3J0IHsgU29mdEJ1dHRvbiB9IGZyb20gJy4uL3N0cnVjdHMvU29mdEJ1dHRvbi5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBJbWFnZSB9IGZyb20gJy4uL3N0cnVjdHMvSW1hZ2UuanMnO1xuXG4vKipcbiAqIFNob3dzIGFuIGFsZXJ0IHdoaWNoIHR5cGljYWxseSBjb25zaXN0cyBvZiB0ZXh0LXRvLXNwZWVjaCBtZXNzYWdlIGFuZCB0ZXh0IG9uIHRoZSBkaXNwbGF5LiBBdCBsZWFzdCBlaXRoZXJcbiAqIGFsZXJ0VGV4dDEsIGFsZXJ0VGV4dDIgb3IgVFRTQ2h1bmtzIG5lZWQgdG8gYmUgcHJvdmlkZWQuXG4gKi9cbmNsYXNzIEFsZXJ0IGV4dGVuZHMgUnBjUmVxdWVzdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5BbGVydCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHRleHQxIC0gVGhlIGZpcnN0IGxpbmUgb2YgdGhlIGFsZXJ0IHRleHQgZmllbGRcbiAgICAgKiBAcmV0dXJuIHtBbGVydH1cbiAgICAgKi9cbiAgICBzZXRBbGVydFRleHQxICh0ZXh0MSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBbGVydC5LRVlfQUxFUlRfVEVYVF8xLCB0ZXh0MSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRBbGVydFRleHQxICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEFsZXJ0LktFWV9BTEVSVF9URVhUXzEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0MiAtIFRoZSBzZWNvbmQgbGluZSBvZiB0aGUgYWxlcnQgdGV4dCBmaWVsZFxuICAgICAqIEByZXR1cm4ge0FsZXJ0fVxuICAgICAqL1xuICAgIHNldEFsZXJ0VGV4dDIgKHRleHQyKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEFsZXJ0LktFWV9BTEVSVF9URVhUXzIsIHRleHQyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldEFsZXJ0VGV4dDIgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQWxlcnQuS0VZX0FMRVJUX1RFWFRfMik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHRleHQzIC0gVGhlIG9wdGlvbmFsIHRoaXJkIGxpbmUgb2YgdGhlIGFsZXJ0IHRleHQgZmllbGRcbiAgICAgKiBAcmV0dXJuIHtBbGVydH1cbiAgICAgKi9cbiAgICBzZXRBbGVydFRleHQzICh0ZXh0Mykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBbGVydC5LRVlfQUxFUlRfVEVYVF8zLCB0ZXh0Myk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRBbGVydFRleHQzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEFsZXJ0LktFWV9BTEVSVF9URVhUXzMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VFRTQ2h1bmtbXX0gY2h1bmtzIC0gQW4gYXJyYXkgb2YgdGV4dCBjaHVua3Mgb2YgdHlwZSBUVFNDaHVuay4gU2VlIFRUU0NodW5rLiBUaGUgYXJyYXkgbXVzdCBoYXZlIGF0IGxlYXN0XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmUgaXRlbS5cbiAgICAgKiBAcmV0dXJuIHtBbGVydH1cbiAgICAgKi9cbiAgICBzZXRUdHNDaHVua3MgKGNodW5rcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShUVFNDaHVuaywgY2h1bmtzLCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQWxlcnQuS0VZX1RUU19DSFVOS1MsIGNodW5rcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1RUU0NodW5rW119XG4gICAgICovXG4gICAgZ2V0VHRzQ2h1bmtzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFRUU0NodW5rLCBBbGVydC5LRVlfVFRTX0NIVU5LUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGR1cmF0aW9uIC0gVGltZW91dCBpbiBtaWxsaXNlY29uZHMuIFR5cGljYWwgdGltZW91dHMgYXJlIDMtNSBzZWNvbmRzLiBJZiBvbWl0dGVkLCB0aW1lb3V0IGlzIHNldFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvIDVzLlxuICAgICAqIEByZXR1cm4ge0FsZXJ0fVxuICAgICAqL1xuICAgIHNldER1cmF0aW9uIChkdXJhdGlvbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBbGVydC5LRVlfRFVSQVRJT04sIGR1cmF0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldER1cmF0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEFsZXJ0LktFWV9EVVJBVElPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSB0b25lIC0gRGVmaW5lcyBpZiB0b25lIHNob3VsZCBiZSBwbGF5ZWQuIFRvbmUgaXMgcGxheWVkIGJlZm9yZSBUVFMuIElmIG9taXR0ZWQsIG5vIHRvbmUgaXNcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBwbGF5ZWQuXG4gICAgICogQHJldHVybiB7QWxlcnR9XG4gICAgICovXG4gICAgc2V0UGxheVRvbmUgKHRvbmUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQWxlcnQuS0VZX1BMQVlfVE9ORSwgdG9uZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0UGxheVRvbmUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQWxlcnQuS0VZX1BMQVlfVE9ORSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBpbmRpY2F0b3IgLSBJZiBzdXBwb3J0ZWQgb24gdGhlIGdpdmVuIHBsYXRmb3JtLCB0aGUgYWxlcnQgR1VJIHdpbGwgaW5jbHVkZSBzb21lIHNvcnQgb2ZcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbiBpbmRpY2F0aW5nIHRoYXQgbG9hZGluZyBvZiBhIGZlYXR1cmUgaXMgcHJvZ3Jlc3NpbmcuIGUuZy4gYSBzcGlubmluZyB3aGVlbFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3IgaG91cmdsYXNzLCBldGMuXG4gICAgICogQHJldHVybiB7QWxlcnR9XG4gICAgICovXG4gICAgc2V0UHJvZ3Jlc3NJbmRpY2F0b3IgKGluZGljYXRvcikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBbGVydC5LRVlfUFJPR1JFU1NfSU5ESUNBVE9SLCBpbmRpY2F0b3IpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFByb2dyZXNzSW5kaWNhdG9yICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEFsZXJ0LktFWV9QUk9HUkVTU19JTkRJQ0FUT1IpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U29mdEJ1dHRvbltdfSBidXR0b25zIC0gQXBwIGRlZmluZWQgU29mdEJ1dHRvbnMuIElmIG9taXR0ZWQgb24gc3VwcG9ydGVkIGRpc3BsYXlzLCB0aGUgZGlzcGxheWVkIGFsZXJ0XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFsbCBub3QgaGF2ZSBhbnkgU29mdEJ1dHRvbnMuXG4gICAgICogQHJldHVybiB7QWxlcnR9XG4gICAgICovXG4gICAgc2V0U29mdEJ1dHRvbnMgKGJ1dHRvbnMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoU29mdEJ1dHRvbiwgYnV0dG9ucywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEFsZXJ0LktFWV9TT0ZUX0JVVFRPTlMsIGJ1dHRvbnMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTb2Z0QnV0dG9uW119XG4gICAgICovXG4gICAgZ2V0U29mdEJ1dHRvbnMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoU29mdEJ1dHRvbiwgQWxlcnQuS0VZX1NPRlRfQlVUVE9OUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtJbWFnZX0gaWNvbiAtIEltYWdlIHN0cnVjdCBkZXRlcm1pbmluZyB3aGV0aGVyIHN0YXRpYyBvciBkeW5hbWljIGljb24uIElmIG9taXR0ZWQgb24gc3VwcG9ydGVkIGRpc3BsYXlzLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICBubyAob3IgdGhlIGRlZmF1bHQgaWYgYXBwbGljYWJsZSkgaWNvbiBzaG91bGQgYmUgZGlzcGxheWVkLlxuICAgICAqIEByZXR1cm4ge0FsZXJ0fVxuICAgICAqL1xuICAgIHNldEFsZXJ0SWNvbiAoaWNvbikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShJbWFnZSwgaWNvbik7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEFsZXJ0LktFWV9BTEVSVF9JQ09OLCBpY29uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7SW1hZ2V9XG4gICAgICovXG4gICAgZ2V0QWxlcnRJY29uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEltYWdlLCBBbGVydC5LRVlfQUxFUlRfSUNPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGlkIC0gQW4gSUQgZm9yIHRoaXMgc3BlY2lmaWMgYWxlcnQgdG8gYWxsb3cgY2FuY2VsbGF0aW9uIHRocm91Z2ggdGhlIGBDYW5jZWxJbnRlcmFjdGlvbmAgUlBDLlxuICAgICAqIEByZXR1cm4ge0FsZXJ0fVxuICAgICAqL1xuICAgIHNldENhbmNlbElEIChpZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBbGVydC5LRVlfQ0FOQ0VMX0lELCBpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRDYW5jZWxJRCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihBbGVydC5LRVlfQ0FOQ0VMX0lEKTtcbiAgICB9XG59XG5cbkFsZXJ0LktFWV9BTEVSVF9URVhUXzEgPSAnYWxlcnRUZXh0MSc7XG5BbGVydC5LRVlfQUxFUlRfVEVYVF8yID0gJ2FsZXJ0VGV4dDInO1xuQWxlcnQuS0VZX0FMRVJUX1RFWFRfMyA9ICdhbGVydFRleHQzJztcbkFsZXJ0LktFWV9UVFNfQ0hVTktTID0gJ3R0c0NodW5rcyc7XG5BbGVydC5LRVlfRFVSQVRJT04gPSAnZHVyYXRpb24nO1xuQWxlcnQuS0VZX1BMQVlfVE9ORSA9ICdwbGF5VG9uZSc7XG5BbGVydC5LRVlfUFJPR1JFU1NfSU5ESUNBVE9SID0gJ3Byb2dyZXNzSW5kaWNhdG9yJztcbkFsZXJ0LktFWV9TT0ZUX0JVVFRPTlMgPSAnc29mdEJ1dHRvbnMnO1xuQWxlcnQuS0VZX0FMRVJUX0lDT04gPSAnYWxlcnRJY29uJztcbkFsZXJ0LktFWV9DQU5DRUxfSUQgPSAnY2FuY2VsSUQnO1xuXG5leHBvcnQgeyBBbGVydCB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG5jbGFzcyBBbGVydFJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuQWxlcnQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB0aW1lIC0gQW1vdW50IG9mIHRpbWUgKGluIHNlY29uZHMpIHRoYXQgYW4gYXBwIG11c3Qgd2FpdCBiZWZvcmUgcmVzZW5kaW5nIGFuIGFsZXJ0LiBJZiBwcm92aWRlZCxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIGFub3RoZXIgc3lzdGVtIGV2ZW50IG9yIG92ZXJsYXkgY3VycmVudGx5IGhhcyBhIGhpZ2hlciBwcmlvcml0eSB0aGFuIHRoaXMgYWxlcnQuIEFuIGFwcFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgbXVzdCBub3Qgc2VuZCBhbiBhbGVydCB3aXRob3V0IHdhaXRpbmcgYXQgbGVhc3QgdGhlIGFtb3VudCBvZiB0aW1lIGRpY3RhdGVkLlxuICAgICAqIEByZXR1cm4ge0FsZXJ0UmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0VHJ5QWdhaW5UaW1lICh0aW1lKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEFsZXJ0UmVzcG9uc2UuS0VZX1RSWV9BR0FJTl9USU1FLCB0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFRyeUFnYWluVGltZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihBbGVydFJlc3BvbnNlLktFWV9UUllfQUdBSU5fVElNRSk7XG4gICAgfVxufVxuXG5BbGVydFJlc3BvbnNlLktFWV9UUllfQUdBSU5fVElNRSA9ICd0cnlBZ2FpblRpbWUnO1xuXG5leHBvcnQgeyBBbGVydFJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogVGhlIGxpc3Qgb2YgcG9zc2libGUgYWxpZ25tZW50cywgbGVmdCwgcmlnaHQsIG9yIGNlbnRlcmVkXG4gKiBAdHlwZWRlZiB7RW51bX0gVGV4dEFsaWdubWVudFxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgVGV4dEFsaWdubWVudCBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBMRUZUX0FMSUdORUQgKCkge1xuICAgICAgICByZXR1cm4gVGV4dEFsaWdubWVudC5fTUFQLkxFRlRfQUxJR05FRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSSUdIVF9BTElHTkVEICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRBbGlnbm1lbnQuX01BUC5SSUdIVF9BTElHTkVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENFTlRFUkVEICgpIHtcbiAgICAgICAgcmV0dXJuIFRleHRBbGlnbm1lbnQuX01BUC5DRU5URVJFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBUZXh0QWxpZ25tZW50Ll92YWx1ZUZvcktleShrZXksIFRleHRBbGlnbm1lbnQuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBUZXh0QWxpZ25tZW50Ll9rZXlGb3JWYWx1ZSh2YWx1ZSwgVGV4dEFsaWdubWVudC5fTUFQKTtcbiAgICB9XG59XG5cblRleHRBbGlnbm1lbnQuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdMRUZUX0FMSUdORUQnOiAnTEVGVF9BTElHTkVEJyxcbiAgICAnUklHSFRfQUxJR05FRCc6ICdSSUdIVF9BTElHTkVEJyxcbiAgICAnQ0VOVEVSRUQnOiAnQ0VOVEVSRUQnLFxufSk7XG5cbmV4cG9ydCB7IFRleHRBbGlnbm1lbnQgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgVGVtcGxhdGVDb2xvclNjaGVtZSB9IGZyb20gJy4vVGVtcGxhdGVDb2xvclNjaGVtZS5qcyc7XG5cbmNsYXNzIFRlbXBsYXRlQ29uZmlndXJhdGlvbiBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHRlbXBsYXRlIC0gUHJlZGVmaW5lZCBvciBkeW5hbWljYWxseSBjcmVhdGVkIHdpbmRvdyB0ZW1wbGF0ZS4gQ3VycmVudGx5IG9ubHkgcHJlZGVmaW5lZCB3aW5kb3dcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZSBsYXlvdXRzIGFyZSBkZWZpbmVkLlxuICAgICAqIEByZXR1cm4ge1RlbXBsYXRlQ29uZmlndXJhdGlvbn1cbiAgICAgKi9cbiAgICBzZXRUZW1wbGF0ZSAodGVtcGxhdGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVGVtcGxhdGVDb25maWd1cmF0aW9uLktFWV9URU1QTEFURSwgdGVtcGxhdGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0VGVtcGxhdGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoVGVtcGxhdGVDb25maWd1cmF0aW9uLktFWV9URU1QTEFURSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtUZW1wbGF0ZUNvbG9yU2NoZW1lfSBzY2hlbWUgLSBBIGNvbG9yIHNjaGVtZSBmb3IgYWxsIGRpc3BsYXkgbGF5b3V0IHRlbXBsYXRlcy5cbiAgICAgKiBAcmV0dXJuIHtUZW1wbGF0ZUNvbmZpZ3VyYXRpb259XG4gICAgICovXG4gICAgc2V0RGF5Q29sb3JTY2hlbWUgKHNjaGVtZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShUZW1wbGF0ZUNvbG9yU2NoZW1lLCBzY2hlbWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihUZW1wbGF0ZUNvbmZpZ3VyYXRpb24uS0VZX0RBWV9DT0xPUl9TQ0hFTUUsIHNjaGVtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1RlbXBsYXRlQ29sb3JTY2hlbWV9XG4gICAgICovXG4gICAgZ2V0RGF5Q29sb3JTY2hlbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVGVtcGxhdGVDb2xvclNjaGVtZSwgVGVtcGxhdGVDb25maWd1cmF0aW9uLktFWV9EQVlfQ09MT1JfU0NIRU1FKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1RlbXBsYXRlQ29sb3JTY2hlbWV9IHNjaGVtZSAtIEEgY29sb3Igc2NoZW1lIGZvciBhbGwgZGlzcGxheSBsYXlvdXQgdGVtcGxhdGVzLlxuICAgICAqIEByZXR1cm4ge1RlbXBsYXRlQ29uZmlndXJhdGlvbn1cbiAgICAgKi9cbiAgICBzZXROaWdodENvbG9yU2NoZW1lIChzY2hlbWUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVGVtcGxhdGVDb2xvclNjaGVtZSwgc2NoZW1lKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVGVtcGxhdGVDb25maWd1cmF0aW9uLktFWV9OSUdIVF9DT0xPUl9TQ0hFTUUsIHNjaGVtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1RlbXBsYXRlQ29sb3JTY2hlbWV9XG4gICAgICovXG4gICAgZ2V0TmlnaHRDb2xvclNjaGVtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChUZW1wbGF0ZUNvbG9yU2NoZW1lLCBUZW1wbGF0ZUNvbmZpZ3VyYXRpb24uS0VZX05JR0hUX0NPTE9SX1NDSEVNRSk7XG4gICAgfVxufVxuXG5UZW1wbGF0ZUNvbmZpZ3VyYXRpb24uS0VZX1RFTVBMQVRFID0gJ3RlbXBsYXRlJztcblRlbXBsYXRlQ29uZmlndXJhdGlvbi5LRVlfREFZX0NPTE9SX1NDSEVNRSA9ICdkYXlDb2xvclNjaGVtZSc7XG5UZW1wbGF0ZUNvbmZpZ3VyYXRpb24uS0VZX05JR0hUX0NPTE9SX1NDSEVNRSA9ICduaWdodENvbG9yU2NoZW1lJztcblxuZXhwb3J0IHsgVGVtcGxhdGVDb25maWd1cmF0aW9uIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYge0VudW19IE1ldGFkYXRhVHlwZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgTWV0YWRhdGFUeXBlIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBkYXRhIGluIHRoaXMgZmllbGQgY29udGFpbnMgdGhlIHRpdGxlIG9mIHRoZSBjdXJyZW50bHkgcGxheWluZyBhdWRpbyB0cmFjay5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBtZWRpYVRpdGxlICgpIHtcbiAgICAgICAgcmV0dXJuIE1ldGFkYXRhVHlwZS5fTUFQLm1lZGlhVGl0bGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGRhdGEgaW4gdGhpcyBmaWVsZCBjb250YWlucyB0aGUgYXJ0aXN0IG9yIGNyZWF0b3Igb2YgdGhlIGN1cnJlbnRseSBwbGF5aW5nIGF1ZGlvIHRyYWNrLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IG1lZGlhQXJ0aXN0ICgpIHtcbiAgICAgICAgcmV0dXJuIE1ldGFkYXRhVHlwZS5fTUFQLm1lZGlhQXJ0aXN0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBkYXRhIGluIHRoaXMgZmllbGQgY29udGFpbnMgdGhlIGFsYnVtIHRpdGxlIG9mIHRoZSBjdXJyZW50bHkgcGxheWluZyBhdWRpbyB0cmFjay5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBtZWRpYUFsYnVtICgpIHtcbiAgICAgICAgcmV0dXJuIE1ldGFkYXRhVHlwZS5fTUFQLm1lZGlhQWxidW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGRhdGEgaW4gdGhpcyBmaWVsZCBjb250YWlucyB0aGUgY3JlYXRpb24geWVhciBvZiB0aGUgY3VycmVudGx5IHBsYXlpbmcgYXVkaW8gdHJhY2suXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgbWVkaWFZZWFyICgpIHtcbiAgICAgICAgcmV0dXJuIE1ldGFkYXRhVHlwZS5fTUFQLm1lZGlhWWVhcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgZGF0YSBpbiB0aGlzIGZpZWxkIGNvbnRhaW5zIHRoZSBnZW5yZSBvZiB0aGUgY3VycmVudGx5IHBsYXlpbmcgYXVkaW8gdHJhY2suXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgbWVkaWFHZW5yZSAoKSB7XG4gICAgICAgIHJldHVybiBNZXRhZGF0YVR5cGUuX01BUC5tZWRpYUdlbnJlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBkYXRhIGluIHRoaXMgZmllbGQgY29udGFpbnMgdGhlIG5hbWUgb2YgdGhlIGN1cnJlbnQgc291cmNlIGZvciB0aGUgbWVkaWEuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgbWVkaWFTdGF0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIE1ldGFkYXRhVHlwZS5fTUFQLm1lZGlhU3RhdGlvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgZGF0YSBpbiB0aGlzIGZpZWxkIGlzIGEgcmF0aW5nLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IHJhdGluZyAoKSB7XG4gICAgICAgIHJldHVybiBNZXRhZGF0YVR5cGUuX01BUC5yYXRpbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGRhdGEgaW4gdGhpcyBmaWVsZCBpcyB0aGUgY3VycmVudCB0ZW1wZXJhdHVyZS5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBjdXJyZW50VGVtcGVyYXR1cmUgKCkge1xuICAgICAgICByZXR1cm4gTWV0YWRhdGFUeXBlLl9NQVAuY3VycmVudFRlbXBlcmF0dXJlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBkYXRhIGluIHRoaXMgZmllbGQgaXMgdGhlIG1heGltdW0gdGVtcGVyYXR1cmUgZm9yIHRoZSBkYXkuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgbWF4aW11bVRlbXBlcmF0dXJlICgpIHtcbiAgICAgICAgcmV0dXJuIE1ldGFkYXRhVHlwZS5fTUFQLm1heGltdW1UZW1wZXJhdHVyZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgZGF0YSBpbiB0aGlzIGZpZWxkIGlzIHRoZSBtaW5pbXVtIHRlbXBlcmF0dXJlIGZvciB0aGUgZGF5LlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IG1pbmltdW1UZW1wZXJhdHVyZSAoKSB7XG4gICAgICAgIHJldHVybiBNZXRhZGF0YVR5cGUuX01BUC5taW5pbXVtVGVtcGVyYXR1cmU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGRhdGEgaW4gdGhpcyBmaWVsZCBkZXNjcmliZXMgdGhlIGN1cnJlbnQgd2VhdGhlciAoZXguIGNsb3VkeSwgY2xlYXIsIGV0Yy4pLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IHdlYXRoZXJUZXJtICgpIHtcbiAgICAgICAgcmV0dXJuIE1ldGFkYXRhVHlwZS5fTUFQLndlYXRoZXJUZXJtO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBkYXRhIGluIHRoaXMgZmllbGQgZGVzY3JpYmVzIHRoZSBjdXJyZW50IGh1bWlkaXR5IHZhbHVlLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IGh1bWlkaXR5ICgpIHtcbiAgICAgICAgcmV0dXJuIE1ldGFkYXRhVHlwZS5fTUFQLmh1bWlkaXR5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIE1ldGFkYXRhVHlwZS5fdmFsdWVGb3JLZXkoa2V5LCBNZXRhZGF0YVR5cGUuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBNZXRhZGF0YVR5cGUuX2tleUZvclZhbHVlKHZhbHVlLCBNZXRhZGF0YVR5cGUuX01BUCk7XG4gICAgfVxufVxuXG5NZXRhZGF0YVR5cGUuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdtZWRpYVRpdGxlJzogJ21lZGlhVGl0bGUnLFxuICAgICdtZWRpYUFydGlzdCc6ICdtZWRpYUFydGlzdCcsXG4gICAgJ21lZGlhQWxidW0nOiAnbWVkaWFBbGJ1bScsXG4gICAgJ21lZGlhWWVhcic6ICdtZWRpYVllYXInLFxuICAgICdtZWRpYUdlbnJlJzogJ21lZGlhR2VucmUnLFxuICAgICdtZWRpYVN0YXRpb24nOiAnbWVkaWFTdGF0aW9uJyxcbiAgICAncmF0aW5nJzogJ3JhdGluZycsXG4gICAgJ2N1cnJlbnRUZW1wZXJhdHVyZSc6ICdjdXJyZW50VGVtcGVyYXR1cmUnLFxuICAgICdtYXhpbXVtVGVtcGVyYXR1cmUnOiAnbWF4aW11bVRlbXBlcmF0dXJlJyxcbiAgICAnbWluaW11bVRlbXBlcmF0dXJlJzogJ21pbmltdW1UZW1wZXJhdHVyZScsXG4gICAgJ3dlYXRoZXJUZXJtJzogJ3dlYXRoZXJUZXJtJyxcbiAgICAnaHVtaWRpdHknOiAnaHVtaWRpdHknLFxufSk7XG5cbmV4cG9ydCB7IE1ldGFkYXRhVHlwZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBNZXRhZGF0YVR5cGUgfSBmcm9tICcuLi9lbnVtcy9NZXRhZGF0YVR5cGUuanMnO1xuXG5jbGFzcyBNZXRhZGF0YVRhZ3MgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TWV0YWRhdGFUeXBlW119IGZpZWxkMSAtIFRoZSB0eXBlIG9mIGRhdGEgY29udGFpbmVkIGluIHRoZSBcIm1haW5GaWVsZDFcIiB0ZXh0IGZpZWxkLlxuICAgICAqIEByZXR1cm4ge01ldGFkYXRhVGFnc31cbiAgICAgKi9cbiAgICBzZXRNYWluRmllbGQxIChmaWVsZDEpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTWV0YWRhdGFUeXBlLCBmaWVsZDEsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihNZXRhZGF0YVRhZ3MuS0VZX01BSU5fRklFTERfMSwgZmllbGQxKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TWV0YWRhdGFUeXBlW119XG4gICAgICovXG4gICAgZ2V0TWFpbkZpZWxkMSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChNZXRhZGF0YVR5cGUsIE1ldGFkYXRhVGFncy5LRVlfTUFJTl9GSUVMRF8xKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge01ldGFkYXRhVHlwZVtdfSBmaWVsZDIgLSBUaGUgdHlwZSBvZiBkYXRhIGNvbnRhaW5lZCBpbiB0aGUgXCJtYWluRmllbGQyXCIgdGV4dCBmaWVsZC5cbiAgICAgKiBAcmV0dXJuIHtNZXRhZGF0YVRhZ3N9XG4gICAgICovXG4gICAgc2V0TWFpbkZpZWxkMiAoZmllbGQyKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKE1ldGFkYXRhVHlwZSwgZmllbGQyLCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTWV0YWRhdGFUYWdzLktFWV9NQUlOX0ZJRUxEXzIsIGZpZWxkMik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge01ldGFkYXRhVHlwZVtdfVxuICAgICAqL1xuICAgIGdldE1haW5GaWVsZDIgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTWV0YWRhdGFUeXBlLCBNZXRhZGF0YVRhZ3MuS0VZX01BSU5fRklFTERfMik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtNZXRhZGF0YVR5cGVbXX0gZmllbGQzIC0gVGhlIHR5cGUgb2YgZGF0YSBjb250YWluZWQgaW4gdGhlIFwibWFpbkZpZWxkM1wiIHRleHQgZmllbGQuXG4gICAgICogQHJldHVybiB7TWV0YWRhdGFUYWdzfVxuICAgICAqL1xuICAgIHNldE1haW5GaWVsZDMgKGZpZWxkMykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShNZXRhZGF0YVR5cGUsIGZpZWxkMywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE1ldGFkYXRhVGFncy5LRVlfTUFJTl9GSUVMRF8zLCBmaWVsZDMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtNZXRhZGF0YVR5cGVbXX1cbiAgICAgKi9cbiAgICBnZXRNYWluRmllbGQzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KE1ldGFkYXRhVHlwZSwgTWV0YWRhdGFUYWdzLktFWV9NQUlOX0ZJRUxEXzMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TWV0YWRhdGFUeXBlW119IGZpZWxkNCAtIFRoZSB0eXBlIG9mIGRhdGEgY29udGFpbmVkIGluIHRoZSBcIm1haW5GaWVsZDRcIiB0ZXh0IGZpZWxkLlxuICAgICAqIEByZXR1cm4ge01ldGFkYXRhVGFnc31cbiAgICAgKi9cbiAgICBzZXRNYWluRmllbGQ0IChmaWVsZDQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTWV0YWRhdGFUeXBlLCBmaWVsZDQsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihNZXRhZGF0YVRhZ3MuS0VZX01BSU5fRklFTERfNCwgZmllbGQ0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TWV0YWRhdGFUeXBlW119XG4gICAgICovXG4gICAgZ2V0TWFpbkZpZWxkNCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChNZXRhZGF0YVR5cGUsIE1ldGFkYXRhVGFncy5LRVlfTUFJTl9GSUVMRF80KTtcbiAgICB9XG59XG5cbk1ldGFkYXRhVGFncy5LRVlfTUFJTl9GSUVMRF8xID0gJ21haW5GaWVsZDEnO1xuTWV0YWRhdGFUYWdzLktFWV9NQUlOX0ZJRUxEXzIgPSAnbWFpbkZpZWxkMic7XG5NZXRhZGF0YVRhZ3MuS0VZX01BSU5fRklFTERfMyA9ICdtYWluRmllbGQzJztcbk1ldGFkYXRhVGFncy5LRVlfTUFJTl9GSUVMRF80ID0gJ21haW5GaWVsZDQnO1xuXG5leHBvcnQgeyBNZXRhZGF0YVRhZ3MgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBUZXh0QWxpZ25tZW50IH0gZnJvbSAnLi4vZW51bXMvVGV4dEFsaWdubWVudC5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBTb2Z0QnV0dG9uIH0gZnJvbSAnLi4vc3RydWN0cy9Tb2Z0QnV0dG9uLmpzJztcbmltcG9ydCB7IFRlbXBsYXRlQ29uZmlndXJhdGlvbiB9IGZyb20gJy4uL3N0cnVjdHMvVGVtcGxhdGVDb25maWd1cmF0aW9uLmpzJztcbmltcG9ydCB7IE1ldGFkYXRhVGFncyB9IGZyb20gJy4uL3N0cnVjdHMvTWV0YWRhdGFUYWdzLmpzJztcbmltcG9ydCB7IFJwY1JlcXVlc3QgfSBmcm9tICcuLi9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IEltYWdlIH0gZnJvbSAnLi4vc3RydWN0cy9JbWFnZS5qcyc7XG5cbi8qKlxuICogVXBkYXRlcyB0aGUgcGVyc2lzdGVudCBkaXNwbGF5LiBTdXBwb3J0ZWQgZmllbGRzIGRlcGVuZCBvbiBkaXNwbGF5IGNhcGFiaWxpdGllcy5cbiAqL1xuY2xhc3MgU2hvdyBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuU2hvdyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGZpZWxkMSAtIFRoZSB0ZXh0IHRoYXQgc2hvdWxkIGJlIGRpc3BsYXllZCBpbiBhIHNpbmdsZSBvciB1cHBlciBkaXNwbGF5IGxpbmUuIElmIHRoaXMgdGV4dCBpcyBub3RcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0LCB0aGUgdGV4dCBvZiBtYWluRmllbGQxIHN0YXlzIHVuY2hhbmdlZC4gSWYgdGhpcyB0ZXh0IGlzIGVtcHR5IFwiXCIsIHRoZSBmaWVsZCB3aWxsIGJlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFyZWQuXG4gICAgICogQHJldHVybiB7U2hvd31cbiAgICAgKi9cbiAgICBzZXRNYWluRmllbGQxIChmaWVsZDEpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2hvdy5LRVlfTUFJTl9GSUVMRF8xLCBmaWVsZDEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0TWFpbkZpZWxkMSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTaG93LktFWV9NQUlOX0ZJRUxEXzEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBmaWVsZDIgLSBUaGUgdGV4dCB0aGF0IHNob3VsZCBiZSBkaXNwbGF5ZWQgb24gdGhlIHNlY29uZCBkaXNwbGF5IGxpbmUuIElmIHRoaXMgdGV4dCBpcyBub3Qgc2V0LFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgdGV4dCBvZiBtYWluRmllbGQyIHN0YXlzIHVuY2hhbmdlZC4gSWYgdGhpcyB0ZXh0IGlzIGVtcHR5IFwiXCIsIHRoZSBmaWVsZCB3aWxsIGJlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFyZWQuXG4gICAgICogQHJldHVybiB7U2hvd31cbiAgICAgKi9cbiAgICBzZXRNYWluRmllbGQyIChmaWVsZDIpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2hvdy5LRVlfTUFJTl9GSUVMRF8yLCBmaWVsZDIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0TWFpbkZpZWxkMiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTaG93LktFWV9NQUlOX0ZJRUxEXzIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBmaWVsZDMgLSBUaGUgdGV4dCB0aGF0IHNob3VsZCBiZSBkaXNwbGF5ZWQgb24gdGhlIHNlY29uZCBcInBhZ2VcIiBmaXJzdCBkaXNwbGF5IGxpbmUuIElmIHRoaXMgdGV4dFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBpcyBub3Qgc2V0LCB0aGUgdGV4dCBvZiBtYWluRmllbGQzIHN0YXlzIHVuY2hhbmdlZC4gSWYgdGhpcyB0ZXh0IGlzIGVtcHR5IFwiXCIsIHRoZSBmaWVsZFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICB3aWxsIGJlIGNsZWFyZWQuXG4gICAgICogQHJldHVybiB7U2hvd31cbiAgICAgKi9cbiAgICBzZXRNYWluRmllbGQzIChmaWVsZDMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2hvdy5LRVlfTUFJTl9GSUVMRF8zLCBmaWVsZDMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0TWFpbkZpZWxkMyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTaG93LktFWV9NQUlOX0ZJRUxEXzMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBmaWVsZDQgLSBUaGUgdGV4dCB0aGF0IHNob3VsZCBiZSBkaXNwbGF5ZWQgb24gdGhlIHNlY29uZCBcInBhZ2VcIiBzZWNvbmQgZGlzcGxheSBsaW5lLiBJZiB0aGlzIHRleHRcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgaXMgbm90IHNldCwgdGhlIHRleHQgb2YgbWFpbkZpZWxkNCBzdGF5cyB1bmNoYW5nZWQuIElmIHRoaXMgdGV4dCBpcyBlbXB0eSBcIlwiLCB0aGUgZmllbGRcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgd2lsbCBiZSBjbGVhcmVkLlxuICAgICAqIEByZXR1cm4ge1Nob3d9XG4gICAgICovXG4gICAgc2V0TWFpbkZpZWxkNCAoZmllbGQ0KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNob3cuS0VZX01BSU5fRklFTERfNCwgZmllbGQ0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldE1haW5GaWVsZDQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2hvdy5LRVlfTUFJTl9GSUVMRF80KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1RleHRBbGlnbm1lbnR9IGFsaWdubWVudCAtIFNwZWNpZmllcyBob3cgbWFpbkZpZWxkMSBhbmQgbWFpbkZpZWxkMiB0ZXh0cyBzaG91bGQgYmUgYWxpZ25lZCBvbiBkaXNwbGF5LiBJZlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb21pdHRlZCwgdGV4dHMgd2lsbCBiZSBjZW50ZXJlZC5cbiAgICAgKiBAcmV0dXJuIHtTaG93fVxuICAgICAqL1xuICAgIHNldEFsaWdubWVudCAoYWxpZ25tZW50KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFRleHRBbGlnbm1lbnQsIGFsaWdubWVudCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNob3cuS0VZX0FMSUdOTUVOVCwgYWxpZ25tZW50KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VGV4dEFsaWdubWVudH1cbiAgICAgKi9cbiAgICBnZXRBbGlnbm1lbnQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVGV4dEFsaWdubWVudCwgU2hvdy5LRVlfQUxJR05NRU5UKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gYmFyIC0gUmVxdWlyZXMgaW52ZXN0aWdhdGlvbiByZWdhcmRpbmcgdGhlIG5hdiBkaXNwbGF5IGNhcGFiaWxpdGllcy4gUG90ZW50aWFsbHkgbG93ZXJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgbG93ZXJTdGF0dXNCYXIsIHVwcGVyU3RhdHVzQmFyLCB0aXRsZUJhciwgZXRjLlxuICAgICAqIEByZXR1cm4ge1Nob3d9XG4gICAgICovXG4gICAgc2V0U3RhdHVzQmFyIChiYXIpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2hvdy5LRVlfU1RBVFVTX0JBUiwgYmFyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldFN0YXR1c0JhciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTaG93LktFWV9TVEFUVVNfQkFSKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gY2xvY2sgLSBUZXh0IHZhbHVlIGZvciBNZWRpYUNsb2NrIGZpZWxkLiBIYXMgdG8gYmUgcHJvcGVybHkgZm9ybWF0dGVkIGJ5IE1vYmlsZSBBcHAgYWNjb3JkaW5nIHRvXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgdGhlIG1vZHVsZSdzIGNhcGFiaWxpdGllcy4gSWYgdGhpcyB0ZXh0IGlzIHNldCwgYW55IGF1dG9tYXRpYyBtZWRpYSBjbG9jayB1cGRhdGVzXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNseSBzZXQgd2l0aCBTZXRNZWRpYUNsb2NrVGltZXIgd2lsbCBiZSBzdG9wcGVkLlxuICAgICAqIEByZXR1cm4ge1Nob3d9XG4gICAgICovXG4gICAgc2V0TWVkaWFDbG9jayAoY2xvY2spIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2hvdy5LRVlfTUVESUFfQ0xPQ0ssIGNsb2NrKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldE1lZGlhQ2xvY2sgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2hvdy5LRVlfTUVESUFfQ0xPQ0spO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0cmFjayAtIFRoZSB0ZXh0IHRoYXQgc2hvdWxkIGJlIGRpc3BsYXllZCBpbiB0aGUgdHJhY2sgZmllbGQuIElmIHRoaXMgdGV4dCBpcyBub3Qgc2V0LCB0aGUgdGV4dFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIG9mIG1lZGlhVHJhY2sgc3RheXMgdW5jaGFuZ2VkLiBJZiB0aGlzIHRleHQgaXMgZW1wdHkgXCJcIiwgdGhlIGZpZWxkIHdpbGwgYmUgY2xlYXJlZC5cbiAgICAgKiBAcmV0dXJuIHtTaG93fVxuICAgICAqL1xuICAgIHNldE1lZGlhVHJhY2sgKHRyYWNrKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNob3cuS0VZX01FRElBX1RSQUNLLCB0cmFjayk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRNZWRpYVRyYWNrICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNob3cuS0VZX01FRElBX1RSQUNLKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0ltYWdlfSBncmFwaGljIC0gSW1hZ2Ugc3RydWN0IGRldGVybWluaW5nIHdoZXRoZXIgc3RhdGljIG9yIGR5bmFtaWMgaW1hZ2UgdG8gZGlzcGxheSBpbiBhcHAuIElmIG9taXR0ZWRcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgb24gc3VwcG9ydGVkIGRpc3BsYXlzLCB0aGUgZGlzcGxheWVkIGdyYXBoaWMgc2hhbGwgbm90IGNoYW5nZS5cbiAgICAgKiBAcmV0dXJuIHtTaG93fVxuICAgICAqL1xuICAgIHNldEdyYXBoaWMgKGdyYXBoaWMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoSW1hZ2UsIGdyYXBoaWMpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTaG93LktFWV9HUkFQSElDLCBncmFwaGljKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7SW1hZ2V9XG4gICAgICovXG4gICAgZ2V0R3JhcGhpYyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChJbWFnZSwgU2hvdy5LRVlfR1JBUEhJQyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtJbWFnZX0gZ3JhcGhpYyAtIEltYWdlIHN0cnVjdCBkZXRlcm1pbmluZyB3aGV0aGVyIHN0YXRpYyBvciBkeW5hbWljIHNlY29uZGFyeSBpbWFnZSB0byBkaXNwbGF5IGluIGFwcC4gSWZcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgb21pdHRlZCBvbiBzdXBwb3J0ZWQgZGlzcGxheXMsIHRoZSBkaXNwbGF5ZWQgc2Vjb25kYXJ5IGdyYXBoaWMgc2hhbGwgbm90IGNoYW5nZS5cbiAgICAgKiBAcmV0dXJuIHtTaG93fVxuICAgICAqL1xuICAgIHNldFNlY29uZGFyeUdyYXBoaWMgKGdyYXBoaWMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoSW1hZ2UsIGdyYXBoaWMpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTaG93LktFWV9TRUNPTkRBUllfR1JBUEhJQywgZ3JhcGhpYyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0ltYWdlfVxuICAgICAqL1xuICAgIGdldFNlY29uZGFyeUdyYXBoaWMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoSW1hZ2UsIFNob3cuS0VZX1NFQ09OREFSWV9HUkFQSElDKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NvZnRCdXR0b25bXX0gYnV0dG9ucyAtIEFwcCBkZWZpbmVkIFNvZnRCdXR0b25zLiBJZiBvbWl0dGVkIG9uIHN1cHBvcnRlZCBkaXNwbGF5cywgdGhlIGN1cnJlbnRseVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheWVkIFNvZnRCdXR0b24gdmFsdWVzIHdpbGwgbm90IGNoYW5nZS5cbiAgICAgKiBAcmV0dXJuIHtTaG93fVxuICAgICAqL1xuICAgIHNldFNvZnRCdXR0b25zIChidXR0b25zKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFNvZnRCdXR0b24sIGJ1dHRvbnMsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTaG93LktFWV9TT0ZUX0JVVFRPTlMsIGJ1dHRvbnMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTb2Z0QnV0dG9uW119XG4gICAgICovXG4gICAgZ2V0U29mdEJ1dHRvbnMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoU29mdEJ1dHRvbiwgU2hvdy5LRVlfU09GVF9CVVRUT05TKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ1tdfSBwcmVzZXRzIC0gQXBwIGxhYmVsZWQgb24tc2NyZWVuIHByZXNldHMgKGkuZS4gb24tc2NyZWVuIG1lZGlhIHByZXNldHMgb3IgZHluYW1pYyBzZWFyY2hcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VnZ2VzdGlvbnMpLiBJZiBvbWl0dGVkIG9uIHN1cHBvcnRlZCBkaXNwbGF5cywgdGhlIHByZXNldHMgd2lsbCBiZSBzaG93biBhcyBub3RcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmaW5lZC5cbiAgICAgKiBAcmV0dXJuIHtTaG93fVxuICAgICAqL1xuICAgIHNldEN1c3RvbVByZXNldHMgKHByZXNldHMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2hvdy5LRVlfQ1VTVE9NX1BSRVNFVFMsIHByZXNldHMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmdbXX1cbiAgICAgKi9cbiAgICBnZXRDdXN0b21QcmVzZXRzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNob3cuS0VZX0NVU1RPTV9QUkVTRVRTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge01ldGFkYXRhVGFnc30gdGFncyAtIEFwcCBkZWZpbmVkIG1ldGFkYXRhIGluZm9ybWF0aW9uLiBTZWUgTWV0YWRhdGFTdHJ1Y3QuIFVzZXMgbWFpbkZpZWxkMSwgbWFpbkZpZWxkMixcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1haW5GaWVsZDMsIG1haW5GaWVsZDQuIElmIG9taXR0ZWQgb24gc3VwcG9ydGVkIGRpc3BsYXlzLCB0aGUgY3VycmVudGx5IHNldCBtZXRhZGF0YVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFncyB3aWxsIG5vdCBjaGFuZ2UuIElmIGFueSB0ZXh0IGZpZWxkIGNvbnRhaW5zIG5vIHRhZ3Mgb3IgdGhlIG5vbmUgdGFnLCB0aGVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhIHRhZyBmb3IgdGhhdCB0ZXh0ZmllbGQgc2hvdWxkIGJlIHJlbW92ZWQuXG4gICAgICogQHJldHVybiB7U2hvd31cbiAgICAgKi9cbiAgICBzZXRNZXRhZGF0YVRhZ3MgKHRhZ3MpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTWV0YWRhdGFUYWdzLCB0YWdzKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2hvdy5LRVlfTUVUQURBVEFfVEFHUywgdGFncyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge01ldGFkYXRhVGFnc31cbiAgICAgKi9cbiAgICBnZXRNZXRhZGF0YVRhZ3MgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTWV0YWRhdGFUYWdzLCBTaG93LktFWV9NRVRBREFUQV9UQUdTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdGl0bGUgLSBUaGUgdGl0bGUgb2YgdGhlIG5ldyB0ZW1wbGF0ZSB0aGF0IHdpbGwgYmUgZGlzcGxheWVkLiBIb3cgdGhpcyB3aWxsIGJlIGRpc3BsYXllZCBpc1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGRlcGVuZGVudCBvbiB0aGUgT0VNIGRlc2lnbiBhbmQgaW1wbGVtZW50YXRpb24gb2YgdGhlIHRlbXBsYXRlLlxuICAgICAqIEByZXR1cm4ge1Nob3d9XG4gICAgICovXG4gICAgc2V0VGVtcGxhdGVUaXRsZSAodGl0bGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2hvdy5LRVlfVEVNUExBVEVfVElUTEUsIHRpdGxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldFRlbXBsYXRlVGl0bGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2hvdy5LRVlfVEVNUExBVEVfVElUTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBpZCAtIFRoaXMgaXMgdGhlIHVuaXF1ZSBJRCBhc3NpZ25lZCB0byB0aGUgd2luZG93IHRoYXQgdGhpcyBSUEMgaXMgaW50ZW5kZWQuIElmIHRoaXMgcGFyYW0gaXMgbm90XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgaW5jbHVkZWQsIGl0IHdpbGwgYmUgYXNzdW1lZCB0aGF0IHRoaXMgcmVxdWVzdCBpcyBzcGVjaWZpY2FsbHkgZm9yIHRoZSBtYWluIHdpbmRvdyBvbiB0aGVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBtYWluIGRpc3BsYXkuIFNlZSBQcmVkZWZpbmVkV2luZG93cyBlbnVtLlxuICAgICAqIEByZXR1cm4ge1Nob3d9XG4gICAgICovXG4gICAgc2V0V2luZG93SUQgKGlkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNob3cuS0VZX1dJTkRPV19JRCwgaWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0V2luZG93SUQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2hvdy5LRVlfV0lORE9XX0lEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1RlbXBsYXRlQ29uZmlndXJhdGlvbn0gY29uZmlndXJhdGlvbiAtIFVzZWQgdG8gc2V0IGFuIGFsdGVybmF0ZSB0ZW1wbGF0ZSBsYXlvdXQgdG8gYSB3aW5kb3cuXG4gICAgICogQHJldHVybiB7U2hvd31cbiAgICAgKi9cbiAgICBzZXRUZW1wbGF0ZUNvbmZpZ3VyYXRpb24gKGNvbmZpZ3VyYXRpb24pIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVGVtcGxhdGVDb25maWd1cmF0aW9uLCBjb25maWd1cmF0aW9uKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2hvdy5LRVlfVEVNUExBVEVfQ09ORklHVVJBVElPTiwgY29uZmlndXJhdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1RlbXBsYXRlQ29uZmlndXJhdGlvbn1cbiAgICAgKi9cbiAgICBnZXRUZW1wbGF0ZUNvbmZpZ3VyYXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVGVtcGxhdGVDb25maWd1cmF0aW9uLCBTaG93LktFWV9URU1QTEFURV9DT05GSUdVUkFUSU9OKTtcbiAgICB9XG59XG5cblNob3cuS0VZX01BSU5fRklFTERfMSA9ICdtYWluRmllbGQxJztcblNob3cuS0VZX01BSU5fRklFTERfMiA9ICdtYWluRmllbGQyJztcblNob3cuS0VZX01BSU5fRklFTERfMyA9ICdtYWluRmllbGQzJztcblNob3cuS0VZX01BSU5fRklFTERfNCA9ICdtYWluRmllbGQ0JztcblNob3cuS0VZX0FMSUdOTUVOVCA9ICdhbGlnbm1lbnQnO1xuU2hvdy5LRVlfU1RBVFVTX0JBUiA9ICdzdGF0dXNCYXInO1xuU2hvdy5LRVlfTUVESUFfQ0xPQ0sgPSAnbWVkaWFDbG9jayc7XG5TaG93LktFWV9NRURJQV9UUkFDSyA9ICdtZWRpYVRyYWNrJztcblNob3cuS0VZX0dSQVBISUMgPSAnZ3JhcGhpYyc7XG5TaG93LktFWV9TRUNPTkRBUllfR1JBUEhJQyA9ICdzZWNvbmRhcnlHcmFwaGljJztcblNob3cuS0VZX1NPRlRfQlVUVE9OUyA9ICdzb2Z0QnV0dG9ucyc7XG5TaG93LktFWV9DVVNUT01fUFJFU0VUUyA9ICdjdXN0b21QcmVzZXRzJztcblNob3cuS0VZX01FVEFEQVRBX1RBR1MgPSAnbWV0YWRhdGFUYWdzJztcblNob3cuS0VZX1RFTVBMQVRFX1RJVExFID0gJ3RlbXBsYXRlVGl0bGUnO1xuU2hvdy5LRVlfV0lORE9XX0lEID0gJ3dpbmRvd0lEJztcblNob3cuS0VZX1RFTVBMQVRFX0NPTkZJR1VSQVRJT04gPSAndGVtcGxhdGVDb25maWd1cmF0aW9uJztcblxuZXhwb3J0IHsgU2hvdyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG5jbGFzcyBTaG93UmVzcG9uc2UgZXh0ZW5kcyBScGNSZXNwb25zZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5TaG93KTtcbiAgICB9XG59XG5cblxuZXhwb3J0IHsgU2hvd1Jlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgVFRTQ2h1bmsgfSBmcm9tICcuLi9zdHJ1Y3RzL1RUU0NodW5rLmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcblxuLyoqXG4gKiBTcGVha3MgYSB0ZXh0LlxuICovXG5jbGFzcyBTcGVhayBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuU3BlYWspO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VFRTQ2h1bmtbXX0gY2h1bmtzIC0gQW4gYXJyYXkgb2YgdGV4dCBjaHVua3Mgb2YgdHlwZSBUVFNDaHVuay4gU2VlIFRUU0NodW5rLiBUaGUgYXJyYXkgbXVzdCBoYXZlIGF0IGxlYXN0XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmUgaXRlbS5cbiAgICAgKiBAcmV0dXJuIHtTcGVha31cbiAgICAgKi9cbiAgICBzZXRUdHNDaHVua3MgKGNodW5rcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShUVFNDaHVuaywgY2h1bmtzLCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3BlYWsuS0VZX1RUU19DSFVOS1MsIGNodW5rcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1RUU0NodW5rW119XG4gICAgICovXG4gICAgZ2V0VHRzQ2h1bmtzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFRUU0NodW5rLCBTcGVhay5LRVlfVFRTX0NIVU5LUyk7XG4gICAgfVxufVxuXG5TcGVhay5LRVlfVFRTX0NIVU5LUyA9ICd0dHNDaHVua3MnO1xuXG5leHBvcnQgeyBTcGVhayB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG5jbGFzcyBTcGVha1Jlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuU3BlYWspO1xuICAgIH1cbn1cblxuXG5leHBvcnQgeyBTcGVha1Jlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcblxuY2xhc3MgU3RhcnRUaW1lIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaG91cnMgLSBUaGUgaG91ciBvZiB0aGUgbWVkaWEgY2xvY2suIFNvbWUgcmFkaW9zIG9ubHkgc3VwcG9ydCBhIG1heCBvZiAxOSBob3Vycy4gSWYgb3V0IG9mIHJhbmdlLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGl0IHdpbGwgYmUgcmVqZWN0ZWQuXG4gICAgICogQHJldHVybiB7U3RhcnRUaW1lfVxuICAgICAqL1xuICAgIHNldEhvdXJzIChob3Vycykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdGFydFRpbWUuS0VZX0hPVVJTLCBob3Vycyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRIb3VycyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTdGFydFRpbWUuS0VZX0hPVVJTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbWludXRlc1xuICAgICAqIEByZXR1cm4ge1N0YXJ0VGltZX1cbiAgICAgKi9cbiAgICBzZXRNaW51dGVzIChtaW51dGVzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFN0YXJ0VGltZS5LRVlfTUlOVVRFUywgbWludXRlcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRNaW51dGVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFN0YXJ0VGltZS5LRVlfTUlOVVRFUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlY29uZHNcbiAgICAgKiBAcmV0dXJuIHtTdGFydFRpbWV9XG4gICAgICovXG4gICAgc2V0U2Vjb25kcyAoc2Vjb25kcykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdGFydFRpbWUuS0VZX1NFQ09ORFMsIHNlY29uZHMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0U2Vjb25kcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTdGFydFRpbWUuS0VZX1NFQ09ORFMpO1xuICAgIH1cbn1cblxuU3RhcnRUaW1lLktFWV9IT1VSUyA9ICdob3Vycyc7XG5TdGFydFRpbWUuS0VZX01JTlVURVMgPSAnbWludXRlcyc7XG5TdGFydFRpbWUuS0VZX1NFQ09ORFMgPSAnc2Vjb25kcyc7XG5cbmV4cG9ydCB7IFN0YXJ0VGltZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIERlc2NyaWJlcyBob3cgdGhlIG1lZGlhIGNsb2NrIHRpbWVyIHNob3VsZCBiZWhhdmUgb24gdGhlIHBsYXRmb3JtXG4gKiBAdHlwZWRlZiB7RW51bX0gVXBkYXRlTW9kZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgVXBkYXRlTW9kZSBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdGFydHMgdGhlIG1lZGlhIGNsb2NrIHRpbWVyIGNvdW50aW5nIHVwd2FyZHMsIGFzIGluIHRpbWUgZWxhcHNlZC5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDT1VOVFVQICgpIHtcbiAgICAgICAgcmV0dXJuIFVwZGF0ZU1vZGUuX01BUC5DT1VOVFVQO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgbWVkaWEgY2xvY2sgdGltZXIgY291bnRpbmcgZG93bndhcmRzLCBhcyBpbiB0aW1lIHJlbWFpbmluZy5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDT1VOVERPV04gKCkge1xuICAgICAgICByZXR1cm4gVXBkYXRlTW9kZS5fTUFQLkNPVU5URE9XTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXVzZXMgdGhlIG1lZGlhIGNsb2NrIHRpbWVyXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUEFVU0UgKCkge1xuICAgICAgICByZXR1cm4gVXBkYXRlTW9kZS5fTUFQLlBBVVNFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc3VtZSB0aGUgbWVkaWEgY2xvY2sgdGltZXJcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSRVNVTUUgKCkge1xuICAgICAgICByZXR1cm4gVXBkYXRlTW9kZS5fTUFQLlJFU1VNRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDbGVhcnMgdGhlIG1lZGlhIGNsb2NrIHRpbWVyIChwcmV2aW91c2x5IGRvbmUgdGhyb3VnaCBTaG93LT5tZWRpYUNsb2NrKVxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENMRUFSICgpIHtcbiAgICAgICAgcmV0dXJuIFVwZGF0ZU1vZGUuX01BUC5DTEVBUjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBVcGRhdGVNb2RlLl92YWx1ZUZvcktleShrZXksIFVwZGF0ZU1vZGUuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBVcGRhdGVNb2RlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgVXBkYXRlTW9kZS5fTUFQKTtcbiAgICB9XG59XG5cblVwZGF0ZU1vZGUuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdDT1VOVFVQJzogJ0NPVU5UVVAnLFxuICAgICdDT1VOVERPV04nOiAnQ09VTlRET1dOJyxcbiAgICAnUEFVU0UnOiAnUEFVU0UnLFxuICAgICdSRVNVTUUnOiAnUkVTVU1FJyxcbiAgICAnQ0xFQVInOiAnQ0xFQVInLFxufSk7XG5cbmV4cG9ydCB7IFVwZGF0ZU1vZGUgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gQXVkaW9TdHJlYW1pbmdJbmRpY2F0b3JcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIEF1ZGlvU3RyZWFtaW5nSW5kaWNhdG9yIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlZmF1bHQgcGxheWJhY2sgaW5kaWNhdG9yLiBCeSBkZWZhdWx0IHRoZSBwbGF5YmFjayBpbmRpY2F0b3Igc2hvdWxkIGJlIFBMQVlfUEFVU0Ugd2hlbjogLSB0aGUgbWVkaWEgYXBwIGlzXG4gICAgICogbmV3bHkgcmVnaXN0ZXJlZCBvbiB0aGUgaGVhZCB1bml0IChhZnRlciBSZWdpc3RlckFwcEludGVyZmFjZSkgLSB0aGUgbWVkaWEgYXBwIHdhcyBjbG9zZWQgYnkgdGhlIHVzZXIgKEFwcFxuICAgICAqIGVudGVycyBITUlfTk9ORSkgLSB0aGUgYXBwIHNlbmRzIFNldE1lZGlhQ2xvY2tUaW1lciB3aXRoIGF1ZGlvU3RyZWFtaW5nSW5kaWNhdG9yIG5vdCBzZXQgdG8gYW55IHZhbHVlXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUExBWV9QQVVTRSAoKSB7XG4gICAgICAgIHJldHVybiBBdWRpb1N0cmVhbWluZ0luZGljYXRvci5fTUFQLlBMQVlfUEFVU0U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW5kaWNhdGVzIHRoYXQgYSBidXR0b24gcHJlc3Mgb2YgdGhlIFBsYXkvUGF1c2UgYnV0dG9uIHN0YXJ0cyB0aGUgYXVkaW8gcGxheWJhY2suXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUExBWSAoKSB7XG4gICAgICAgIHJldHVybiBBdWRpb1N0cmVhbWluZ0luZGljYXRvci5fTUFQLlBMQVk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW5kaWNhdGVzIHRoYXQgYSBidXR0b24gcHJlc3Mgb2YgdGhlIFBsYXkvUGF1c2UgYnV0dG9uIHBhdXNlcyB0aGUgY3VycmVudCBhdWRpbyBwbGF5YmFjay5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBQQVVTRSAoKSB7XG4gICAgICAgIHJldHVybiBBdWRpb1N0cmVhbWluZ0luZGljYXRvci5fTUFQLlBBVVNFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEluZGljYXRlcyB0aGF0IGEgYnV0dG9uIHByZXNzIG9mIHRoZSBQbGF5L1BhdXNlIGJ1dHRvbiBzdG9wcyB0aGUgY3VycmVudCBhdWRpbyBwbGF5YmFjay5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTVE9QICgpIHtcbiAgICAgICAgcmV0dXJuIEF1ZGlvU3RyZWFtaW5nSW5kaWNhdG9yLl9NQVAuU1RPUDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBBdWRpb1N0cmVhbWluZ0luZGljYXRvci5fdmFsdWVGb3JLZXkoa2V5LCBBdWRpb1N0cmVhbWluZ0luZGljYXRvci5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIEF1ZGlvU3RyZWFtaW5nSW5kaWNhdG9yLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgQXVkaW9TdHJlYW1pbmdJbmRpY2F0b3IuX01BUCk7XG4gICAgfVxufVxuXG5BdWRpb1N0cmVhbWluZ0luZGljYXRvci5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1BMQVlfUEFVU0UnOiAnUExBWV9QQVVTRScsXG4gICAgJ1BMQVknOiAnUExBWScsXG4gICAgJ1BBVVNFJzogJ1BBVVNFJyxcbiAgICAnU1RPUCc6ICdTVE9QJyxcbn0pO1xuXG5leHBvcnQgeyBBdWRpb1N0cmVhbWluZ0luZGljYXRvciB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFN0YXJ0VGltZSB9IGZyb20gJy4uL3N0cnVjdHMvU3RhcnRUaW1lLmpzJztcbmltcG9ydCB7IFVwZGF0ZU1vZGUgfSBmcm9tICcuLi9lbnVtcy9VcGRhdGVNb2RlLmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IEF1ZGlvU3RyZWFtaW5nSW5kaWNhdG9yIH0gZnJvbSAnLi4vZW51bXMvQXVkaW9TdHJlYW1pbmdJbmRpY2F0b3IuanMnO1xuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuXG4vKipcbiAqIFNldHMgdGhlIGluaXRpYWwgbWVkaWEgY2xvY2sgdmFsdWUgYW5kIGF1dG9tYXRpYyB1cGRhdGUgbWV0aG9kLlxuICovXG5jbGFzcyBTZXRNZWRpYUNsb2NrVGltZXIgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlNldE1lZGlhQ2xvY2tUaW1lcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdGFydFRpbWV9IHRpbWUgLSBTZWUgU3RhcnRUaW1lLiBzdGFydFRpbWUgbXVzdCBiZSBwcm92aWRlZCBmb3IgXCJDT1VOVFVQXCIgYW5kIFwiQ09VTlRET1dOXCIuIHN0YXJ0VGltZSB3aWxsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICBiZSBpZ25vcmVkIGZvciBcIlJFU1VNRVwiLCBhbmQgXCJDTEVBUlwiIHN0YXJ0VGltZSBjYW4gYmUgc2VudCBmb3IgXCJQQVVTRVwiLCBpbiB3aGljaCBjYXNlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICBpdCB3aWxsIHVwZGF0ZSB0aGUgcGF1c2VkIHN0YXJ0VGltZVxuICAgICAqIEByZXR1cm4ge1NldE1lZGlhQ2xvY2tUaW1lcn1cbiAgICAgKi9cbiAgICBzZXRTdGFydFRpbWUgKHRpbWUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoU3RhcnRUaW1lLCB0aW1lKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2V0TWVkaWFDbG9ja1RpbWVyLktFWV9TVEFSVF9USU1FLCB0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RhcnRUaW1lfVxuICAgICAqL1xuICAgIGdldFN0YXJ0VGltZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChTdGFydFRpbWUsIFNldE1lZGlhQ2xvY2tUaW1lci5LRVlfU1RBUlRfVElNRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdGFydFRpbWV9IHRpbWUgLSBTZWUgU3RhcnRUaW1lLiBlbmRUaW1lIGNhbiBiZSBwcm92aWRlZCBmb3IgXCJDT1VOVFVQXCIgYW5kIFwiQ09VTlRET1dOXCI7IHRvIGJlIHVzZWQgdG9cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGN1bGF0ZSBhbnkgdmlzdWFsIHByb2dyZXNzIGJhciAoaWYgbm90IHByb3ZpZGVkLCB0aGlzIGZlYXR1cmUgaXMgaWdub3JlZCkgSWYgZW5kVGltZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMgZ3JlYXRlciB0aGVuIHN0YXJ0VGltZSBmb3IgQ09VTlRET1dOIG9yIGxlc3MgdGhhbiBzdGFydFRpbWUgZm9yIENPVU5UVVAsIHRoZW4gdGhlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0IHdpbGwgcmV0dXJuIGFuIElOVkFMSURfREFUQS4gZW5kVGltZSB3aWxsIGJlIGlnbm9yZWQgZm9yIFwiUkVTVU1FXCIsIGFuZCBcIkNMRUFSXCJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZFRpbWUgY2FuIGJlIHNlbnQgZm9yIFwiUEFVU0VcIiwgaW4gd2hpY2ggY2FzZSBpdCB3aWxsIHVwZGF0ZSB0aGUgcGF1c2VkIGVuZFRpbWVcbiAgICAgKiBAcmV0dXJuIHtTZXRNZWRpYUNsb2NrVGltZXJ9XG4gICAgICovXG4gICAgc2V0RW5kVGltZSAodGltZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShTdGFydFRpbWUsIHRpbWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZXRNZWRpYUNsb2NrVGltZXIuS0VZX0VORF9USU1FLCB0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RhcnRUaW1lfVxuICAgICAqL1xuICAgIGdldEVuZFRpbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoU3RhcnRUaW1lLCBTZXRNZWRpYUNsb2NrVGltZXIuS0VZX0VORF9USU1FKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1VwZGF0ZU1vZGV9IG1vZGUgLSBFbnVtZXJhdGlvbiB0byBjb250cm9sIHRoZSBtZWRpYSBjbG9jay4gSW4gY2FzZSBvZiBwYXVzZSwgcmVzdW1lLCBvciBjbGVhciwgdGhlIHN0YXJ0XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZSB2YWx1ZSBpcyBpZ25vcmVkIGFuZCBzaGFsbCBiZSBsZWZ0IG91dC4gRm9yIHJlc3VtZSwgdGhlIHRpbWUgY29udGludWVzIHdpdGggdGhlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FtZSB2YWx1ZSBhcyBpdCB3YXMgd2hlbiBwYXVzZWQuXG4gICAgICogQHJldHVybiB7U2V0TWVkaWFDbG9ja1RpbWVyfVxuICAgICAqL1xuICAgIHNldFVwZGF0ZU1vZGUgKG1vZGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVXBkYXRlTW9kZSwgbW9kZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNldE1lZGlhQ2xvY2tUaW1lci5LRVlfVVBEQVRFX01PREUsIG1vZGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtVcGRhdGVNb2RlfVxuICAgICAqL1xuICAgIGdldFVwZGF0ZU1vZGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVXBkYXRlTW9kZSwgU2V0TWVkaWFDbG9ja1RpbWVyLktFWV9VUERBVEVfTU9ERSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtBdWRpb1N0cmVhbWluZ0luZGljYXRvcn0gaW5kaWNhdG9yIC0gRW51bWVyYXRpb24gZm9yIHRoZSBpbmRpY2F0b3IgaWNvbiBvbiBhIHBsYXkvcGF1c2UgYnV0dG9uLiBzZWVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdWRpb1N0cmVhbWluZ0luZGljYXRvci5cbiAgICAgKiBAcmV0dXJuIHtTZXRNZWRpYUNsb2NrVGltZXJ9XG4gICAgICovXG4gICAgc2V0QXVkaW9TdHJlYW1pbmdJbmRpY2F0b3IgKGluZGljYXRvcikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShBdWRpb1N0cmVhbWluZ0luZGljYXRvciwgaW5kaWNhdG9yKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2V0TWVkaWFDbG9ja1RpbWVyLktFWV9BVURJT19TVFJFQU1JTkdfSU5ESUNBVE9SLCBpbmRpY2F0b3IpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtBdWRpb1N0cmVhbWluZ0luZGljYXRvcn1cbiAgICAgKi9cbiAgICBnZXRBdWRpb1N0cmVhbWluZ0luZGljYXRvciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChBdWRpb1N0cmVhbWluZ0luZGljYXRvciwgU2V0TWVkaWFDbG9ja1RpbWVyLktFWV9BVURJT19TVFJFQU1JTkdfSU5ESUNBVE9SKTtcbiAgICB9XG59XG5cblNldE1lZGlhQ2xvY2tUaW1lci5LRVlfU1RBUlRfVElNRSA9ICdzdGFydFRpbWUnO1xuU2V0TWVkaWFDbG9ja1RpbWVyLktFWV9FTkRfVElNRSA9ICdlbmRUaW1lJztcblNldE1lZGlhQ2xvY2tUaW1lci5LRVlfVVBEQVRFX01PREUgPSAndXBkYXRlTW9kZSc7XG5TZXRNZWRpYUNsb2NrVGltZXIuS0VZX0FVRElPX1NUUkVBTUlOR19JTkRJQ0FUT1IgPSAnYXVkaW9TdHJlYW1pbmdJbmRpY2F0b3InO1xuXG5leHBvcnQgeyBTZXRNZWRpYUNsb2NrVGltZXIgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBScGNSZXNwb25zZSB9IGZyb20gJy4uL1JwY1Jlc3BvbnNlLmpzJztcblxuY2xhc3MgU2V0TWVkaWFDbG9ja1RpbWVyUmVzcG9uc2UgZXh0ZW5kcyBScGNSZXNwb25zZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5TZXRNZWRpYUNsb2NrVGltZXIpO1xuICAgIH1cbn1cblxuXG5leHBvcnQgeyBTZXRNZWRpYUNsb2NrVGltZXJSZXNwb25zZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFRUU0NodW5rIH0gZnJvbSAnLi4vc3RydWN0cy9UVFNDaHVuay5qcyc7XG5pbXBvcnQgeyBBdWRpb1R5cGUgfSBmcm9tICcuLi9lbnVtcy9BdWRpb1R5cGUuanMnO1xuaW1wb3J0IHsgQml0c1BlclNhbXBsZSB9IGZyb20gJy4uL2VudW1zL0JpdHNQZXJTYW1wbGUuanMnO1xuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgU2FtcGxpbmdSYXRlIH0gZnJvbSAnLi4vZW51bXMvU2FtcGxpbmdSYXRlLmpzJztcblxuLyoqXG4gKiBTdGFydHMgYXVkaW8gcGFzcyB0aHJ1IHNlc3Npb25cbiAqL1xuY2xhc3MgUGVyZm9ybUF1ZGlvUGFzc1RocnUgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlBlcmZvcm1BdWRpb1Bhc3NUaHJ1KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1RUU0NodW5rW119IHByb21wdCAtIFRoZSBtb2R1bGUgd2lsbCBzcGVhayB0aGlzIHByb21wdCBiZWZvcmUgb3BlbmluZyB0aGUgYXVkaW8gcGFzcyB0aHJ1IHNlc3Npb24uIEFuXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheSBvZiB0ZXh0IGNodW5rcyBvZiB0eXBlIFRUU0NodW5rLiBTZWUgVFRTQ2h1bmsuIFRoZSBhcnJheSBtdXN0IGhhdmUgYXQgbGVhc3RcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uZSBpdGVtLiBJZiBvbWl0dGVkLCB0aGVuIG5vIGluaXRpYWwgcHJvbXB0IGlzIHNwb2tlbi5cbiAgICAgKiBAcmV0dXJuIHtQZXJmb3JtQXVkaW9QYXNzVGhydX1cbiAgICAgKi9cbiAgICBzZXRJbml0aWFsUHJvbXB0IChwcm9tcHQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVFRTQ2h1bmssIHByb21wdCwgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFBlcmZvcm1BdWRpb1Bhc3NUaHJ1LktFWV9JTklUSUFMX1BST01QVCwgcHJvbXB0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VFRTQ2h1bmtbXX1cbiAgICAgKi9cbiAgICBnZXRJbml0aWFsUHJvbXB0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFRUU0NodW5rLCBQZXJmb3JtQXVkaW9QYXNzVGhydS5LRVlfSU5JVElBTF9QUk9NUFQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0MSAtIEZpcnN0IGxpbmUgb2YgdGV4dCBkaXNwbGF5ZWQgZHVyaW5nIGF1ZGlvIGNhcHR1cmUuXG4gICAgICogQHJldHVybiB7UGVyZm9ybUF1ZGlvUGFzc1RocnV9XG4gICAgICovXG4gICAgc2V0QXVkaW9QYXNzVGhydURpc3BsYXlUZXh0MSAodGV4dDEpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUGVyZm9ybUF1ZGlvUGFzc1RocnUuS0VZX0FVRElPX1BBU1NfVEhSVV9ESVNQTEFZX1RFWFRfMSwgdGV4dDEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0QXVkaW9QYXNzVGhydURpc3BsYXlUZXh0MSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihQZXJmb3JtQXVkaW9QYXNzVGhydS5LRVlfQVVESU9fUEFTU19USFJVX0RJU1BMQVlfVEVYVF8xKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdGV4dDIgLSBTZWNvbmQgbGluZSBvZiB0ZXh0IGRpc3BsYXllZCBkdXJpbmcgYXVkaW8gY2FwdHVyZS5cbiAgICAgKiBAcmV0dXJuIHtQZXJmb3JtQXVkaW9QYXNzVGhydX1cbiAgICAgKi9cbiAgICBzZXRBdWRpb1Bhc3NUaHJ1RGlzcGxheVRleHQyICh0ZXh0Mikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihQZXJmb3JtQXVkaW9QYXNzVGhydS5LRVlfQVVESU9fUEFTU19USFJVX0RJU1BMQVlfVEVYVF8yLCB0ZXh0Mik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRBdWRpb1Bhc3NUaHJ1RGlzcGxheVRleHQyICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFBlcmZvcm1BdWRpb1Bhc3NUaHJ1LktFWV9BVURJT19QQVNTX1RIUlVfRElTUExBWV9URVhUXzIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2FtcGxpbmdSYXRlfSByYXRlIC0gVGhpcyB2YWx1ZSBzaGFsbCBiZSBhbGxvd2VkIGF0IDgga0h6IG9yIDE2IG9yIDIyIG9yIDQ0IGtIei5cbiAgICAgKiBAcmV0dXJuIHtQZXJmb3JtQXVkaW9QYXNzVGhydX1cbiAgICAgKi9cbiAgICBzZXRTYW1wbGluZ1JhdGUgKHJhdGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoU2FtcGxpbmdSYXRlLCByYXRlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUGVyZm9ybUF1ZGlvUGFzc1RocnUuS0VZX1NBTVBMSU5HX1JBVEUsIHJhdGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTYW1wbGluZ1JhdGV9XG4gICAgICovXG4gICAgZ2V0U2FtcGxpbmdSYXRlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFNhbXBsaW5nUmF0ZSwgUGVyZm9ybUF1ZGlvUGFzc1RocnUuS0VZX1NBTVBMSU5HX1JBVEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBkdXJhdGlvbiAtIFRoZSBtYXhpbXVtIGR1cmF0aW9uIG9mIGF1ZGlvIHJlY29yZGluZyBpbiBtaWxsaXNlY29uZHMuXG4gICAgICogQHJldHVybiB7UGVyZm9ybUF1ZGlvUGFzc1RocnV9XG4gICAgICovXG4gICAgc2V0TWF4RHVyYXRpb24gKGR1cmF0aW9uKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFBlcmZvcm1BdWRpb1Bhc3NUaHJ1LktFWV9NQVhfRFVSQVRJT04sIGR1cmF0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldE1heER1cmF0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFBlcmZvcm1BdWRpb1Bhc3NUaHJ1LktFWV9NQVhfRFVSQVRJT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qml0c1BlclNhbXBsZX0gc2FtcGxlIC0gU3BlY2lmaWVzIHRoZSBxdWFsaXR5IHRoZSBhdWRpbyBpcyByZWNvcmRlZC4gQ3VycmVudGx5IDggYml0IG9yIDE2IGJpdC5cbiAgICAgKiBAcmV0dXJuIHtQZXJmb3JtQXVkaW9QYXNzVGhydX1cbiAgICAgKi9cbiAgICBzZXRCaXRzUGVyU2FtcGxlIChzYW1wbGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQml0c1BlclNhbXBsZSwgc2FtcGxlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUGVyZm9ybUF1ZGlvUGFzc1RocnUuS0VZX0JJVFNfUEVSX1NBTVBMRSwgc2FtcGxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qml0c1BlclNhbXBsZX1cbiAgICAgKi9cbiAgICBnZXRCaXRzUGVyU2FtcGxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEJpdHNQZXJTYW1wbGUsIFBlcmZvcm1BdWRpb1Bhc3NUaHJ1LktFWV9CSVRTX1BFUl9TQU1QTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7QXVkaW9UeXBlfSB0eXBlIC0gU3BlY2lmaWVzIHRoZSB0eXBlIG9mIGF1ZGlvIGRhdGEgYmVpbmcgcmVxdWVzdGVkLlxuICAgICAqIEByZXR1cm4ge1BlcmZvcm1BdWRpb1Bhc3NUaHJ1fVxuICAgICAqL1xuICAgIHNldEF1ZGlvVHlwZSAodHlwZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShBdWRpb1R5cGUsIHR5cGUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihQZXJmb3JtQXVkaW9QYXNzVGhydS5LRVlfQVVESU9fVFlQRSwgdHlwZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0F1ZGlvVHlwZX1cbiAgICAgKi9cbiAgICBnZXRBdWRpb1R5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQXVkaW9UeXBlLCBQZXJmb3JtQXVkaW9QYXNzVGhydS5LRVlfQVVESU9fVFlQRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhdWRpbyAtIERlZmluZXMgaWYgdGhlIGN1cnJlbnQgYXVkaW8gc291cmNlIHNob3VsZCBiZSBtdXRlZCBkdXJpbmcgdGhlIEFQVCBzZXNzaW9uLiBJZiBub3QsIHRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBhdWRpbyBzb3VyY2Ugd2lsbCBwbGF5IHdpdGhvdXQgaW50ZXJydXB0aW9uLiBJZiBvbWl0dGVkLCB0aGUgdmFsdWUgaXMgc2V0IHRvIHRydWUuXG4gICAgICogQHJldHVybiB7UGVyZm9ybUF1ZGlvUGFzc1RocnV9XG4gICAgICovXG4gICAgc2V0TXV0ZUF1ZGlvIChhdWRpbykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihQZXJmb3JtQXVkaW9QYXNzVGhydS5LRVlfTVVURV9BVURJTywgYXVkaW8pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldE11dGVBdWRpbyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihQZXJmb3JtQXVkaW9QYXNzVGhydS5LRVlfTVVURV9BVURJTyk7XG4gICAgfVxufVxuXG5QZXJmb3JtQXVkaW9QYXNzVGhydS5LRVlfSU5JVElBTF9QUk9NUFQgPSAnaW5pdGlhbFByb21wdCc7XG5QZXJmb3JtQXVkaW9QYXNzVGhydS5LRVlfQVVESU9fUEFTU19USFJVX0RJU1BMQVlfVEVYVF8xID0gJ2F1ZGlvUGFzc1RocnVEaXNwbGF5VGV4dDEnO1xuUGVyZm9ybUF1ZGlvUGFzc1RocnUuS0VZX0FVRElPX1BBU1NfVEhSVV9ESVNQTEFZX1RFWFRfMiA9ICdhdWRpb1Bhc3NUaHJ1RGlzcGxheVRleHQyJztcblBlcmZvcm1BdWRpb1Bhc3NUaHJ1LktFWV9TQU1QTElOR19SQVRFID0gJ3NhbXBsaW5nUmF0ZSc7XG5QZXJmb3JtQXVkaW9QYXNzVGhydS5LRVlfTUFYX0RVUkFUSU9OID0gJ21heER1cmF0aW9uJztcblBlcmZvcm1BdWRpb1Bhc3NUaHJ1LktFWV9CSVRTX1BFUl9TQU1QTEUgPSAnYml0c1BlclNhbXBsZSc7XG5QZXJmb3JtQXVkaW9QYXNzVGhydS5LRVlfQVVESU9fVFlQRSA9ICdhdWRpb1R5cGUnO1xuUGVyZm9ybUF1ZGlvUGFzc1RocnUuS0VZX01VVEVfQVVESU8gPSAnbXV0ZUF1ZGlvJztcblxuZXhwb3J0IHsgUGVyZm9ybUF1ZGlvUGFzc1RocnUgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBScGNSZXNwb25zZSB9IGZyb20gJy4uL1JwY1Jlc3BvbnNlLmpzJztcblxuY2xhc3MgUGVyZm9ybUF1ZGlvUGFzc1RocnVSZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlBlcmZvcm1BdWRpb1Bhc3NUaHJ1KTtcbiAgICB9XG59XG5cblxuZXhwb3J0IHsgUGVyZm9ybUF1ZGlvUGFzc1RocnVSZXNwb25zZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1JlcXVlc3QgfSBmcm9tICcuLi9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcblxuLyoqXG4gKiBXaGVuIHRoaXMgcmVxdWVzdCBpcyBpbnZva2VkLCB0aGUgYXVkaW8gY2FwdHVyZSBzdG9wcy5cbiAqL1xuY2xhc3MgRW5kQXVkaW9QYXNzVGhydSBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuRW5kQXVkaW9QYXNzVGhydSk7XG4gICAgfVxufVxuXG5cbmV4cG9ydCB7IEVuZEF1ZGlvUGFzc1RocnUgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBScGNSZXNwb25zZSB9IGZyb20gJy4uL1JwY1Jlc3BvbnNlLmpzJztcblxuY2xhc3MgRW5kQXVkaW9QYXNzVGhydVJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuRW5kQXVkaW9QYXNzVGhydSk7XG4gICAgfVxufVxuXG5cbmV4cG9ydCB7IEVuZEF1ZGlvUGFzc1RocnVSZXNwb25zZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1JlcXVlc3QgfSBmcm9tICcuLi9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IEJ1dHRvbk5hbWUgfSBmcm9tICcuLi9lbnVtcy9CdXR0b25OYW1lLmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcblxuLyoqXG4gKiBTdWJzY3JpYmVzIHRvIGJ1aWx0LWluIEhNSSBidXR0b25zLiBUaGUgYXBwbGljYXRpb24gd2lsbCBiZSBub3RpZmllZCBieSB0aGUgT25CdXR0b25FdmVudCBhbmQgT25CdXR0b25QcmVzcy4gVG9cbiAqIHVuc3Vic2NyaWJlIHRoZSBub3RpZmljYXRpb25zLCB1c2UgdW5zdWJzY3JpYmVCdXR0b24uXG4gKi9cbmNsYXNzIFN1YnNjcmliZUJ1dHRvbiBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuU3Vic2NyaWJlQnV0dG9uKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0J1dHRvbk5hbWV9IG5hbWUgLSBOYW1lIG9mIHRoZSBidXR0b24gdG8gc3Vic2NyaWJlLlxuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZUJ1dHRvbn1cbiAgICAgKi9cbiAgICBzZXRCdXR0b25OYW1lIChuYW1lKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEJ1dHRvbk5hbWUsIG5hbWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVCdXR0b24uS0VZX0JVVFRPTl9OQU1FLCBuYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7QnV0dG9uTmFtZX1cbiAgICAgKi9cbiAgICBnZXRCdXR0b25OYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEJ1dHRvbk5hbWUsIFN1YnNjcmliZUJ1dHRvbi5LRVlfQlVUVE9OX05BTUUpO1xuICAgIH1cbn1cblxuU3Vic2NyaWJlQnV0dG9uLktFWV9CVVRUT05fTkFNRSA9ICdidXR0b25OYW1lJztcblxuZXhwb3J0IHsgU3Vic2NyaWJlQnV0dG9uIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbmNsYXNzIFN1YnNjcmliZUJ1dHRvblJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuU3Vic2NyaWJlQnV0dG9uKTtcbiAgICB9XG59XG5cblxuZXhwb3J0IHsgU3Vic2NyaWJlQnV0dG9uUmVzcG9uc2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBCdXR0b25OYW1lIH0gZnJvbSAnLi4vZW51bXMvQnV0dG9uTmFtZS5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5cbi8qKlxuICogVW5zdWJzY3JpYmVzIGZyb20gYnVpbHQtaW4gSE1JIGJ1dHRvbnMuXG4gKi9cbmNsYXNzIFVuc3Vic2NyaWJlQnV0dG9uIGV4dGVuZHMgUnBjUmVxdWVzdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5VbnN1YnNjcmliZUJ1dHRvbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCdXR0b25OYW1lfSBuYW1lIC0gTmFtZSBvZiB0aGUgYnV0dG9uIHRvIHVuc3Vic2NyaWJlLlxuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlQnV0dG9ufVxuICAgICAqL1xuICAgIHNldEJ1dHRvbk5hbWUgKG5hbWUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQnV0dG9uTmFtZSwgbmFtZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlQnV0dG9uLktFWV9CVVRUT05fTkFNRSwgbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0J1dHRvbk5hbWV9XG4gICAgICovXG4gICAgZ2V0QnV0dG9uTmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChCdXR0b25OYW1lLCBVbnN1YnNjcmliZUJ1dHRvbi5LRVlfQlVUVE9OX05BTUUpO1xuICAgIH1cbn1cblxuVW5zdWJzY3JpYmVCdXR0b24uS0VZX0JVVFRPTl9OQU1FID0gJ2J1dHRvbk5hbWUnO1xuXG5leHBvcnQgeyBVbnN1YnNjcmliZUJ1dHRvbiB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG5jbGFzcyBVbnN1YnNjcmliZUJ1dHRvblJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuVW5zdWJzY3JpYmVCdXR0b24pO1xuICAgIH1cbn1cblxuXG5leHBvcnQgeyBVbnN1YnNjcmliZUJ1dHRvblJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG4vKipcbiAqIFN1YnNjcmliZXMgZm9yIHNwZWNpZmljIHB1Ymxpc2hlZCBkYXRhIGl0ZW1zLiBUaGUgZGF0YSB3aWxsIGJlIG9ubHkgc2VudCBpZiBpdCBoYXMgY2hhbmdlZC4gVGhlIGFwcGxpY2F0aW9uIHdpbGwgYmVcbiAqIG5vdGlmaWVkIGJ5IHRoZSBvblZlaGljbGVEYXRhIG5vdGlmaWNhdGlvbiB3aGVuZXZlciBuZXcgZGF0YSBpcyBhdmFpbGFibGUuIFRvIHVuc3Vic2NyaWJlIHRoZSBub3RpZmljYXRpb25zLCB1c2VcbiAqIHVuc3Vic2NyaWJlIHdpdGggdGhlIHNhbWUgc3Vic2NyaXB0aW9uVHlwZS5cbiAqL1xuY2xhc3MgU3Vic2NyaWJlVmVoaWNsZURhdGEgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlN1YnNjcmliZVZlaGljbGVEYXRhKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGdwcyAtIFNlZSBHUFNEYXRhXG4gICAgICogQHJldHVybiB7U3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0R3BzIChncHMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0dQUywgZ3BzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRHcHMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0dQUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBzcGVlZCAtIFRoZSB2ZWhpY2xlIHNwZWVkIGluIGtpbG9tZXRlcnMgcGVyIGhvdXJcbiAgICAgKiBAcmV0dXJuIHtTdWJzY3JpYmVWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRTcGVlZCAoc3BlZWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX1NQRUVELCBzcGVlZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0U3BlZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX1NQRUVEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHJwbSAtIFRoZSBudW1iZXIgb2YgcmV2b2x1dGlvbnMgcGVyIG1pbnV0ZSBvZiB0aGUgZW5naW5lXG4gICAgICogQHJldHVybiB7U3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0UnBtIChycG0pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX1JQTSwgcnBtKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRScG0gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX1JQTSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBsZXZlbCAtIFRoZSBmdWVsIGxldmVsIGluIHRoZSB0YW5rIChwZXJjZW50YWdlKVxuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldEZ1ZWxMZXZlbCAobGV2ZWwpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0ZVRUxfTEVWRUwsIGxldmVsKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRGdWVsTGV2ZWwgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0ZVRUxfTEVWRUwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gbGV2ZWxfc3RhdGUgLSBUaGUgZnVlbCBsZXZlbCBzdGF0ZVxuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldEZ1ZWxMZXZlbF9TdGF0ZSAobGV2ZWxfc3RhdGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0ZVRUxfTEVWRUxfU1RBVEUsIGxldmVsX3N0YXRlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRGdWVsTGV2ZWxfU3RhdGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0ZVRUxfTEVWRUxfU1RBVEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gY29uc3VtcHRpb24gLSBUaGUgaW5zdGFudGFuZW91cyBmdWVsIGNvbnN1bXB0aW9uIGluIG1pY3JvbGl0cmVzXG4gICAgICogQHJldHVybiB7U3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0SW5zdGFudEZ1ZWxDb25zdW1wdGlvbiAoY29uc3VtcHRpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0lOU1RBTlRfRlVFTF9DT05TVU1QVElPTiwgY29uc3VtcHRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEluc3RhbnRGdWVsQ29uc3VtcHRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0lOU1RBTlRfRlVFTF9DT05TVU1QVElPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSByYW5nZSAtIFRoZSBlc3RpbWF0ZSByYW5nZSBpbiBLTSB0aGUgdmVoaWNsZSBjYW4gdHJhdmVsIGJhc2VkIG9uIGZ1ZWwgbGV2ZWwgYW5kIGNvbnN1bXB0aW9uXG4gICAgICogQHJldHVybiB7U3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0RnVlbFJhbmdlIChyYW5nZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfRlVFTF9SQU5HRSwgcmFuZ2UpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEZ1ZWxSYW5nZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfRlVFTF9SQU5HRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSB0ZW1wZXJhdHVyZSAtIFRoZSBleHRlcm5hbCB0ZW1wZXJhdHVyZSBpbiBkZWdyZWVzIGNlbHNpdXNcbiAgICAgKiBAcmV0dXJuIHtTdWJzY3JpYmVWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRFeHRlcm5hbFRlbXBlcmF0dXJlICh0ZW1wZXJhdHVyZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfRVhURVJOQUxfVEVNUEVSQVRVUkUsIHRlbXBlcmF0dXJlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRFeHRlcm5hbFRlbXBlcmF0dXJlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9FWFRFUk5BTF9URU1QRVJBVFVSRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBzaWduYWwgLSBTZWUgVHVyblNpZ25hbFxuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldFR1cm5TaWduYWwgKHNpZ25hbCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfVFVSTl9TSUdOQUwsIHNpZ25hbCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0VHVyblNpZ25hbCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfVFVSTl9TSUdOQUwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gcHJuZGwgLSBTZWUgUFJORExcbiAgICAgKiBAcmV0dXJuIHtTdWJzY3JpYmVWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRQcm5kbCAocHJuZGwpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX1BSTkRMLCBwcm5kbCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0UHJuZGwgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX1BSTkRMKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHByZXNzdXJlIC0gU2VlIFRpcmVTdGF0dXNcbiAgICAgKiBAcmV0dXJuIHtTdWJzY3JpYmVWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRUaXJlUHJlc3N1cmUgKHByZXNzdXJlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9USVJFX1BSRVNTVVJFLCBwcmVzc3VyZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0VGlyZVByZXNzdXJlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9USVJFX1BSRVNTVVJFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IG9kb21ldGVyIC0gT2RvbWV0ZXIgaW4ga21cbiAgICAgKiBAcmV0dXJuIHtTdWJzY3JpYmVWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRPZG9tZXRlciAob2RvbWV0ZXIpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX09ET01FVEVSLCBvZG9tZXRlcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0T2RvbWV0ZXIgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX09ET01FVEVSKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHN0YXR1cyAtIFRoZSBzdGF0dXMgb2YgdGhlIHNlYXQgYmVsdHNcbiAgICAgKiBAcmV0dXJuIHtTdWJzY3JpYmVWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRCZWx0U3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0JFTFRfU1RBVFVTLCBzdGF0dXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEJlbHRTdGF0dXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0JFTFRfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGluZm9ybWF0aW9uIC0gVGhlIGJvZHkgaW5mb3JtYXRpb24gaW5jbHVkaW5nIHBvd2VyIG1vZGVzXG4gICAgICogQHJldHVybiB7U3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0Qm9keUluZm9ybWF0aW9uIChpbmZvcm1hdGlvbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfQk9EWV9JTkZPUk1BVElPTiwgaW5mb3JtYXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEJvZHlJbmZvcm1hdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfQk9EWV9JTkZPUk1BVElPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBzdGF0dXMgLSBUaGUgZGV2aWNlIHN0YXR1cyBpbmNsdWRpbmcgc2lnbmFsIGFuZCBiYXR0ZXJ5IHN0cmVuZ3RoXG4gICAgICogQHJldHVybiB7U3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0RGV2aWNlU3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0RFVklDRV9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0RGV2aWNlU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9ERVZJQ0VfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGJyYWtpbmcgLSBUaGUgc3RhdHVzIG9mIHRoZSBicmFrZSBwZWRhbFxuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldERyaXZlckJyYWtpbmcgKGJyYWtpbmcpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0RSSVZFUl9CUkFLSU5HLCBicmFraW5nKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXREcml2ZXJCcmFraW5nICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9EUklWRVJfQlJBS0lORyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBzdGF0dXMgLSBUaGUgc3RhdHVzIG9mIHRoZSB3aXBlcnNcbiAgICAgKiBAcmV0dXJuIHtTdWJzY3JpYmVWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRXaXBlclN0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9XSVBFUl9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0V2lwZXJTdGF0dXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX1dJUEVSX1NUQVRVUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBzdGF0dXMgLSBTdGF0dXMgb2YgdGhlIGhlYWQgbGFtcHNcbiAgICAgKiBAcmV0dXJuIHtTdWJzY3JpYmVWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRIZWFkTGFtcFN0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9IRUFEX0xBTVBfU1RBVFVTLCBzdGF0dXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEhlYWRMYW1wU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9IRUFEX0xBTVBfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHRvcnF1ZSAtIFRvcnF1ZSB2YWx1ZSBmb3IgZW5naW5lIChpbiBObSkgb24gbm9uLWRpZXNlbCB2YXJpYW50c1xuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldEVuZ2luZVRvcnF1ZSAodG9ycXVlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9FTkdJTkVfVE9SUVVFLCB0b3JxdWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEVuZ2luZVRvcnF1ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfRU5HSU5FX1RPUlFVRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBwb3NpdGlvbiAtIEFjY2VsZXJhdG9yIHBlZGFsIHBvc2l0aW9uIChwZXJjZW50YWdlIGRlcHJlc3NlZClcbiAgICAgKiBAcmV0dXJuIHtTdWJzY3JpYmVWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRBY2NQZWRhbFBvc2l0aW9uIChwb3NpdGlvbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfQUNDX1BFREFMX1BPU0lUSU9OLCBwb3NpdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0QWNjUGVkYWxQb3NpdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfQUNDX1BFREFMX1BPU0lUSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGFuZ2xlIC0gQ3VycmVudCBhbmdsZSBvZiB0aGUgc3RlZXJpbmcgd2hlZWwgKGluIGRlZylcbiAgICAgKiBAcmV0dXJuIHtTdWJzY3JpYmVWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRTdGVlcmluZ1doZWVsQW5nbGUgKGFuZ2xlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9TVEVFUklOR19XSEVFTF9BTkdMRSwgYW5nbGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFN0ZWVyaW5nV2hlZWxBbmdsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfU1RFRVJJTkdfV0hFRUxfQU5HTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gbGlmZSAtIFRoZSBlc3RpbWF0ZWQgcGVyY2VudGFnZSBvZiByZW1haW5pbmcgb2lsIGxpZmUgb2YgdGhlIGVuZ2luZS5cbiAgICAgKiBAcmV0dXJuIHtTdWJzY3JpYmVWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRFbmdpbmVPaWxMaWZlIChsaWZlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9FTkdJTkVfT0lMX0xJRkUsIGxpZmUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEVuZ2luZU9pbExpZmUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0VOR0lORV9PSUxfTElGRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBzdGF0dXMgLSBUaGUgc3RhdHVzIG9mIHRoZSBwYXJrIGJyYWtlIGFzIHByb3ZpZGVkIGJ5IEVsZWN0cmljIFBhcmsgQnJha2UgKEVQQikgc3lzdGVtLlxuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldEVsZWN0cm9uaWNQYXJrQnJha2VTdGF0dXMgKHN0YXR1cykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfRUxFQ1RST05JQ19QQVJLX0JSQUtFX1NUQVRVUywgc3RhdHVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRFbGVjdHJvbmljUGFya0JyYWtlU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9FTEVDVFJPTklDX1BBUktfQlJBS0VfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGlkIC0gUGFyYW1ldGVyIHVzZWQgYnkgY2xvdWQgYXBwcyB0byBpZGVudGlmeSBhIGhlYWQgdW5pdFxuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldENsb3VkQXBwVmVoaWNsZUlEIChpZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfQ0xPVURfQVBQX1ZFSElDTEVfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRDbG91ZEFwcFZlaGljbGVJRCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfQ0xPVURfQVBQX1ZFSElDTEVfSUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gaW5mbyAtIEVtZXJnZW5jeSBDYWxsIG5vdGlmaWNhdGlvbiBhbmQgY29uZmlybWF0aW9uIGRhdGFcbiAgICAgKiBAcmV0dXJuIHtTdWJzY3JpYmVWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRFQ2FsbEluZm8gKGluZm8pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0VfQ0FMTF9JTkZPLCBpbmZvKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRFQ2FsbEluZm8gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0VfQ0FMTF9JTkZPKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHN0YXR1cyAtIFRoZSBzdGF0dXMgb2YgdGhlIGFpciBiYWdzXG4gICAgICogQHJldHVybiB7U3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0QWlyYmFnU3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0FJUkJBR19TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0QWlyYmFnU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9BSVJCQUdfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGV2ZW50IC0gSW5mb3JtYXRpb24gcmVsYXRlZCB0byBhbiBlbWVyZ2VuY3kgZXZlbnQgKGFuZCBpZiBpdCBvY2N1cnJlZClcbiAgICAgKiBAcmV0dXJuIHtTdWJzY3JpYmVWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRFbWVyZ2VuY3lFdmVudCAoZXZlbnQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0VNRVJHRU5DWV9FVkVOVCwgZXZlbnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEVtZXJnZW5jeUV2ZW50ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9FTUVSR0VOQ1lfRVZFTlQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gc3RhdHVzIC0gVGhlIHN0YXR1cyBtb2RlcyBvZiB0aGUgY2x1c3RlclxuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldENsdXN0ZXJNb2RlU3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0NMVVNURVJfTU9ERV9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0Q2x1c3Rlck1vZGVTdGF0dXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0NMVVNURVJfTU9ERV9TVEFUVVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0ga2V5IC0gSW5mb3JtYXRpb24gcmVsYXRlZCB0byB0aGUgTXlLZXkgZmVhdHVyZVxuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldE15S2V5IChrZXkpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX01ZX0tFWSwga2V5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRNeUtleSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfTVlfS0VZKTtcbiAgICB9XG59XG5cblN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9HUFMgPSAnZ3BzJztcblN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9TUEVFRCA9ICdzcGVlZCc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfUlBNID0gJ3JwbSc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfRlVFTF9MRVZFTCA9ICdmdWVsTGV2ZWwnO1xuU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0ZVRUxfTEVWRUxfU1RBVEUgPSAnZnVlbExldmVsX1N0YXRlJztcblN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9JTlNUQU5UX0ZVRUxfQ09OU1VNUFRJT04gPSAnaW5zdGFudEZ1ZWxDb25zdW1wdGlvbic7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfRlVFTF9SQU5HRSA9ICdmdWVsUmFuZ2UnO1xuU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0VYVEVSTkFMX1RFTVBFUkFUVVJFID0gJ2V4dGVybmFsVGVtcGVyYXR1cmUnO1xuU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX1RVUk5fU0lHTkFMID0gJ3R1cm5TaWduYWwnO1xuU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX1BSTkRMID0gJ3BybmRsJztcblN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9USVJFX1BSRVNTVVJFID0gJ3RpcmVQcmVzc3VyZSc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfT0RPTUVURVIgPSAnb2RvbWV0ZXInO1xuU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0JFTFRfU1RBVFVTID0gJ2JlbHRTdGF0dXMnO1xuU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0JPRFlfSU5GT1JNQVRJT04gPSAnYm9keUluZm9ybWF0aW9uJztcblN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9ERVZJQ0VfU1RBVFVTID0gJ2RldmljZVN0YXR1cyc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfRFJJVkVSX0JSQUtJTkcgPSAnZHJpdmVyQnJha2luZyc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfV0lQRVJfU1RBVFVTID0gJ3dpcGVyU3RhdHVzJztcblN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9IRUFEX0xBTVBfU1RBVFVTID0gJ2hlYWRMYW1wU3RhdHVzJztcblN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9FTkdJTkVfVE9SUVVFID0gJ2VuZ2luZVRvcnF1ZSc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfQUNDX1BFREFMX1BPU0lUSU9OID0gJ2FjY1BlZGFsUG9zaXRpb24nO1xuU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX1NURUVSSU5HX1dIRUVMX0FOR0xFID0gJ3N0ZWVyaW5nV2hlZWxBbmdsZSc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfRU5HSU5FX09JTF9MSUZFID0gJ2VuZ2luZU9pbExpZmUnO1xuU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0VMRUNUUk9OSUNfUEFSS19CUkFLRV9TVEFUVVMgPSAnZWxlY3Ryb25pY1BhcmtCcmFrZVN0YXR1cyc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfQ0xPVURfQVBQX1ZFSElDTEVfSUQgPSAnY2xvdWRBcHBWZWhpY2xlSUQnO1xuU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0VfQ0FMTF9JTkZPID0gJ2VDYWxsSW5mbyc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfQUlSQkFHX1NUQVRVUyA9ICdhaXJiYWdTdGF0dXMnO1xuU3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0VNRVJHRU5DWV9FVkVOVCA9ICdlbWVyZ2VuY3lFdmVudCc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfQ0xVU1RFUl9NT0RFX1NUQVRVUyA9ICdjbHVzdGVyTW9kZVN0YXR1cyc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfTVlfS0VZID0gJ215S2V5JztcblxuZXhwb3J0IHsgU3Vic2NyaWJlVmVoaWNsZURhdGEgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBFbnVtZXJhdGlvbiB0aGF0IGRlc2NyaWJlcyBwb3NzaWJsZSByZXN1bHQgY29kZXMgb2YgYSB2ZWhpY2xlIGRhdGEgZW50cnkgcmVxdWVzdC5cbiAqIEB0eXBlZGVmIHtFbnVtfSBWZWhpY2xlRGF0YVJlc3VsdENvZGVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIFZlaGljbGVEYXRhUmVzdWx0Q29kZSBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbmRpdmlkdWFsIHZlaGljbGUgZGF0YSBpdGVtIC8gRFRDIC8gRElEIHJlcXVlc3Qgb3Igc3Vic2NyaXB0aW9uIHN1Y2Nlc3NmdWxcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBWRFJDX1NVQ0NFU1MgKCkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFSZXN1bHRDb2RlLl9NQVAuVkRSQ19TVUNDRVNTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERUQyAvIERJRCByZXF1ZXN0IHN1Y2Nlc3NmdWwsIGhvd2V2ZXIsIG5vdCBhbGwgYWN0aXZlIERUQ3Mgb3IgZnVsbCBjb250ZW50cyBvZiBESUQgbG9jYXRpb24gYXZhaWxhYmxlXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVkRSQ19UUlVOQ0FURURfREFUQSAoKSB7XG4gICAgICAgIHJldHVybiBWZWhpY2xlRGF0YVJlc3VsdENvZGUuX01BUC5WRFJDX1RSVU5DQVRFRF9EQVRBO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgdmVoaWNsZSBkYXRhIGl0ZW0gaXMgbm90IGFsbG93ZWQgZm9yIHRoaXMgYXBwIGJ5IHRoZSBPRU0vTWFudWZhY3RvcmVyIG9mIHRoZSBjb25uZWN0ZWQgbW9kdWxlLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZEUkNfRElTQUxMT1dFRCAoKSB7XG4gICAgICAgIHJldHVybiBWZWhpY2xlRGF0YVJlc3VsdENvZGUuX01BUC5WRFJDX0RJU0FMTE9XRUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIHVzZXIgaGFzIG5vdCBncmFudGVkIGFjY2VzcyB0byB0aGlzIHR5cGUgb2YgdmVoaWNsZSBkYXRhIGl0ZW0gYXQgdGhpcyB0aW1lLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZEUkNfVVNFUl9ESVNBTExPV0VEICgpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhUmVzdWx0Q29kZS5fTUFQLlZEUkNfVVNFUl9ESVNBTExPV0VEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBFQ1UgSUQgcmVmZXJlbmNlZCBpcyBub3QgYSB2YWxpZCBJRCBvbiB0aGUgYnVzIC8gc3lzdGVtLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZEUkNfSU5WQUxJRF9JRCAoKSB7XG4gICAgICAgIHJldHVybiBWZWhpY2xlRGF0YVJlc3VsdENvZGUuX01BUC5WRFJDX0lOVkFMSURfSUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIHJlcXVlc3RlZCB2ZWhpY2xlIGRhdGEgaXRlbSAvIERUQyAvIERJRCBpcyBub3QgY3VycmVudGx5IGF2YWlsYWJsZSBvciByZXNwb25kaW5nIG9uIHRoZSBidXMgLyBzeXN0ZW0uXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVkRSQ19EQVRBX05PVF9BVkFJTEFCTEUgKCkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFSZXN1bHRDb2RlLl9NQVAuVkRSQ19EQVRBX05PVF9BVkFJTEFCTEU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIHZlaGljbGUgZGF0YSBpdGVtIGlzIGFscmVhZHkgc3Vic2NyaWJlZC5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBWRFJDX0RBVEFfQUxSRUFEWV9TVUJTQ1JJQkVEICgpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhUmVzdWx0Q29kZS5fTUFQLlZEUkNfREFUQV9BTFJFQURZX1NVQlNDUklCRUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIHZlaGljbGUgZGF0YSBpdGVtIGNhbm5vdCBiZSB1bnN1YnNjcmliZWQgYmVjYXVzZSBpdCBpcyBub3QgY3VycmVudGx5IHN1YnNjcmliZWQuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVkRSQ19EQVRBX05PVF9TVUJTQ1JJQkVEICgpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhUmVzdWx0Q29kZS5fTUFQLlZEUkNfREFUQV9OT1RfU1VCU0NSSUJFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVxdWVzdCBmb3IgdGhpcyBpdGVtIGlzIGlnbm9yZWQgYmVjYXVzZSBpdCBpcyBhbHJlYWR5IGluIHByb2dyZXNzLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZEUkNfSUdOT1JFRCAoKSB7XG4gICAgICAgIHJldHVybiBWZWhpY2xlRGF0YVJlc3VsdENvZGUuX01BUC5WRFJDX0lHTk9SRUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFSZXN1bHRDb2RlLl92YWx1ZUZvcktleShrZXksIFZlaGljbGVEYXRhUmVzdWx0Q29kZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhUmVzdWx0Q29kZS5fa2V5Rm9yVmFsdWUodmFsdWUsIFZlaGljbGVEYXRhUmVzdWx0Q29kZS5fTUFQKTtcbiAgICB9XG59XG5cblZlaGljbGVEYXRhUmVzdWx0Q29kZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1ZEUkNfU1VDQ0VTUyc6ICdTVUNDRVNTJyxcbiAgICAnVkRSQ19UUlVOQ0FURURfREFUQSc6ICdUUlVOQ0FURURfREFUQScsXG4gICAgJ1ZEUkNfRElTQUxMT1dFRCc6ICdESVNBTExPV0VEJyxcbiAgICAnVkRSQ19VU0VSX0RJU0FMTE9XRUQnOiAnVVNFUl9ESVNBTExPV0VEJyxcbiAgICAnVkRSQ19JTlZBTElEX0lEJzogJ0lOVkFMSURfSUQnLFxuICAgICdWRFJDX0RBVEFfTk9UX0FWQUlMQUJMRSc6ICdWRUhJQ0xFX0RBVEFfTk9UX0FWQUlMQUJMRScsXG4gICAgJ1ZEUkNfREFUQV9BTFJFQURZX1NVQlNDUklCRUQnOiAnREFUQV9BTFJFQURZX1NVQlNDUklCRUQnLFxuICAgICdWRFJDX0RBVEFfTk9UX1NVQlNDUklCRUQnOiAnREFUQV9OT1RfU1VCU0NSSUJFRCcsXG4gICAgJ1ZEUkNfSUdOT1JFRCc6ICdJR05PUkVEJyxcbn0pO1xuXG5leHBvcnQgeyBWZWhpY2xlRGF0YVJlc3VsdENvZGUgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBkYXRhIHR5cGVzIHRoYXQgY2FuIGJlIHB1Ymxpc2hlZCBhbmQgc3Vic2NyaWJlZCB0by5cbiAqIEB0eXBlZGVmIHtFbnVtfSBWZWhpY2xlRGF0YVR5cGVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIFZlaGljbGVEYXRhVHlwZSBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBOb3RpZmllcyBHUFNEYXRhIG1heSBiZSBzdWJzY3JpYmVkXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVkVISUNMRURBVEFfR1BTICgpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhVHlwZS5fTUFQLlZFSElDTEVEQVRBX0dQUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBWRUhJQ0xFREFUQV9TUEVFRCAoKSB7XG4gICAgICAgIHJldHVybiBWZWhpY2xlRGF0YVR5cGUuX01BUC5WRUhJQ0xFREFUQV9TUEVFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBWRUhJQ0xFREFUQV9SUE0gKCkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFUeXBlLl9NQVAuVkVISUNMRURBVEFfUlBNO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZFSElDTEVEQVRBX0ZVRUxMRVZFTCAoKSB7XG4gICAgICAgIHJldHVybiBWZWhpY2xlRGF0YVR5cGUuX01BUC5WRUhJQ0xFREFUQV9GVUVMTEVWRUw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVkVISUNMRURBVEFfRlVFTExFVkVMX1NUQVRFICgpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhVHlwZS5fTUFQLlZFSElDTEVEQVRBX0ZVRUxMRVZFTF9TVEFURTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBWRUhJQ0xFREFUQV9GVUVMQ09OU1VNUFRJT04gKCkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFUeXBlLl9NQVAuVkVISUNMRURBVEFfRlVFTENPTlNVTVBUSU9OO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZFSElDTEVEQVRBX0VYVEVSTlRFTVAgKCkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFUeXBlLl9NQVAuVkVISUNMRURBVEFfRVhURVJOVEVNUDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBWRUhJQ0xFREFUQV9WSU4gKCkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFUeXBlLl9NQVAuVkVISUNMRURBVEFfVklOO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZFSElDTEVEQVRBX1BSTkRMICgpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhVHlwZS5fTUFQLlZFSElDTEVEQVRBX1BSTkRMO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZFSElDTEVEQVRBX1RJUkVQUkVTU1VSRSAoKSB7XG4gICAgICAgIHJldHVybiBWZWhpY2xlRGF0YVR5cGUuX01BUC5WRUhJQ0xFREFUQV9USVJFUFJFU1NVUkU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVkVISUNMRURBVEFfT0RPTUVURVIgKCkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFUeXBlLl9NQVAuVkVISUNMRURBVEFfT0RPTUVURVI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVkVISUNMRURBVEFfQkVMVFNUQVRVUyAoKSB7XG4gICAgICAgIHJldHVybiBWZWhpY2xlRGF0YVR5cGUuX01BUC5WRUhJQ0xFREFUQV9CRUxUU1RBVFVTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZFSElDTEVEQVRBX0JPRFlJTkZPICgpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhVHlwZS5fTUFQLlZFSElDTEVEQVRBX0JPRFlJTkZPO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZFSElDTEVEQVRBX0RFVklDRVNUQVRVUyAoKSB7XG4gICAgICAgIHJldHVybiBWZWhpY2xlRGF0YVR5cGUuX01BUC5WRUhJQ0xFREFUQV9ERVZJQ0VTVEFUVVM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVkVISUNMRURBVEFfRUNBTExJTkZPICgpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhVHlwZS5fTUFQLlZFSElDTEVEQVRBX0VDQUxMSU5GTztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBWRUhJQ0xFREFUQV9BSVJCQUdTVEFUVVMgKCkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFUeXBlLl9NQVAuVkVISUNMRURBVEFfQUlSQkFHU1RBVFVTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZFSElDTEVEQVRBX0VNRVJHRU5DWUVWRU5UICgpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhVHlwZS5fTUFQLlZFSElDTEVEQVRBX0VNRVJHRU5DWUVWRU5UO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZFSElDTEVEQVRBX0NMVVNURVJNT0RFU1RBVFVTICgpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhVHlwZS5fTUFQLlZFSElDTEVEQVRBX0NMVVNURVJNT0RFU1RBVFVTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZFSElDTEVEQVRBX01ZS0VZICgpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhVHlwZS5fTUFQLlZFSElDTEVEQVRBX01ZS0VZO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZFSElDTEVEQVRBX0JSQUtJTkcgKCkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFUeXBlLl9NQVAuVkVISUNMRURBVEFfQlJBS0lORztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBWRUhJQ0xFREFUQV9XSVBFUlNUQVRVUyAoKSB7XG4gICAgICAgIHJldHVybiBWZWhpY2xlRGF0YVR5cGUuX01BUC5WRUhJQ0xFREFUQV9XSVBFUlNUQVRVUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBWRUhJQ0xFREFUQV9IRUFETEFNUFNUQVRVUyAoKSB7XG4gICAgICAgIHJldHVybiBWZWhpY2xlRGF0YVR5cGUuX01BUC5WRUhJQ0xFREFUQV9IRUFETEFNUFNUQVRVUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBWRUhJQ0xFREFUQV9CQVRUVk9MVEFHRSAoKSB7XG4gICAgICAgIHJldHVybiBWZWhpY2xlRGF0YVR5cGUuX01BUC5WRUhJQ0xFREFUQV9CQVRUVk9MVEFHRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBWRUhJQ0xFREFUQV9FTkdJTkVUT1JRVUUgKCkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFUeXBlLl9NQVAuVkVISUNMRURBVEFfRU5HSU5FVE9SUVVFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZFSElDTEVEQVRBX0FDQ1BFREFMICgpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhVHlwZS5fTUFQLlZFSElDTEVEQVRBX0FDQ1BFREFMO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZFSElDTEVEQVRBX1NURUVSSU5HV0hFRUwgKCkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFUeXBlLl9NQVAuVkVISUNMRURBVEFfU1RFRVJJTkdXSEVFTDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBWRUhJQ0xFREFUQV9UVVJOU0lHTkFMICgpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhVHlwZS5fTUFQLlZFSElDTEVEQVRBX1RVUk5TSUdOQUw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVkVISUNMRURBVEFfRlVFTFJBTkdFICgpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhVHlwZS5fTUFQLlZFSElDTEVEQVRBX0ZVRUxSQU5HRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBWRUhJQ0xFREFUQV9FTkdJTkVPSUxMSUZFICgpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhVHlwZS5fTUFQLlZFSElDTEVEQVRBX0VOR0lORU9JTExJRkU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVkVISUNMRURBVEFfRUxFQ1RST05JQ1BBUktCUkFLRVNUQVRVUyAoKSB7XG4gICAgICAgIHJldHVybiBWZWhpY2xlRGF0YVR5cGUuX01BUC5WRUhJQ0xFREFUQV9FTEVDVFJPTklDUEFSS0JSQUtFU1RBVFVTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZFSElDTEVEQVRBX0NMT1VEQVBQVkVISUNMRUlEICgpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhVHlwZS5fTUFQLlZFSElDTEVEQVRBX0NMT1VEQVBQVkVISUNMRUlEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZFSElDTEVEQVRBX09FTV9DVVNUT01fREFUQSAoKSB7XG4gICAgICAgIHJldHVybiBWZWhpY2xlRGF0YVR5cGUuX01BUC5WRUhJQ0xFREFUQV9PRU1fQ1VTVE9NX0RBVEE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFUeXBlLl92YWx1ZUZvcktleShrZXksIFZlaGljbGVEYXRhVHlwZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhVHlwZS5fa2V5Rm9yVmFsdWUodmFsdWUsIFZlaGljbGVEYXRhVHlwZS5fTUFQKTtcbiAgICB9XG59XG5cblZlaGljbGVEYXRhVHlwZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1ZFSElDTEVEQVRBX0dQUyc6ICdWRUhJQ0xFREFUQV9HUFMnLFxuICAgICdWRUhJQ0xFREFUQV9TUEVFRCc6ICdWRUhJQ0xFREFUQV9TUEVFRCcsXG4gICAgJ1ZFSElDTEVEQVRBX1JQTSc6ICdWRUhJQ0xFREFUQV9SUE0nLFxuICAgICdWRUhJQ0xFREFUQV9GVUVMTEVWRUwnOiAnVkVISUNMRURBVEFfRlVFTExFVkVMJyxcbiAgICAnVkVISUNMRURBVEFfRlVFTExFVkVMX1NUQVRFJzogJ1ZFSElDTEVEQVRBX0ZVRUxMRVZFTF9TVEFURScsXG4gICAgJ1ZFSElDTEVEQVRBX0ZVRUxDT05TVU1QVElPTic6ICdWRUhJQ0xFREFUQV9GVUVMQ09OU1VNUFRJT04nLFxuICAgICdWRUhJQ0xFREFUQV9FWFRFUk5URU1QJzogJ1ZFSElDTEVEQVRBX0VYVEVSTlRFTVAnLFxuICAgICdWRUhJQ0xFREFUQV9WSU4nOiAnVkVISUNMRURBVEFfVklOJyxcbiAgICAnVkVISUNMRURBVEFfUFJOREwnOiAnVkVISUNMRURBVEFfUFJOREwnLFxuICAgICdWRUhJQ0xFREFUQV9USVJFUFJFU1NVUkUnOiAnVkVISUNMRURBVEFfVElSRVBSRVNTVVJFJyxcbiAgICAnVkVISUNMRURBVEFfT0RPTUVURVInOiAnVkVISUNMRURBVEFfT0RPTUVURVInLFxuICAgICdWRUhJQ0xFREFUQV9CRUxUU1RBVFVTJzogJ1ZFSElDTEVEQVRBX0JFTFRTVEFUVVMnLFxuICAgICdWRUhJQ0xFREFUQV9CT0RZSU5GTyc6ICdWRUhJQ0xFREFUQV9CT0RZSU5GTycsXG4gICAgJ1ZFSElDTEVEQVRBX0RFVklDRVNUQVRVUyc6ICdWRUhJQ0xFREFUQV9ERVZJQ0VTVEFUVVMnLFxuICAgICdWRUhJQ0xFREFUQV9FQ0FMTElORk8nOiAnVkVISUNMRURBVEFfRUNBTExJTkZPJyxcbiAgICAnVkVISUNMRURBVEFfQUlSQkFHU1RBVFVTJzogJ1ZFSElDTEVEQVRBX0FJUkJBR1NUQVRVUycsXG4gICAgJ1ZFSElDTEVEQVRBX0VNRVJHRU5DWUVWRU5UJzogJ1ZFSElDTEVEQVRBX0VNRVJHRU5DWUVWRU5UJyxcbiAgICAnVkVISUNMRURBVEFfQ0xVU1RFUk1PREVTVEFUVVMnOiAnVkVISUNMRURBVEFfQ0xVU1RFUk1PREVTVEFUVVMnLFxuICAgICdWRUhJQ0xFREFUQV9NWUtFWSc6ICdWRUhJQ0xFREFUQV9NWUtFWScsXG4gICAgJ1ZFSElDTEVEQVRBX0JSQUtJTkcnOiAnVkVISUNMRURBVEFfQlJBS0lORycsXG4gICAgJ1ZFSElDTEVEQVRBX1dJUEVSU1RBVFVTJzogJ1ZFSElDTEVEQVRBX1dJUEVSU1RBVFVTJyxcbiAgICAnVkVISUNMRURBVEFfSEVBRExBTVBTVEFUVVMnOiAnVkVISUNMRURBVEFfSEVBRExBTVBTVEFUVVMnLFxuICAgICdWRUhJQ0xFREFUQV9CQVRUVk9MVEFHRSc6ICdWRUhJQ0xFREFUQV9CQVRUVk9MVEFHRScsXG4gICAgJ1ZFSElDTEVEQVRBX0VOR0lORVRPUlFVRSc6ICdWRUhJQ0xFREFUQV9FTkdJTkVUT1JRVUUnLFxuICAgICdWRUhJQ0xFREFUQV9BQ0NQRURBTCc6ICdWRUhJQ0xFREFUQV9BQ0NQRURBTCcsXG4gICAgJ1ZFSElDTEVEQVRBX1NURUVSSU5HV0hFRUwnOiAnVkVISUNMRURBVEFfU1RFRVJJTkdXSEVFTCcsXG4gICAgJ1ZFSElDTEVEQVRBX1RVUk5TSUdOQUwnOiAnVkVISUNMRURBVEFfVFVSTlNJR05BTCcsXG4gICAgJ1ZFSElDTEVEQVRBX0ZVRUxSQU5HRSc6ICdWRUhJQ0xFREFUQV9GVUVMUkFOR0UnLFxuICAgICdWRUhJQ0xFREFUQV9FTkdJTkVPSUxMSUZFJzogJ1ZFSElDTEVEQVRBX0VOR0lORU9JTExJRkUnLFxuICAgICdWRUhJQ0xFREFUQV9FTEVDVFJPTklDUEFSS0JSQUtFU1RBVFVTJzogJ1ZFSElDTEVEQVRBX0VMRUNUUk9OSUNQQVJLQlJBS0VTVEFUVVMnLFxuICAgICdWRUhJQ0xFREFUQV9DTE9VREFQUFZFSElDTEVJRCc6ICdWRUhJQ0xFREFUQV9DTE9VREFQUFZFSElDTEVJRCcsXG4gICAgJ1ZFSElDTEVEQVRBX09FTV9DVVNUT01fREFUQSc6ICdWRUhJQ0xFREFUQV9PRU1fQ1VTVE9NX0RBVEEnLFxufSk7XG5cbmV4cG9ydCB7IFZlaGljbGVEYXRhVHlwZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBWZWhpY2xlRGF0YVJlc3VsdENvZGUgfSBmcm9tICcuLi9lbnVtcy9WZWhpY2xlRGF0YVJlc3VsdENvZGUuanMnO1xuaW1wb3J0IHsgVmVoaWNsZURhdGFUeXBlIH0gZnJvbSAnLi4vZW51bXMvVmVoaWNsZURhdGFUeXBlLmpzJztcblxuLyoqXG4gKiBJbmRpdmlkdWFsIHB1Ymxpc2hlZCBkYXRhIHJlcXVlc3QgcmVzdWx0XG4gKi9cbmNsYXNzIFZlaGljbGVEYXRhUmVzdWx0IGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlaGljbGVEYXRhVHlwZX0gdHlwZSAtIERlZmluZWQgcHVibGlzaGVkIGRhdGEgZWxlbWVudCB0eXBlLlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIHNldERhdGFUeXBlICh0eXBlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhVHlwZSwgdHlwZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFZlaGljbGVEYXRhUmVzdWx0LktFWV9EQVRBX1RZUEUsIHR5cGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YVR5cGV9XG4gICAgICovXG4gICAgZ2V0RGF0YVR5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFUeXBlLCBWZWhpY2xlRGF0YVJlc3VsdC5LRVlfREFUQV9UWVBFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlaGljbGVEYXRhUmVzdWx0Q29kZX0gY29kZSAtIFB1Ymxpc2hlZCBkYXRhIHJlc3VsdCBjb2RlLlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIHNldFJlc3VsdENvZGUgKGNvZGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFSZXN1bHRDb2RlLCBjb2RlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVmVoaWNsZURhdGFSZXN1bHQuS0VZX1JFU1VMVF9DT0RFLCBjb2RlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFSZXN1bHRDb2RlfVxuICAgICAqL1xuICAgIGdldFJlc3VsdENvZGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFSZXN1bHRDb2RlLCBWZWhpY2xlRGF0YVJlc3VsdC5LRVlfUkVTVUxUX0NPREUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIC0gVHlwZSBvZiByZXF1ZXN0ZWQgb2VtIHNwZWNpZmljIHBhcmFtZXRlclxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIHNldE9lbUN1c3RvbURhdGFUeXBlICh0eXBlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFZlaGljbGVEYXRhUmVzdWx0LktFWV9PRU1fQ1VTVE9NX0RBVEFfVFlQRSwgdHlwZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRPZW1DdXN0b21EYXRhVHlwZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihWZWhpY2xlRGF0YVJlc3VsdC5LRVlfT0VNX0NVU1RPTV9EQVRBX1RZUEUpO1xuICAgIH1cbn1cblxuVmVoaWNsZURhdGFSZXN1bHQuS0VZX0RBVEFfVFlQRSA9ICdkYXRhVHlwZSc7XG5WZWhpY2xlRGF0YVJlc3VsdC5LRVlfUkVTVUxUX0NPREUgPSAncmVzdWx0Q29kZSc7XG5WZWhpY2xlRGF0YVJlc3VsdC5LRVlfT0VNX0NVU1RPTV9EQVRBX1RZUEUgPSAnb2VtQ3VzdG9tRGF0YVR5cGUnO1xuXG5leHBvcnQgeyBWZWhpY2xlRGF0YVJlc3VsdCB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgVmVoaWNsZURhdGFSZXN1bHQgfSBmcm9tICcuLi9zdHJ1Y3RzL1ZlaGljbGVEYXRhUmVzdWx0LmpzJztcblxuY2xhc3MgU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlN1YnNjcmliZVZlaGljbGVEYXRhKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlaGljbGVEYXRhUmVzdWx0fSBncHMgLSBTZWUgR1BTRGF0YVxuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0R3BzIChncHMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFSZXN1bHQsIGdwcyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0dQUywgZ3BzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFSZXN1bHR9XG4gICAgICovXG4gICAgZ2V0R3BzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhUmVzdWx0LCBTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9HUFMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IHNwZWVkIC0gVGhlIHZlaGljbGUgc3BlZWQgaW4ga2lsb21ldGVycyBwZXIgaG91clxuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0U3BlZWQgKHNwZWVkKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhUmVzdWx0LCBzcGVlZCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1NQRUVELCBzcGVlZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIGdldFNwZWVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhUmVzdWx0LCBTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9TUEVFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YVJlc3VsdH0gcnBtIC0gVGhlIG51bWJlciBvZiByZXZvbHV0aW9ucyBwZXIgbWludXRlIG9mIHRoZSBlbmdpbmVcbiAgICAgKiBAcmV0dXJuIHtTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldFJwbSAocnBtKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhUmVzdWx0LCBycG0pO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9SUE0sIHJwbSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIGdldFJwbSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfUlBNKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlaGljbGVEYXRhUmVzdWx0fSBsZXZlbCAtIFRoZSBmdWVsIGxldmVsIGluIHRoZSB0YW5rIChwZXJjZW50YWdlKVxuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0RnVlbExldmVsIChsZXZlbCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgbGV2ZWwpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9GVUVMX0xFVkVMLCBsZXZlbCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIGdldEZ1ZWxMZXZlbCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRlVFTF9MRVZFTCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YVJlc3VsdH0gbGV2ZWxfc3RhdGUgLSBUaGUgZnVlbCBsZXZlbCBzdGF0ZVxuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0RnVlbExldmVsX1N0YXRlIChsZXZlbF9zdGF0ZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgbGV2ZWxfc3RhdGUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9GVUVMX0xFVkVMX1NUQVRFLCBsZXZlbF9zdGF0ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIGdldEZ1ZWxMZXZlbF9TdGF0ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRlVFTF9MRVZFTF9TVEFURSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YVJlc3VsdH0gY29uc3VtcHRpb24gLSBUaGUgaW5zdGFudGFuZW91cyBmdWVsIGNvbnN1bXB0aW9uIGluIG1pY3JvbGl0cmVzXG4gICAgICogQHJldHVybiB7U3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRJbnN0YW50RnVlbENvbnN1bXB0aW9uIChjb25zdW1wdGlvbikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgY29uc3VtcHRpb24pO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9JTlNUQU5UX0ZVRUxfQ09OU1VNUFRJT04sIGNvbnN1bXB0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFSZXN1bHR9XG4gICAgICovXG4gICAgZ2V0SW5zdGFudEZ1ZWxDb25zdW1wdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfSU5TVEFOVF9GVUVMX0NPTlNVTVBUSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlaGljbGVEYXRhUmVzdWx0fSByYW5nZSAtIFRoZSBlc3RpbWF0ZSByYW5nZSBpbiBLTSB0aGUgdmVoaWNsZSBjYW4gdHJhdmVsIGJhc2VkIG9uIGZ1ZWwgbGV2ZWwgYW5kXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdW1wdGlvblxuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0RnVlbFJhbmdlIChyYW5nZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgcmFuZ2UpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9GVUVMX1JBTkdFLCByYW5nZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIGdldEZ1ZWxSYW5nZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRlVFTF9SQU5HRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YVJlc3VsdH0gdGVtcGVyYXR1cmUgLSBUaGUgZXh0ZXJuYWwgdGVtcGVyYXR1cmUgaW4gZGVncmVlcyBjZWxzaXVzLlxuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0RXh0ZXJuYWxUZW1wZXJhdHVyZSAodGVtcGVyYXR1cmUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFSZXN1bHQsIHRlbXBlcmF0dXJlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRVhURVJOQUxfVEVNUEVSQVRVUkUsIHRlbXBlcmF0dXJlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFSZXN1bHR9XG4gICAgICovXG4gICAgZ2V0RXh0ZXJuYWxUZW1wZXJhdHVyZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRVhURVJOQUxfVEVNUEVSQVRVUkUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IHNpZ25hbCAtIFNlZSBUdXJuU2lnbmFsXG4gICAgICogQHJldHVybiB7U3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRUdXJuU2lnbmFsIChzaWduYWwpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFSZXN1bHQsIHNpZ25hbCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1RVUk5fU0lHTkFMLCBzaWduYWwpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YVJlc3VsdH1cbiAgICAgKi9cbiAgICBnZXRUdXJuU2lnbmFsICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhUmVzdWx0LCBTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9UVVJOX1NJR05BTCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YVJlc3VsdH0gcHJuZGwgLSBTZWUgUFJORExcbiAgICAgKiBAcmV0dXJuIHtTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldFBybmRsIChwcm5kbCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgcHJuZGwpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9QUk5ETCwgcHJuZGwpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YVJlc3VsdH1cbiAgICAgKi9cbiAgICBnZXRQcm5kbCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfUFJOREwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IHByZXNzdXJlIC0gU2VlIFRpcmVTdGF0dXNcbiAgICAgKiBAcmV0dXJuIHtTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldFRpcmVQcmVzc3VyZSAocHJlc3N1cmUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFSZXN1bHQsIHByZXNzdXJlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfVElSRV9QUkVTU1VSRSwgcHJlc3N1cmUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YVJlc3VsdH1cbiAgICAgKi9cbiAgICBnZXRUaXJlUHJlc3N1cmUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFSZXN1bHQsIFN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1RJUkVfUFJFU1NVUkUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IG9kb21ldGVyIC0gT2RvbWV0ZXIgaW4ga21cbiAgICAgKiBAcmV0dXJuIHtTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldE9kb21ldGVyIChvZG9tZXRlcikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgb2RvbWV0ZXIpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9PRE9NRVRFUiwgb2RvbWV0ZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YVJlc3VsdH1cbiAgICAgKi9cbiAgICBnZXRPZG9tZXRlciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfT0RPTUVURVIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IHN0YXR1cyAtIFRoZSBzdGF0dXMgb2YgdGhlIHNlYXQgYmVsdHNcbiAgICAgKiBAcmV0dXJuIHtTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldEJlbHRTdGF0dXMgKHN0YXR1cykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgc3RhdHVzKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQkVMVF9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIGdldEJlbHRTdGF0dXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFSZXN1bHQsIFN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0JFTFRfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlaGljbGVEYXRhUmVzdWx0fSBpbmZvcm1hdGlvbiAtIFRoZSBib2R5IGluZm9ybWF0aW9uIGluY2x1ZGluZyBwb3dlciBtb2Rlc1xuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0Qm9keUluZm9ybWF0aW9uIChpbmZvcm1hdGlvbikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgaW5mb3JtYXRpb24pO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9CT0RZX0lORk9STUFUSU9OLCBpbmZvcm1hdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIGdldEJvZHlJbmZvcm1hdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQk9EWV9JTkZPUk1BVElPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YVJlc3VsdH0gc3RhdHVzIC0gVGhlIGRldmljZSBzdGF0dXMgaW5jbHVkaW5nIHNpZ25hbCBhbmQgYmF0dGVyeSBzdHJlbmd0aFxuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0RGV2aWNlU3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFSZXN1bHQsIHN0YXR1cyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0RFVklDRV9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIGdldERldmljZVN0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfREVWSUNFX1NUQVRVUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YVJlc3VsdH0gYnJha2luZyAtIFRoZSBzdGF0dXMgb2YgdGhlIGJyYWtlIHBlZGFsXG4gICAgICogQHJldHVybiB7U3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXREcml2ZXJCcmFraW5nIChicmFraW5nKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhUmVzdWx0LCBicmFraW5nKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRFJJVkVSX0JSQUtJTkcsIGJyYWtpbmcpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YVJlc3VsdH1cbiAgICAgKi9cbiAgICBnZXREcml2ZXJCcmFraW5nICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhUmVzdWx0LCBTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9EUklWRVJfQlJBS0lORyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YVJlc3VsdH0gc3RhdHVzIC0gVGhlIHN0YXR1cyBvZiB0aGUgd2lwZXJzXG4gICAgICogQHJldHVybiB7U3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRXaXBlclN0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhUmVzdWx0LCBzdGF0dXMpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9XSVBFUl9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIGdldFdpcGVyU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhUmVzdWx0LCBTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9XSVBFUl9TVEFUVVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IHN0YXR1cyAtIFN0YXR1cyBvZiB0aGUgaGVhZCBsYW1wc1xuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0SGVhZExhbXBTdGF0dXMgKHN0YXR1cykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgc3RhdHVzKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfSEVBRF9MQU1QX1NUQVRVUywgc3RhdHVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFSZXN1bHR9XG4gICAgICovXG4gICAgZ2V0SGVhZExhbXBTdGF0dXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFSZXN1bHQsIFN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0hFQURfTEFNUF9TVEFUVVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IHRvcnF1ZSAtIFRvcnF1ZSB2YWx1ZSBmb3IgZW5naW5lIChpbiBObSkgb24gbm9uLWRpZXNlbCB2YXJpYW50c1xuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0RW5naW5lVG9ycXVlICh0b3JxdWUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFSZXN1bHQsIHRvcnF1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0VOR0lORV9UT1JRVUUsIHRvcnF1ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIGdldEVuZ2luZVRvcnF1ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRU5HSU5FX1RPUlFVRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YVJlc3VsdH0gcG9zaXRpb24gLSBBY2NlbGVyYXRvciBwZWRhbCBwb3NpdGlvbiAocGVyY2VudGFnZSBkZXByZXNzZWQpXG4gICAgICogQHJldHVybiB7U3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRBY2NQZWRhbFBvc2l0aW9uIChwb3NpdGlvbikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgcG9zaXRpb24pO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9BQ0NfUEVEQUxfUE9TSVRJT04sIHBvc2l0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFSZXN1bHR9XG4gICAgICovXG4gICAgZ2V0QWNjUGVkYWxQb3NpdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQUNDX1BFREFMX1BPU0lUSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlaGljbGVEYXRhUmVzdWx0fSBhbmdsZSAtIEN1cnJlbnQgYW5nbGUgb2YgdGhlIHN0ZWVyaW5nIHdoZWVsIChpbiBkZWcpXG4gICAgICogQHJldHVybiB7U3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRTdGVlcmluZ1doZWVsQW5nbGUgKGFuZ2xlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhUmVzdWx0LCBhbmdsZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1NURUVSSU5HX1dIRUVMX0FOR0xFLCBhbmdsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIGdldFN0ZWVyaW5nV2hlZWxBbmdsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfU1RFRVJJTkdfV0hFRUxfQU5HTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IGxpZmUgLSBUaGUgZXN0aW1hdGVkIHBlcmNlbnRhZ2Ugb2YgcmVtYWluaW5nIG9pbCBsaWZlIG9mIHRoZSBlbmdpbmUuXG4gICAgICogQHJldHVybiB7U3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRFbmdpbmVPaWxMaWZlIChsaWZlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhUmVzdWx0LCBsaWZlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRU5HSU5FX09JTF9MSUZFLCBsaWZlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFSZXN1bHR9XG4gICAgICovXG4gICAgZ2V0RW5naW5lT2lsTGlmZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRU5HSU5FX09JTF9MSUZFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlaGljbGVEYXRhUmVzdWx0fSBzdGF0dXMgLSBUaGUgc3RhdHVzIG9mIHRoZSBwYXJrIGJyYWtlIGFzIHByb3ZpZGVkIGJ5IEVsZWN0cmljIFBhcmsgQnJha2UgKEVQQikgc3lzdGVtLlxuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0RWxlY3Ryb25pY1BhcmtCcmFrZVN0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhUmVzdWx0LCBzdGF0dXMpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9FTEVDVFJPTklDX1BBUktfQlJBS0VfU1RBVFVTLCBzdGF0dXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YVJlc3VsdH1cbiAgICAgKi9cbiAgICBnZXRFbGVjdHJvbmljUGFya0JyYWtlU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhUmVzdWx0LCBTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9FTEVDVFJPTklDX1BBUktfQlJBS0VfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlaGljbGVEYXRhUmVzdWx0fSBpZCAtIFBhcmFtZXRlciB1c2VkIGJ5IGNsb3VkIGFwcHMgdG8gaWRlbnRpZnkgYSBoZWFkIHVuaXRcbiAgICAgKiBAcmV0dXJuIHtTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldENsb3VkQXBwVmVoaWNsZUlEIChpZCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgaWQpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9DTE9VRF9BUFBfVkVISUNMRV9JRCwgaWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YVJlc3VsdH1cbiAgICAgKi9cbiAgICBnZXRDbG91ZEFwcFZlaGljbGVJRCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQ0xPVURfQVBQX1ZFSElDTEVfSUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IGluZm8gLSBFbWVyZ2VuY3kgQ2FsbCBub3RpZmljYXRpb24gYW5kIGNvbmZpcm1hdGlvbiBkYXRhXG4gICAgICogQHJldHVybiB7U3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRFQ2FsbEluZm8gKGluZm8pIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFSZXN1bHQsIGluZm8pO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9FX0NBTExfSU5GTywgaW5mbyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIGdldEVDYWxsSW5mbyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRV9DQUxMX0lORk8pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IHN0YXR1cyAtIFRoZSBzdGF0dXMgb2YgdGhlIGFpciBiYWdzXG4gICAgICogQHJldHVybiB7U3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRBaXJiYWdTdGF0dXMgKHN0YXR1cykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgc3RhdHVzKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQUlSQkFHX1NUQVRVUywgc3RhdHVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFSZXN1bHR9XG4gICAgICovXG4gICAgZ2V0QWlyYmFnU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhUmVzdWx0LCBTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9BSVJCQUdfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlaGljbGVEYXRhUmVzdWx0fSBldmVudCAtIEluZm9ybWF0aW9uIHJlbGF0ZWQgdG8gYW4gZW1lcmdlbmN5IGV2ZW50IChhbmQgaWYgaXQgb2NjdXJyZWQpXG4gICAgICogQHJldHVybiB7U3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRFbWVyZ2VuY3lFdmVudCAoZXZlbnQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFSZXN1bHQsIGV2ZW50KTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRU1FUkdFTkNZX0VWRU5ULCBldmVudCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIGdldEVtZXJnZW5jeUV2ZW50ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhUmVzdWx0LCBTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9FTUVSR0VOQ1lfRVZFTlQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IG1vZGVzIC0gVGhlIHN0YXR1cyBtb2RlcyBvZiB0aGUgY2x1c3RlclxuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0Q2x1c3Rlck1vZGVzIChtb2Rlcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgbW9kZXMpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9DTFVTVEVSX01PREVTLCBtb2Rlcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIGdldENsdXN0ZXJNb2RlcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQ0xVU1RFUl9NT0RFUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YVJlc3VsdH0ga2V5IC0gSW5mb3JtYXRpb24gcmVsYXRlZCB0byB0aGUgTXlLZXkgZmVhdHVyZVxuICAgICAqIEByZXR1cm4ge1N1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0TXlLZXkgKGtleSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwga2V5KTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfTVlfS0VZLCBrZXkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YVJlc3VsdH1cbiAgICAgKi9cbiAgICBnZXRNeUtleSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfTVlfS0VZKTtcbiAgICB9XG59XG5cblN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0dQUyA9ICdncHMnO1xuU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfU1BFRUQgPSAnc3BlZWQnO1xuU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfUlBNID0gJ3JwbSc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9GVUVMX0xFVkVMID0gJ2Z1ZWxMZXZlbCc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9GVUVMX0xFVkVMX1NUQVRFID0gJ2Z1ZWxMZXZlbF9TdGF0ZSc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9JTlNUQU5UX0ZVRUxfQ09OU1VNUFRJT04gPSAnaW5zdGFudEZ1ZWxDb25zdW1wdGlvbic7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9GVUVMX1JBTkdFID0gJ2Z1ZWxSYW5nZSc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9FWFRFUk5BTF9URU1QRVJBVFVSRSA9ICdleHRlcm5hbFRlbXBlcmF0dXJlJztcblN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1RVUk5fU0lHTkFMID0gJ3R1cm5TaWduYWwnO1xuU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfUFJOREwgPSAncHJuZGwnO1xuU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfVElSRV9QUkVTU1VSRSA9ICd0aXJlUHJlc3N1cmUnO1xuU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfT0RPTUVURVIgPSAnb2RvbWV0ZXInO1xuU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQkVMVF9TVEFUVVMgPSAnYmVsdFN0YXR1cyc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9CT0RZX0lORk9STUFUSU9OID0gJ2JvZHlJbmZvcm1hdGlvbic7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9ERVZJQ0VfU1RBVFVTID0gJ2RldmljZVN0YXR1cyc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9EUklWRVJfQlJBS0lORyA9ICdkcml2ZXJCcmFraW5nJztcblN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1dJUEVSX1NUQVRVUyA9ICd3aXBlclN0YXR1cyc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9IRUFEX0xBTVBfU1RBVFVTID0gJ2hlYWRMYW1wU3RhdHVzJztcblN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0VOR0lORV9UT1JRVUUgPSAnZW5naW5lVG9ycXVlJztcblN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0FDQ19QRURBTF9QT1NJVElPTiA9ICdhY2NQZWRhbFBvc2l0aW9uJztcblN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1NURUVSSU5HX1dIRUVMX0FOR0xFID0gJ3N0ZWVyaW5nV2hlZWxBbmdsZSc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9FTkdJTkVfT0lMX0xJRkUgPSAnZW5naW5lT2lsTGlmZSc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9FTEVDVFJPTklDX1BBUktfQlJBS0VfU1RBVFVTID0gJ2VsZWN0cm9uaWNQYXJrQnJha2VTdGF0dXMnO1xuU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQ0xPVURfQVBQX1ZFSElDTEVfSUQgPSAnY2xvdWRBcHBWZWhpY2xlSUQnO1xuU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRV9DQUxMX0lORk8gPSAnZUNhbGxJbmZvJztcblN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0FJUkJBR19TVEFUVVMgPSAnYWlyYmFnU3RhdHVzJztcblN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0VNRVJHRU5DWV9FVkVOVCA9ICdlbWVyZ2VuY3lFdmVudCc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9DTFVTVEVSX01PREVTID0gJ2NsdXN0ZXJNb2Rlcyc7XG5TdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9NWV9LRVkgPSAnbXlLZXknO1xuXG5leHBvcnQgeyBTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG4vKipcbiAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byB1bnN1YnNjcmliZSB0aGUgbm90aWZpY2F0aW9ucyBmcm9tIHRoZSBzdWJzY3JpYmVWZWhpY2xlRGF0YSBmdW5jdGlvbi5cbiAqL1xuY2xhc3MgVW5zdWJzY3JpYmVWZWhpY2xlRGF0YSBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBncHMgLSBTZWUgR1BTRGF0YVxuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0R3BzIChncHMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfR1BTLCBncHMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEdwcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9HUFMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gc3BlZWQgLSBUaGUgdmVoaWNsZSBzcGVlZCBpbiBraWxvbWV0ZXJzIHBlciBob3VyXG4gICAgICogQHJldHVybiB7VW5zdWJzY3JpYmVWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRTcGVlZCAoc3BlZWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfU1BFRUQsIHNwZWVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRTcGVlZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9TUEVFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBycG0gLSBUaGUgbnVtYmVyIG9mIHJldm9sdXRpb25zIHBlciBtaW51dGUgb2YgdGhlIGVuZ2luZVxuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0UnBtIChycG0pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfUlBNLCBycG0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFJwbSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9SUE0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gbGV2ZWwgLSBUaGUgZnVlbCBsZXZlbCBpbiB0aGUgdGFuayAocGVyY2VudGFnZSlcbiAgICAgKiBAcmV0dXJuIHtVbnN1YnNjcmliZVZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldEZ1ZWxMZXZlbCAobGV2ZWwpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfRlVFTF9MRVZFTCwgbGV2ZWwpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEZ1ZWxMZXZlbCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9GVUVMX0xFVkVMKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGxldmVsX3N0YXRlIC0gVGhlIGZ1ZWwgbGV2ZWwgc3RhdGVcbiAgICAgKiBAcmV0dXJuIHtVbnN1YnNjcmliZVZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldEZ1ZWxMZXZlbF9TdGF0ZSAobGV2ZWxfc3RhdGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfRlVFTF9MRVZFTF9TVEFURSwgbGV2ZWxfc3RhdGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEZ1ZWxMZXZlbF9TdGF0ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9GVUVMX0xFVkVMX1NUQVRFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGNvbnN1bXB0aW9uIC0gVGhlIGluc3RhbnRhbmVvdXMgZnVlbCBjb25zdW1wdGlvbiBpbiBtaWNyb2xpdHJlc1xuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0SW5zdGFudEZ1ZWxDb25zdW1wdGlvbiAoY29uc3VtcHRpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfSU5TVEFOVF9GVUVMX0NPTlNVTVBUSU9OLCBjb25zdW1wdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0SW5zdGFudEZ1ZWxDb25zdW1wdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9JTlNUQU5UX0ZVRUxfQ09OU1VNUFRJT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gcmFuZ2UgLSBUaGUgZXN0aW1hdGUgcmFuZ2UgaW4gS00gdGhlIHZlaGljbGUgY2FuIHRyYXZlbCBiYXNlZCBvbiBmdWVsIGxldmVsIGFuZCBjb25zdW1wdGlvblxuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0RnVlbFJhbmdlIChyYW5nZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9GVUVMX1JBTkdFLCByYW5nZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0RnVlbFJhbmdlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0ZVRUxfUkFOR0UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gdGVtcGVyYXR1cmUgLSBUaGUgZXh0ZXJuYWwgdGVtcGVyYXR1cmUgaW4gZGVncmVlcyBjZWxzaXVzLlxuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0RXh0ZXJuYWxUZW1wZXJhdHVyZSAodGVtcGVyYXR1cmUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfRVhURVJOQUxfVEVNUEVSQVRVUkUsIHRlbXBlcmF0dXJlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRFeHRlcm5hbFRlbXBlcmF0dXJlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0VYVEVSTkFMX1RFTVBFUkFUVVJFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHNpZ25hbCAtIFNlZSBUdXJuU2lnbmFsXG4gICAgICogQHJldHVybiB7VW5zdWJzY3JpYmVWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRUdXJuU2lnbmFsIChzaWduYWwpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfVFVSTl9TSUdOQUwsIHNpZ25hbCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0VHVyblNpZ25hbCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9UVVJOX1NJR05BTCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBwcm5kbCAtIFNlZSBQUk5ETFxuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0UHJuZGwgKHBybmRsKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX1BSTkRMLCBwcm5kbCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0UHJuZGwgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfUFJOREwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gcHJlc3N1cmUgLSBTZWUgVGlyZVN0YXR1c1xuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0VGlyZVByZXNzdXJlIChwcmVzc3VyZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9USVJFX1BSRVNTVVJFLCBwcmVzc3VyZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0VGlyZVByZXNzdXJlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX1RJUkVfUFJFU1NVUkUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gb2RvbWV0ZXIgLSBPZG9tZXRlciBpbiBrbVxuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0T2RvbWV0ZXIgKG9kb21ldGVyKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX09ET01FVEVSLCBvZG9tZXRlcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0T2RvbWV0ZXIgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfT0RPTUVURVIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gc3RhdHVzIC0gVGhlIHN0YXR1cyBvZiB0aGUgc2VhdCBiZWx0c1xuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0QmVsdFN0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0JFTFRfU1RBVFVTLCBzdGF0dXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEJlbHRTdGF0dXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfQkVMVF9TVEFUVVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gaW5mb3JtYXRpb24gLSBUaGUgYm9keSBpbmZvcm1hdGlvbiBpbmNsdWRpbmcgcG93ZXIgbW9kZXNcbiAgICAgKiBAcmV0dXJuIHtVbnN1YnNjcmliZVZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldEJvZHlJbmZvcm1hdGlvbiAoaW5mb3JtYXRpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfQk9EWV9JTkZPUk1BVElPTiwgaW5mb3JtYXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEJvZHlJbmZvcm1hdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9CT0RZX0lORk9STUFUSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHN0YXR1cyAtIFRoZSBkZXZpY2Ugc3RhdHVzIGluY2x1ZGluZyBzaWduYWwgYW5kIGJhdHRlcnkgc3RyZW5ndGhcbiAgICAgKiBAcmV0dXJuIHtVbnN1YnNjcmliZVZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldERldmljZVN0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0RFVklDRV9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0RGV2aWNlU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0RFVklDRV9TVEFUVVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYnJha2luZyAtIFRoZSBzdGF0dXMgb2YgdGhlIGJyYWtlIHBlZGFsXG4gICAgICogQHJldHVybiB7VW5zdWJzY3JpYmVWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXREcml2ZXJCcmFraW5nIChicmFraW5nKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0RSSVZFUl9CUkFLSU5HLCBicmFraW5nKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXREcml2ZXJCcmFraW5nICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0RSSVZFUl9CUkFLSU5HKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHN0YXR1cyAtIFRoZSBzdGF0dXMgb2YgdGhlIHdpcGVyc1xuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0V2lwZXJTdGF0dXMgKHN0YXR1cykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9XSVBFUl9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0V2lwZXJTdGF0dXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfV0lQRVJfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHN0YXR1cyAtIFN0YXR1cyBvZiB0aGUgaGVhZCBsYW1wc1xuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0SGVhZExhbXBTdGF0dXMgKHN0YXR1cykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9IRUFEX0xBTVBfU1RBVFVTLCBzdGF0dXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEhlYWRMYW1wU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0hFQURfTEFNUF9TVEFUVVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gdG9ycXVlIC0gVG9ycXVlIHZhbHVlIGZvciBlbmdpbmUgKGluIE5tKSBvbiBub24tZGllc2VsIHZhcmlhbnRzXG4gICAgICogQHJldHVybiB7VW5zdWJzY3JpYmVWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRFbmdpbmVUb3JxdWUgKHRvcnF1ZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9FTkdJTkVfVE9SUVVFLCB0b3JxdWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEVuZ2luZVRvcnF1ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9FTkdJTkVfVE9SUVVFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHBvc2l0aW9uIC0gQWNjZWxlcmF0b3IgcGVkYWwgcG9zaXRpb24gKHBlcmNlbnRhZ2UgZGVwcmVzc2VkKVxuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0QWNjUGVkYWxQb3NpdGlvbiAocG9zaXRpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfQUNDX1BFREFMX1BPU0lUSU9OLCBwb3NpdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0QWNjUGVkYWxQb3NpdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9BQ0NfUEVEQUxfUE9TSVRJT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYW5nbGUgLSBDdXJyZW50IGFuZ2xlIG9mIHRoZSBzdGVlcmluZyB3aGVlbCAoaW4gZGVnKVxuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0U3RlZXJpbmdXaGVlbEFuZ2xlIChhbmdsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9TVEVFUklOR19XSEVFTF9BTkdMRSwgYW5nbGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFN0ZWVyaW5nV2hlZWxBbmdsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9TVEVFUklOR19XSEVFTF9BTkdMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBsaWZlIC0gVGhlIGVzdGltYXRlZCBwZXJjZW50YWdlIG9mIHJlbWFpbmluZyBvaWwgbGlmZSBvZiB0aGUgZW5naW5lLlxuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0RW5naW5lT2lsTGlmZSAobGlmZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9FTkdJTkVfT0lMX0xJRkUsIGxpZmUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEVuZ2luZU9pbExpZmUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfRU5HSU5FX09JTF9MSUZFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHN0YXR1cyAtIFRoZSBzdGF0dXMgb2YgdGhlIHBhcmsgYnJha2UgYXMgcHJvdmlkZWQgYnkgRWxlY3RyaWMgUGFyayBCcmFrZSAoRVBCKSBzeXN0ZW0uXG4gICAgICogQHJldHVybiB7VW5zdWJzY3JpYmVWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRFbGVjdHJvbmljUGFya0JyYWtlU3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfRUxFQ1RST05JQ19QQVJLX0JSQUtFX1NUQVRVUywgc3RhdHVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRFbGVjdHJvbmljUGFya0JyYWtlU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0VMRUNUUk9OSUNfUEFSS19CUkFLRV9TVEFUVVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gaWQgLSBQYXJhbWV0ZXIgdXNlZCBieSBjbG91ZCBhcHBzIHRvIGlkZW50aWZ5IGEgaGVhZCB1bml0XG4gICAgICogQHJldHVybiB7VW5zdWJzY3JpYmVWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRDbG91ZEFwcFZlaGljbGVJRCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfQ0xPVURfQVBQX1ZFSElDTEVfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRDbG91ZEFwcFZlaGljbGVJRCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9DTE9VRF9BUFBfVkVISUNMRV9JRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBpbmZvIC0gRW1lcmdlbmN5IENhbGwgbm90aWZpY2F0aW9uIGFuZCBjb25maXJtYXRpb24gZGF0YVxuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0RUNhbGxJbmZvIChpbmZvKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0VfQ0FMTF9JTkZPLCBpbmZvKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRFQ2FsbEluZm8gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfRV9DQUxMX0lORk8pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gc3RhdHVzIC0gVGhlIHN0YXR1cyBvZiB0aGUgYWlyIGJhZ3NcbiAgICAgKiBAcmV0dXJuIHtVbnN1YnNjcmliZVZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldEFpcmJhZ1N0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0FJUkJBR19TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0QWlyYmFnU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0FJUkJBR19TVEFUVVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gZXZlbnQgLSBJbmZvcm1hdGlvbiByZWxhdGVkIHRvIGFuIGVtZXJnZW5jeSBldmVudCAoYW5kIGlmIGl0IG9jY3VycmVkKVxuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0RW1lcmdlbmN5RXZlbnQgKGV2ZW50KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0VNRVJHRU5DWV9FVkVOVCwgZXZlbnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEVtZXJnZW5jeUV2ZW50ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0VNRVJHRU5DWV9FVkVOVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBzdGF0dXMgLSBUaGUgc3RhdHVzIG1vZGVzIG9mIHRoZSBjbHVzdGVyXG4gICAgICogQHJldHVybiB7VW5zdWJzY3JpYmVWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRDbHVzdGVyTW9kZVN0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0NMVVNURVJfTU9ERV9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0Q2x1c3Rlck1vZGVTdGF0dXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfQ0xVU1RFUl9NT0RFX1NUQVRVUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBrZXkgLSBJbmZvcm1hdGlvbiByZWxhdGVkIHRvIHRoZSBNeUtleSBmZWF0dXJlXG4gICAgICogQHJldHVybiB7VW5zdWJzY3JpYmVWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRNeUtleSAoa2V5KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX01ZX0tFWSwga2V5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRNeUtleSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9NWV9LRVkpO1xuICAgIH1cbn1cblxuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfR1BTID0gJ2dwcyc7XG5VbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9TUEVFRCA9ICdzcGVlZCc7XG5VbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9SUE0gPSAncnBtJztcblVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0ZVRUxfTEVWRUwgPSAnZnVlbExldmVsJztcblVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0ZVRUxfTEVWRUxfU1RBVEUgPSAnZnVlbExldmVsX1N0YXRlJztcblVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0lOU1RBTlRfRlVFTF9DT05TVU1QVElPTiA9ICdpbnN0YW50RnVlbENvbnN1bXB0aW9uJztcblVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0ZVRUxfUkFOR0UgPSAnZnVlbFJhbmdlJztcblVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0VYVEVSTkFMX1RFTVBFUkFUVVJFID0gJ2V4dGVybmFsVGVtcGVyYXR1cmUnO1xuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfVFVSTl9TSUdOQUwgPSAndHVyblNpZ25hbCc7XG5VbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9QUk5ETCA9ICdwcm5kbCc7XG5VbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9USVJFX1BSRVNTVVJFID0gJ3RpcmVQcmVzc3VyZSc7XG5VbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9PRE9NRVRFUiA9ICdvZG9tZXRlcic7XG5VbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9CRUxUX1NUQVRVUyA9ICdiZWx0U3RhdHVzJztcblVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0JPRFlfSU5GT1JNQVRJT04gPSAnYm9keUluZm9ybWF0aW9uJztcblVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0RFVklDRV9TVEFUVVMgPSAnZGV2aWNlU3RhdHVzJztcblVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0RSSVZFUl9CUkFLSU5HID0gJ2RyaXZlckJyYWtpbmcnO1xuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfV0lQRVJfU1RBVFVTID0gJ3dpcGVyU3RhdHVzJztcblVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0hFQURfTEFNUF9TVEFUVVMgPSAnaGVhZExhbXBTdGF0dXMnO1xuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfRU5HSU5FX1RPUlFVRSA9ICdlbmdpbmVUb3JxdWUnO1xuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfQUNDX1BFREFMX1BPU0lUSU9OID0gJ2FjY1BlZGFsUG9zaXRpb24nO1xuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfU1RFRVJJTkdfV0hFRUxfQU5HTEUgPSAnc3RlZXJpbmdXaGVlbEFuZ2xlJztcblVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0VOR0lORV9PSUxfTElGRSA9ICdlbmdpbmVPaWxMaWZlJztcblVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0VMRUNUUk9OSUNfUEFSS19CUkFLRV9TVEFUVVMgPSAnZWxlY3Ryb25pY1BhcmtCcmFrZVN0YXR1cyc7XG5VbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9DTE9VRF9BUFBfVkVISUNMRV9JRCA9ICdjbG91ZEFwcFZlaGljbGVJRCc7XG5VbnN1YnNjcmliZVZlaGljbGVEYXRhLktFWV9FX0NBTExfSU5GTyA9ICdlQ2FsbEluZm8nO1xuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfQUlSQkFHX1NUQVRVUyA9ICdhaXJiYWdTdGF0dXMnO1xuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfRU1FUkdFTkNZX0VWRU5UID0gJ2VtZXJnZW5jeUV2ZW50JztcblVuc3Vic2NyaWJlVmVoaWNsZURhdGEuS0VZX0NMVVNURVJfTU9ERV9TVEFUVVMgPSAnY2x1c3Rlck1vZGVTdGF0dXMnO1xuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YS5LRVlfTVlfS0VZID0gJ215S2V5JztcblxuZXhwb3J0IHsgVW5zdWJzY3JpYmVWZWhpY2xlRGF0YSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgVmVoaWNsZURhdGFSZXN1bHQgfSBmcm9tICcuLi9zdHJ1Y3RzL1ZlaGljbGVEYXRhUmVzdWx0LmpzJztcblxuY2xhc3MgVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YVJlc3VsdH0gZ3BzIC0gU2VlIEdQU0RhdGFcbiAgICAgKiBAcmV0dXJuIHtVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0R3BzIChncHMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFSZXN1bHQsIGdwcyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfR1BTLCBncHMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YVJlc3VsdH1cbiAgICAgKi9cbiAgICBnZXRHcHMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFSZXN1bHQsIFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfR1BTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlaGljbGVEYXRhUmVzdWx0fSBzcGVlZCAtIFRoZSB2ZWhpY2xlIHNwZWVkIGluIGtpbG9tZXRlcnMgcGVyIGhvdXJcbiAgICAgKiBAcmV0dXJuIHtVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0U3BlZWQgKHNwZWVkKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhUmVzdWx0LCBzcGVlZCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfU1BFRUQsIHNwZWVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFSZXN1bHR9XG4gICAgICovXG4gICAgZ2V0U3BlZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFSZXN1bHQsIFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfU1BFRUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IHJwbSAtIFRoZSBudW1iZXIgb2YgcmV2b2x1dGlvbnMgcGVyIG1pbnV0ZSBvZiB0aGUgZW5naW5lXG4gICAgICogQHJldHVybiB7VW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldFJwbSAocnBtKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhUmVzdWx0LCBycG0pO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1JQTSwgcnBtKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFSZXN1bHR9XG4gICAgICovXG4gICAgZ2V0UnBtICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhUmVzdWx0LCBVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1JQTSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YVJlc3VsdH0gbGV2ZWwgLSBUaGUgZnVlbCBsZXZlbCBpbiB0aGUgdGFuayAocGVyY2VudGFnZSlcbiAgICAgKiBAcmV0dXJuIHtVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0RnVlbExldmVsIChsZXZlbCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgbGV2ZWwpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0ZVRUxfTEVWRUwsIGxldmVsKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFSZXN1bHR9XG4gICAgICovXG4gICAgZ2V0RnVlbExldmVsICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhUmVzdWx0LCBVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0ZVRUxfTEVWRUwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IGxldmVsX3N0YXRlIC0gVGhlIGZ1ZWwgbGV2ZWwgc3RhdGVcbiAgICAgKiBAcmV0dXJuIHtVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0RnVlbExldmVsX1N0YXRlIChsZXZlbF9zdGF0ZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgbGV2ZWxfc3RhdGUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0ZVRUxfTEVWRUxfU1RBVEUsIGxldmVsX3N0YXRlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFSZXN1bHR9XG4gICAgICovXG4gICAgZ2V0RnVlbExldmVsX1N0YXRlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhUmVzdWx0LCBVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0ZVRUxfTEVWRUxfU1RBVEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IGNvbnN1bXB0aW9uIC0gVGhlIGluc3RhbnRhbmVvdXMgZnVlbCBjb25zdW1wdGlvbiBpbiBtaWNyb2xpdHJlc1xuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRJbnN0YW50RnVlbENvbnN1bXB0aW9uIChjb25zdW1wdGlvbikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgY29uc3VtcHRpb24pO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0lOU1RBTlRfRlVFTF9DT05TVU1QVElPTiwgY29uc3VtcHRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YVJlc3VsdH1cbiAgICAgKi9cbiAgICBnZXRJbnN0YW50RnVlbENvbnN1bXB0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhUmVzdWx0LCBVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0lOU1RBTlRfRlVFTF9DT05TVU1QVElPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YVJlc3VsdH0gcmFuZ2UgLSBUaGUgZXN0aW1hdGUgcmFuZ2UgaW4gS00gdGhlIHZlaGljbGUgY2FuIHRyYXZlbCBiYXNlZCBvbiBmdWVsIGxldmVsIGFuZFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3VtcHRpb25cbiAgICAgKiBAcmV0dXJuIHtVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0RnVlbFJhbmdlIChyYW5nZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgcmFuZ2UpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0ZVRUxfUkFOR0UsIHJhbmdlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFSZXN1bHR9XG4gICAgICovXG4gICAgZ2V0RnVlbFJhbmdlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhUmVzdWx0LCBVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0ZVRUxfUkFOR0UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IHRlbXBlcmF0dXJlIC0gVGhlIGV4dGVybmFsIHRlbXBlcmF0dXJlIGluIGRlZ3JlZXMgY2Vsc2l1c1xuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRFeHRlcm5hbFRlbXBlcmF0dXJlICh0ZW1wZXJhdHVyZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgdGVtcGVyYXR1cmUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0VYVEVSTkFMX1RFTVBFUkFUVVJFLCB0ZW1wZXJhdHVyZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIGdldEV4dGVybmFsVGVtcGVyYXR1cmUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFSZXN1bHQsIFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRVhURVJOQUxfVEVNUEVSQVRVUkUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IHNpZ25hbCAtIFNlZSBUdXJuU2lnbmFsXG4gICAgICogQHJldHVybiB7VW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldFR1cm5TaWduYWwgKHNpZ25hbCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgc2lnbmFsKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9UVVJOX1NJR05BTCwgc2lnbmFsKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFSZXN1bHR9XG4gICAgICovXG4gICAgZ2V0VHVyblNpZ25hbCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9UVVJOX1NJR05BTCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YVJlc3VsdH0gcHJuZGwgLSBTZWUgUFJORExcbiAgICAgKiBAcmV0dXJuIHtVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0UHJuZGwgKHBybmRsKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhUmVzdWx0LCBwcm5kbCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfUFJOREwsIHBybmRsKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFSZXN1bHR9XG4gICAgICovXG4gICAgZ2V0UHJuZGwgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFSZXN1bHQsIFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfUFJOREwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IHByZXNzdXJlIC0gU2VlIFRpcmVTdGF0dXNcbiAgICAgKiBAcmV0dXJuIHtVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0VGlyZVByZXNzdXJlIChwcmVzc3VyZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgcHJlc3N1cmUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1RJUkVfUFJFU1NVUkUsIHByZXNzdXJlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFSZXN1bHR9XG4gICAgICovXG4gICAgZ2V0VGlyZVByZXNzdXJlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhUmVzdWx0LCBVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1RJUkVfUFJFU1NVUkUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IG9kb21ldGVyIC0gT2RvbWV0ZXIgaW4ga21cbiAgICAgKiBAcmV0dXJuIHtVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0T2RvbWV0ZXIgKG9kb21ldGVyKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhUmVzdWx0LCBvZG9tZXRlcik7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfT0RPTUVURVIsIG9kb21ldGVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFSZXN1bHR9XG4gICAgICovXG4gICAgZ2V0T2RvbWV0ZXIgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFSZXN1bHQsIFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfT0RPTUVURVIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IHN0YXR1cyAtIFRoZSBzdGF0dXMgb2YgdGhlIHNlYXQgYmVsdHNcbiAgICAgKiBAcmV0dXJuIHtVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0QmVsdFN0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhUmVzdWx0LCBzdGF0dXMpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0JFTFRfU1RBVFVTLCBzdGF0dXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YVJlc3VsdH1cbiAgICAgKi9cbiAgICBnZXRCZWx0U3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhUmVzdWx0LCBVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0JFTFRfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlaGljbGVEYXRhUmVzdWx0fSBpbmZvcm1hdGlvbiAtIFRoZSBib2R5IGluZm9ybWF0aW9uIGluY2x1ZGluZyBwb3dlciBtb2Rlc1xuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRCb2R5SW5mb3JtYXRpb24gKGluZm9ybWF0aW9uKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhUmVzdWx0LCBpbmZvcm1hdGlvbik7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQk9EWV9JTkZPUk1BVElPTiwgaW5mb3JtYXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YVJlc3VsdH1cbiAgICAgKi9cbiAgICBnZXRCb2R5SW5mb3JtYXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFSZXN1bHQsIFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQk9EWV9JTkZPUk1BVElPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YVJlc3VsdH0gc3RhdHVzIC0gVGhlIGRldmljZSBzdGF0dXMgaW5jbHVkaW5nIHNpZ25hbCBhbmQgYmF0dGVyeSBzdHJlbmd0aFxuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXREZXZpY2VTdGF0dXMgKHN0YXR1cykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgc3RhdHVzKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9ERVZJQ0VfU1RBVFVTLCBzdGF0dXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YVJlc3VsdH1cbiAgICAgKi9cbiAgICBnZXREZXZpY2VTdGF0dXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFSZXN1bHQsIFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfREVWSUNFX1NUQVRVUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YVJlc3VsdH0gYnJha2luZyAtIFRoZSBzdGF0dXMgb2YgdGhlIGJyYWtlIHBlZGFsXG4gICAgICogQHJldHVybiB7VW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldERyaXZlckJyYWtpbmcgKGJyYWtpbmcpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFSZXN1bHQsIGJyYWtpbmcpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0RSSVZFUl9CUkFLSU5HLCBicmFraW5nKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFSZXN1bHR9XG4gICAgICovXG4gICAgZ2V0RHJpdmVyQnJha2luZyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9EUklWRVJfQlJBS0lORyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YVJlc3VsdH0gc3RhdHVzIC0gVGhlIHN0YXR1cyBvZiB0aGUgd2lwZXJzXG4gICAgICogQHJldHVybiB7VW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldFdpcGVyU3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFSZXN1bHQsIHN0YXR1cyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfV0lQRVJfU1RBVFVTLCBzdGF0dXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YVJlc3VsdH1cbiAgICAgKi9cbiAgICBnZXRXaXBlclN0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9XSVBFUl9TVEFUVVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IHN0YXR1cyAtIFN0YXR1cyBvZiB0aGUgaGVhZCBsYW1wc1xuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRIZWFkTGFtcFN0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhUmVzdWx0LCBzdGF0dXMpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0hFQURfTEFNUF9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIGdldEhlYWRMYW1wU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhUmVzdWx0LCBVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0hFQURfTEFNUF9TVEFUVVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IHRvcnF1ZSAtIFRvcnF1ZSB2YWx1ZSBmb3IgZW5naW5lIChpbiBObSkgb24gbm9uLWRpZXNlbCB2YXJpYW50c1xuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRFbmdpbmVUb3JxdWUgKHRvcnF1ZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgdG9ycXVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9FTkdJTkVfVE9SUVVFLCB0b3JxdWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YVJlc3VsdH1cbiAgICAgKi9cbiAgICBnZXRFbmdpbmVUb3JxdWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFSZXN1bHQsIFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRU5HSU5FX1RPUlFVRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YVJlc3VsdH0gcG9zaXRpb24gLSBBY2NlbGVyYXRvciBwZWRhbCBwb3NpdGlvbiAocGVyY2VudGFnZSBkZXByZXNzZWQpXG4gICAgICogQHJldHVybiB7VW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldEFjY1BlZGFsUG9zaXRpb24gKHBvc2l0aW9uKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhUmVzdWx0LCBwb3NpdGlvbik7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQUNDX1BFREFMX1BPU0lUSU9OLCBwb3NpdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIGdldEFjY1BlZGFsUG9zaXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFSZXN1bHQsIFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQUNDX1BFREFMX1BPU0lUSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlaGljbGVEYXRhUmVzdWx0fSBhbmdsZSAtIEN1cnJlbnQgYW5nbGUgb2YgdGhlIHN0ZWVyaW5nIHdoZWVsIChpbiBkZWcpXG4gICAgICogQHJldHVybiB7VW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldFN0ZWVyaW5nV2hlZWxBbmdsZSAoYW5nbGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFSZXN1bHQsIGFuZ2xlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9TVEVFUklOR19XSEVFTF9BTkdMRSwgYW5nbGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YVJlc3VsdH1cbiAgICAgKi9cbiAgICBnZXRTdGVlcmluZ1doZWVsQW5nbGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFSZXN1bHQsIFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfU1RFRVJJTkdfV0hFRUxfQU5HTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IGxpZmUgLSBUaGUgZXN0aW1hdGVkIHBlcmNlbnRhZ2Ugb2YgcmVtYWluaW5nIG9pbCBsaWZlIG9mIHRoZSBlbmdpbmUuXG4gICAgICogQHJldHVybiB7VW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldEVuZ2luZU9pbExpZmUgKGxpZmUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFSZXN1bHQsIGxpZmUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0VOR0lORV9PSUxfTElGRSwgbGlmZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIGdldEVuZ2luZU9pbExpZmUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFSZXN1bHQsIFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRU5HSU5FX09JTF9MSUZFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlaGljbGVEYXRhUmVzdWx0fSBzdGF0dXMgLSBUaGUgc3RhdHVzIG9mIHRoZSBwYXJrIGJyYWtlIGFzIHByb3ZpZGVkIGJ5IEVsZWN0cmljIFBhcmsgQnJha2UgKEVQQikgc3lzdGVtLlxuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRFbGVjdHJvbmljUGFya0JyYWtlU3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFSZXN1bHQsIHN0YXR1cyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRUxFQ1RST05JQ19QQVJLX0JSQUtFX1NUQVRVUywgc3RhdHVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFSZXN1bHR9XG4gICAgICovXG4gICAgZ2V0RWxlY3Ryb25pY1BhcmtCcmFrZVN0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9FTEVDVFJPTklDX1BBUktfQlJBS0VfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlaGljbGVEYXRhUmVzdWx0fSBpZCAtIFBhcmFtZXRlciB1c2VkIGJ5IGNsb3VkIGFwcHMgdG8gaWRlbnRpZnkgYSBoZWFkIHVuaXRcbiAgICAgKiBAcmV0dXJuIHtVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0Q2xvdWRBcHBWZWhpY2xlSUQgKGlkKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhUmVzdWx0LCBpZCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQ0xPVURfQVBQX1ZFSElDTEVfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFSZXN1bHR9XG4gICAgICovXG4gICAgZ2V0Q2xvdWRBcHBWZWhpY2xlSUQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFSZXN1bHQsIFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQ0xPVURfQVBQX1ZFSElDTEVfSUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IGluZm8gLSBFbWVyZ2VuY3kgQ2FsbCBub3RpZmljYXRpb24gYW5kIGNvbmZpcm1hdGlvbiBkYXRhXG4gICAgICogQHJldHVybiB7VW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldEVDYWxsSW5mbyAoaW5mbykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgaW5mbyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRV9DQUxMX0lORk8sIGluZm8pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YVJlc3VsdH1cbiAgICAgKi9cbiAgICBnZXRFQ2FsbEluZm8gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFSZXN1bHQsIFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRV9DQUxMX0lORk8pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IHN0YXR1cyAtIFRoZSBzdGF0dXMgb2YgdGhlIGFpciBiYWdzXG4gICAgICogQHJldHVybiB7VW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldEFpcmJhZ1N0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhUmVzdWx0LCBzdGF0dXMpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0FJUkJBR19TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0fVxuICAgICAqL1xuICAgIGdldEFpcmJhZ1N0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9BSVJCQUdfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlaGljbGVEYXRhUmVzdWx0fSBldmVudCAtIEluZm9ybWF0aW9uIHJlbGF0ZWQgdG8gYW4gZW1lcmdlbmN5IGV2ZW50IChhbmQgaWYgaXQgb2NjdXJyZWQpXG4gICAgICogQHJldHVybiB7VW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldEVtZXJnZW5jeUV2ZW50IChldmVudCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YVJlc3VsdCwgZXZlbnQpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0VNRVJHRU5DWV9FVkVOVCwgZXZlbnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YVJlc3VsdH1cbiAgICAgKi9cbiAgICBnZXRFbWVyZ2VuY3lFdmVudCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YVJlc3VsdCwgVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9FTUVSR0VOQ1lfRVZFTlQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHR9IG1vZGVzIC0gVGhlIHN0YXR1cyBtb2RlcyBvZiB0aGUgY2x1c3RlclxuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRDbHVzdGVyTW9kZXMgKG1vZGVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhUmVzdWx0LCBtb2Rlcyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQ0xVU1RFUl9NT0RFUywgbW9kZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YVJlc3VsdH1cbiAgICAgKi9cbiAgICBnZXRDbHVzdGVyTW9kZXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFSZXN1bHQsIFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQ0xVU1RFUl9NT0RFUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YVJlc3VsdH0ga2V5IC0gSW5mb3JtYXRpb24gcmVsYXRlZCB0byB0aGUgTXlLZXkgZmVhdHVyZVxuICAgICAqIEByZXR1cm4ge1Vuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRNeUtleSAoa2V5KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhUmVzdWx0LCBrZXkpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX01ZX0tFWSwga2V5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFSZXN1bHR9XG4gICAgICovXG4gICAgZ2V0TXlLZXkgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFSZXN1bHQsIFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfTVlfS0VZKTtcbiAgICB9XG59XG5cblVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfR1BTID0gJ2dwcyc7XG5VbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1NQRUVEID0gJ3NwZWVkJztcblVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfUlBNID0gJ3JwbSc7XG5VbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0ZVRUxfTEVWRUwgPSAnZnVlbExldmVsJztcblVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRlVFTF9MRVZFTF9TVEFURSA9ICdmdWVsTGV2ZWxfU3RhdGUnO1xuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9JTlNUQU5UX0ZVRUxfQ09OU1VNUFRJT04gPSAnaW5zdGFudEZ1ZWxDb25zdW1wdGlvbic7XG5VbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0ZVRUxfUkFOR0UgPSAnZnVlbFJhbmdlJztcblVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRVhURVJOQUxfVEVNUEVSQVRVUkUgPSAnZXh0ZXJuYWxUZW1wZXJhdHVyZSc7XG5VbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1RVUk5fU0lHTkFMID0gJ3R1cm5TaWduYWwnO1xuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9QUk5ETCA9ICdwcm5kbCc7XG5VbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1RJUkVfUFJFU1NVUkUgPSAndGlyZVByZXNzdXJlJztcblVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfT0RPTUVURVIgPSAnb2RvbWV0ZXInO1xuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9CRUxUX1NUQVRVUyA9ICdiZWx0U3RhdHVzJztcblVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQk9EWV9JTkZPUk1BVElPTiA9ICdib2R5SW5mb3JtYXRpb24nO1xuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9ERVZJQ0VfU1RBVFVTID0gJ2RldmljZVN0YXR1cyc7XG5VbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0RSSVZFUl9CUkFLSU5HID0gJ2RyaXZlckJyYWtpbmcnO1xuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9XSVBFUl9TVEFUVVMgPSAnd2lwZXJTdGF0dXMnO1xuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9IRUFEX0xBTVBfU1RBVFVTID0gJ2hlYWRMYW1wU3RhdHVzJztcblVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRU5HSU5FX1RPUlFVRSA9ICdlbmdpbmVUb3JxdWUnO1xuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9BQ0NfUEVEQUxfUE9TSVRJT04gPSAnYWNjUGVkYWxQb3NpdGlvbic7XG5VbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1NURUVSSU5HX1dIRUVMX0FOR0xFID0gJ3N0ZWVyaW5nV2hlZWxBbmdsZSc7XG5VbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0VOR0lORV9PSUxfTElGRSA9ICdlbmdpbmVPaWxMaWZlJztcblVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRUxFQ1RST05JQ19QQVJLX0JSQUtFX1NUQVRVUyA9ICdlbGVjdHJvbmljUGFya0JyYWtlU3RhdHVzJztcblVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQ0xPVURfQVBQX1ZFSElDTEVfSUQgPSAnY2xvdWRBcHBWZWhpY2xlSUQnO1xuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9FX0NBTExfSU5GTyA9ICdlQ2FsbEluZm8nO1xuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9BSVJCQUdfU1RBVFVTID0gJ2FpcmJhZ1N0YXR1cyc7XG5VbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0VNRVJHRU5DWV9FVkVOVCA9ICdlbWVyZ2VuY3lFdmVudCc7XG5VbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0NMVVNURVJfTU9ERVMgPSAnY2x1c3Rlck1vZGVzJztcblVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfTVlfS0VZID0gJ215S2V5JztcblxuZXhwb3J0IHsgVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG4vKipcbiAqIE5vbiBwZXJpb2RpYyB2ZWhpY2xlIGRhdGEgcmVhZCByZXF1ZXN0LlxuICovXG5jbGFzcyBHZXRWZWhpY2xlRGF0YSBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuR2V0VmVoaWNsZURhdGEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gZ3BzIC0gU2VlIEdQU0RhdGFcbiAgICAgKiBAcmV0dXJuIHtHZXRWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRHcHMgKGdwcykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfR1BTLCBncHMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEdwcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfR1BTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHNwZWVkIC0gVGhlIHZlaGljbGUgc3BlZWQgaW4ga2lsb21ldGVycyBwZXIgaG91clxuICAgICAqIEByZXR1cm4ge0dldFZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldFNwZWVkIChzcGVlZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfU1BFRUQsIHNwZWVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRTcGVlZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfU1BFRUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gcnBtIC0gVGhlIG51bWJlciBvZiByZXZvbHV0aW9ucyBwZXIgbWludXRlIG9mIHRoZSBlbmdpbmVcbiAgICAgKiBAcmV0dXJuIHtHZXRWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRScG0gKHJwbSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfUlBNLCBycG0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFJwbSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfUlBNKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGxldmVsIC0gVGhlIGZ1ZWwgbGV2ZWwgaW4gdGhlIHRhbmsgKHBlcmNlbnRhZ2UpXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0RnVlbExldmVsIChsZXZlbCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfRlVFTF9MRVZFTCwgbGV2ZWwpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEZ1ZWxMZXZlbCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfRlVFTF9MRVZFTCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBsZXZlbF9zdGF0ZSAtIFRoZSBmdWVsIGxldmVsIHN0YXRlXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0RnVlbExldmVsX1N0YXRlIChsZXZlbF9zdGF0ZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfRlVFTF9MRVZFTF9TVEFURSwgbGV2ZWxfc3RhdGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEZ1ZWxMZXZlbF9TdGF0ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfRlVFTF9MRVZFTF9TVEFURSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBjb25zdW1wdGlvbiAtIFRoZSBpbnN0YW50YW5lb3VzIGZ1ZWwgY29uc3VtcHRpb24gaW4gbWljcm9saXRyZXNcbiAgICAgKiBAcmV0dXJuIHtHZXRWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRJbnN0YW50RnVlbENvbnN1bXB0aW9uIChjb25zdW1wdGlvbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfSU5TVEFOVF9GVUVMX0NPTlNVTVBUSU9OLCBjb25zdW1wdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0SW5zdGFudEZ1ZWxDb25zdW1wdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfSU5TVEFOVF9GVUVMX0NPTlNVTVBUSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHJhbmdlIC0gVGhlIGVzdGltYXRlIHJhbmdlIGluIEtNIHRoZSB2ZWhpY2xlIGNhbiB0cmF2ZWwgYmFzZWQgb24gZnVlbCBsZXZlbCBhbmQgY29uc3VtcHRpb25cbiAgICAgKiBAcmV0dXJuIHtHZXRWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRGdWVsUmFuZ2UgKHJhbmdlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhLktFWV9GVUVMX1JBTkdFLCByYW5nZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0RnVlbFJhbmdlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhLktFWV9GVUVMX1JBTkdFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHRlbXBlcmF0dXJlIC0gVGhlIGV4dGVybmFsIHRlbXBlcmF0dXJlIGluIGRlZ3JlZXMgY2Vsc2l1c1xuICAgICAqIEByZXR1cm4ge0dldFZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldEV4dGVybmFsVGVtcGVyYXR1cmUgKHRlbXBlcmF0dXJlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhLktFWV9FWFRFUk5BTF9URU1QRVJBVFVSRSwgdGVtcGVyYXR1cmUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEV4dGVybmFsVGVtcGVyYXR1cmUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGEuS0VZX0VYVEVSTkFMX1RFTVBFUkFUVVJFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHNpZ25hbCAtIFNlZSBUdXJuU2lnbmFsXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0VHVyblNpZ25hbCAoc2lnbmFsKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhLktFWV9UVVJOX1NJR05BTCwgc2lnbmFsKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRUdXJuU2lnbmFsICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhLktFWV9UVVJOX1NJR05BTCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSB2aW4gLSBWZWhpY2xlIGlkZW50aWZpY2F0aW9uIG51bWJlclxuICAgICAqIEByZXR1cm4ge0dldFZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldFZpbiAodmluKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhLktFWV9WSU4sIHZpbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0VmluICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhLktFWV9WSU4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gcHJuZGwgLSBTZWUgUFJORExcbiAgICAgKiBAcmV0dXJuIHtHZXRWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRQcm5kbCAocHJuZGwpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGEuS0VZX1BSTkRMLCBwcm5kbCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0UHJuZGwgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGEuS0VZX1BSTkRMKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHByZXNzdXJlIC0gU2VlIFRpcmVTdGF0dXNcbiAgICAgKiBAcmV0dXJuIHtHZXRWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRUaXJlUHJlc3N1cmUgKHByZXNzdXJlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhLktFWV9USVJFX1BSRVNTVVJFLCBwcmVzc3VyZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0VGlyZVByZXNzdXJlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhLktFWV9USVJFX1BSRVNTVVJFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IG9kb21ldGVyIC0gT2RvbWV0ZXIgaW4ga21cbiAgICAgKiBAcmV0dXJuIHtHZXRWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRPZG9tZXRlciAob2RvbWV0ZXIpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGEuS0VZX09ET01FVEVSLCBvZG9tZXRlcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0T2RvbWV0ZXIgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGEuS0VZX09ET01FVEVSKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHN0YXR1cyAtIFRoZSBzdGF0dXMgb2YgdGhlIHNlYXQgYmVsdHNcbiAgICAgKiBAcmV0dXJuIHtHZXRWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRCZWx0U3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGEuS0VZX0JFTFRfU1RBVFVTLCBzdGF0dXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEJlbHRTdGF0dXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGEuS0VZX0JFTFRfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGluZm9ybWF0aW9uIC0gVGhlIGJvZHkgaW5mb3JtYXRpb24gaW5jbHVkaW5nIGlnbml0aW9uIHN0YXR1cyBhbmQgaW50ZXJuYWwgdGVtcFxuICAgICAqIEByZXR1cm4ge0dldFZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldEJvZHlJbmZvcm1hdGlvbiAoaW5mb3JtYXRpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGEuS0VZX0JPRFlfSU5GT1JNQVRJT04sIGluZm9ybWF0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRCb2R5SW5mb3JtYXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGEuS0VZX0JPRFlfSU5GT1JNQVRJT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gc3RhdHVzIC0gVGhlIGRldmljZSBzdGF0dXMgaW5jbHVkaW5nIHNpZ25hbCBhbmQgYmF0dGVyeSBzdHJlbmd0aFxuICAgICAqIEByZXR1cm4ge0dldFZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldERldmljZVN0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhLktFWV9ERVZJQ0VfU1RBVFVTLCBzdGF0dXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldERldmljZVN0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfREVWSUNFX1NUQVRVUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBicmFraW5nIC0gVGhlIHN0YXR1cyBvZiB0aGUgYnJha2UgcGVkYWxcbiAgICAgKiBAcmV0dXJuIHtHZXRWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXREcml2ZXJCcmFraW5nIChicmFraW5nKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhLktFWV9EUklWRVJfQlJBS0lORywgYnJha2luZyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0RHJpdmVyQnJha2luZyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfRFJJVkVSX0JSQUtJTkcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gc3RhdHVzIC0gVGhlIHN0YXR1cyBvZiB0aGUgd2lwZXJzXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0V2lwZXJTdGF0dXMgKHN0YXR1cykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfV0lQRVJfU1RBVFVTLCBzdGF0dXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFdpcGVyU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhLktFWV9XSVBFUl9TVEFUVVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gc3RhdHVzIC0gU3RhdHVzIG9mIHRoZSBoZWFkIGxhbXBzXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0SGVhZExhbXBTdGF0dXMgKHN0YXR1cykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfSEVBRF9MQU1QX1NUQVRVUywgc3RhdHVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRIZWFkTGFtcFN0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfSEVBRF9MQU1QX1NUQVRVUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSB0b3JxdWUgLSBUb3JxdWUgdmFsdWUgZm9yIGVuZ2luZSAoaW4gTm0pIG9uIG5vbi1kaWVzZWwgdmFyaWFudHNcbiAgICAgKiBAcmV0dXJuIHtHZXRWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRFbmdpbmVUb3JxdWUgKHRvcnF1ZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfRU5HSU5FX1RPUlFVRSwgdG9ycXVlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRFbmdpbmVUb3JxdWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGEuS0VZX0VOR0lORV9UT1JRVUUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gcG9zaXRpb24gLSBBY2NlbGVyYXRvciBwZWRhbCBwb3NpdGlvbiAocGVyY2VudGFnZSBkZXByZXNzZWQpXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0QWNjUGVkYWxQb3NpdGlvbiAocG9zaXRpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGEuS0VZX0FDQ19QRURBTF9QT1NJVElPTiwgcG9zaXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEFjY1BlZGFsUG9zaXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGEuS0VZX0FDQ19QRURBTF9QT1NJVElPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhbmdsZSAtIEN1cnJlbnQgYW5nbGUgb2YgdGhlIHN0ZWVyaW5nIHdoZWVsIChpbiBkZWcpXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0U3RlZXJpbmdXaGVlbEFuZ2xlIChhbmdsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfU1RFRVJJTkdfV0hFRUxfQU5HTEUsIGFuZ2xlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRTdGVlcmluZ1doZWVsQW5nbGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGEuS0VZX1NURUVSSU5HX1dIRUVMX0FOR0xFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGxpZmUgLSBUaGUgZXN0aW1hdGVkIHBlcmNlbnRhZ2Ugb2YgcmVtYWluaW5nIG9pbCBsaWZlIG9mIHRoZSBlbmdpbmUuXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0RW5naW5lT2lsTGlmZSAobGlmZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfRU5HSU5FX09JTF9MSUZFLCBsaWZlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRFbmdpbmVPaWxMaWZlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhLktFWV9FTkdJTkVfT0lMX0xJRkUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gc3RhdHVzIC0gVGhlIHN0YXR1cyBvZiB0aGUgcGFyayBicmFrZSBhcyBwcm92aWRlZCBieSBFbGVjdHJpYyBQYXJrIEJyYWtlIChFUEIpIHN5c3RlbS5cbiAgICAgKiBAcmV0dXJuIHtHZXRWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRFbGVjdHJvbmljUGFya0JyYWtlU3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGEuS0VZX0VMRUNUUk9OSUNfUEFSS19CUkFLRV9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0RWxlY3Ryb25pY1BhcmtCcmFrZVN0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfRUxFQ1RST05JQ19QQVJLX0JSQUtFX1NUQVRVUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBpZCAtIFBhcmFtZXRlciB1c2VkIGJ5IGNsb3VkIGFwcHMgdG8gaWRlbnRpZnkgYSBoZWFkIHVuaXRcbiAgICAgKiBAcmV0dXJuIHtHZXRWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRDbG91ZEFwcFZlaGljbGVJRCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGEuS0VZX0NMT1VEX0FQUF9WRUhJQ0xFX0lELCBpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0Q2xvdWRBcHBWZWhpY2xlSUQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGEuS0VZX0NMT1VEX0FQUF9WRUhJQ0xFX0lEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGluZm8gLSBFbWVyZ2VuY3kgQ2FsbCBub3RpZmljYXRpb24gYW5kIGNvbmZpcm1hdGlvbiBkYXRhXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0RUNhbGxJbmZvIChpbmZvKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhLktFWV9FX0NBTExfSU5GTywgaW5mbyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0RUNhbGxJbmZvICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhLktFWV9FX0NBTExfSU5GTyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBzdGF0dXMgLSBUaGUgc3RhdHVzIG9mIHRoZSBhaXIgYmFnc1xuICAgICAqIEByZXR1cm4ge0dldFZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldEFpcmJhZ1N0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhLktFWV9BSVJCQUdfU1RBVFVTLCBzdGF0dXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEFpcmJhZ1N0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfQUlSQkFHX1NUQVRVUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBldmVudCAtIEluZm9ybWF0aW9uIHJlbGF0ZWQgdG8gYW4gZW1lcmdlbmN5IGV2ZW50IChhbmQgaWYgaXQgb2NjdXJyZWQpXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0RW1lcmdlbmN5RXZlbnQgKGV2ZW50KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhLktFWV9FTUVSR0VOQ1lfRVZFTlQsIGV2ZW50KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRFbWVyZ2VuY3lFdmVudCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YS5LRVlfRU1FUkdFTkNZX0VWRU5UKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHN0YXR1cyAtIFRoZSBzdGF0dXMgbW9kZXMgb2YgdGhlIGNsdXN0ZXJcbiAgICAgKiBAcmV0dXJuIHtHZXRWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRDbHVzdGVyTW9kZVN0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhLktFWV9DTFVTVEVSX01PREVfU1RBVFVTLCBzdGF0dXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldENsdXN0ZXJNb2RlU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhLktFWV9DTFVTVEVSX01PREVfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGtleSAtIEluZm9ybWF0aW9uIHJlbGF0ZWQgdG8gdGhlIE15S2V5IGZlYXR1cmVcbiAgICAgKiBAcmV0dXJuIHtHZXRWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRNeUtleSAoa2V5KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhLktFWV9NWV9LRVksIGtleSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0TXlLZXkgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGEuS0VZX01ZX0tFWSk7XG4gICAgfVxufVxuXG5HZXRWZWhpY2xlRGF0YS5LRVlfR1BTID0gJ2dwcyc7XG5HZXRWZWhpY2xlRGF0YS5LRVlfU1BFRUQgPSAnc3BlZWQnO1xuR2V0VmVoaWNsZURhdGEuS0VZX1JQTSA9ICdycG0nO1xuR2V0VmVoaWNsZURhdGEuS0VZX0ZVRUxfTEVWRUwgPSAnZnVlbExldmVsJztcbkdldFZlaGljbGVEYXRhLktFWV9GVUVMX0xFVkVMX1NUQVRFID0gJ2Z1ZWxMZXZlbF9TdGF0ZSc7XG5HZXRWZWhpY2xlRGF0YS5LRVlfSU5TVEFOVF9GVUVMX0NPTlNVTVBUSU9OID0gJ2luc3RhbnRGdWVsQ29uc3VtcHRpb24nO1xuR2V0VmVoaWNsZURhdGEuS0VZX0ZVRUxfUkFOR0UgPSAnZnVlbFJhbmdlJztcbkdldFZlaGljbGVEYXRhLktFWV9FWFRFUk5BTF9URU1QRVJBVFVSRSA9ICdleHRlcm5hbFRlbXBlcmF0dXJlJztcbkdldFZlaGljbGVEYXRhLktFWV9UVVJOX1NJR05BTCA9ICd0dXJuU2lnbmFsJztcbkdldFZlaGljbGVEYXRhLktFWV9WSU4gPSAndmluJztcbkdldFZlaGljbGVEYXRhLktFWV9QUk5ETCA9ICdwcm5kbCc7XG5HZXRWZWhpY2xlRGF0YS5LRVlfVElSRV9QUkVTU1VSRSA9ICd0aXJlUHJlc3N1cmUnO1xuR2V0VmVoaWNsZURhdGEuS0VZX09ET01FVEVSID0gJ29kb21ldGVyJztcbkdldFZlaGljbGVEYXRhLktFWV9CRUxUX1NUQVRVUyA9ICdiZWx0U3RhdHVzJztcbkdldFZlaGljbGVEYXRhLktFWV9CT0RZX0lORk9STUFUSU9OID0gJ2JvZHlJbmZvcm1hdGlvbic7XG5HZXRWZWhpY2xlRGF0YS5LRVlfREVWSUNFX1NUQVRVUyA9ICdkZXZpY2VTdGF0dXMnO1xuR2V0VmVoaWNsZURhdGEuS0VZX0RSSVZFUl9CUkFLSU5HID0gJ2RyaXZlckJyYWtpbmcnO1xuR2V0VmVoaWNsZURhdGEuS0VZX1dJUEVSX1NUQVRVUyA9ICd3aXBlclN0YXR1cyc7XG5HZXRWZWhpY2xlRGF0YS5LRVlfSEVBRF9MQU1QX1NUQVRVUyA9ICdoZWFkTGFtcFN0YXR1cyc7XG5HZXRWZWhpY2xlRGF0YS5LRVlfRU5HSU5FX1RPUlFVRSA9ICdlbmdpbmVUb3JxdWUnO1xuR2V0VmVoaWNsZURhdGEuS0VZX0FDQ19QRURBTF9QT1NJVElPTiA9ICdhY2NQZWRhbFBvc2l0aW9uJztcbkdldFZlaGljbGVEYXRhLktFWV9TVEVFUklOR19XSEVFTF9BTkdMRSA9ICdzdGVlcmluZ1doZWVsQW5nbGUnO1xuR2V0VmVoaWNsZURhdGEuS0VZX0VOR0lORV9PSUxfTElGRSA9ICdlbmdpbmVPaWxMaWZlJztcbkdldFZlaGljbGVEYXRhLktFWV9FTEVDVFJPTklDX1BBUktfQlJBS0VfU1RBVFVTID0gJ2VsZWN0cm9uaWNQYXJrQnJha2VTdGF0dXMnO1xuR2V0VmVoaWNsZURhdGEuS0VZX0NMT1VEX0FQUF9WRUhJQ0xFX0lEID0gJ2Nsb3VkQXBwVmVoaWNsZUlEJztcbkdldFZlaGljbGVEYXRhLktFWV9FX0NBTExfSU5GTyA9ICdlQ2FsbEluZm8nO1xuR2V0VmVoaWNsZURhdGEuS0VZX0FJUkJBR19TVEFUVVMgPSAnYWlyYmFnU3RhdHVzJztcbkdldFZlaGljbGVEYXRhLktFWV9FTUVSR0VOQ1lfRVZFTlQgPSAnZW1lcmdlbmN5RXZlbnQnO1xuR2V0VmVoaWNsZURhdGEuS0VZX0NMVVNURVJfTU9ERV9TVEFUVVMgPSAnY2x1c3Rlck1vZGVTdGF0dXMnO1xuR2V0VmVoaWNsZURhdGEuS0VZX01ZX0tFWSA9ICdteUtleSc7XG5cbmV4cG9ydCB7IEdldFZlaGljbGVEYXRhIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogUmVmbGVjdHMgdGhlIHN0YXR1cyBvZiBhIHZlaGljbGUgZGF0YSBldmVudDsgZS5nLiBhIHNlYXQgYmVsdCBldmVudCBzdGF0dXMuXG4gKiBAdHlwZWRlZiB7RW51bX0gVmVoaWNsZURhdGFFdmVudFN0YXR1c1xuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgVmVoaWNsZURhdGFFdmVudFN0YXR1cyBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBWREVTX05PX0VWRU5UICgpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhRXZlbnRTdGF0dXMuX01BUC5WREVTX05PX0VWRU5UO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZERVNfTk8gKCkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFFdmVudFN0YXR1cy5fTUFQLlZERVNfTk87XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVkRFU19ZRVMgKCkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFFdmVudFN0YXR1cy5fTUFQLlZERVNfWUVTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZERVNfTk9UX1NVUFBPUlRFRCAoKSB7XG4gICAgICAgIHJldHVybiBWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLl9NQVAuVkRFU19OT1RfU1VQUE9SVEVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZERVNfRkFVTFQgKCkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFFdmVudFN0YXR1cy5fTUFQLlZERVNfRkFVTFQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFFdmVudFN0YXR1cy5fdmFsdWVGb3JLZXkoa2V5LCBWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFFdmVudFN0YXR1cy5fa2V5Rm9yVmFsdWUodmFsdWUsIFZlaGljbGVEYXRhRXZlbnRTdGF0dXMuX01BUCk7XG4gICAgfVxufVxuXG5WZWhpY2xlRGF0YUV2ZW50U3RhdHVzLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnVkRFU19OT19FVkVOVCc6ICdOT19FVkVOVCcsXG4gICAgJ1ZERVNfTk8nOiAnTk8nLFxuICAgICdWREVTX1lFUyc6ICdZRVMnLFxuICAgICdWREVTX05PVF9TVVBQT1JURUQnOiAnTk9UX1NVUFBPUlRFRCcsXG4gICAgJ1ZERVNfRkFVTFQnOiAnRkFVTFQnLFxufSk7XG5cbmV4cG9ydCB7IFZlaGljbGVEYXRhRXZlbnRTdGF0dXMgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgVmVoaWNsZURhdGFFdmVudFN0YXR1cyB9IGZyb20gJy4uL2VudW1zL1ZlaGljbGVEYXRhRXZlbnRTdGF0dXMuanMnO1xuXG5jbGFzcyBBaXJiYWdTdGF0dXMgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFFdmVudFN0YXR1c30gZGVwbG95ZWQgLSBSZWZlcmVuY2VzIHNpZ25hbCBcIlZlZHNEcnZCYWdfRF9MdGNoZFwiLiBTZWUgVmVoaWNsZURhdGFFdmVudFN0YXR1cy5cbiAgICAgKiBAcmV0dXJuIHtBaXJiYWdTdGF0dXN9XG4gICAgICovXG4gICAgc2V0RHJpdmVyQWlyYmFnRGVwbG95ZWQgKGRlcGxveWVkKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIGRlcGxveWVkKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQWlyYmFnU3RhdHVzLktFWV9EUklWRVJfQUlSQkFHX0RFUExPWUVELCBkZXBsb3llZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhRXZlbnRTdGF0dXN9XG4gICAgICovXG4gICAgZ2V0RHJpdmVyQWlyYmFnRGVwbG95ZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFFdmVudFN0YXR1cywgQWlyYmFnU3RhdHVzLktFWV9EUklWRVJfQUlSQkFHX0RFUExPWUVEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlaGljbGVEYXRhRXZlbnRTdGF0dXN9IGRlcGxveWVkIC0gUmVmZXJlbmNlcyBzaWduYWwgXCJWZWRzRHJ2U2lkZUJhZ19EX0x0Y2hkXCIuIFNlZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLlxuICAgICAqIEByZXR1cm4ge0FpcmJhZ1N0YXR1c31cbiAgICAgKi9cbiAgICBzZXREcml2ZXJTaWRlQWlyYmFnRGVwbG95ZWQgKGRlcGxveWVkKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIGRlcGxveWVkKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQWlyYmFnU3RhdHVzLktFWV9EUklWRVJfU0lERV9BSVJCQUdfREVQTE9ZRUQsIGRlcGxveWVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFFdmVudFN0YXR1c31cbiAgICAgKi9cbiAgICBnZXREcml2ZXJTaWRlQWlyYmFnRGVwbG95ZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFFdmVudFN0YXR1cywgQWlyYmFnU3RhdHVzLktFWV9EUklWRVJfU0lERV9BSVJCQUdfREVQTE9ZRUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFFdmVudFN0YXR1c30gZGVwbG95ZWQgLSBSZWZlcmVuY2VzIHNpZ25hbCBcIlZlZHNEcnZDcnRuQmFnX0RfTHRjaGRcIi4gU2VlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlaGljbGVEYXRhRXZlbnRTdGF0dXMuXG4gICAgICogQHJldHVybiB7QWlyYmFnU3RhdHVzfVxuICAgICAqL1xuICAgIHNldERyaXZlckN1cnRhaW5BaXJiYWdEZXBsb3llZCAoZGVwbG95ZWQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFFdmVudFN0YXR1cywgZGVwbG95ZWQpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBaXJiYWdTdGF0dXMuS0VZX0RSSVZFUl9DVVJUQUlOX0FJUkJBR19ERVBMT1lFRCwgZGVwbG95ZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfVxuICAgICAqL1xuICAgIGdldERyaXZlckN1cnRhaW5BaXJiYWdEZXBsb3llZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLCBBaXJiYWdTdGF0dXMuS0VZX0RSSVZFUl9DVVJUQUlOX0FJUkJBR19ERVBMT1lFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfSBkZXBsb3llZCAtIFJlZmVyZW5jZXMgc2lnbmFsIFwiVmVkc1Bhc0JhZ19EX0x0Y2hkXCIuIFNlZSBWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLlxuICAgICAqIEByZXR1cm4ge0FpcmJhZ1N0YXR1c31cbiAgICAgKi9cbiAgICBzZXRQYXNzZW5nZXJBaXJiYWdEZXBsb3llZCAoZGVwbG95ZWQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFFdmVudFN0YXR1cywgZGVwbG95ZWQpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBaXJiYWdTdGF0dXMuS0VZX1BBU1NFTkdFUl9BSVJCQUdfREVQTE9ZRUQsIGRlcGxveWVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFFdmVudFN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRQYXNzZW5nZXJBaXJiYWdEZXBsb3llZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLCBBaXJiYWdTdGF0dXMuS0VZX1BBU1NFTkdFUl9BSVJCQUdfREVQTE9ZRUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFFdmVudFN0YXR1c30gZGVwbG95ZWQgLSBSZWZlcmVuY2VzIHNpZ25hbCBcIlZlZHNQYXNDcnRuQmFnX0RfTHRjaGRcIi4gU2VlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlaGljbGVEYXRhRXZlbnRTdGF0dXMuXG4gICAgICogQHJldHVybiB7QWlyYmFnU3RhdHVzfVxuICAgICAqL1xuICAgIHNldFBhc3NlbmdlckN1cnRhaW5BaXJiYWdEZXBsb3llZCAoZGVwbG95ZWQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFFdmVudFN0YXR1cywgZGVwbG95ZWQpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBaXJiYWdTdGF0dXMuS0VZX1BBU1NFTkdFUl9DVVJUQUlOX0FJUkJBR19ERVBMT1lFRCwgZGVwbG95ZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfVxuICAgICAqL1xuICAgIGdldFBhc3NlbmdlckN1cnRhaW5BaXJiYWdEZXBsb3llZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLCBBaXJiYWdTdGF0dXMuS0VZX1BBU1NFTkdFUl9DVVJUQUlOX0FJUkJBR19ERVBMT1lFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfSBkZXBsb3llZCAtIFJlZmVyZW5jZXMgc2lnbmFsIFwiVmVkc0tuZWVEcnZCYWdfRF9MdGNoZFwiLiBTZWVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVoaWNsZURhdGFFdmVudFN0YXR1cy5cbiAgICAgKiBAcmV0dXJuIHtBaXJiYWdTdGF0dXN9XG4gICAgICovXG4gICAgc2V0RHJpdmVyS25lZUFpcmJhZ0RlcGxveWVkIChkZXBsb3llZCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLCBkZXBsb3llZCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEFpcmJhZ1N0YXR1cy5LRVlfRFJJVkVSX0tORUVfQUlSQkFHX0RFUExPWUVELCBkZXBsb3llZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhRXZlbnRTdGF0dXN9XG4gICAgICovXG4gICAgZ2V0RHJpdmVyS25lZUFpcmJhZ0RlcGxveWVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIEFpcmJhZ1N0YXR1cy5LRVlfRFJJVkVSX0tORUVfQUlSQkFHX0RFUExPWUVEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlaGljbGVEYXRhRXZlbnRTdGF0dXN9IGRlcGxveWVkIC0gUmVmZXJlbmNlcyBzaWduYWwgXCJWZWRzUGFzU2lkZUJhZ19EX0x0Y2hkXCIuIFNlZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLlxuICAgICAqIEByZXR1cm4ge0FpcmJhZ1N0YXR1c31cbiAgICAgKi9cbiAgICBzZXRQYXNzZW5nZXJTaWRlQWlyYmFnRGVwbG95ZWQgKGRlcGxveWVkKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIGRlcGxveWVkKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQWlyYmFnU3RhdHVzLktFWV9QQVNTRU5HRVJfU0lERV9BSVJCQUdfREVQTE9ZRUQsIGRlcGxveWVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFFdmVudFN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRQYXNzZW5nZXJTaWRlQWlyYmFnRGVwbG95ZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFFdmVudFN0YXR1cywgQWlyYmFnU3RhdHVzLktFWV9QQVNTRU5HRVJfU0lERV9BSVJCQUdfREVQTE9ZRUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFFdmVudFN0YXR1c30gZGVwbG95ZWQgLSBSZWZlcmVuY2VzIHNpZ25hbCBcIlZlZHNLbmVlUGFzQmFnX0RfTHRjaGRcIi4gU2VlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlaGljbGVEYXRhRXZlbnRTdGF0dXMuXG4gICAgICogQHJldHVybiB7QWlyYmFnU3RhdHVzfVxuICAgICAqL1xuICAgIHNldFBhc3NlbmdlcktuZWVBaXJiYWdEZXBsb3llZCAoZGVwbG95ZWQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFFdmVudFN0YXR1cywgZGVwbG95ZWQpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBaXJiYWdTdGF0dXMuS0VZX1BBU1NFTkdFUl9LTkVFX0FJUkJBR19ERVBMT1lFRCwgZGVwbG95ZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfVxuICAgICAqL1xuICAgIGdldFBhc3NlbmdlcktuZWVBaXJiYWdEZXBsb3llZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLCBBaXJiYWdTdGF0dXMuS0VZX1BBU1NFTkdFUl9LTkVFX0FJUkJBR19ERVBMT1lFRCk7XG4gICAgfVxufVxuXG5BaXJiYWdTdGF0dXMuS0VZX0RSSVZFUl9BSVJCQUdfREVQTE9ZRUQgPSAnZHJpdmVyQWlyYmFnRGVwbG95ZWQnO1xuQWlyYmFnU3RhdHVzLktFWV9EUklWRVJfU0lERV9BSVJCQUdfREVQTE9ZRUQgPSAnZHJpdmVyU2lkZUFpcmJhZ0RlcGxveWVkJztcbkFpcmJhZ1N0YXR1cy5LRVlfRFJJVkVSX0NVUlRBSU5fQUlSQkFHX0RFUExPWUVEID0gJ2RyaXZlckN1cnRhaW5BaXJiYWdEZXBsb3llZCc7XG5BaXJiYWdTdGF0dXMuS0VZX1BBU1NFTkdFUl9BSVJCQUdfREVQTE9ZRUQgPSAncGFzc2VuZ2VyQWlyYmFnRGVwbG95ZWQnO1xuQWlyYmFnU3RhdHVzLktFWV9QQVNTRU5HRVJfQ1VSVEFJTl9BSVJCQUdfREVQTE9ZRUQgPSAncGFzc2VuZ2VyQ3VydGFpbkFpcmJhZ0RlcGxveWVkJztcbkFpcmJhZ1N0YXR1cy5LRVlfRFJJVkVSX0tORUVfQUlSQkFHX0RFUExPWUVEID0gJ2RyaXZlcktuZWVBaXJiYWdEZXBsb3llZCc7XG5BaXJiYWdTdGF0dXMuS0VZX1BBU1NFTkdFUl9TSURFX0FJUkJBR19ERVBMT1lFRCA9ICdwYXNzZW5nZXJTaWRlQWlyYmFnRGVwbG95ZWQnO1xuQWlyYmFnU3RhdHVzLktFWV9QQVNTRU5HRVJfS05FRV9BSVJCQUdfREVQTE9ZRUQgPSAncGFzc2VuZ2VyS25lZUFpcmJhZ0RlcGxveWVkJztcblxuZXhwb3J0IHsgQWlyYmFnU3RhdHVzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogUmVmbGVjdHMgdGhlIHN0YXR1cyBvZiB0aGUgY3VycmVudCBwb3dlciBtb2RlLlxuICogQHR5cGVkZWYge0VudW19IFBvd2VyTW9kZVN0YXR1c1xuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgUG93ZXJNb2RlU3RhdHVzIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEtFWV9PVVQgKCkge1xuICAgICAgICByZXR1cm4gUG93ZXJNb2RlU3RhdHVzLl9NQVAuS0VZX09VVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBLRVlfUkVDRU5UTFlfT1VUICgpIHtcbiAgICAgICAgcmV0dXJuIFBvd2VyTW9kZVN0YXR1cy5fTUFQLktFWV9SRUNFTlRMWV9PVVQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgS0VZX0FQUFJPVkVEXzAgKCkge1xuICAgICAgICByZXR1cm4gUG93ZXJNb2RlU3RhdHVzLl9NQVAuS0VZX0FQUFJPVkVEXzA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUE9TVF9BQ0NFU09SWV8wICgpIHtcbiAgICAgICAgcmV0dXJuIFBvd2VyTW9kZVN0YXR1cy5fTUFQLlBPU1RfQUNDRVNPUllfMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBBQ0NFU09SWV8xICgpIHtcbiAgICAgICAgcmV0dXJuIFBvd2VyTW9kZVN0YXR1cy5fTUFQLkFDQ0VTT1JZXzE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUE9TVF9JR05JVElPTl8xICgpIHtcbiAgICAgICAgcmV0dXJuIFBvd2VyTW9kZVN0YXR1cy5fTUFQLlBPU1RfSUdOSVRJT05fMTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBJR05JVElPTl9PTl8yICgpIHtcbiAgICAgICAgcmV0dXJuIFBvd2VyTW9kZVN0YXR1cy5fTUFQLklHTklUSU9OX09OXzI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUlVOTklOR18yICgpIHtcbiAgICAgICAgcmV0dXJuIFBvd2VyTW9kZVN0YXR1cy5fTUFQLlJVTk5JTkdfMjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDUkFOS18zICgpIHtcbiAgICAgICAgcmV0dXJuIFBvd2VyTW9kZVN0YXR1cy5fTUFQLkNSQU5LXzM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gUG93ZXJNb2RlU3RhdHVzLl92YWx1ZUZvcktleShrZXksIFBvd2VyTW9kZVN0YXR1cy5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFBvd2VyTW9kZVN0YXR1cy5fa2V5Rm9yVmFsdWUodmFsdWUsIFBvd2VyTW9kZVN0YXR1cy5fTUFQKTtcbiAgICB9XG59XG5cblBvd2VyTW9kZVN0YXR1cy5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0tFWV9PVVQnOiAnS0VZX09VVCcsXG4gICAgJ0tFWV9SRUNFTlRMWV9PVVQnOiAnS0VZX1JFQ0VOVExZX09VVCcsXG4gICAgJ0tFWV9BUFBST1ZFRF8wJzogJ0tFWV9BUFBST1ZFRF8wJyxcbiAgICAnUE9TVF9BQ0NFU09SWV8wJzogJ1BPU1RfQUNDRVNPUllfMCcsXG4gICAgJ0FDQ0VTT1JZXzEnOiAnQUNDRVNPUllfMScsXG4gICAgJ1BPU1RfSUdOSVRJT05fMSc6ICdQT1NUX0lHTklUSU9OXzEnLFxuICAgICdJR05JVElPTl9PTl8yJzogJ0lHTklUSU9OX09OXzInLFxuICAgICdSVU5OSU5HXzInOiAnUlVOTklOR18yJyxcbiAgICAnQ1JBTktfMyc6ICdDUkFOS18zJyxcbn0pO1xuXG5leHBvcnQgeyBQb3dlck1vZGVTdGF0dXMgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBSZWZsZWN0cyB0aGUgc3RhdHVzIG9mIHRoZSBjdXJyZW50IGNhciBtb2RlLlxuICogQHR5cGVkZWYge0VudW19IENhck1vZGVTdGF0dXNcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIENhck1vZGVTdGF0dXMgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ01TX05PUk1BTCAoKSB7XG4gICAgICAgIHJldHVybiBDYXJNb2RlU3RhdHVzLl9NQVAuQ01TX05PUk1BTDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDTVNfRkFDVE9SWSAoKSB7XG4gICAgICAgIHJldHVybiBDYXJNb2RlU3RhdHVzLl9NQVAuQ01TX0ZBQ1RPUlk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ01TX1RSQU5TUE9SVCAoKSB7XG4gICAgICAgIHJldHVybiBDYXJNb2RlU3RhdHVzLl9NQVAuQ01TX1RSQU5TUE9SVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDTVNfQ1JBU0ggKCkge1xuICAgICAgICByZXR1cm4gQ2FyTW9kZVN0YXR1cy5fTUFQLkNNU19DUkFTSDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBDYXJNb2RlU3RhdHVzLl92YWx1ZUZvcktleShrZXksIENhck1vZGVTdGF0dXMuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBDYXJNb2RlU3RhdHVzLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgQ2FyTW9kZVN0YXR1cy5fTUFQKTtcbiAgICB9XG59XG5cbkNhck1vZGVTdGF0dXMuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdDTVNfTk9STUFMJzogJ05PUk1BTCcsXG4gICAgJ0NNU19GQUNUT1JZJzogJ0ZBQ1RPUlknLFxuICAgICdDTVNfVFJBTlNQT1JUJzogJ1RSQU5TUE9SVCcsXG4gICAgJ0NNU19DUkFTSCc6ICdDUkFTSCcsXG59KTtcblxuZXhwb3J0IHsgQ2FyTW9kZVN0YXR1cyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIFJlZmxlY3RzIHRoZSBzdGF0dXMgb2YgdGhlIGN1cnJlbnQgcG93ZXIgbW9kZSBxdWFsaWZpY2F0aW9uLlxuICogQHR5cGVkZWYge0VudW19IFBvd2VyTW9kZVF1YWxpZmljYXRpb25TdGF0dXNcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIFBvd2VyTW9kZVF1YWxpZmljYXRpb25TdGF0dXMgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUE9XRVJfTU9ERV9VTkRFRklORUQgKCkge1xuICAgICAgICByZXR1cm4gUG93ZXJNb2RlUXVhbGlmaWNhdGlvblN0YXR1cy5fTUFQLlBPV0VSX01PREVfVU5ERUZJTkVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFBPV0VSX01PREVfRVZBTFVBVElPTl9JTl9QUk9HUkVTUyAoKSB7XG4gICAgICAgIHJldHVybiBQb3dlck1vZGVRdWFsaWZpY2F0aW9uU3RhdHVzLl9NQVAuUE9XRVJfTU9ERV9FVkFMVUFUSU9OX0lOX1BST0dSRVNTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5PVF9ERUZJTkVEICgpIHtcbiAgICAgICAgcmV0dXJuIFBvd2VyTW9kZVF1YWxpZmljYXRpb25TdGF0dXMuX01BUC5OT1RfREVGSU5FRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBQT1dFUl9NT0RFX09LICgpIHtcbiAgICAgICAgcmV0dXJuIFBvd2VyTW9kZVF1YWxpZmljYXRpb25TdGF0dXMuX01BUC5QT1dFUl9NT0RFX09LO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFBvd2VyTW9kZVF1YWxpZmljYXRpb25TdGF0dXMuX3ZhbHVlRm9yS2V5KGtleSwgUG93ZXJNb2RlUXVhbGlmaWNhdGlvblN0YXR1cy5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFBvd2VyTW9kZVF1YWxpZmljYXRpb25TdGF0dXMuX2tleUZvclZhbHVlKHZhbHVlLCBQb3dlck1vZGVRdWFsaWZpY2F0aW9uU3RhdHVzLl9NQVApO1xuICAgIH1cbn1cblxuUG93ZXJNb2RlUXVhbGlmaWNhdGlvblN0YXR1cy5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1BPV0VSX01PREVfVU5ERUZJTkVEJzogJ1BPV0VSX01PREVfVU5ERUZJTkVEJyxcbiAgICAnUE9XRVJfTU9ERV9FVkFMVUFUSU9OX0lOX1BST0dSRVNTJzogJ1BPV0VSX01PREVfRVZBTFVBVElPTl9JTl9QUk9HUkVTUycsXG4gICAgJ05PVF9ERUZJTkVEJzogJ05PVF9ERUZJTkVEJyxcbiAgICAnUE9XRVJfTU9ERV9PSyc6ICdQT1dFUl9NT0RFX09LJyxcbn0pO1xuXG5leHBvcnQgeyBQb3dlck1vZGVRdWFsaWZpY2F0aW9uU3RhdHVzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IFBvd2VyTW9kZVN0YXR1cyB9IGZyb20gJy4uL2VudW1zL1Bvd2VyTW9kZVN0YXR1cy5qcyc7XG5pbXBvcnQgeyBDYXJNb2RlU3RhdHVzIH0gZnJvbSAnLi4vZW51bXMvQ2FyTW9kZVN0YXR1cy5qcyc7XG5pbXBvcnQgeyBQb3dlck1vZGVRdWFsaWZpY2F0aW9uU3RhdHVzIH0gZnJvbSAnLi4vZW51bXMvUG93ZXJNb2RlUXVhbGlmaWNhdGlvblN0YXR1cy5qcyc7XG5cbmNsYXNzIENsdXN0ZXJNb2RlU3RhdHVzIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGFjdGl2ZSAtIFJlZmVyZW5jZXMgc2lnbmFsIFwiUG93ZXJNb2RlX1VCXCIuXG4gICAgICogQHJldHVybiB7Q2x1c3Rlck1vZGVTdGF0dXN9XG4gICAgICovXG4gICAgc2V0UG93ZXJNb2RlQWN0aXZlIChhY3RpdmUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2x1c3Rlck1vZGVTdGF0dXMuS0VZX1BPV0VSX01PREVfQUNUSVZFLCBhY3RpdmUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFBvd2VyTW9kZUFjdGl2ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihDbHVzdGVyTW9kZVN0YXR1cy5LRVlfUE9XRVJfTU9ERV9BQ1RJVkUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7UG93ZXJNb2RlUXVhbGlmaWNhdGlvblN0YXR1c30gc3RhdHVzIC0gUmVmZXJlbmNlcyBzaWduYWwgXCJQb3dlck1vZGVRRlwiLiBTZWUgUG93ZXJNb2RlUXVhbGlmaWNhdGlvblN0YXR1cy5cbiAgICAgKiBAcmV0dXJuIHtDbHVzdGVyTW9kZVN0YXR1c31cbiAgICAgKi9cbiAgICBzZXRQb3dlck1vZGVRdWFsaWZpY2F0aW9uU3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoUG93ZXJNb2RlUXVhbGlmaWNhdGlvblN0YXR1cywgc3RhdHVzKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2x1c3Rlck1vZGVTdGF0dXMuS0VZX1BPV0VSX01PREVfUVVBTElGSUNBVElPTl9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1Bvd2VyTW9kZVF1YWxpZmljYXRpb25TdGF0dXN9XG4gICAgICovXG4gICAgZ2V0UG93ZXJNb2RlUXVhbGlmaWNhdGlvblN0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChQb3dlck1vZGVRdWFsaWZpY2F0aW9uU3RhdHVzLCBDbHVzdGVyTW9kZVN0YXR1cy5LRVlfUE9XRVJfTU9ERV9RVUFMSUZJQ0FUSU9OX1NUQVRVUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtDYXJNb2RlU3RhdHVzfSBzdGF0dXMgLSBSZWZlcmVuY2VzIHNpZ25hbCBcIkNhck1vZGVcIi4gU2VlIENhck1vZGUuXG4gICAgICogQHJldHVybiB7Q2x1c3Rlck1vZGVTdGF0dXN9XG4gICAgICovXG4gICAgc2V0Q2FyTW9kZVN0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKENhck1vZGVTdGF0dXMsIHN0YXR1cyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENsdXN0ZXJNb2RlU3RhdHVzLktFWV9DQVJfTU9ERV9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Nhck1vZGVTdGF0dXN9XG4gICAgICovXG4gICAgZ2V0Q2FyTW9kZVN0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChDYXJNb2RlU3RhdHVzLCBDbHVzdGVyTW9kZVN0YXR1cy5LRVlfQ0FSX01PREVfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1Bvd2VyTW9kZVN0YXR1c30gc3RhdHVzIC0gUmVmZXJlbmNlcyBzaWduYWwgXCJQb3dlck1vZGVcIi4gU2VlIFBvd2VyTW9kZS5cbiAgICAgKiBAcmV0dXJuIHtDbHVzdGVyTW9kZVN0YXR1c31cbiAgICAgKi9cbiAgICBzZXRQb3dlck1vZGVTdGF0dXMgKHN0YXR1cykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShQb3dlck1vZGVTdGF0dXMsIHN0YXR1cyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENsdXN0ZXJNb2RlU3RhdHVzLktFWV9QT1dFUl9NT0RFX1NUQVRVUywgc3RhdHVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7UG93ZXJNb2RlU3RhdHVzfVxuICAgICAqL1xuICAgIGdldFBvd2VyTW9kZVN0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChQb3dlck1vZGVTdGF0dXMsIENsdXN0ZXJNb2RlU3RhdHVzLktFWV9QT1dFUl9NT0RFX1NUQVRVUyk7XG4gICAgfVxufVxuXG5DbHVzdGVyTW9kZVN0YXR1cy5LRVlfUE9XRVJfTU9ERV9BQ1RJVkUgPSAncG93ZXJNb2RlQWN0aXZlJztcbkNsdXN0ZXJNb2RlU3RhdHVzLktFWV9QT1dFUl9NT0RFX1FVQUxJRklDQVRJT05fU1RBVFVTID0gJ3Bvd2VyTW9kZVF1YWxpZmljYXRpb25TdGF0dXMnO1xuQ2x1c3Rlck1vZGVTdGF0dXMuS0VZX0NBUl9NT0RFX1NUQVRVUyA9ICdjYXJNb2RlU3RhdHVzJztcbkNsdXN0ZXJNb2RlU3RhdHVzLktFWV9QT1dFUl9NT0RFX1NUQVRVUyA9ICdwb3dlck1vZGVTdGF0dXMnO1xuXG5leHBvcnQgeyBDbHVzdGVyTW9kZVN0YXR1cyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIFJlZmxlY3RzIHRoZSBzdGF0dXMgb2YgdGhlIFJDTSBmdWVsIGN1dG9mZi5cbiAqIEB0eXBlZGVmIHtFbnVtfSBGdWVsQ3V0b2ZmU3RhdHVzXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBGdWVsQ3V0b2ZmU3RhdHVzIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEZDU19URVJNSU5BVEVfRlVFTCAoKSB7XG4gICAgICAgIHJldHVybiBGdWVsQ3V0b2ZmU3RhdHVzLl9NQVAuRkNTX1RFUk1JTkFURV9GVUVMO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEZDU19OT1JNQUxfT1BFUkFUSU9OICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1ZWxDdXRvZmZTdGF0dXMuX01BUC5GQ1NfTk9STUFMX09QRVJBVElPTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBGQ1NfRkFVTFQgKCkge1xuICAgICAgICByZXR1cm4gRnVlbEN1dG9mZlN0YXR1cy5fTUFQLkZDU19GQVVMVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBGdWVsQ3V0b2ZmU3RhdHVzLl92YWx1ZUZvcktleShrZXksIEZ1ZWxDdXRvZmZTdGF0dXMuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBGdWVsQ3V0b2ZmU3RhdHVzLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgRnVlbEN1dG9mZlN0YXR1cy5fTUFQKTtcbiAgICB9XG59XG5cbkZ1ZWxDdXRvZmZTdGF0dXMuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdGQ1NfVEVSTUlOQVRFX0ZVRUwnOiAnVEVSTUlOQVRFX0ZVRUwnLFxuICAgICdGQ1NfTk9STUFMX09QRVJBVElPTic6ICdOT1JNQUxfT1BFUkFUSU9OJyxcbiAgICAnRkNTX0ZBVUxUJzogJ0ZBVUxUJyxcbn0pO1xuXG5leHBvcnQgeyBGdWVsQ3V0b2ZmU3RhdHVzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogUmVmbGVjdHMgdGhlIGVtZXJnZW5jeSBldmVudCBzdGF0dXMgb2YgdGhlIHZlaGljbGUuXG4gKiBAdHlwZWRlZiB7RW51bX0gRW1lcmdlbmN5RXZlbnRUeXBlXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBFbWVyZ2VuY3lFdmVudFR5cGUgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRUVUX05PX0VWRU5UICgpIHtcbiAgICAgICAgcmV0dXJuIEVtZXJnZW5jeUV2ZW50VHlwZS5fTUFQLkVFVF9OT19FVkVOVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFRVRfRlJPTlRBTCAoKSB7XG4gICAgICAgIHJldHVybiBFbWVyZ2VuY3lFdmVudFR5cGUuX01BUC5FRVRfRlJPTlRBTDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFRVRfU0lERSAoKSB7XG4gICAgICAgIHJldHVybiBFbWVyZ2VuY3lFdmVudFR5cGUuX01BUC5FRVRfU0lERTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFRVRfUkVBUiAoKSB7XG4gICAgICAgIHJldHVybiBFbWVyZ2VuY3lFdmVudFR5cGUuX01BUC5FRVRfUkVBUjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFRVRfUk9MTE9WRVIgKCkge1xuICAgICAgICByZXR1cm4gRW1lcmdlbmN5RXZlbnRUeXBlLl9NQVAuRUVUX1JPTExPVkVSO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEVFVF9OT1RfU1VQUE9SVEVEICgpIHtcbiAgICAgICAgcmV0dXJuIEVtZXJnZW5jeUV2ZW50VHlwZS5fTUFQLkVFVF9OT1RfU1VQUE9SVEVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEVFVF9GQVVMVCAoKSB7XG4gICAgICAgIHJldHVybiBFbWVyZ2VuY3lFdmVudFR5cGUuX01BUC5FRVRfRkFVTFQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gRW1lcmdlbmN5RXZlbnRUeXBlLl92YWx1ZUZvcktleShrZXksIEVtZXJnZW5jeUV2ZW50VHlwZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIEVtZXJnZW5jeUV2ZW50VHlwZS5fa2V5Rm9yVmFsdWUodmFsdWUsIEVtZXJnZW5jeUV2ZW50VHlwZS5fTUFQKTtcbiAgICB9XG59XG5cbkVtZXJnZW5jeUV2ZW50VHlwZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0VFVF9OT19FVkVOVCc6ICdOT19FVkVOVCcsXG4gICAgJ0VFVF9GUk9OVEFMJzogJ0ZST05UQUwnLFxuICAgICdFRVRfU0lERSc6ICdTSURFJyxcbiAgICAnRUVUX1JFQVInOiAnUkVBUicsXG4gICAgJ0VFVF9ST0xMT1ZFUic6ICdST0xMT1ZFUicsXG4gICAgJ0VFVF9OT1RfU1VQUE9SVEVEJzogJ05PVF9TVVBQT1JURUQnLFxuICAgICdFRVRfRkFVTFQnOiAnRkFVTFQnLFxufSk7XG5cbmV4cG9ydCB7IEVtZXJnZW5jeUV2ZW50VHlwZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBGdWVsQ3V0b2ZmU3RhdHVzIH0gZnJvbSAnLi4vZW51bXMvRnVlbEN1dG9mZlN0YXR1cy5qcyc7XG5pbXBvcnQgeyBFbWVyZ2VuY3lFdmVudFR5cGUgfSBmcm9tICcuLi9lbnVtcy9FbWVyZ2VuY3lFdmVudFR5cGUuanMnO1xuaW1wb3J0IHsgVmVoaWNsZURhdGFFdmVudFN0YXR1cyB9IGZyb20gJy4uL2VudW1zL1ZlaGljbGVEYXRhRXZlbnRTdGF0dXMuanMnO1xuXG5jbGFzcyBFbWVyZ2VuY3lFdmVudCBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtFbWVyZ2VuY3lFdmVudFR5cGV9IHR5cGUgLSBSZWZlcmVuY2VzIHNpZ25hbCBcIlZlZHNFdm50VHlwZV9EX0x0Y2hkXCIuIFNlZSBFbWVyZ2VuY3lFdmVudFR5cGUuXG4gICAgICogQHJldHVybiB7RW1lcmdlbmN5RXZlbnR9XG4gICAgICovXG4gICAgc2V0RW1lcmdlbmN5RXZlbnRUeXBlICh0eXBlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEVtZXJnZW5jeUV2ZW50VHlwZSwgdHlwZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEVtZXJnZW5jeUV2ZW50LktFWV9FTUVSR0VOQ1lfRVZFTlRfVFlQRSwgdHlwZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0VtZXJnZW5jeUV2ZW50VHlwZX1cbiAgICAgKi9cbiAgICBnZXRFbWVyZ2VuY3lFdmVudFR5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoRW1lcmdlbmN5RXZlbnRUeXBlLCBFbWVyZ2VuY3lFdmVudC5LRVlfRU1FUkdFTkNZX0VWRU5UX1RZUEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RnVlbEN1dG9mZlN0YXR1c30gc3RhdHVzIC0gUmVmZXJlbmNlcyBzaWduYWwgXCJSQ01fRnVlbEN1dG9mZlwiLiBTZWUgRnVlbEN1dG9mZlN0YXR1cy5cbiAgICAgKiBAcmV0dXJuIHtFbWVyZ2VuY3lFdmVudH1cbiAgICAgKi9cbiAgICBzZXRGdWVsQ3V0b2ZmU3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoRnVlbEN1dG9mZlN0YXR1cywgc3RhdHVzKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRW1lcmdlbmN5RXZlbnQuS0VZX0ZVRUxfQ1VUT0ZGX1NUQVRVUywgc3RhdHVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7RnVlbEN1dG9mZlN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRGdWVsQ3V0b2ZmU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEZ1ZWxDdXRvZmZTdGF0dXMsIEVtZXJnZW5jeUV2ZW50LktFWV9GVUVMX0NVVE9GRl9TVEFUVVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFFdmVudFN0YXR1c30gZXZlbnQgLSBSZWZlcmVuY2VzIHNpZ25hbCBcIlZlZHNFdm50Um9sbF9EX0x0Y2hkXCIuIFNlZSBWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLlxuICAgICAqIEByZXR1cm4ge0VtZXJnZW5jeUV2ZW50fVxuICAgICAqL1xuICAgIHNldFJvbGxvdmVyRXZlbnQgKGV2ZW50KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIGV2ZW50KTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRW1lcmdlbmN5RXZlbnQuS0VZX1JPTExPVkVSX0VWRU5ULCBldmVudCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhRXZlbnRTdGF0dXN9XG4gICAgICovXG4gICAgZ2V0Um9sbG92ZXJFdmVudCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLCBFbWVyZ2VuY3lFdmVudC5LRVlfUk9MTE9WRVJfRVZFTlQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB2ZWxvY2l0eSAtIFJlZmVyZW5jZXMgc2lnbmFsIFwiVmVkc01heERlbHRhVl9EX0x0Y2hkXCIuIENoYW5nZSBpbiB2ZWxvY2l0eSBpbiBLUEguIEFkZGl0aW9uYWxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNlcnZlZCB2YWx1ZXM6IDB4MDAgTm8gZXZlbnQgMHhGRSBOb3Qgc3VwcG9ydGVkIDB4RkYgRmF1bHRcbiAgICAgKiBAcmV0dXJuIHtFbWVyZ2VuY3lFdmVudH1cbiAgICAgKi9cbiAgICBzZXRNYXhpbXVtQ2hhbmdlVmVsb2NpdHkgKHZlbG9jaXR5KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEVtZXJnZW5jeUV2ZW50LktFWV9NQVhJTVVNX0NIQU5HRV9WRUxPQ0lUWSwgdmVsb2NpdHkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0TWF4aW11bUNoYW5nZVZlbG9jaXR5ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEVtZXJnZW5jeUV2ZW50LktFWV9NQVhJTVVNX0NIQU5HRV9WRUxPQ0lUWSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfSBldmVudHMgLSBSZWZlcmVuY2VzIHNpZ25hbCBcIlZlZHNNdWx0aUV2bnRfRF9MdGNoZFwiLiBTZWUgVmVoaWNsZURhdGFFdmVudFN0YXR1cy5cbiAgICAgKiBAcmV0dXJuIHtFbWVyZ2VuY3lFdmVudH1cbiAgICAgKi9cbiAgICBzZXRNdWx0aXBsZUV2ZW50cyAoZXZlbnRzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIGV2ZW50cyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEVtZXJnZW5jeUV2ZW50LktFWV9NVUxUSVBMRV9FVkVOVFMsIGV2ZW50cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhRXZlbnRTdGF0dXN9XG4gICAgICovXG4gICAgZ2V0TXVsdGlwbGVFdmVudHMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFFdmVudFN0YXR1cywgRW1lcmdlbmN5RXZlbnQuS0VZX01VTFRJUExFX0VWRU5UUyk7XG4gICAgfVxufVxuXG5FbWVyZ2VuY3lFdmVudC5LRVlfRU1FUkdFTkNZX0VWRU5UX1RZUEUgPSAnZW1lcmdlbmN5RXZlbnRUeXBlJztcbkVtZXJnZW5jeUV2ZW50LktFWV9GVUVMX0NVVE9GRl9TVEFUVVMgPSAnZnVlbEN1dG9mZlN0YXR1cyc7XG5FbWVyZ2VuY3lFdmVudC5LRVlfUk9MTE9WRVJfRVZFTlQgPSAncm9sbG92ZXJFdmVudCc7XG5FbWVyZ2VuY3lFdmVudC5LRVlfTUFYSU1VTV9DSEFOR0VfVkVMT0NJVFkgPSAnbWF4aW11bUNoYW5nZVZlbG9jaXR5JztcbkVtZXJnZW5jeUV2ZW50LktFWV9NVUxUSVBMRV9FVkVOVFMgPSAnbXVsdGlwbGVFdmVudHMnO1xuXG5leHBvcnQgeyBFbWVyZ2VuY3lFdmVudCB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEVudW1lcmF0aW9uIHRoYXQgZGVzY3JpYmVzIHRoZSBzdGF0dXMgb2YgdGhlIHR1cm4gbGlnaHQgaW5kaWNhdG9yLlxuICogQHR5cGVkZWYge0VudW19IFR1cm5TaWduYWxcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIFR1cm5TaWduYWwgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHVybiBzaWduYWwgaXMgT0ZGXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgT0ZGICgpIHtcbiAgICAgICAgcmV0dXJuIFR1cm5TaWduYWwuX01BUC5PRkY7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTGVmdCB0dXJuIHNpZ25hbCBpcyBvblxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IExFRlQgKCkge1xuICAgICAgICByZXR1cm4gVHVyblNpZ25hbC5fTUFQLkxFRlQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmlnaHQgdHVybiBzaWduYWwgaXMgb25cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSSUdIVCAoKSB7XG4gICAgICAgIHJldHVybiBUdXJuU2lnbmFsLl9NQVAuUklHSFQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQm90aCBzaWduYWxzIChsZWZ0IGFuZCByaWdodCkgYXJlIG9uLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEJPVEggKCkge1xuICAgICAgICByZXR1cm4gVHVyblNpZ25hbC5fTUFQLkJPVEg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gVHVyblNpZ25hbC5fdmFsdWVGb3JLZXkoa2V5LCBUdXJuU2lnbmFsLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gVHVyblNpZ25hbC5fa2V5Rm9yVmFsdWUodmFsdWUsIFR1cm5TaWduYWwuX01BUCk7XG4gICAgfVxufVxuXG5UdXJuU2lnbmFsLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnT0ZGJzogJ09GRicsXG4gICAgJ0xFRlQnOiAnTEVGVCcsXG4gICAgJ1JJR0hUJzogJ1JJR0hUJyxcbiAgICAnQk9USCc6ICdCT1RIJyxcbn0pO1xuXG5leHBvcnQgeyBUdXJuU2lnbmFsIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogUmVmbGVjdHMgdGhlIHN0YXR1cyBvZiB0aGUgYW1iaWVudCBsaWdodCBzZW5zb3IuXG4gKiBAdHlwZWRlZiB7RW51bX0gQW1iaWVudExpZ2h0U3RhdHVzXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBBbWJpZW50TGlnaHRTdGF0dXMgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTklHSFQgKCkge1xuICAgICAgICByZXR1cm4gQW1iaWVudExpZ2h0U3RhdHVzLl9NQVAuTklHSFQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVFdJTElHSFRfMSAoKSB7XG4gICAgICAgIHJldHVybiBBbWJpZW50TGlnaHRTdGF0dXMuX01BUC5UV0lMSUdIVF8xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFRXSUxJR0hUXzIgKCkge1xuICAgICAgICByZXR1cm4gQW1iaWVudExpZ2h0U3RhdHVzLl9NQVAuVFdJTElHSFRfMjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBUV0lMSUdIVF8zICgpIHtcbiAgICAgICAgcmV0dXJuIEFtYmllbnRMaWdodFN0YXR1cy5fTUFQLlRXSUxJR0hUXzM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVFdJTElHSFRfNCAoKSB7XG4gICAgICAgIHJldHVybiBBbWJpZW50TGlnaHRTdGF0dXMuX01BUC5UV0lMSUdIVF80O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IERBWSAoKSB7XG4gICAgICAgIHJldHVybiBBbWJpZW50TGlnaHRTdGF0dXMuX01BUC5EQVk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQUxTX1VOS05PV04gKCkge1xuICAgICAgICByZXR1cm4gQW1iaWVudExpZ2h0U3RhdHVzLl9NQVAuQUxTX1VOS05PV047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSU5WQUxJRCAoKSB7XG4gICAgICAgIHJldHVybiBBbWJpZW50TGlnaHRTdGF0dXMuX01BUC5JTlZBTElEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIEFtYmllbnRMaWdodFN0YXR1cy5fdmFsdWVGb3JLZXkoa2V5LCBBbWJpZW50TGlnaHRTdGF0dXMuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBBbWJpZW50TGlnaHRTdGF0dXMuX2tleUZvclZhbHVlKHZhbHVlLCBBbWJpZW50TGlnaHRTdGF0dXMuX01BUCk7XG4gICAgfVxufVxuXG5BbWJpZW50TGlnaHRTdGF0dXMuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdOSUdIVCc6ICdOSUdIVCcsXG4gICAgJ1RXSUxJR0hUXzEnOiAnVFdJTElHSFRfMScsXG4gICAgJ1RXSUxJR0hUXzInOiAnVFdJTElHSFRfMicsXG4gICAgJ1RXSUxJR0hUXzMnOiAnVFdJTElHSFRfMycsXG4gICAgJ1RXSUxJR0hUXzQnOiAnVFdJTElHSFRfNCcsXG4gICAgJ0RBWSc6ICdEQVknLFxuICAgICdBTFNfVU5LTk9XTic6ICdVTktOT1dOJyxcbiAgICAnSU5WQUxJRCc6ICdJTlZBTElEJyxcbn0pO1xuXG5leHBvcnQgeyBBbWJpZW50TGlnaHRTdGF0dXMgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgQW1iaWVudExpZ2h0U3RhdHVzIH0gZnJvbSAnLi4vZW51bXMvQW1iaWVudExpZ2h0U3RhdHVzLmpzJztcblxuY2xhc3MgSGVhZExhbXBTdGF0dXMgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gb24gLSBTdGF0dXMgb2YgdGhlIGxvdyBiZWFtIGxhbXBzLiBSZWZlcmVuY2VzIHNpZ25hbCBcIkhlYWRMYW1wTG9BY3R2X0JfU3RhdFwiLlxuICAgICAqIEByZXR1cm4ge0hlYWRMYW1wU3RhdHVzfVxuICAgICAqL1xuICAgIHNldExvd0JlYW1zT24gKG9uKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEhlYWRMYW1wU3RhdHVzLktFWV9MT1dfQkVBTVNfT04sIG9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRMb3dCZWFtc09uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEhlYWRMYW1wU3RhdHVzLktFWV9MT1dfQkVBTVNfT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gb24gLSBTdGF0dXMgb2YgdGhlIGhpZ2ggYmVhbSBsYW1wcy4gUmVmZXJlbmNlcyBzaWduYWwgXCJIZWFkTGdodEhpT25fQl9TdGF0XCIuXG4gICAgICogQHJldHVybiB7SGVhZExhbXBTdGF0dXN9XG4gICAgICovXG4gICAgc2V0SGlnaEJlYW1zT24gKG9uKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEhlYWRMYW1wU3RhdHVzLktFWV9ISUdIX0JFQU1TX09OLCBvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0SGlnaEJlYW1zT24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoSGVhZExhbXBTdGF0dXMuS0VZX0hJR0hfQkVBTVNfT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7QW1iaWVudExpZ2h0U3RhdHVzfSBzdGF0dXMgLSBTdGF0dXMgb2YgdGhlIGFtYmllbnQgbGlnaHQgc2Vuc29yLlxuICAgICAqIEByZXR1cm4ge0hlYWRMYW1wU3RhdHVzfVxuICAgICAqL1xuICAgIHNldEFtYmllbnRMaWdodFNlbnNvclN0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEFtYmllbnRMaWdodFN0YXR1cywgc3RhdHVzKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoSGVhZExhbXBTdGF0dXMuS0VZX0FNQklFTlRfTElHSFRfU0VOU09SX1NUQVRVUywgc3RhdHVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7QW1iaWVudExpZ2h0U3RhdHVzfVxuICAgICAqL1xuICAgIGdldEFtYmllbnRMaWdodFNlbnNvclN0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChBbWJpZW50TGlnaHRTdGF0dXMsIEhlYWRMYW1wU3RhdHVzLktFWV9BTUJJRU5UX0xJR0hUX1NFTlNPUl9TVEFUVVMpO1xuICAgIH1cbn1cblxuSGVhZExhbXBTdGF0dXMuS0VZX0xPV19CRUFNU19PTiA9ICdsb3dCZWFtc09uJztcbkhlYWRMYW1wU3RhdHVzLktFWV9ISUdIX0JFQU1TX09OID0gJ2hpZ2hCZWFtc09uJztcbkhlYWRMYW1wU3RhdHVzLktFWV9BTUJJRU5UX0xJR0hUX1NFTlNPUl9TVEFUVVMgPSAnYW1iaWVudExpZ2h0U2Vuc29yU3RhdHVzJztcblxuZXhwb3J0IHsgSGVhZExhbXBTdGF0dXMgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBSZWZsZWN0cyB0aGUgY3VycmVudCBwcmltYXJ5IGF1ZGlvIHNvdXJjZSAoaWYgc2VsZWN0ZWQpLlxuICogQHR5cGVkZWYge0VudW19IFByaW1hcnlBdWRpb1NvdXJjZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgUHJpbWFyeUF1ZGlvU291cmNlIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5PX1NPVVJDRV9TRUxFQ1RFRCAoKSB7XG4gICAgICAgIHJldHVybiBQcmltYXJ5QXVkaW9Tb3VyY2UuX01BUC5OT19TT1VSQ0VfU0VMRUNURUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ0QgKCkge1xuICAgICAgICByZXR1cm4gUHJpbWFyeUF1ZGlvU291cmNlLl9NQVAuQ0Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVVNCICgpIHtcbiAgICAgICAgcmV0dXJuIFByaW1hcnlBdWRpb1NvdXJjZS5fTUFQLlVTQjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBVU0IyICgpIHtcbiAgICAgICAgcmV0dXJuIFByaW1hcnlBdWRpb1NvdXJjZS5fTUFQLlVTQjI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQkxVRVRPT1RIX1NURVJFT19CVFNUICgpIHtcbiAgICAgICAgcmV0dXJuIFByaW1hcnlBdWRpb1NvdXJjZS5fTUFQLkJMVUVUT09USF9TVEVSRU9fQlRTVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBMSU5FX0lOICgpIHtcbiAgICAgICAgcmV0dXJuIFByaW1hcnlBdWRpb1NvdXJjZS5fTUFQLkxJTkVfSU47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSVBPRCAoKSB7XG4gICAgICAgIHJldHVybiBQcmltYXJ5QXVkaW9Tb3VyY2UuX01BUC5JUE9EO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE1PQklMRV9BUFAgKCkge1xuICAgICAgICByZXR1cm4gUHJpbWFyeUF1ZGlvU291cmNlLl9NQVAuTU9CSUxFX0FQUDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBBTSAoKSB7XG4gICAgICAgIHJldHVybiBQcmltYXJ5QXVkaW9Tb3VyY2UuX01BUC5BTTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBGTSAoKSB7XG4gICAgICAgIHJldHVybiBQcmltYXJ5QXVkaW9Tb3VyY2UuX01BUC5GTTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBYTSAoKSB7XG4gICAgICAgIHJldHVybiBQcmltYXJ5QXVkaW9Tb3VyY2UuX01BUC5YTTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBEQUIgKCkge1xuICAgICAgICByZXR1cm4gUHJpbWFyeUF1ZGlvU291cmNlLl9NQVAuREFCO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFByaW1hcnlBdWRpb1NvdXJjZS5fdmFsdWVGb3JLZXkoa2V5LCBQcmltYXJ5QXVkaW9Tb3VyY2UuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBQcmltYXJ5QXVkaW9Tb3VyY2UuX2tleUZvclZhbHVlKHZhbHVlLCBQcmltYXJ5QXVkaW9Tb3VyY2UuX01BUCk7XG4gICAgfVxufVxuXG5QcmltYXJ5QXVkaW9Tb3VyY2UuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdOT19TT1VSQ0VfU0VMRUNURUQnOiAnTk9fU09VUkNFX1NFTEVDVEVEJyxcbiAgICAnQ0QnOiAnQ0QnLFxuICAgICdVU0InOiAnVVNCJyxcbiAgICAnVVNCMic6ICdVU0IyJyxcbiAgICAnQkxVRVRPT1RIX1NURVJFT19CVFNUJzogJ0JMVUVUT09USF9TVEVSRU9fQlRTVCcsXG4gICAgJ0xJTkVfSU4nOiAnTElORV9JTicsXG4gICAgJ0lQT0QnOiAnSVBPRCcsXG4gICAgJ01PQklMRV9BUFAnOiAnTU9CSUxFX0FQUCcsXG4gICAgJ0FNJzogJ0FNJyxcbiAgICAnRk0nOiAnRk0nLFxuICAgICdYTSc6ICdYTScsXG4gICAgJ0RBQic6ICdEQUInLFxufSk7XG5cbmV4cG9ydCB7IFByaW1hcnlBdWRpb1NvdXJjZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIFJlZmxlY3RzIHRoZSByZXBvcnRlZCBiYXR0ZXJ5IHN0YXR1cyBvZiB0aGUgY29ubmVjdGVkIGRldmljZSwgaWYgcmVwb3J0ZWQuXG4gKiBAdHlwZWRlZiB7RW51bX0gRGV2aWNlTGV2ZWxTdGF0dXNcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIERldmljZUxldmVsU3RhdHVzIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFpFUk9fTEVWRUxfQkFSUyAoKSB7XG4gICAgICAgIHJldHVybiBEZXZpY2VMZXZlbFN0YXR1cy5fTUFQLlpFUk9fTEVWRUxfQkFSUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBPTkVfTEVWRUxfQkFSUyAoKSB7XG4gICAgICAgIHJldHVybiBEZXZpY2VMZXZlbFN0YXR1cy5fTUFQLk9ORV9MRVZFTF9CQVJTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFRXT19MRVZFTF9CQVJTICgpIHtcbiAgICAgICAgcmV0dXJuIERldmljZUxldmVsU3RhdHVzLl9NQVAuVFdPX0xFVkVMX0JBUlM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVEhSRUVfTEVWRUxfQkFSUyAoKSB7XG4gICAgICAgIHJldHVybiBEZXZpY2VMZXZlbFN0YXR1cy5fTUFQLlRIUkVFX0xFVkVMX0JBUlM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRk9VUl9MRVZFTF9CQVJTICgpIHtcbiAgICAgICAgcmV0dXJuIERldmljZUxldmVsU3RhdHVzLl9NQVAuRk9VUl9MRVZFTF9CQVJTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5PVF9QUk9WSURFRCAoKSB7XG4gICAgICAgIHJldHVybiBEZXZpY2VMZXZlbFN0YXR1cy5fTUFQLk5PVF9QUk9WSURFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBEZXZpY2VMZXZlbFN0YXR1cy5fdmFsdWVGb3JLZXkoa2V5LCBEZXZpY2VMZXZlbFN0YXR1cy5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIERldmljZUxldmVsU3RhdHVzLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgRGV2aWNlTGV2ZWxTdGF0dXMuX01BUCk7XG4gICAgfVxufVxuXG5EZXZpY2VMZXZlbFN0YXR1cy5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1pFUk9fTEVWRUxfQkFSUyc6ICdaRVJPX0xFVkVMX0JBUlMnLFxuICAgICdPTkVfTEVWRUxfQkFSUyc6ICdPTkVfTEVWRUxfQkFSUycsXG4gICAgJ1RXT19MRVZFTF9CQVJTJzogJ1RXT19MRVZFTF9CQVJTJyxcbiAgICAnVEhSRUVfTEVWRUxfQkFSUyc6ICdUSFJFRV9MRVZFTF9CQVJTJyxcbiAgICAnRk9VUl9MRVZFTF9CQVJTJzogJ0ZPVVJfTEVWRUxfQkFSUycsXG4gICAgJ05PVF9QUk9WSURFRCc6ICdOT1RfUFJPVklERUQnLFxufSk7XG5cbmV4cG9ydCB7IERldmljZUxldmVsU3RhdHVzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IFByaW1hcnlBdWRpb1NvdXJjZSB9IGZyb20gJy4uL2VudW1zL1ByaW1hcnlBdWRpb1NvdXJjZS5qcyc7XG5pbXBvcnQgeyBEZXZpY2VMZXZlbFN0YXR1cyB9IGZyb20gJy4uL2VudW1zL0RldmljZUxldmVsU3RhdHVzLmpzJztcblxuY2xhc3MgRGV2aWNlU3RhdHVzIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IG9uIC0gUmVmZXJlbmNlcyBzaWduYWwgXCJDUE1fVm9pY2VSZWNfU1RBVFwiLlxuICAgICAqIEByZXR1cm4ge0RldmljZVN0YXR1c31cbiAgICAgKi9cbiAgICBzZXRWb2ljZVJlY09uIChvbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihEZXZpY2VTdGF0dXMuS0VZX1ZPSUNFX1JFQ19PTiwgb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFZvaWNlUmVjT24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoRGV2aWNlU3RhdHVzLktFWV9WT0lDRV9SRUNfT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gb24gLSBSZWZlcmVuY2VzIHNpZ25hbCBcIkJUX0lDT05cIi5cbiAgICAgKiBAcmV0dXJuIHtEZXZpY2VTdGF0dXN9XG4gICAgICovXG4gICAgc2V0QnRJY29uT24gKG9uKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKERldmljZVN0YXR1cy5LRVlfQlRfSUNPTl9PTiwgb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEJ0SWNvbk9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKERldmljZVN0YXR1cy5LRVlfQlRfSUNPTl9PTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhY3RpdmUgLSBSZWZlcmVuY2VzIHNpZ25hbCBcIkNQTV9DYWxsX0FjdGl2ZV9TVEFUXCIuXG4gICAgICogQHJldHVybiB7RGV2aWNlU3RhdHVzfVxuICAgICAqL1xuICAgIHNldENhbGxBY3RpdmUgKGFjdGl2ZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihEZXZpY2VTdGF0dXMuS0VZX0NBTExfQUNUSVZFLCBhY3RpdmUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldENhbGxBY3RpdmUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoRGV2aWNlU3RhdHVzLktFWV9DQUxMX0FDVElWRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSByb2FtaW5nIC0gUmVmZXJlbmNlcyBzaWduYWwgXCJDUE1fUGhvbmVfUm9hbWluZ19TVEFUXCIuXG4gICAgICogQHJldHVybiB7RGV2aWNlU3RhdHVzfVxuICAgICAqL1xuICAgIHNldFBob25lUm9hbWluZyAocm9hbWluZykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihEZXZpY2VTdGF0dXMuS0VZX1BIT05FX1JPQU1JTkcsIHJvYW1pbmcpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFBob25lUm9hbWluZyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihEZXZpY2VTdGF0dXMuS0VZX1BIT05FX1JPQU1JTkcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlIC0gUmVmZXJlbmNlcyBzaWduYWwgXCJDUE1fVGV4dE1zZ19BVkFMXCIuXG4gICAgICogQHJldHVybiB7RGV2aWNlU3RhdHVzfVxuICAgICAqL1xuICAgIHNldFRleHRNc2dBdmFpbGFibGUgKGF2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihEZXZpY2VTdGF0dXMuS0VZX1RFWFRfTVNHX0FWQUlMQUJMRSwgYXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRUZXh0TXNnQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKERldmljZVN0YXR1cy5LRVlfVEVYVF9NU0dfQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0RldmljZUxldmVsU3RhdHVzfSBzdGF0dXMgLSBEZXZpY2UgYmF0dGVyeSBsZXZlbCBzdGF0dXMuIFJlZmVyZW5jZXMgc2lnbmFsIFwiQ1BNX0JhdHRfTGV2ZWxfU1RBVFwiLiBTZWVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXZpY2VMZXZlbFN0YXR1cy5cbiAgICAgKiBAcmV0dXJuIHtEZXZpY2VTdGF0dXN9XG4gICAgICovXG4gICAgc2V0QmF0dExldmVsU3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoRGV2aWNlTGV2ZWxTdGF0dXMsIHN0YXR1cyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKERldmljZVN0YXR1cy5LRVlfQkFUVF9MRVZFTF9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0RldmljZUxldmVsU3RhdHVzfVxuICAgICAqL1xuICAgIGdldEJhdHRMZXZlbFN0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChEZXZpY2VMZXZlbFN0YXR1cywgRGV2aWNlU3RhdHVzLktFWV9CQVRUX0xFVkVMX1NUQVRVUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBtdXRlZCAtIFJlZmVyZW5jZXMgc2lnbmFsIFwiQ1BNX1N0ZXJlb19BdWRpb19PdXRwdXRcIi5cbiAgICAgKiBAcmV0dXJuIHtEZXZpY2VTdGF0dXN9XG4gICAgICovXG4gICAgc2V0U3RlcmVvQXVkaW9PdXRwdXRNdXRlZCAobXV0ZWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGV2aWNlU3RhdHVzLktFWV9TVEVSRU9fQVVESU9fT1VUUFVUX01VVEVELCBtdXRlZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0U3RlcmVvQXVkaW9PdXRwdXRNdXRlZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihEZXZpY2VTdGF0dXMuS0VZX1NURVJFT19BVURJT19PVVRQVVRfTVVURUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gbXV0ZWQgLSBSZWZlcmVuY2VzIHNpZ25hbCBcIkNQTV9Nb25vX0F1ZGlvX091dHB1dFwiLlxuICAgICAqIEByZXR1cm4ge0RldmljZVN0YXR1c31cbiAgICAgKi9cbiAgICBzZXRNb25vQXVkaW9PdXRwdXRNdXRlZCAobXV0ZWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGV2aWNlU3RhdHVzLktFWV9NT05PX0FVRElPX09VVFBVVF9NVVRFRCwgbXV0ZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldE1vbm9BdWRpb091dHB1dE11dGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKERldmljZVN0YXR1cy5LRVlfTU9OT19BVURJT19PVVRQVVRfTVVURUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RGV2aWNlTGV2ZWxTdGF0dXN9IHN0YXR1cyAtIERldmljZSBzaWduYWwgbGV2ZWwgc3RhdHVzLiBSZWZlcmVuY2VzIHNpZ25hbCBcIkNQTV9TaWduYWxfU3RyZW5ndGhfU1RBVFwiLiBTZWVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXZpY2VMZXZlbFN0YXR1cy5cbiAgICAgKiBAcmV0dXJuIHtEZXZpY2VTdGF0dXN9XG4gICAgICovXG4gICAgc2V0U2lnbmFsTGV2ZWxTdGF0dXMgKHN0YXR1cykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShEZXZpY2VMZXZlbFN0YXR1cywgc3RhdHVzKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGV2aWNlU3RhdHVzLktFWV9TSUdOQUxfTEVWRUxfU1RBVFVTLCBzdGF0dXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtEZXZpY2VMZXZlbFN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRTaWduYWxMZXZlbFN0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChEZXZpY2VMZXZlbFN0YXR1cywgRGV2aWNlU3RhdHVzLktFWV9TSUdOQUxfTEVWRUxfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ByaW1hcnlBdWRpb1NvdXJjZX0gc291cmNlIC0gUmVmZXJlbmNlcyBzaWduYWwgXCJDUE1fU3RlcmVvX1BBU19Tb3VyY2VcIi4gU2VlIFByaW1hcnlBdWRpb1NvdXJjZS5cbiAgICAgKiBAcmV0dXJuIHtEZXZpY2VTdGF0dXN9XG4gICAgICovXG4gICAgc2V0UHJpbWFyeUF1ZGlvU291cmNlIChzb3VyY2UpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoUHJpbWFyeUF1ZGlvU291cmNlLCBzb3VyY2UpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihEZXZpY2VTdGF0dXMuS0VZX1BSSU1BUllfQVVESU9fU09VUkNFLCBzb3VyY2UpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtQcmltYXJ5QXVkaW9Tb3VyY2V9XG4gICAgICovXG4gICAgZ2V0UHJpbWFyeUF1ZGlvU291cmNlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFByaW1hcnlBdWRpb1NvdXJjZSwgRGV2aWNlU3RhdHVzLktFWV9QUklNQVJZX0FVRElPX1NPVVJDRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhY3RpdmUgLSBSZWZlcmVuY2VzIHNpZ25hbCBcImVDYWxsX0V2ZW50XCIuXG4gICAgICogQHJldHVybiB7RGV2aWNlU3RhdHVzfVxuICAgICAqL1xuICAgIHNldEVDYWxsRXZlbnRBY3RpdmUgKGFjdGl2ZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihEZXZpY2VTdGF0dXMuS0VZX0VfQ0FMTF9FVkVOVF9BQ1RJVkUsIGFjdGl2ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0RUNhbGxFdmVudEFjdGl2ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihEZXZpY2VTdGF0dXMuS0VZX0VfQ0FMTF9FVkVOVF9BQ1RJVkUpO1xuICAgIH1cbn1cblxuRGV2aWNlU3RhdHVzLktFWV9WT0lDRV9SRUNfT04gPSAndm9pY2VSZWNPbic7XG5EZXZpY2VTdGF0dXMuS0VZX0JUX0lDT05fT04gPSAnYnRJY29uT24nO1xuRGV2aWNlU3RhdHVzLktFWV9DQUxMX0FDVElWRSA9ICdjYWxsQWN0aXZlJztcbkRldmljZVN0YXR1cy5LRVlfUEhPTkVfUk9BTUlORyA9ICdwaG9uZVJvYW1pbmcnO1xuRGV2aWNlU3RhdHVzLktFWV9URVhUX01TR19BVkFJTEFCTEUgPSAndGV4dE1zZ0F2YWlsYWJsZSc7XG5EZXZpY2VTdGF0dXMuS0VZX0JBVFRfTEVWRUxfU1RBVFVTID0gJ2JhdHRMZXZlbFN0YXR1cyc7XG5EZXZpY2VTdGF0dXMuS0VZX1NURVJFT19BVURJT19PVVRQVVRfTVVURUQgPSAnc3RlcmVvQXVkaW9PdXRwdXRNdXRlZCc7XG5EZXZpY2VTdGF0dXMuS0VZX01PTk9fQVVESU9fT1VUUFVUX01VVEVEID0gJ21vbm9BdWRpb091dHB1dE11dGVkJztcbkRldmljZVN0YXR1cy5LRVlfU0lHTkFMX0xFVkVMX1NUQVRVUyA9ICdzaWduYWxMZXZlbFN0YXR1cyc7XG5EZXZpY2VTdGF0dXMuS0VZX1BSSU1BUllfQVVESU9fU09VUkNFID0gJ3ByaW1hcnlBdWRpb1NvdXJjZSc7XG5EZXZpY2VTdGF0dXMuS0VZX0VfQ0FMTF9FVkVOVF9BQ1RJVkUgPSAnZUNhbGxFdmVudEFjdGl2ZSc7XG5cbmV4cG9ydCB7IERldmljZVN0YXR1cyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIFJlZmxlY3RzIHRoZSBzdGF0dXMgb2YgdGhlIHdpcGVycy5cbiAqIEB0eXBlZGVmIHtFbnVtfSBXaXBlclN0YXR1c1xuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgV2lwZXJTdGF0dXMgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgT0ZGICgpIHtcbiAgICAgICAgcmV0dXJuIFdpcGVyU3RhdHVzLl9NQVAuT0ZGO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFVVE9fT0ZGICgpIHtcbiAgICAgICAgcmV0dXJuIFdpcGVyU3RhdHVzLl9NQVAuQVVUT19PRkY7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgT0ZGX01PVklORyAoKSB7XG4gICAgICAgIHJldHVybiBXaXBlclN0YXR1cy5fTUFQLk9GRl9NT1ZJTkc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTUFOX0lOVF9PRkYgKCkge1xuICAgICAgICByZXR1cm4gV2lwZXJTdGF0dXMuX01BUC5NQU5fSU5UX09GRjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBNQU5fSU5UX09OICgpIHtcbiAgICAgICAgcmV0dXJuIFdpcGVyU3RhdHVzLl9NQVAuTUFOX0lOVF9PTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBNQU5fTE9XICgpIHtcbiAgICAgICAgcmV0dXJuIFdpcGVyU3RhdHVzLl9NQVAuTUFOX0xPVztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBNQU5fSElHSCAoKSB7XG4gICAgICAgIHJldHVybiBXaXBlclN0YXR1cy5fTUFQLk1BTl9ISUdIO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE1BTl9GTElDSyAoKSB7XG4gICAgICAgIHJldHVybiBXaXBlclN0YXR1cy5fTUFQLk1BTl9GTElDSztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBXQVNIICgpIHtcbiAgICAgICAgcmV0dXJuIFdpcGVyU3RhdHVzLl9NQVAuV0FTSDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBBVVRPX0xPVyAoKSB7XG4gICAgICAgIHJldHVybiBXaXBlclN0YXR1cy5fTUFQLkFVVE9fTE9XO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFVVE9fSElHSCAoKSB7XG4gICAgICAgIHJldHVybiBXaXBlclN0YXR1cy5fTUFQLkFVVE9fSElHSDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDT1VSVEVTWVdJUEUgKCkge1xuICAgICAgICByZXR1cm4gV2lwZXJTdGF0dXMuX01BUC5DT1VSVEVTWVdJUEU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQVVUT19BREpVU1QgKCkge1xuICAgICAgICByZXR1cm4gV2lwZXJTdGF0dXMuX01BUC5BVVRPX0FESlVTVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTVEFMTEVEICgpIHtcbiAgICAgICAgcmV0dXJuIFdpcGVyU3RhdHVzLl9NQVAuU1RBTExFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOT19EQVRBX0VYSVNUUyAoKSB7XG4gICAgICAgIHJldHVybiBXaXBlclN0YXR1cy5fTUFQLk5PX0RBVEFfRVhJU1RTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFdpcGVyU3RhdHVzLl92YWx1ZUZvcktleShrZXksIFdpcGVyU3RhdHVzLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gV2lwZXJTdGF0dXMuX2tleUZvclZhbHVlKHZhbHVlLCBXaXBlclN0YXR1cy5fTUFQKTtcbiAgICB9XG59XG5cbldpcGVyU3RhdHVzLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnT0ZGJzogJ09GRicsXG4gICAgJ0FVVE9fT0ZGJzogJ0FVVE9fT0ZGJyxcbiAgICAnT0ZGX01PVklORyc6ICdPRkZfTU9WSU5HJyxcbiAgICAnTUFOX0lOVF9PRkYnOiAnTUFOX0lOVF9PRkYnLFxuICAgICdNQU5fSU5UX09OJzogJ01BTl9JTlRfT04nLFxuICAgICdNQU5fTE9XJzogJ01BTl9MT1cnLFxuICAgICdNQU5fSElHSCc6ICdNQU5fSElHSCcsXG4gICAgJ01BTl9GTElDSyc6ICdNQU5fRkxJQ0snLFxuICAgICdXQVNIJzogJ1dBU0gnLFxuICAgICdBVVRPX0xPVyc6ICdBVVRPX0xPVycsXG4gICAgJ0FVVE9fSElHSCc6ICdBVVRPX0hJR0gnLFxuICAgICdDT1VSVEVTWVdJUEUnOiAnQ09VUlRFU1lXSVBFJyxcbiAgICAnQVVUT19BREpVU1QnOiAnQVVUT19BREpVU1QnLFxuICAgICdTVEFMTEVEJzogJ1NUQUxMRUQnLFxuICAgICdOT19EQVRBX0VYSVNUUyc6ICdOT19EQVRBX0VYSVNUUycsXG59KTtcblxuZXhwb3J0IHsgV2lwZXJTdGF0dXMgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gRWxlY3Ryb25pY1BhcmtCcmFrZVN0YXR1c1xuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgRWxlY3Ryb25pY1BhcmtCcmFrZVN0YXR1cyBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJrIGJyYWtlIGFjdHVhdG9ycyBoYXZlIGJlZW4gZnVsbHkgYXBwbGllZC5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDTE9TRUQgKCkge1xuICAgICAgICByZXR1cm4gRWxlY3Ryb25pY1BhcmtCcmFrZVN0YXR1cy5fTUFQLkNMT1NFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJrIGJyYWtlIGFjdHVhdG9ycyBhcmUgdHJhbnNpdGlvbmluZyB0byBlaXRoZXIgQXBwbHkvQ2xvc2VkIG9yIFJlbGVhc2UvT3BlbiBzdGF0ZS5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBUUkFOU0lUSU9OICgpIHtcbiAgICAgICAgcmV0dXJuIEVsZWN0cm9uaWNQYXJrQnJha2VTdGF0dXMuX01BUC5UUkFOU0lUSU9OO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcmsgYnJha2UgYWN0dWF0b3JzIGFyZSByZWxlYXNlZC5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBPUEVOICgpIHtcbiAgICAgICAgcmV0dXJuIEVsZWN0cm9uaWNQYXJrQnJha2VTdGF0dXMuX01BUC5PUEVOO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdoZW4gZHJpdmVyIHB1bGxzIHRoZSBFbGVjdHJvbmljIFBhcmsgQnJha2Ugc3dpdGNoIHdoaWxlIGRyaXZpbmcgXCJhdCBzcGVlZFwiLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IERSSVZFX0FDVElWRSAoKSB7XG4gICAgICAgIHJldHVybiBFbGVjdHJvbmljUGFya0JyYWtlU3RhdHVzLl9NQVAuRFJJVkVfQUNUSVZFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdoZW4gc3lzdGVtIGhhcyBhIGZhdWx0IG9yIGlzIHVuZGVyIG1haW50ZW5hbmNlLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEZBVUxUICgpIHtcbiAgICAgICAgcmV0dXJuIEVsZWN0cm9uaWNQYXJrQnJha2VTdGF0dXMuX01BUC5GQVVMVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBFbGVjdHJvbmljUGFya0JyYWtlU3RhdHVzLl92YWx1ZUZvcktleShrZXksIEVsZWN0cm9uaWNQYXJrQnJha2VTdGF0dXMuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBFbGVjdHJvbmljUGFya0JyYWtlU3RhdHVzLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgRWxlY3Ryb25pY1BhcmtCcmFrZVN0YXR1cy5fTUFQKTtcbiAgICB9XG59XG5cbkVsZWN0cm9uaWNQYXJrQnJha2VTdGF0dXMuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdDTE9TRUQnOiAnQ0xPU0VEJyxcbiAgICAnVFJBTlNJVElPTic6ICdUUkFOU0lUSU9OJyxcbiAgICAnT1BFTic6ICdPUEVOJyxcbiAgICAnRFJJVkVfQUNUSVZFJzogJ0RSSVZFX0FDVElWRScsXG4gICAgJ0ZBVUxUJzogJ0ZBVUxUJyxcbn0pO1xuXG5leHBvcnQgeyBFbGVjdHJvbmljUGFya0JyYWtlU3RhdHVzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogUmVmbGVjdHMgdGhlIHN0YXR1cyBvZiBhIGJpbmFyeSB2ZWhpY2xlIGRhdGEgaXRlbS5cbiAqIEB0eXBlZGVmIHtFbnVtfSBWZWhpY2xlRGF0YVN0YXR1c1xuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgVmVoaWNsZURhdGFTdGF0dXMgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVkRTX05PX0RBVEFfRVhJU1RTICgpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhU3RhdHVzLl9NQVAuVkRTX05PX0RBVEFfRVhJU1RTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZEU19PRkYgKCkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFTdGF0dXMuX01BUC5WRFNfT0ZGO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZEU19PTiAoKSB7XG4gICAgICAgIHJldHVybiBWZWhpY2xlRGF0YVN0YXR1cy5fTUFQLlZEU19PTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBWZWhpY2xlRGF0YVN0YXR1cy5fdmFsdWVGb3JLZXkoa2V5LCBWZWhpY2xlRGF0YVN0YXR1cy5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhU3RhdHVzLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgVmVoaWNsZURhdGFTdGF0dXMuX01BUCk7XG4gICAgfVxufVxuXG5WZWhpY2xlRGF0YVN0YXR1cy5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1ZEU19OT19EQVRBX0VYSVNUUyc6ICdOT19EQVRBX0VYSVNUUycsXG4gICAgJ1ZEU19PRkYnOiAnT0ZGJyxcbiAgICAnVkRTX09OJzogJ09OJyxcbn0pO1xuXG5leHBvcnQgeyBWZWhpY2xlRGF0YVN0YXR1cyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBWZWhpY2xlRGF0YVN0YXR1cyB9IGZyb20gJy4uL2VudW1zL1ZlaGljbGVEYXRhU3RhdHVzLmpzJztcblxuY2xhc3MgTXlLZXkgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFTdGF0dXN9IGU5MTFvdmVycmlkZSAtIEluZGljYXRlcyB3aGV0aGVyIGU5MTEgb3ZlcnJpZGUgaXMgb24uIFJlZmVyZW5jZXMgc2lnbmFsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJNeUtleV9lOTExT3ZlcnJpZGVfU3RcIi4gU2VlIFZlaGljbGVEYXRhU3RhdHVzLlxuICAgICAqIEByZXR1cm4ge015S2V5fVxuICAgICAqL1xuICAgIHNldEU5MTFPdmVycmlkZSAoZTkxMW92ZXJyaWRlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhU3RhdHVzLCBlOTExb3ZlcnJpZGUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihNeUtleS5LRVlfRTkxMU9WRVJSSURFLCBlOTExb3ZlcnJpZGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YVN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRFOTExT3ZlcnJpZGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFTdGF0dXMsIE15S2V5LktFWV9FOTExT1ZFUlJJREUpO1xuICAgIH1cbn1cblxuTXlLZXkuS0VZX0U5MTFPVkVSUklERSA9ICdlOTExT3ZlcnJpZGUnO1xuXG5leHBvcnQgeyBNeUtleSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIFRoZSBsaXN0IG9mIHBvdGVudGlhbCBjb21wYXNzIGRpcmVjdGlvbnNcbiAqIEB0eXBlZGVmIHtFbnVtfSBDb21wYXNzRGlyZWN0aW9uXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBDb21wYXNzRGlyZWN0aW9uIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5PUlRIICgpIHtcbiAgICAgICAgcmV0dXJuIENvbXBhc3NEaXJlY3Rpb24uX01BUC5OT1JUSDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOT1JUSFdFU1QgKCkge1xuICAgICAgICByZXR1cm4gQ29tcGFzc0RpcmVjdGlvbi5fTUFQLk5PUlRIV0VTVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBXRVNUICgpIHtcbiAgICAgICAgcmV0dXJuIENvbXBhc3NEaXJlY3Rpb24uX01BUC5XRVNUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNPVVRIV0VTVCAoKSB7XG4gICAgICAgIHJldHVybiBDb21wYXNzRGlyZWN0aW9uLl9NQVAuU09VVEhXRVNUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNPVVRIICgpIHtcbiAgICAgICAgcmV0dXJuIENvbXBhc3NEaXJlY3Rpb24uX01BUC5TT1VUSDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTT1VUSEVBU1QgKCkge1xuICAgICAgICByZXR1cm4gQ29tcGFzc0RpcmVjdGlvbi5fTUFQLlNPVVRIRUFTVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFQVNUICgpIHtcbiAgICAgICAgcmV0dXJuIENvbXBhc3NEaXJlY3Rpb24uX01BUC5FQVNUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5PUlRIRUFTVCAoKSB7XG4gICAgICAgIHJldHVybiBDb21wYXNzRGlyZWN0aW9uLl9NQVAuTk9SVEhFQVNUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIENvbXBhc3NEaXJlY3Rpb24uX3ZhbHVlRm9yS2V5KGtleSwgQ29tcGFzc0RpcmVjdGlvbi5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIENvbXBhc3NEaXJlY3Rpb24uX2tleUZvclZhbHVlKHZhbHVlLCBDb21wYXNzRGlyZWN0aW9uLl9NQVApO1xuICAgIH1cbn1cblxuQ29tcGFzc0RpcmVjdGlvbi5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ05PUlRIJzogJ05PUlRIJyxcbiAgICAnTk9SVEhXRVNUJzogJ05PUlRIV0VTVCcsXG4gICAgJ1dFU1QnOiAnV0VTVCcsXG4gICAgJ1NPVVRIV0VTVCc6ICdTT1VUSFdFU1QnLFxuICAgICdTT1VUSCc6ICdTT1VUSCcsXG4gICAgJ1NPVVRIRUFTVCc6ICdTT1VUSEVBU1QnLFxuICAgICdFQVNUJzogJ0VBU1QnLFxuICAgICdOT1JUSEVBU1QnOiAnTk9SVEhFQVNUJyxcbn0pO1xuXG5leHBvcnQgeyBDb21wYXNzRGlyZWN0aW9uIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogVGhlIHN1cHBvcnRlZCBkaW1lbnNpb25zIG9mIHRoZSBHUFNcbiAqIEB0eXBlZGVmIHtFbnVtfSBEaW1lbnNpb25cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIERpbWVuc2lvbiBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBObyBHUFMgYXQgYWxsXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRGltZW5zaW9uX05PX0ZJWCAoKSB7XG4gICAgICAgIHJldHVybiBEaW1lbnNpb24uX01BUC5EaW1lbnNpb25fTk9fRklYO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIExvbmdpdHVkZSBhbmQgbGF0aXR1ZGVcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBEaW1lbnNpb25fMkQgKCkge1xuICAgICAgICByZXR1cm4gRGltZW5zaW9uLl9NQVAuRGltZW5zaW9uXzJEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIExvbmdpdHVkZSBhbmQgbGF0aXR1ZGUgYW5kIGFsdGl0dWRlXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRGltZW5zaW9uXzNEICgpIHtcbiAgICAgICAgcmV0dXJuIERpbWVuc2lvbi5fTUFQLkRpbWVuc2lvbl8zRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBEaW1lbnNpb24uX3ZhbHVlRm9yS2V5KGtleSwgRGltZW5zaW9uLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gRGltZW5zaW9uLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgRGltZW5zaW9uLl9NQVApO1xuICAgIH1cbn1cblxuRGltZW5zaW9uLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnRGltZW5zaW9uX05PX0ZJWCc6ICdOT19GSVgnLFxuICAgICdEaW1lbnNpb25fMkQnOiAnMkQnLFxuICAgICdEaW1lbnNpb25fM0QnOiAnM0QnLFxufSk7XG5cbmV4cG9ydCB7IERpbWVuc2lvbiB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBDb21wYXNzRGlyZWN0aW9uIH0gZnJvbSAnLi4vZW51bXMvQ29tcGFzc0RpcmVjdGlvbi5qcyc7XG5pbXBvcnQgeyBEaW1lbnNpb24gfSBmcm9tICcuLi9lbnVtcy9EaW1lbnNpb24uanMnO1xuXG4vKipcbiAqIFN0cnVjdCB3aXRoIHRoZSBHUFMgZGF0YS5cbiAqL1xuY2xhc3MgR1BTRGF0YSBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGRlZ3JlZXNcbiAgICAgKiBAcmV0dXJuIHtHUFNEYXRhfVxuICAgICAqL1xuICAgIHNldExvbmdpdHVkZURlZ3JlZXMgKGRlZ3JlZXMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR1BTRGF0YS5LRVlfTE9OR0lUVURFX0RFR1JFRVMsIGRlZ3JlZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0TG9uZ2l0dWRlRGVncmVlcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHUFNEYXRhLktFWV9MT05HSVRVREVfREVHUkVFUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGRlZ3JlZXNcbiAgICAgKiBAcmV0dXJuIHtHUFNEYXRhfVxuICAgICAqL1xuICAgIHNldExhdGl0dWRlRGVncmVlcyAoZGVncmVlcykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHUFNEYXRhLktFWV9MQVRJVFVERV9ERUdSRUVTLCBkZWdyZWVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldExhdGl0dWRlRGVncmVlcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHUFNEYXRhLktFWV9MQVRJVFVERV9ERUdSRUVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geWVhciAtIFRoZSBjdXJyZW50IFVUQyB5ZWFyLlxuICAgICAqIEByZXR1cm4ge0dQU0RhdGF9XG4gICAgICovXG4gICAgc2V0VXRjWWVhciAoeWVhcikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHUFNEYXRhLktFWV9VVENfWUVBUiwgeWVhcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRVdGNZZWFyICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdQU0RhdGEuS0VZX1VUQ19ZRUFSKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbW9udGggLSBUaGUgY3VycmVudCBVVEMgbW9udGguXG4gICAgICogQHJldHVybiB7R1BTRGF0YX1cbiAgICAgKi9cbiAgICBzZXRVdGNNb250aCAobW9udGgpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR1BTRGF0YS5LRVlfVVRDX01PTlRILCBtb250aCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRVdGNNb250aCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHUFNEYXRhLktFWV9VVENfTU9OVEgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBkYXkgLSBUaGUgY3VycmVudCBVVEMgZGF5LlxuICAgICAqIEByZXR1cm4ge0dQU0RhdGF9XG4gICAgICovXG4gICAgc2V0VXRjRGF5IChkYXkpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR1BTRGF0YS5LRVlfVVRDX0RBWSwgZGF5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFV0Y0RheSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHUFNEYXRhLktFWV9VVENfREFZKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaG91cnMgLSBUaGUgY3VycmVudCBVVEMgaG91ci5cbiAgICAgKiBAcmV0dXJuIHtHUFNEYXRhfVxuICAgICAqL1xuICAgIHNldFV0Y0hvdXJzIChob3Vycykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHUFNEYXRhLktFWV9VVENfSE9VUlMsIGhvdXJzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFV0Y0hvdXJzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdQU0RhdGEuS0VZX1VUQ19IT1VSUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG1pbnV0ZXMgLSBUaGUgY3VycmVudCBVVEMgbWludXRlLlxuICAgICAqIEByZXR1cm4ge0dQU0RhdGF9XG4gICAgICovXG4gICAgc2V0VXRjTWludXRlcyAobWludXRlcykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHUFNEYXRhLktFWV9VVENfTUlOVVRFUywgbWludXRlcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRVdGNNaW51dGVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdQU0RhdGEuS0VZX1VUQ19NSU5VVEVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc2Vjb25kcyAtIFRoZSBjdXJyZW50IFVUQyBzZWNvbmQuXG4gICAgICogQHJldHVybiB7R1BTRGF0YX1cbiAgICAgKi9cbiAgICBzZXRVdGNTZWNvbmRzIChzZWNvbmRzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdQU0RhdGEuS0VZX1VUQ19TRUNPTkRTLCBzZWNvbmRzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFV0Y1NlY29uZHMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR1BTRGF0YS5LRVlfVVRDX1NFQ09ORFMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Q29tcGFzc0RpcmVjdGlvbn0gZGlyZWN0aW9uIC0gU2VlIENvbXBhc3NEaXJlY3Rpb24uXG4gICAgICogQHJldHVybiB7R1BTRGF0YX1cbiAgICAgKi9cbiAgICBzZXRDb21wYXNzRGlyZWN0aW9uIChkaXJlY3Rpb24pIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQ29tcGFzc0RpcmVjdGlvbiwgZGlyZWN0aW9uKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR1BTRGF0YS5LRVlfQ09NUEFTU19ESVJFQ1RJT04sIGRpcmVjdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0NvbXBhc3NEaXJlY3Rpb259XG4gICAgICovXG4gICAgZ2V0Q29tcGFzc0RpcmVjdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChDb21wYXNzRGlyZWN0aW9uLCBHUFNEYXRhLktFWV9DT01QQVNTX0RJUkVDVElPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHBkb3AgLSBQRE9QLiBJZiB1bmRlZmluZWQgb3IgdW5hdmFpbGFibGUsIHRoZW4gdmFsdWUgc2hhbGwgYmUgc2V0IHRvIDAuXG4gICAgICogQHJldHVybiB7R1BTRGF0YX1cbiAgICAgKi9cbiAgICBzZXRQZG9wIChwZG9wKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdQU0RhdGEuS0VZX1BET1AsIHBkb3ApO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0UGRvcCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHUFNEYXRhLktFWV9QRE9QKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaGRvcCAtIEhET1AuIElmIHZhbHVlIGlzIHVua25vd24sIHZhbHVlIHNoYWxsIGJlIHNldCB0byAwLlxuICAgICAqIEByZXR1cm4ge0dQU0RhdGF9XG4gICAgICovXG4gICAgc2V0SGRvcCAoaGRvcCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHUFNEYXRhLktFWV9IRE9QLCBoZG9wKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldEhkb3AgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR1BTRGF0YS5LRVlfSERPUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHZkb3AgLSBWRE9QLiBJZiB2YWx1ZSBpcyB1bmtub3duLCB2YWx1ZSBzaGFsbCBiZSBzZXQgdG8gMC5cbiAgICAgKiBAcmV0dXJuIHtHUFNEYXRhfVxuICAgICAqL1xuICAgIHNldFZkb3AgKHZkb3ApIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR1BTRGF0YS5LRVlfVkRPUCwgdmRvcCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRWZG9wICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdQU0RhdGEuS0VZX1ZET1ApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYWN0dWFsIC0gVHJ1ZSwgaWYgYWN0dWFsLiBGYWxzZSwgaWYgaW5mZXJyZWQuXG4gICAgICogQHJldHVybiB7R1BTRGF0YX1cbiAgICAgKi9cbiAgICBzZXRBY3R1YWwgKGFjdHVhbCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHUFNEYXRhLktFWV9BQ1RVQUwsIGFjdHVhbCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0QWN0dWFsICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdQU0RhdGEuS0VZX0FDVFVBTCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNhdGVsbGl0ZXMgLSBOdW1iZXIgb2Ygc2F0ZWxsaXRlcyBpbiB2aWV3XG4gICAgICogQHJldHVybiB7R1BTRGF0YX1cbiAgICAgKi9cbiAgICBzZXRTYXRlbGxpdGVzIChzYXRlbGxpdGVzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdQU0RhdGEuS0VZX1NBVEVMTElURVMsIHNhdGVsbGl0ZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0U2F0ZWxsaXRlcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHUFNEYXRhLktFWV9TQVRFTExJVEVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0RpbWVuc2lvbn0gZGltZW5zaW9uIC0gU2VlIERpbWVuc2lvblxuICAgICAqIEByZXR1cm4ge0dQU0RhdGF9XG4gICAgICovXG4gICAgc2V0RGltZW5zaW9uIChkaW1lbnNpb24pIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoRGltZW5zaW9uLCBkaW1lbnNpb24pO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHUFNEYXRhLktFWV9ESU1FTlNJT04sIGRpbWVuc2lvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0RpbWVuc2lvbn1cbiAgICAgKi9cbiAgICBnZXREaW1lbnNpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoRGltZW5zaW9uLCBHUFNEYXRhLktFWV9ESU1FTlNJT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBhbHRpdHVkZSAtIEFsdGl0dWRlIGluIG1ldGVyc1xuICAgICAqIEByZXR1cm4ge0dQU0RhdGF9XG4gICAgICovXG4gICAgc2V0QWx0aXR1ZGUgKGFsdGl0dWRlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdQU0RhdGEuS0VZX0FMVElUVURFLCBhbHRpdHVkZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRBbHRpdHVkZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHUFNEYXRhLktFWV9BTFRJVFVERSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGhlYWRpbmcgLSBUaGUgaGVhZGluZy4gTm9ydGggaXMgMC4gUmVzb2x1dGlvbiBpcyAwLjAxXG4gICAgICogQHJldHVybiB7R1BTRGF0YX1cbiAgICAgKi9cbiAgICBzZXRIZWFkaW5nIChoZWFkaW5nKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdQU0RhdGEuS0VZX0hFQURJTkcsIGhlYWRpbmcpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0SGVhZGluZyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHUFNEYXRhLktFWV9IRUFESU5HKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc3BlZWQgLSBUaGUgc3BlZWQgaW4gS1BIXG4gICAgICogQHJldHVybiB7R1BTRGF0YX1cbiAgICAgKi9cbiAgICBzZXRTcGVlZCAoc3BlZWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR1BTRGF0YS5LRVlfU1BFRUQsIHNwZWVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFNwZWVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdQU0RhdGEuS0VZX1NQRUVEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHNoaWZ0ZWQgLSBUcnVlLCBpZiBHUFMgbGF0L2xvbmcsIHRpbWUsIGFuZCBhbHRpdHVkZSBoYXZlIGJlZW4gcHVycG9zZWZ1bGx5IHNoaWZ0ZWQgKHJlcXVpcmVzIGFcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9wcmlldGFyeSBhbGdvcml0aG0gdG8gdW5zaGlmdCkuIEZhbHNlLCBpZiB0aGUgR1BTIGRhdGEgaXMgcmF3IGFuZCB1bi1zaGlmdGVkLiBJZlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdCBwcm92aWRlZCwgdGhlbiB2YWx1ZSBpcyBhc3N1bWVkIEZhbHNlLlxuICAgICAqIEByZXR1cm4ge0dQU0RhdGF9XG4gICAgICovXG4gICAgc2V0U2hpZnRlZCAoc2hpZnRlZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHUFNEYXRhLktFWV9TSElGVEVELCBzaGlmdGVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRTaGlmdGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdQU0RhdGEuS0VZX1NISUZURUQpO1xuICAgIH1cbn1cblxuR1BTRGF0YS5LRVlfTE9OR0lUVURFX0RFR1JFRVMgPSAnbG9uZ2l0dWRlRGVncmVlcyc7XG5HUFNEYXRhLktFWV9MQVRJVFVERV9ERUdSRUVTID0gJ2xhdGl0dWRlRGVncmVlcyc7XG5HUFNEYXRhLktFWV9VVENfWUVBUiA9ICd1dGNZZWFyJztcbkdQU0RhdGEuS0VZX1VUQ19NT05USCA9ICd1dGNNb250aCc7XG5HUFNEYXRhLktFWV9VVENfREFZID0gJ3V0Y0RheSc7XG5HUFNEYXRhLktFWV9VVENfSE9VUlMgPSAndXRjSG91cnMnO1xuR1BTRGF0YS5LRVlfVVRDX01JTlVURVMgPSAndXRjTWludXRlcyc7XG5HUFNEYXRhLktFWV9VVENfU0VDT05EUyA9ICd1dGNTZWNvbmRzJztcbkdQU0RhdGEuS0VZX0NPTVBBU1NfRElSRUNUSU9OID0gJ2NvbXBhc3NEaXJlY3Rpb24nO1xuR1BTRGF0YS5LRVlfUERPUCA9ICdwZG9wJztcbkdQU0RhdGEuS0VZX0hET1AgPSAnaGRvcCc7XG5HUFNEYXRhLktFWV9WRE9QID0gJ3Zkb3AnO1xuR1BTRGF0YS5LRVlfQUNUVUFMID0gJ2FjdHVhbCc7XG5HUFNEYXRhLktFWV9TQVRFTExJVEVTID0gJ3NhdGVsbGl0ZXMnO1xuR1BTRGF0YS5LRVlfRElNRU5TSU9OID0gJ2RpbWVuc2lvbic7XG5HUFNEYXRhLktFWV9BTFRJVFVERSA9ICdhbHRpdHVkZSc7XG5HUFNEYXRhLktFWV9IRUFESU5HID0gJ2hlYWRpbmcnO1xuR1BTRGF0YS5LRVlfU1BFRUQgPSAnc3BlZWQnO1xuR1BTRGF0YS5LRVlfU0hJRlRFRCA9ICdzaGlmdGVkJztcblxuZXhwb3J0IHsgR1BTRGF0YSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIFRoZSBzZWxlY3RlZCBnZWFyLlxuICogQHR5cGVkZWYge0VudW19IFBSTkRMXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBQUk5ETCBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJraW5nXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUEFSSyAoKSB7XG4gICAgICAgIHJldHVybiBQUk5ETC5fTUFQLlBBUks7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV2ZXJzZSBnZWFyXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUkVWRVJTRSAoKSB7XG4gICAgICAgIHJldHVybiBQUk5ETC5fTUFQLlJFVkVSU0U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTm8gZ2VhclxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5FVVRSQUwgKCkge1xuICAgICAgICByZXR1cm4gUFJOREwuX01BUC5ORVVUUkFMO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IERSSVZFICgpIHtcbiAgICAgICAgcmV0dXJuIFBSTkRMLl9NQVAuRFJJVkU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRHJpdmUgU3BvcnQgbW9kZVxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNQT1JUICgpIHtcbiAgICAgICAgcmV0dXJuIFBSTkRMLl9NQVAuU1BPUlQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogMXN0IGdlYXIgaG9sZFxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IExPV0dFQVIgKCkge1xuICAgICAgICByZXR1cm4gUFJOREwuX01BUC5MT1dHRUFSO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEZJUlNUICgpIHtcbiAgICAgICAgcmV0dXJuIFBSTkRMLl9NQVAuRklSU1Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0VDT05EICgpIHtcbiAgICAgICAgcmV0dXJuIFBSTkRMLl9NQVAuU0VDT05EO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFRISVJEICgpIHtcbiAgICAgICAgcmV0dXJuIFBSTkRMLl9NQVAuVEhJUkQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRk9VUlRIICgpIHtcbiAgICAgICAgcmV0dXJuIFBSTkRMLl9NQVAuRk9VUlRIO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEZJRlRIICgpIHtcbiAgICAgICAgcmV0dXJuIFBSTkRMLl9NQVAuRklGVEg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0lYVEggKCkge1xuICAgICAgICByZXR1cm4gUFJOREwuX01BUC5TSVhUSDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTRVZFTlRIICgpIHtcbiAgICAgICAgcmV0dXJuIFBSTkRMLl9NQVAuU0VWRU5USDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFSUdIVEggKCkge1xuICAgICAgICByZXR1cm4gUFJOREwuX01BUC5FSUdIVEg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVU5LTk9XTiAoKSB7XG4gICAgICAgIHJldHVybiBQUk5ETC5fTUFQLlVOS05PV047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRkFVTFQgKCkge1xuICAgICAgICByZXR1cm4gUFJOREwuX01BUC5GQVVMVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBQUk5ETC5fdmFsdWVGb3JLZXkoa2V5LCBQUk5ETC5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFBSTkRMLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgUFJOREwuX01BUCk7XG4gICAgfVxufVxuXG5QUk5ETC5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1BBUksnOiAnUEFSSycsXG4gICAgJ1JFVkVSU0UnOiAnUkVWRVJTRScsXG4gICAgJ05FVVRSQUwnOiAnTkVVVFJBTCcsXG4gICAgJ0RSSVZFJzogJ0RSSVZFJyxcbiAgICAnU1BPUlQnOiAnU1BPUlQnLFxuICAgICdMT1dHRUFSJzogJ0xPV0dFQVInLFxuICAgICdGSVJTVCc6ICdGSVJTVCcsXG4gICAgJ1NFQ09ORCc6ICdTRUNPTkQnLFxuICAgICdUSElSRCc6ICdUSElSRCcsXG4gICAgJ0ZPVVJUSCc6ICdGT1VSVEgnLFxuICAgICdGSUZUSCc6ICdGSUZUSCcsXG4gICAgJ1NJWFRIJzogJ1NJWFRIJyxcbiAgICAnU0VWRU5USCc6ICdTRVZFTlRIJyxcbiAgICAnRUlHSFRIJzogJ0VJR0hUSCcsXG4gICAgJ1VOS05PV04nOiAnVU5LTk9XTicsXG4gICAgJ0ZBVUxUJzogJ0ZBVUxUJyxcbn0pO1xuXG5leHBvcnQgeyBQUk5ETCB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBGdWVsVHlwZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgRnVlbFR5cGUgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgR0FTT0xJTkUgKCkge1xuICAgICAgICByZXR1cm4gRnVlbFR5cGUuX01BUC5HQVNPTElORTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBESUVTRUwgKCkge1xuICAgICAgICByZXR1cm4gRnVlbFR5cGUuX01BUC5ESUVTRUw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRm9yIHZlaGljbGVzIHVzaW5nIGNvbXByZXNzZWQgbmF0dXJhbCBnYXMuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ05HICgpIHtcbiAgICAgICAgcmV0dXJuIEZ1ZWxUeXBlLl9NQVAuQ05HO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZvciB2ZWhpY2xlcyB1c2luZyBsaXF1ZWZpZWQgcGV0cm9sZXVtIGdhcy5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBMUEcgKCkge1xuICAgICAgICByZXR1cm4gRnVlbFR5cGUuX01BUC5MUEc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRm9yIEZDRVYgKGZ1ZWwgY2VsbCBlbGVjdHJpYyB2ZWhpY2xlKS5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBIWURST0dFTiAoKSB7XG4gICAgICAgIHJldHVybiBGdWVsVHlwZS5fTUFQLkhZRFJPR0VOO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZvciBCRVYgKEJhdHRlcnkgRWxlY3RyaWMgVmVoaWNsZSksIFBIRVYgKFBsdWctaW4gSHlicmlkIEVsZWN0cmljIFZlaGljbGUpLCBzb2xhciB2ZWhpY2xlcyBhbmQgb3RoZXIgdmVoaWNsZXNcbiAgICAgKiB3aGljaCBydW4gb24gYSBiYXR0ZXJ5LlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEJBVFRFUlkgKCkge1xuICAgICAgICByZXR1cm4gRnVlbFR5cGUuX01BUC5CQVRURVJZO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIEZ1ZWxUeXBlLl92YWx1ZUZvcktleShrZXksIEZ1ZWxUeXBlLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gRnVlbFR5cGUuX2tleUZvclZhbHVlKHZhbHVlLCBGdWVsVHlwZS5fTUFQKTtcbiAgICB9XG59XG5cbkZ1ZWxUeXBlLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnR0FTT0xJTkUnOiAnR0FTT0xJTkUnLFxuICAgICdESUVTRUwnOiAnRElFU0VMJyxcbiAgICAnQ05HJzogJ0NORycsXG4gICAgJ0xQRyc6ICdMUEcnLFxuICAgICdIWURST0dFTic6ICdIWURST0dFTicsXG4gICAgJ0JBVFRFUlknOiAnQkFUVEVSWScsXG59KTtcblxuZXhwb3J0IHsgRnVlbFR5cGUgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgRnVlbFR5cGUgfSBmcm9tICcuLi9lbnVtcy9GdWVsVHlwZS5qcyc7XG5cbmNsYXNzIEZ1ZWxSYW5nZSBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtGdWVsVHlwZX0gdHlwZVxuICAgICAqIEByZXR1cm4ge0Z1ZWxSYW5nZX1cbiAgICAgKi9cbiAgICBzZXRUeXBlICh0eXBlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEZ1ZWxUeXBlLCB0eXBlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRnVlbFJhbmdlLktFWV9UWVBFLCB0eXBlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7RnVlbFR5cGV9XG4gICAgICovXG4gICAgZ2V0VHlwZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChGdWVsVHlwZSwgRnVlbFJhbmdlLktFWV9UWVBFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gcmFuZ2UgLSBUaGUgZXN0aW1hdGUgcmFuZ2UgaW4gS00gdGhlIHZlaGljbGUgY2FuIHRyYXZlbCBiYXNlZCBvbiBmdWVsIGxldmVsIGFuZCBjb25zdW1wdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtGdWVsUmFuZ2V9XG4gICAgICovXG4gICAgc2V0UmFuZ2UgKHJhbmdlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEZ1ZWxSYW5nZS5LRVlfUkFOR0UsIHJhbmdlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFJhbmdlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEZ1ZWxSYW5nZS5LRVlfUkFOR0UpO1xuICAgIH1cbn1cblxuRnVlbFJhbmdlLktFWV9UWVBFID0gJ3R5cGUnO1xuRnVlbFJhbmdlLktFWV9SQU5HRSA9ICdyYW5nZSc7XG5cbmV4cG9ydCB7IEZ1ZWxSYW5nZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIFJlZmxlY3RzIHRoZSBzdGF0dXMgb2YgYSB2ZWhpY2xlIGRhdGEgbm90aWZpY2F0aW9uLlxuICogQHR5cGVkZWYge0VudW19IFZlaGljbGVEYXRhTm90aWZpY2F0aW9uU3RhdHVzXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBWZWhpY2xlRGF0YU5vdGlmaWNhdGlvblN0YXR1cyBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBWRE5TX05PVF9TVVBQT1JURUQgKCkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFOb3RpZmljYXRpb25TdGF0dXMuX01BUC5WRE5TX05PVF9TVVBQT1JURUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVkROU19OT1JNQUwgKCkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFOb3RpZmljYXRpb25TdGF0dXMuX01BUC5WRE5TX05PUk1BTDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBWRE5TX0FDVElWRSAoKSB7XG4gICAgICAgIHJldHVybiBWZWhpY2xlRGF0YU5vdGlmaWNhdGlvblN0YXR1cy5fTUFQLlZETlNfQUNUSVZFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZETlNfTk9UX1VTRUQgKCkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFOb3RpZmljYXRpb25TdGF0dXMuX01BUC5WRE5TX05PVF9VU0VEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhTm90aWZpY2F0aW9uU3RhdHVzLl92YWx1ZUZvcktleShrZXksIFZlaGljbGVEYXRhTm90aWZpY2F0aW9uU3RhdHVzLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFOb3RpZmljYXRpb25TdGF0dXMuX2tleUZvclZhbHVlKHZhbHVlLCBWZWhpY2xlRGF0YU5vdGlmaWNhdGlvblN0YXR1cy5fTUFQKTtcbiAgICB9XG59XG5cblZlaGljbGVEYXRhTm90aWZpY2F0aW9uU3RhdHVzLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnVkROU19OT1RfU1VQUE9SVEVEJzogJ05PVF9TVVBQT1JURUQnLFxuICAgICdWRE5TX05PUk1BTCc6ICdOT1JNQUwnLFxuICAgICdWRE5TX0FDVElWRSc6ICdBQ1RJVkUnLFxuICAgICdWRE5TX05PVF9VU0VEJzogJ05PVF9VU0VEJyxcbn0pO1xuXG5leHBvcnQgeyBWZWhpY2xlRGF0YU5vdGlmaWNhdGlvblN0YXR1cyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIFJlZmxlY3RzIHRoZSBzdGF0dXMgb2YgdGhlIGVDYWxsIE5vdGlmaWNhdGlvbi5cbiAqIEB0eXBlZGVmIHtFbnVtfSBFQ2FsbENvbmZpcm1hdGlvblN0YXR1c1xuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgRUNhbGxDb25maXJtYXRpb25TdGF0dXMgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRUNDU19OT1JNQUwgKCkge1xuICAgICAgICByZXR1cm4gRUNhbGxDb25maXJtYXRpb25TdGF0dXMuX01BUC5FQ0NTX05PUk1BTDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFQ0NTX0NBTExfSU5fUFJPR1JFU1MgKCkge1xuICAgICAgICByZXR1cm4gRUNhbGxDb25maXJtYXRpb25TdGF0dXMuX01BUC5FQ0NTX0NBTExfSU5fUFJPR1JFU1M7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRUNDU19DQUxMX0NBTkNFTExFRCAoKSB7XG4gICAgICAgIHJldHVybiBFQ2FsbENvbmZpcm1hdGlvblN0YXR1cy5fTUFQLkVDQ1NfQ0FMTF9DQU5DRUxMRUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ0FMTF9DT01QTEVURUQgKCkge1xuICAgICAgICByZXR1cm4gRUNhbGxDb25maXJtYXRpb25TdGF0dXMuX01BUC5DQUxMX0NPTVBMRVRFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFQ0NTX0NBTExfVU5TVUNDRVNTRlVMICgpIHtcbiAgICAgICAgcmV0dXJuIEVDYWxsQ29uZmlybWF0aW9uU3RhdHVzLl9NQVAuRUNDU19DQUxMX1VOU1VDQ0VTU0ZVTDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFQ0NTX0VDQUxMX0NPTkZJR1VSRURfT0ZGICgpIHtcbiAgICAgICAgcmV0dXJuIEVDYWxsQ29uZmlybWF0aW9uU3RhdHVzLl9NQVAuRUNDU19FQ0FMTF9DT05GSUdVUkVEX09GRjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFQ0NTX0NBTExfQ09NUExFVEVfRFRNRl9USU1FT1VUICgpIHtcbiAgICAgICAgcmV0dXJuIEVDYWxsQ29uZmlybWF0aW9uU3RhdHVzLl9NQVAuRUNDU19DQUxMX0NPTVBMRVRFX0RUTUZfVElNRU9VVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBFQ2FsbENvbmZpcm1hdGlvblN0YXR1cy5fdmFsdWVGb3JLZXkoa2V5LCBFQ2FsbENvbmZpcm1hdGlvblN0YXR1cy5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIEVDYWxsQ29uZmlybWF0aW9uU3RhdHVzLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgRUNhbGxDb25maXJtYXRpb25TdGF0dXMuX01BUCk7XG4gICAgfVxufVxuXG5FQ2FsbENvbmZpcm1hdGlvblN0YXR1cy5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0VDQ1NfTk9STUFMJzogJ05PUk1BTCcsXG4gICAgJ0VDQ1NfQ0FMTF9JTl9QUk9HUkVTUyc6ICdDQUxMX0lOX1BST0dSRVNTJyxcbiAgICAnRUNDU19DQUxMX0NBTkNFTExFRCc6ICdDQUxMX0NBTkNFTExFRCcsXG4gICAgJ0NBTExfQ09NUExFVEVEJzogJ0NBTExfQ09NUExFVEVEJyxcbiAgICAnRUNDU19DQUxMX1VOU1VDQ0VTU0ZVTCc6ICdDQUxMX1VOU1VDQ0VTU0ZVTCcsXG4gICAgJ0VDQ1NfRUNBTExfQ09ORklHVVJFRF9PRkYnOiAnRUNBTExfQ09ORklHVVJFRF9PRkYnLFxuICAgICdFQ0NTX0NBTExfQ09NUExFVEVfRFRNRl9USU1FT1VUJzogJ0NBTExfQ09NUExFVEVfRFRNRl9USU1FT1VUJyxcbn0pO1xuXG5leHBvcnQgeyBFQ2FsbENvbmZpcm1hdGlvblN0YXR1cyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBWZWhpY2xlRGF0YU5vdGlmaWNhdGlvblN0YXR1cyB9IGZyb20gJy4uL2VudW1zL1ZlaGljbGVEYXRhTm90aWZpY2F0aW9uU3RhdHVzLmpzJztcbmltcG9ydCB7IEVDYWxsQ29uZmlybWF0aW9uU3RhdHVzIH0gZnJvbSAnLi4vZW51bXMvRUNhbGxDb25maXJtYXRpb25TdGF0dXMuanMnO1xuXG5jbGFzcyBFQ2FsbEluZm8gZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFOb3RpZmljYXRpb25TdGF0dXN9IHN0YXR1cyAtIFJlZmVyZW5jZXMgc2lnbmFsIFwiZUNhbGxOb3RpZmljYXRpb25fNEFcIi4gU2VlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVoaWNsZURhdGFOb3RpZmljYXRpb25TdGF0dXMuXG4gICAgICogQHJldHVybiB7RUNhbGxJbmZvfVxuICAgICAqL1xuICAgIHNldEVDYWxsTm90aWZpY2F0aW9uU3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFOb3RpZmljYXRpb25TdGF0dXMsIHN0YXR1cyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEVDYWxsSW5mby5LRVlfRV9DQUxMX05PVElGSUNBVElPTl9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhTm90aWZpY2F0aW9uU3RhdHVzfVxuICAgICAqL1xuICAgIGdldEVDYWxsTm90aWZpY2F0aW9uU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhTm90aWZpY2F0aW9uU3RhdHVzLCBFQ2FsbEluZm8uS0VZX0VfQ0FMTF9OT1RJRklDQVRJT05fU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlaGljbGVEYXRhTm90aWZpY2F0aW9uU3RhdHVzfSBzdGF0dXMgLSBSZWZlcmVuY2VzIHNpZ25hbCBcImVDYWxsTm90aWZpY2F0aW9uXCIuIFNlZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlaGljbGVEYXRhTm90aWZpY2F0aW9uU3RhdHVzLlxuICAgICAqIEByZXR1cm4ge0VDYWxsSW5mb31cbiAgICAgKi9cbiAgICBzZXRBdXhFQ2FsbE5vdGlmaWNhdGlvblN0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhTm90aWZpY2F0aW9uU3RhdHVzLCBzdGF0dXMpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihFQ2FsbEluZm8uS0VZX0FVWF9FQ0FMTF9OT1RJRklDQVRJT05fU1RBVFVTLCBzdGF0dXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YU5vdGlmaWNhdGlvblN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRBdXhFQ2FsbE5vdGlmaWNhdGlvblN0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YU5vdGlmaWNhdGlvblN0YXR1cywgRUNhbGxJbmZvLktFWV9BVVhfRUNBTExfTk9USUZJQ0FUSU9OX1NUQVRVUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtFQ2FsbENvbmZpcm1hdGlvblN0YXR1c30gc3RhdHVzIC0gUmVmZXJlbmNlcyBzaWduYWwgXCJlQ2FsbENvbmZpcm1hdGlvblwiLiBTZWUgRUNhbGxDb25maXJtYXRpb25TdGF0dXMuXG4gICAgICogQHJldHVybiB7RUNhbGxJbmZvfVxuICAgICAqL1xuICAgIHNldEVDYWxsQ29uZmlybWF0aW9uU3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoRUNhbGxDb25maXJtYXRpb25TdGF0dXMsIHN0YXR1cyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEVDYWxsSW5mby5LRVlfRV9DQUxMX0NPTkZJUk1BVElPTl9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0VDYWxsQ29uZmlybWF0aW9uU3RhdHVzfVxuICAgICAqL1xuICAgIGdldEVDYWxsQ29uZmlybWF0aW9uU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEVDYWxsQ29uZmlybWF0aW9uU3RhdHVzLCBFQ2FsbEluZm8uS0VZX0VfQ0FMTF9DT05GSVJNQVRJT05fU1RBVFVTKTtcbiAgICB9XG59XG5cbkVDYWxsSW5mby5LRVlfRV9DQUxMX05PVElGSUNBVElPTl9TVEFUVVMgPSAnZUNhbGxOb3RpZmljYXRpb25TdGF0dXMnO1xuRUNhbGxJbmZvLktFWV9BVVhfRUNBTExfTk9USUZJQ0FUSU9OX1NUQVRVUyA9ICdhdXhFQ2FsbE5vdGlmaWNhdGlvblN0YXR1cyc7XG5FQ2FsbEluZm8uS0VZX0VfQ0FMTF9DT05GSVJNQVRJT05fU1RBVFVTID0gJ2VDYWxsQ29uZmlybWF0aW9uU3RhdHVzJztcblxuZXhwb3J0IHsgRUNhbGxJbmZvIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IFZlaGljbGVEYXRhRXZlbnRTdGF0dXMgfSBmcm9tICcuLi9lbnVtcy9WZWhpY2xlRGF0YUV2ZW50U3RhdHVzLmpzJztcblxuY2xhc3MgQmVsdFN0YXR1cyBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfSBkZXBsb3llZCAtIFJlZmVyZW5jZXMgc2lnbmFsIFwiVmVkc0RydkJlbHRfRF9MdGNoZFwiLiBTZWUgVmVoaWNsZURhdGFFdmVudFN0YXR1cy5cbiAgICAgKiBAcmV0dXJuIHtCZWx0U3RhdHVzfVxuICAgICAqL1xuICAgIHNldERyaXZlckJlbHREZXBsb3llZCAoZGVwbG95ZWQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFFdmVudFN0YXR1cywgZGVwbG95ZWQpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihCZWx0U3RhdHVzLktFWV9EUklWRVJfQkVMVF9ERVBMT1lFRCwgZGVwbG95ZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfVxuICAgICAqL1xuICAgIGdldERyaXZlckJlbHREZXBsb3llZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLCBCZWx0U3RhdHVzLktFWV9EUklWRVJfQkVMVF9ERVBMT1lFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfSBkZXBsb3llZCAtIFJlZmVyZW5jZXMgc2lnbmFsIFwiVmVkc1Bhc0JlbHRfRF9MdGNoZFwiLiBTZWUgVmVoaWNsZURhdGFFdmVudFN0YXR1cy5cbiAgICAgKiBAcmV0dXJuIHtCZWx0U3RhdHVzfVxuICAgICAqL1xuICAgIHNldFBhc3NlbmdlckJlbHREZXBsb3llZCAoZGVwbG95ZWQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFFdmVudFN0YXR1cywgZGVwbG95ZWQpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihCZWx0U3RhdHVzLktFWV9QQVNTRU5HRVJfQkVMVF9ERVBMT1lFRCwgZGVwbG95ZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfVxuICAgICAqL1xuICAgIGdldFBhc3NlbmdlckJlbHREZXBsb3llZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLCBCZWx0U3RhdHVzLktFWV9QQVNTRU5HRVJfQkVMVF9ERVBMT1lFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfSBiZWx0ZWQgLSBSZWZlcmVuY2VzIHNpZ25hbCBcIlZlZHNSdzFQYXNCY2tsX0RfTHRjaGRcIi4gU2VlIFZlaGljbGVEYXRhRXZlbnRTdGF0dXMuXG4gICAgICogQHJldHVybiB7QmVsdFN0YXR1c31cbiAgICAgKi9cbiAgICBzZXRQYXNzZW5nZXJCdWNrbGVCZWx0ZWQgKGJlbHRlZCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLCBiZWx0ZWQpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihCZWx0U3RhdHVzLktFWV9QQVNTRU5HRVJfQlVDS0xFX0JFTFRFRCwgYmVsdGVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFFdmVudFN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRQYXNzZW5nZXJCdWNrbGVCZWx0ZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFFdmVudFN0YXR1cywgQmVsdFN0YXR1cy5LRVlfUEFTU0VOR0VSX0JVQ0tMRV9CRUxURUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFFdmVudFN0YXR1c30gYmVsdGVkIC0gUmVmZXJlbmNlcyBzaWduYWwgXCJWZWRzUncxRHJ2QmNrbF9EX0x0Y2hkXCIuIFNlZSBWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLlxuICAgICAqIEByZXR1cm4ge0JlbHRTdGF0dXN9XG4gICAgICovXG4gICAgc2V0RHJpdmVyQnVja2xlQmVsdGVkIChiZWx0ZWQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFFdmVudFN0YXR1cywgYmVsdGVkKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQmVsdFN0YXR1cy5LRVlfRFJJVkVSX0JVQ0tMRV9CRUxURUQsIGJlbHRlZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhRXZlbnRTdGF0dXN9XG4gICAgICovXG4gICAgZ2V0RHJpdmVyQnVja2xlQmVsdGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIEJlbHRTdGF0dXMuS0VZX0RSSVZFUl9CVUNLTEVfQkVMVEVEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlaGljbGVEYXRhRXZlbnRTdGF0dXN9IGJlbHRlZCAtIFJlZmVyZW5jZXMgc2lnbmFsIFwiVmVkc1J3MmxCY2tsX0RfTHRjaGRcIi4gU2VlIFZlaGljbGVEYXRhRXZlbnRTdGF0dXMuXG4gICAgICogQHJldHVybiB7QmVsdFN0YXR1c31cbiAgICAgKi9cbiAgICBzZXRMZWZ0Um93MkJ1Y2tsZUJlbHRlZCAoYmVsdGVkKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIGJlbHRlZCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEJlbHRTdGF0dXMuS0VZX0xFRlRfUk9XMkJVQ0tMRV9CRUxURUQsIGJlbHRlZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhRXZlbnRTdGF0dXN9XG4gICAgICovXG4gICAgZ2V0TGVmdFJvdzJCdWNrbGVCZWx0ZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVmVoaWNsZURhdGFFdmVudFN0YXR1cywgQmVsdFN0YXR1cy5LRVlfTEVGVF9ST1cyQlVDS0xFX0JFTFRFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfSBkZXRlY3RlZCAtIFJlZmVyZW5jZXMgc2lnbmFsIFwiVmVkc1J3MVBhc0NobGRfRF9MdGNoZFwiLiBTZWVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVoaWNsZURhdGFFdmVudFN0YXR1cy5cbiAgICAgKiBAcmV0dXJuIHtCZWx0U3RhdHVzfVxuICAgICAqL1xuICAgIHNldFBhc3NlbmdlckNoaWxkRGV0ZWN0ZWQgKGRldGVjdGVkKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIGRldGVjdGVkKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQmVsdFN0YXR1cy5LRVlfUEFTU0VOR0VSX0NISUxEX0RFVEVDVEVELCBkZXRlY3RlZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhRXZlbnRTdGF0dXN9XG4gICAgICovXG4gICAgZ2V0UGFzc2VuZ2VyQ2hpbGREZXRlY3RlZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLCBCZWx0U3RhdHVzLktFWV9QQVNTRU5HRVJfQ0hJTERfREVURUNURUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFFdmVudFN0YXR1c30gYmVsdGVkIC0gUmVmZXJlbmNlcyBzaWduYWwgXCJWZWRzUncyckJja2xfRF9MdGNoZFwiLiBTZWUgVmVoaWNsZURhdGFFdmVudFN0YXR1cy5cbiAgICAgKiBAcmV0dXJuIHtCZWx0U3RhdHVzfVxuICAgICAqL1xuICAgIHNldFJpZ2h0Um93MkJ1Y2tsZUJlbHRlZCAoYmVsdGVkKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIGJlbHRlZCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEJlbHRTdGF0dXMuS0VZX1JJR0hUX1JPVzJCVUNLTEVfQkVMVEVELCBiZWx0ZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfVxuICAgICAqL1xuICAgIGdldFJpZ2h0Um93MkJ1Y2tsZUJlbHRlZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLCBCZWx0U3RhdHVzLktFWV9SSUdIVF9ST1cyQlVDS0xFX0JFTFRFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfSBiZWx0ZWQgLSBSZWZlcmVuY2VzIHNpZ25hbCBcIlZlZHNSdzJtQmNrbF9EX0x0Y2hkXCIuIFNlZSBWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLlxuICAgICAqIEByZXR1cm4ge0JlbHRTdGF0dXN9XG4gICAgICovXG4gICAgc2V0TWlkZGxlUm93MkJ1Y2tsZUJlbHRlZCAoYmVsdGVkKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIGJlbHRlZCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEJlbHRTdGF0dXMuS0VZX01JRERMRV9ST1cyQlVDS0xFX0JFTFRFRCwgYmVsdGVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFFdmVudFN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRNaWRkbGVSb3cyQnVja2xlQmVsdGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIEJlbHRTdGF0dXMuS0VZX01JRERMRV9ST1cyQlVDS0xFX0JFTFRFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfSBiZWx0ZWQgLSBSZWZlcmVuY2VzIHNpZ25hbCBcIlZlZHNSdzNtQmNrbF9EX0x0Y2hkXCIuIFNlZSBWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLlxuICAgICAqIEByZXR1cm4ge0JlbHRTdGF0dXN9XG4gICAgICovXG4gICAgc2V0TWlkZGxlUm93M0J1Y2tsZUJlbHRlZCAoYmVsdGVkKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIGJlbHRlZCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEJlbHRTdGF0dXMuS0VZX01JRERMRV9ST1czQlVDS0xFX0JFTFRFRCwgYmVsdGVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFFdmVudFN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRNaWRkbGVSb3czQnVja2xlQmVsdGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIEJlbHRTdGF0dXMuS0VZX01JRERMRV9ST1czQlVDS0xFX0JFTFRFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfSBiZWx0ZWQgLSBSZWZlcmVuY2VzIHNpZ25hbCBcIlZlZHNSdzNsQmNrbF9EX0x0Y2hkXCIuIFNlZSBWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLlxuICAgICAqIEByZXR1cm4ge0JlbHRTdGF0dXN9XG4gICAgICovXG4gICAgc2V0TGVmdFJvdzNCdWNrbGVCZWx0ZWQgKGJlbHRlZCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLCBiZWx0ZWQpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihCZWx0U3RhdHVzLktFWV9MRUZUX1JPVzNCVUNLTEVfQkVMVEVELCBiZWx0ZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfVxuICAgICAqL1xuICAgIGdldExlZnRSb3czQnVja2xlQmVsdGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIEJlbHRTdGF0dXMuS0VZX0xFRlRfUk9XM0JVQ0tMRV9CRUxURUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFFdmVudFN0YXR1c30gYmVsdGVkIC0gUmVmZXJlbmNlcyBzaWduYWwgXCJWZWRzUnczckJja2xfRF9MdGNoZFwiLiBTZWUgVmVoaWNsZURhdGFFdmVudFN0YXR1cy5cbiAgICAgKiBAcmV0dXJuIHtCZWx0U3RhdHVzfVxuICAgICAqL1xuICAgIHNldFJpZ2h0Um93M0J1Y2tsZUJlbHRlZCAoYmVsdGVkKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIGJlbHRlZCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEJlbHRTdGF0dXMuS0VZX1JJR0hUX1JPVzNCVUNLTEVfQkVMVEVELCBiZWx0ZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfVxuICAgICAqL1xuICAgIGdldFJpZ2h0Um93M0J1Y2tsZUJlbHRlZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLCBCZWx0U3RhdHVzLktFWV9SSUdIVF9ST1czQlVDS0xFX0JFTFRFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfSBiZWx0ZWQgLSBSZWZlcmVuY2VzIHNpZ25hbCBcIlZlZHNSdzJsUmliX0RfTHRjaGRcIi4gU2VlIFZlaGljbGVEYXRhRXZlbnRTdGF0dXMuXG4gICAgICogQHJldHVybiB7QmVsdFN0YXR1c31cbiAgICAgKi9cbiAgICBzZXRMZWZ0UmVhckluZmxhdGFibGVCZWx0ZWQgKGJlbHRlZCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLCBiZWx0ZWQpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihCZWx0U3RhdHVzLktFWV9MRUZUX1JFQVJfSU5GTEFUQUJMRV9CRUxURUQsIGJlbHRlZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhRXZlbnRTdGF0dXN9XG4gICAgICovXG4gICAgZ2V0TGVmdFJlYXJJbmZsYXRhYmxlQmVsdGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIEJlbHRTdGF0dXMuS0VZX0xFRlRfUkVBUl9JTkZMQVRBQkxFX0JFTFRFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfSBiZWx0ZWQgLSBSZWZlcmVuY2VzIHNpZ25hbCBcIlZlZHNSdzJyUmliX0RfTHRjaGRcIi4gU2VlIFZlaGljbGVEYXRhRXZlbnRTdGF0dXMuXG4gICAgICogQHJldHVybiB7QmVsdFN0YXR1c31cbiAgICAgKi9cbiAgICBzZXRSaWdodFJlYXJJbmZsYXRhYmxlQmVsdGVkIChiZWx0ZWQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFFdmVudFN0YXR1cywgYmVsdGVkKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQmVsdFN0YXR1cy5LRVlfUklHSFRfUkVBUl9JTkZMQVRBQkxFX0JFTFRFRCwgYmVsdGVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFFdmVudFN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRSaWdodFJlYXJJbmZsYXRhYmxlQmVsdGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIEJlbHRTdGF0dXMuS0VZX1JJR0hUX1JFQVJfSU5GTEFUQUJMRV9CRUxURUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFFdmVudFN0YXR1c30gZGVwbG95ZWQgLSBSZWZlcmVuY2VzIHNpZ25hbCBcIlZlZHNSdzFtQmVsdF9EX0x0Y2hkXCIuIFNlZSBWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLlxuICAgICAqIEByZXR1cm4ge0JlbHRTdGF0dXN9XG4gICAgICovXG4gICAgc2V0TWlkZGxlUm93MUJlbHREZXBsb3llZCAoZGVwbG95ZWQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFFdmVudFN0YXR1cywgZGVwbG95ZWQpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihCZWx0U3RhdHVzLktFWV9NSURETEVfUk9XMUJFTFRfREVQTE9ZRUQsIGRlcGxveWVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFFdmVudFN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRNaWRkbGVSb3cxQmVsdERlcGxveWVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIEJlbHRTdGF0dXMuS0VZX01JRERMRV9ST1cxQkVMVF9ERVBMT1lFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfSBiZWx0ZWQgLSBSZWZlcmVuY2VzIHNpZ25hbCBcIlZlZHNSdzFtQmNrbF9EX0x0Y2hkXCIuIFNlZSBWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLlxuICAgICAqIEByZXR1cm4ge0JlbHRTdGF0dXN9XG4gICAgICovXG4gICAgc2V0TWlkZGxlUm93MUJ1Y2tsZUJlbHRlZCAoYmVsdGVkKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIGJlbHRlZCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEJlbHRTdGF0dXMuS0VZX01JRERMRV9ST1cxQlVDS0xFX0JFTFRFRCwgYmVsdGVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFFdmVudFN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRNaWRkbGVSb3cxQnVja2xlQmVsdGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIEJlbHRTdGF0dXMuS0VZX01JRERMRV9ST1cxQlVDS0xFX0JFTFRFRCk7XG4gICAgfVxufVxuXG5CZWx0U3RhdHVzLktFWV9EUklWRVJfQkVMVF9ERVBMT1lFRCA9ICdkcml2ZXJCZWx0RGVwbG95ZWQnO1xuQmVsdFN0YXR1cy5LRVlfUEFTU0VOR0VSX0JFTFRfREVQTE9ZRUQgPSAncGFzc2VuZ2VyQmVsdERlcGxveWVkJztcbkJlbHRTdGF0dXMuS0VZX1BBU1NFTkdFUl9CVUNLTEVfQkVMVEVEID0gJ3Bhc3NlbmdlckJ1Y2tsZUJlbHRlZCc7XG5CZWx0U3RhdHVzLktFWV9EUklWRVJfQlVDS0xFX0JFTFRFRCA9ICdkcml2ZXJCdWNrbGVCZWx0ZWQnO1xuQmVsdFN0YXR1cy5LRVlfTEVGVF9ST1cyQlVDS0xFX0JFTFRFRCA9ICdsZWZ0Um93MkJ1Y2tsZUJlbHRlZCc7XG5CZWx0U3RhdHVzLktFWV9QQVNTRU5HRVJfQ0hJTERfREVURUNURUQgPSAncGFzc2VuZ2VyQ2hpbGREZXRlY3RlZCc7XG5CZWx0U3RhdHVzLktFWV9SSUdIVF9ST1cyQlVDS0xFX0JFTFRFRCA9ICdyaWdodFJvdzJCdWNrbGVCZWx0ZWQnO1xuQmVsdFN0YXR1cy5LRVlfTUlERExFX1JPVzJCVUNLTEVfQkVMVEVEID0gJ21pZGRsZVJvdzJCdWNrbGVCZWx0ZWQnO1xuQmVsdFN0YXR1cy5LRVlfTUlERExFX1JPVzNCVUNLTEVfQkVMVEVEID0gJ21pZGRsZVJvdzNCdWNrbGVCZWx0ZWQnO1xuQmVsdFN0YXR1cy5LRVlfTEVGVF9ST1czQlVDS0xFX0JFTFRFRCA9ICdsZWZ0Um93M0J1Y2tsZUJlbHRlZCc7XG5CZWx0U3RhdHVzLktFWV9SSUdIVF9ST1czQlVDS0xFX0JFTFRFRCA9ICdyaWdodFJvdzNCdWNrbGVCZWx0ZWQnO1xuQmVsdFN0YXR1cy5LRVlfTEVGVF9SRUFSX0lORkxBVEFCTEVfQkVMVEVEID0gJ2xlZnRSZWFySW5mbGF0YWJsZUJlbHRlZCc7XG5CZWx0U3RhdHVzLktFWV9SSUdIVF9SRUFSX0lORkxBVEFCTEVfQkVMVEVEID0gJ3JpZ2h0UmVhckluZmxhdGFibGVCZWx0ZWQnO1xuQmVsdFN0YXR1cy5LRVlfTUlERExFX1JPVzFCRUxUX0RFUExPWUVEID0gJ21pZGRsZVJvdzFCZWx0RGVwbG95ZWQnO1xuQmVsdFN0YXR1cy5LRVlfTUlERExFX1JPVzFCVUNLTEVfQkVMVEVEID0gJ21pZGRsZVJvdzFCdWNrbGVCZWx0ZWQnO1xuXG5leHBvcnQgeyBCZWx0U3RhdHVzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogVGhlIHZvbHVtZSBzdGF0dXMgb2YgYSB2ZWhpY2xlIGNvbXBvbmVudC5cbiAqIEB0eXBlZGVmIHtFbnVtfSBDb21wb25lbnRWb2x1bWVTdGF0dXNcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIENvbXBvbmVudFZvbHVtZVN0YXR1cyBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDVlNfVU5LTk9XTiAoKSB7XG4gICAgICAgIHJldHVybiBDb21wb25lbnRWb2x1bWVTdGF0dXMuX01BUC5DVlNfVU5LTk9XTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDVlNfTk9STUFMICgpIHtcbiAgICAgICAgcmV0dXJuIENvbXBvbmVudFZvbHVtZVN0YXR1cy5fTUFQLkNWU19OT1JNQUw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ1ZTX0xPVyAoKSB7XG4gICAgICAgIHJldHVybiBDb21wb25lbnRWb2x1bWVTdGF0dXMuX01BUC5DVlNfTE9XO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENWU19GQVVMVCAoKSB7XG4gICAgICAgIHJldHVybiBDb21wb25lbnRWb2x1bWVTdGF0dXMuX01BUC5DVlNfRkFVTFQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ1ZTX0FMRVJUICgpIHtcbiAgICAgICAgcmV0dXJuIENvbXBvbmVudFZvbHVtZVN0YXR1cy5fTUFQLkNWU19BTEVSVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDVlNfTk9UX1NVUFBPUlRFRCAoKSB7XG4gICAgICAgIHJldHVybiBDb21wb25lbnRWb2x1bWVTdGF0dXMuX01BUC5DVlNfTk9UX1NVUFBPUlRFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBDb21wb25lbnRWb2x1bWVTdGF0dXMuX3ZhbHVlRm9yS2V5KGtleSwgQ29tcG9uZW50Vm9sdW1lU3RhdHVzLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gQ29tcG9uZW50Vm9sdW1lU3RhdHVzLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgQ29tcG9uZW50Vm9sdW1lU3RhdHVzLl9NQVApO1xuICAgIH1cbn1cblxuQ29tcG9uZW50Vm9sdW1lU3RhdHVzLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnQ1ZTX1VOS05PV04nOiAnVU5LTk9XTicsXG4gICAgJ0NWU19OT1JNQUwnOiAnTk9STUFMJyxcbiAgICAnQ1ZTX0xPVyc6ICdMT1cnLFxuICAgICdDVlNfRkFVTFQnOiAnRkFVTFQnLFxuICAgICdDVlNfQUxFUlQnOiAnQUxFUlQnLFxuICAgICdDVlNfTk9UX1NVUFBPUlRFRCc6ICdOT1RfU1VQUE9SVEVEJyxcbn0pO1xuXG5leHBvcnQgeyBDb21wb25lbnRWb2x1bWVTdGF0dXMgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBSZWZsZWN0cyB0aGUgc3RhdHVzIG9mIGlnbml0aW9uLlxuICogQHR5cGVkZWYge0VudW19IElnbml0aW9uU3RhdHVzXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBJZ25pdGlvblN0YXR1cyBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBJU19VTktOT1dOICgpIHtcbiAgICAgICAgcmV0dXJuIElnbml0aW9uU3RhdHVzLl9NQVAuSVNfVU5LTk9XTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBJU19PRkYgKCkge1xuICAgICAgICByZXR1cm4gSWduaXRpb25TdGF0dXMuX01BUC5JU19PRkY7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSVNfQUNDRVNTT1JZICgpIHtcbiAgICAgICAgcmV0dXJuIElnbml0aW9uU3RhdHVzLl9NQVAuSVNfQUNDRVNTT1JZO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IElTX1JVTiAoKSB7XG4gICAgICAgIHJldHVybiBJZ25pdGlvblN0YXR1cy5fTUFQLklTX1JVTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBJU19TVEFSVCAoKSB7XG4gICAgICAgIHJldHVybiBJZ25pdGlvblN0YXR1cy5fTUFQLklTX1NUQVJUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IElTX0lOVkFMSUQgKCkge1xuICAgICAgICByZXR1cm4gSWduaXRpb25TdGF0dXMuX01BUC5JU19JTlZBTElEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIElnbml0aW9uU3RhdHVzLl92YWx1ZUZvcktleShrZXksIElnbml0aW9uU3RhdHVzLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gSWduaXRpb25TdGF0dXMuX2tleUZvclZhbHVlKHZhbHVlLCBJZ25pdGlvblN0YXR1cy5fTUFQKTtcbiAgICB9XG59XG5cbklnbml0aW9uU3RhdHVzLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnSVNfVU5LTk9XTic6ICdVTktOT1dOJyxcbiAgICAnSVNfT0ZGJzogJ09GRicsXG4gICAgJ0lTX0FDQ0VTU09SWSc6ICdBQ0NFU1NPUlknLFxuICAgICdJU19SVU4nOiAnUlVOJyxcbiAgICAnSVNfU1RBUlQnOiAnU1RBUlQnLFxuICAgICdJU19JTlZBTElEJzogJ0lOVkFMSUQnLFxufSk7XG5cbmV4cG9ydCB7IElnbml0aW9uU3RhdHVzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogUmVmbGVjdHMgdGhlIGlnbml0aW9uIHN3aXRjaCBzdGFiaWxpdHkuXG4gKiBAdHlwZWRlZiB7RW51bX0gSWduaXRpb25TdGFibGVTdGF0dXNcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIElnbml0aW9uU3RhYmxlU3RhdHVzIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IElHTklUSU9OX1NXSVRDSF9OT1RfU1RBQkxFICgpIHtcbiAgICAgICAgcmV0dXJuIElnbml0aW9uU3RhYmxlU3RhdHVzLl9NQVAuSUdOSVRJT05fU1dJVENIX05PVF9TVEFCTEU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSUdOSVRJT05fU1dJVENIX1NUQUJMRSAoKSB7XG4gICAgICAgIHJldHVybiBJZ25pdGlvblN0YWJsZVN0YXR1cy5fTUFQLklHTklUSU9OX1NXSVRDSF9TVEFCTEU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTUlTU0lOR19GUk9NX1RSQU5TTUlUVEVSICgpIHtcbiAgICAgICAgcmV0dXJuIElnbml0aW9uU3RhYmxlU3RhdHVzLl9NQVAuTUlTU0lOR19GUk9NX1RSQU5TTUlUVEVSO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIElnbml0aW9uU3RhYmxlU3RhdHVzLl92YWx1ZUZvcktleShrZXksIElnbml0aW9uU3RhYmxlU3RhdHVzLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gSWduaXRpb25TdGFibGVTdGF0dXMuX2tleUZvclZhbHVlKHZhbHVlLCBJZ25pdGlvblN0YWJsZVN0YXR1cy5fTUFQKTtcbiAgICB9XG59XG5cbklnbml0aW9uU3RhYmxlU3RhdHVzLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnSUdOSVRJT05fU1dJVENIX05PVF9TVEFCTEUnOiAnSUdOSVRJT05fU1dJVENIX05PVF9TVEFCTEUnLFxuICAgICdJR05JVElPTl9TV0lUQ0hfU1RBQkxFJzogJ0lHTklUSU9OX1NXSVRDSF9TVEFCTEUnLFxuICAgICdNSVNTSU5HX0ZST01fVFJBTlNNSVRURVInOiAnTUlTU0lOR19GUk9NX1RSQU5TTUlUVEVSJyxcbn0pO1xuXG5leHBvcnQgeyBJZ25pdGlvblN0YWJsZVN0YXR1cyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBJZ25pdGlvblN0YXR1cyB9IGZyb20gJy4uL2VudW1zL0lnbml0aW9uU3RhdHVzLmpzJztcbmltcG9ydCB7IElnbml0aW9uU3RhYmxlU3RhdHVzIH0gZnJvbSAnLi4vZW51bXMvSWduaXRpb25TdGFibGVTdGF0dXMuanMnO1xuXG5jbGFzcyBCb2R5SW5mb3JtYXRpb24gZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYWN0aXZlIC0gUmVmZXJlbmNlcyBzaWduYWwgXCJQcmtCcmtBY3R2X0JfQWN0bFwiLlxuICAgICAqIEByZXR1cm4ge0JvZHlJbmZvcm1hdGlvbn1cbiAgICAgKi9cbiAgICBzZXRQYXJrQnJha2VBY3RpdmUgKGFjdGl2ZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihCb2R5SW5mb3JtYXRpb24uS0VZX1BBUktfQlJBS0VfQUNUSVZFLCBhY3RpdmUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFBhcmtCcmFrZUFjdGl2ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihCb2R5SW5mb3JtYXRpb24uS0VZX1BBUktfQlJBS0VfQUNUSVZFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0lnbml0aW9uU3RhYmxlU3RhdHVzfSBzdGF0dXMgLSBSZWZlcmVuY2VzIHNpZ25hbCBcIklnbml0aW9uX1N3aXRjaF9TdGFibGVcIi4gU2VlIElnbml0aW9uU3RhYmxlU3RhdHVzLlxuICAgICAqIEByZXR1cm4ge0JvZHlJbmZvcm1hdGlvbn1cbiAgICAgKi9cbiAgICBzZXRJZ25pdGlvblN0YWJsZVN0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKElnbml0aW9uU3RhYmxlU3RhdHVzLCBzdGF0dXMpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihCb2R5SW5mb3JtYXRpb24uS0VZX0lHTklUSU9OX1NUQUJMRV9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0lnbml0aW9uU3RhYmxlU3RhdHVzfVxuICAgICAqL1xuICAgIGdldElnbml0aW9uU3RhYmxlU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KElnbml0aW9uU3RhYmxlU3RhdHVzLCBCb2R5SW5mb3JtYXRpb24uS0VZX0lHTklUSU9OX1NUQUJMRV9TVEFUVVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7SWduaXRpb25TdGF0dXN9IHN0YXR1cyAtIFJlZmVyZW5jZXMgc2lnbmFsIFwiSWduaXRpb25fc3RhdHVzXCIuIFNlZSBJZ25pdGlvblN0YXR1cy5cbiAgICAgKiBAcmV0dXJuIHtCb2R5SW5mb3JtYXRpb259XG4gICAgICovXG4gICAgc2V0SWduaXRpb25TdGF0dXMgKHN0YXR1cykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShJZ25pdGlvblN0YXR1cywgc3RhdHVzKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQm9keUluZm9ybWF0aW9uLktFWV9JR05JVElPTl9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0lnbml0aW9uU3RhdHVzfVxuICAgICAqL1xuICAgIGdldElnbml0aW9uU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KElnbml0aW9uU3RhdHVzLCBCb2R5SW5mb3JtYXRpb24uS0VZX0lHTklUSU9OX1NUQVRVUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhamFyIC0gUmVmZXJlbmNlcyBzaWduYWwgXCJEclN0YXREcnZfQl9BY3RsXCIuXG4gICAgICogQHJldHVybiB7Qm9keUluZm9ybWF0aW9ufVxuICAgICAqL1xuICAgIHNldERyaXZlckRvb3JBamFyIChhamFyKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEJvZHlJbmZvcm1hdGlvbi5LRVlfRFJJVkVSX0RPT1JfQUpBUiwgYWphcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0RHJpdmVyRG9vckFqYXIgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQm9keUluZm9ybWF0aW9uLktFWV9EUklWRVJfRE9PUl9BSkFSKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGFqYXIgLSBSZWZlcmVuY2VzIHNpZ25hbCBcIkRyU3RhdFBzbmdyX0JfQWN0bFwiLlxuICAgICAqIEByZXR1cm4ge0JvZHlJbmZvcm1hdGlvbn1cbiAgICAgKi9cbiAgICBzZXRQYXNzZW5nZXJEb29yQWphciAoYWphcikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihCb2R5SW5mb3JtYXRpb24uS0VZX1BBU1NFTkdFUl9ET09SX0FKQVIsIGFqYXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFBhc3NlbmdlckRvb3JBamFyICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEJvZHlJbmZvcm1hdGlvbi5LRVlfUEFTU0VOR0VSX0RPT1JfQUpBUik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhamFyIC0gUmVmZXJlbmNlcyBzaWduYWwgXCJEclN0YXRSbF9CX0FjdGxcIi5cbiAgICAgKiBAcmV0dXJuIHtCb2R5SW5mb3JtYXRpb259XG4gICAgICovXG4gICAgc2V0UmVhckxlZnREb29yQWphciAoYWphcikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihCb2R5SW5mb3JtYXRpb24uS0VZX1JFQVJfTEVGVF9ET09SX0FKQVIsIGFqYXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFJlYXJMZWZ0RG9vckFqYXIgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQm9keUluZm9ybWF0aW9uLktFWV9SRUFSX0xFRlRfRE9PUl9BSkFSKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGFqYXIgLSBSZWZlcmVuY2VzIHNpZ25hbCBcIkRyU3RhdFJyX0JfQWN0bFwiLlxuICAgICAqIEByZXR1cm4ge0JvZHlJbmZvcm1hdGlvbn1cbiAgICAgKi9cbiAgICBzZXRSZWFyUmlnaHREb29yQWphciAoYWphcikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihCb2R5SW5mb3JtYXRpb24uS0VZX1JFQVJfUklHSFRfRE9PUl9BSkFSLCBhamFyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRSZWFyUmlnaHREb29yQWphciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihCb2R5SW5mb3JtYXRpb24uS0VZX1JFQVJfUklHSFRfRE9PUl9BSkFSKTtcbiAgICB9XG59XG5cbkJvZHlJbmZvcm1hdGlvbi5LRVlfUEFSS19CUkFLRV9BQ1RJVkUgPSAncGFya0JyYWtlQWN0aXZlJztcbkJvZHlJbmZvcm1hdGlvbi5LRVlfSUdOSVRJT05fU1RBQkxFX1NUQVRVUyA9ICdpZ25pdGlvblN0YWJsZVN0YXR1cyc7XG5Cb2R5SW5mb3JtYXRpb24uS0VZX0lHTklUSU9OX1NUQVRVUyA9ICdpZ25pdGlvblN0YXR1cyc7XG5Cb2R5SW5mb3JtYXRpb24uS0VZX0RSSVZFUl9ET09SX0FKQVIgPSAnZHJpdmVyRG9vckFqYXInO1xuQm9keUluZm9ybWF0aW9uLktFWV9QQVNTRU5HRVJfRE9PUl9BSkFSID0gJ3Bhc3NlbmdlckRvb3JBamFyJztcbkJvZHlJbmZvcm1hdGlvbi5LRVlfUkVBUl9MRUZUX0RPT1JfQUpBUiA9ICdyZWFyTGVmdERvb3JBamFyJztcbkJvZHlJbmZvcm1hdGlvbi5LRVlfUkVBUl9SSUdIVF9ET09SX0FKQVIgPSAncmVhclJpZ2h0RG9vckFqYXInO1xuXG5leHBvcnQgeyBCb2R5SW5mb3JtYXRpb24gfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gVFBNU1xuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgVFBNUyBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJZiBzZXQgdGhlIHN0YXR1cyBvZiB0aGUgdGlyZSBpcyBub3Qga25vd24uXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVU5LTk9XTiAoKSB7XG4gICAgICAgIHJldHVybiBUUE1TLl9NQVAuVU5LTk9XTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUUE1TIGRvZXMgbm90IGZ1bmN0aW9uLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNZU1RFTV9GQVVMVCAoKSB7XG4gICAgICAgIHJldHVybiBUUE1TLl9NQVAuU1lTVEVNX0ZBVUxUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBzZW5zb3Igb2YgdGhlIHRpcmUgZG9lcyBub3QgZnVuY3Rpb24uXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0VOU09SX0ZBVUxUICgpIHtcbiAgICAgICAgcmV0dXJuIFRQTVMuX01BUC5TRU5TT1JfRkFVTFQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVFBNUyBpcyByZXBvcnRpbmcgYSBsb3cgdGlyZSBwcmVzc3VyZSBmb3IgdGhlIHRpcmUuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTE9XICgpIHtcbiAgICAgICAgcmV0dXJuIFRQTVMuX01BUC5MT1c7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVFBNUyBpcyBhY3RpdmUgYW5kIHRoZSB0aXJlIHByZXNzdXJlIGlzIG1vbml0b3JlZC5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTWVNURU1fQUNUSVZFICgpIHtcbiAgICAgICAgcmV0dXJuIFRQTVMuX01BUC5TWVNURU1fQUNUSVZFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRQTVMgaXMgcmVwb3J0aW5nIHRoYXQgdGhlIHRpcmUgbXVzdCBiZSB0cmFpbmVkLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFRSQUlOICgpIHtcbiAgICAgICAgcmV0dXJuIFRQTVMuX01BUC5UUkFJTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUUE1TIHJlcG9ydHMgdGhlIHRyYWluaW5nIGZvciB0aGUgdGlyZSBpcyBjb21wbGV0ZWQuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVFJBSU5JTkdfQ09NUExFVEUgKCkge1xuICAgICAgICByZXR1cm4gVFBNUy5fTUFQLlRSQUlOSU5HX0NPTVBMRVRFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRQTVMgcmVwb3J0cyB0aGUgdGlyZSBpcyBub3QgdHJhaW5lZC5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOT1RfVFJBSU5FRCAoKSB7XG4gICAgICAgIHJldHVybiBUUE1TLl9NQVAuTk9UX1RSQUlORUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gVFBNUy5fdmFsdWVGb3JLZXkoa2V5LCBUUE1TLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gVFBNUy5fa2V5Rm9yVmFsdWUodmFsdWUsIFRQTVMuX01BUCk7XG4gICAgfVxufVxuXG5UUE1TLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnVU5LTk9XTic6ICdVTktOT1dOJyxcbiAgICAnU1lTVEVNX0ZBVUxUJzogJ1NZU1RFTV9GQVVMVCcsXG4gICAgJ1NFTlNPUl9GQVVMVCc6ICdTRU5TT1JfRkFVTFQnLFxuICAgICdMT1cnOiAnTE9XJyxcbiAgICAnU1lTVEVNX0FDVElWRSc6ICdTWVNURU1fQUNUSVZFJyxcbiAgICAnVFJBSU4nOiAnVFJBSU4nLFxuICAgICdUUkFJTklOR19DT01QTEVURSc6ICdUUkFJTklOR19DT01QTEVURScsXG4gICAgJ05PVF9UUkFJTkVEJzogJ05PVF9UUkFJTkVEJyxcbn0pO1xuXG5leHBvcnQgeyBUUE1TIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgQ29tcG9uZW50Vm9sdW1lU3RhdHVzIH0gZnJvbSAnLi4vZW51bXMvQ29tcG9uZW50Vm9sdW1lU3RhdHVzLmpzJztcbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBUUE1TIH0gZnJvbSAnLi4vZW51bXMvVFBNUy5qcyc7XG5cbmNsYXNzIFNpbmdsZVRpcmVTdGF0dXMgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Q29tcG9uZW50Vm9sdW1lU3RhdHVzfSBzdGF0dXMgLSBTZWUgQ29tcG9uZW50Vm9sdW1lU3RhdHVzLlxuICAgICAqIEByZXR1cm4ge1NpbmdsZVRpcmVTdGF0dXN9XG4gICAgICovXG4gICAgc2V0U3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQ29tcG9uZW50Vm9sdW1lU3RhdHVzLCBzdGF0dXMpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTaW5nbGVUaXJlU3RhdHVzLktFWV9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0NvbXBvbmVudFZvbHVtZVN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRTdGF0dXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQ29tcG9uZW50Vm9sdW1lU3RhdHVzLCBTaW5nbGVUaXJlU3RhdHVzLktFWV9TVEFUVVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VFBNU30gdHBtcyAtIFRoZSBzdGF0dXMgb2YgVFBNUyBhY2NvcmRpbmcgdG8gdGhlIHBhcnRpY3VsYXIgdGlyZS5cbiAgICAgKiBAcmV0dXJuIHtTaW5nbGVUaXJlU3RhdHVzfVxuICAgICAqL1xuICAgIHNldFRwbXMgKHRwbXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVFBNUywgdHBtcyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNpbmdsZVRpcmVTdGF0dXMuS0VZX1RQTVMsIHRwbXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtUUE1TfVxuICAgICAqL1xuICAgIGdldFRwbXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVFBNUywgU2luZ2xlVGlyZVN0YXR1cy5LRVlfVFBNUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHByZXNzdXJlIC0gVGhlIHByZXNzdXJlIHZhbHVlIG9mIHRoZSBwYXJ0aWN1bGFyIHRpcmUgaW4ga2lsbyBwYXNjYWwuXG4gICAgICogQHJldHVybiB7U2luZ2xlVGlyZVN0YXR1c31cbiAgICAgKi9cbiAgICBzZXRQcmVzc3VyZSAocHJlc3N1cmUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2luZ2xlVGlyZVN0YXR1cy5LRVlfUFJFU1NVUkUsIHByZXNzdXJlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFByZXNzdXJlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNpbmdsZVRpcmVTdGF0dXMuS0VZX1BSRVNTVVJFKTtcbiAgICB9XG59XG5cblNpbmdsZVRpcmVTdGF0dXMuS0VZX1NUQVRVUyA9ICdzdGF0dXMnO1xuU2luZ2xlVGlyZVN0YXR1cy5LRVlfVFBNUyA9ICd0cG1zJztcblNpbmdsZVRpcmVTdGF0dXMuS0VZX1BSRVNTVVJFID0gJ3ByZXNzdXJlJztcblxuZXhwb3J0IHsgU2luZ2xlVGlyZVN0YXR1cyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIFJlZmxlY3RzIHRoZSBzdGF0dXMgb2YgYSBjbHVzdGVyIGluc3RydW1lbnQgd2FybmluZyBsaWdodC5cbiAqIEB0eXBlZGVmIHtFbnVtfSBXYXJuaW5nTGlnaHRTdGF0dXNcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIFdhcm5pbmdMaWdodFN0YXR1cyBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBXTFNfT0ZGICgpIHtcbiAgICAgICAgcmV0dXJuIFdhcm5pbmdMaWdodFN0YXR1cy5fTUFQLldMU19PRkY7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgV0xTX09OICgpIHtcbiAgICAgICAgcmV0dXJuIFdhcm5pbmdMaWdodFN0YXR1cy5fTUFQLldMU19PTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBXTFNfRkxBU0ggKCkge1xuICAgICAgICByZXR1cm4gV2FybmluZ0xpZ2h0U3RhdHVzLl9NQVAuV0xTX0ZMQVNIO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFdMU19OT1RfVVNFRCAoKSB7XG4gICAgICAgIHJldHVybiBXYXJuaW5nTGlnaHRTdGF0dXMuX01BUC5XTFNfTk9UX1VTRUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gV2FybmluZ0xpZ2h0U3RhdHVzLl92YWx1ZUZvcktleShrZXksIFdhcm5pbmdMaWdodFN0YXR1cy5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFdhcm5pbmdMaWdodFN0YXR1cy5fa2V5Rm9yVmFsdWUodmFsdWUsIFdhcm5pbmdMaWdodFN0YXR1cy5fTUFQKTtcbiAgICB9XG59XG5cbldhcm5pbmdMaWdodFN0YXR1cy5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1dMU19PRkYnOiAnT0ZGJyxcbiAgICAnV0xTX09OJzogJ09OJyxcbiAgICAnV0xTX0ZMQVNIJzogJ0ZMQVNIJyxcbiAgICAnV0xTX05PVF9VU0VEJzogJ05PVF9VU0VEJyxcbn0pO1xuXG5leHBvcnQgeyBXYXJuaW5nTGlnaHRTdGF0dXMgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgU2luZ2xlVGlyZVN0YXR1cyB9IGZyb20gJy4vU2luZ2xlVGlyZVN0YXR1cy5qcyc7XG5pbXBvcnQgeyBXYXJuaW5nTGlnaHRTdGF0dXMgfSBmcm9tICcuLi9lbnVtcy9XYXJuaW5nTGlnaHRTdGF0dXMuanMnO1xuXG4vKipcbiAqIFRoZSBzdGF0dXMgYW5kIHByZXNzdXJlIG9mIHRoZSB0aXJlcy5cbiAqL1xuY2xhc3MgVGlyZVN0YXR1cyBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtXYXJuaW5nTGlnaHRTdGF0dXN9IHRlbGx0YWxlIC0gU3RhdHVzIG9mIHRoZSBUaXJlIFByZXNzdXJlIFRlbGx0YWxlLiBTZWUgV2FybmluZ0xpZ2h0U3RhdHVzLlxuICAgICAqIEByZXR1cm4ge1RpcmVTdGF0dXN9XG4gICAgICovXG4gICAgc2V0UHJlc3N1cmVUZWxsdGFsZSAodGVsbHRhbGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoV2FybmluZ0xpZ2h0U3RhdHVzLCB0ZWxsdGFsZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFRpcmVTdGF0dXMuS0VZX1BSRVNTVVJFX1RFTExUQUxFLCB0ZWxsdGFsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1dhcm5pbmdMaWdodFN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRQcmVzc3VyZVRlbGx0YWxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFdhcm5pbmdMaWdodFN0YXR1cywgVGlyZVN0YXR1cy5LRVlfUFJFU1NVUkVfVEVMTFRBTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2luZ2xlVGlyZVN0YXR1c30gZnJvbnQgLSBUaGUgc3RhdHVzIG9mIHRoZSBsZWZ0IGZyb250IHRpcmUuXG4gICAgICogQHJldHVybiB7VGlyZVN0YXR1c31cbiAgICAgKi9cbiAgICBzZXRMZWZ0RnJvbnQgKGZyb250KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFNpbmdsZVRpcmVTdGF0dXMsIGZyb250KTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVGlyZVN0YXR1cy5LRVlfTEVGVF9GUk9OVCwgZnJvbnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTaW5nbGVUaXJlU3RhdHVzfVxuICAgICAqL1xuICAgIGdldExlZnRGcm9udCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChTaW5nbGVUaXJlU3RhdHVzLCBUaXJlU3RhdHVzLktFWV9MRUZUX0ZST05UKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NpbmdsZVRpcmVTdGF0dXN9IGZyb250IC0gVGhlIHN0YXR1cyBvZiB0aGUgcmlnaHQgZnJvbnQgdGlyZS5cbiAgICAgKiBAcmV0dXJuIHtUaXJlU3RhdHVzfVxuICAgICAqL1xuICAgIHNldFJpZ2h0RnJvbnQgKGZyb250KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFNpbmdsZVRpcmVTdGF0dXMsIGZyb250KTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVGlyZVN0YXR1cy5LRVlfUklHSFRfRlJPTlQsIGZyb250KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U2luZ2xlVGlyZVN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRSaWdodEZyb250ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFNpbmdsZVRpcmVTdGF0dXMsIFRpcmVTdGF0dXMuS0VZX1JJR0hUX0ZST05UKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NpbmdsZVRpcmVTdGF0dXN9IHJlYXIgLSBUaGUgc3RhdHVzIG9mIHRoZSBsZWZ0IHJlYXIgdGlyZS5cbiAgICAgKiBAcmV0dXJuIHtUaXJlU3RhdHVzfVxuICAgICAqL1xuICAgIHNldExlZnRSZWFyIChyZWFyKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFNpbmdsZVRpcmVTdGF0dXMsIHJlYXIpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihUaXJlU3RhdHVzLktFWV9MRUZUX1JFQVIsIHJlYXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTaW5nbGVUaXJlU3RhdHVzfVxuICAgICAqL1xuICAgIGdldExlZnRSZWFyICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFNpbmdsZVRpcmVTdGF0dXMsIFRpcmVTdGF0dXMuS0VZX0xFRlRfUkVBUik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTaW5nbGVUaXJlU3RhdHVzfSByZWFyIC0gVGhlIHN0YXR1cyBvZiB0aGUgcmlnaHQgcmVhciB0aXJlLlxuICAgICAqIEByZXR1cm4ge1RpcmVTdGF0dXN9XG4gICAgICovXG4gICAgc2V0UmlnaHRSZWFyIChyZWFyKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFNpbmdsZVRpcmVTdGF0dXMsIHJlYXIpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihUaXJlU3RhdHVzLktFWV9SSUdIVF9SRUFSLCByZWFyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U2luZ2xlVGlyZVN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRSaWdodFJlYXIgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoU2luZ2xlVGlyZVN0YXR1cywgVGlyZVN0YXR1cy5LRVlfUklHSFRfUkVBUik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTaW5nbGVUaXJlU3RhdHVzfSByZWFyIC0gVGhlIHN0YXR1cyBvZiB0aGUgaW5uZXIgbGVmdCByZWFyLlxuICAgICAqIEByZXR1cm4ge1RpcmVTdGF0dXN9XG4gICAgICovXG4gICAgc2V0SW5uZXJMZWZ0UmVhciAocmVhcikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShTaW5nbGVUaXJlU3RhdHVzLCByZWFyKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVGlyZVN0YXR1cy5LRVlfSU5ORVJfTEVGVF9SRUFSLCByZWFyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U2luZ2xlVGlyZVN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRJbm5lckxlZnRSZWFyICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFNpbmdsZVRpcmVTdGF0dXMsIFRpcmVTdGF0dXMuS0VZX0lOTkVSX0xFRlRfUkVBUik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTaW5nbGVUaXJlU3RhdHVzfSByZWFyIC0gVGhlIHN0YXR1cyBvZiB0aGUgaW5uZXIgcmlnaHQgcmVhci5cbiAgICAgKiBAcmV0dXJuIHtUaXJlU3RhdHVzfVxuICAgICAqL1xuICAgIHNldElubmVyUmlnaHRSZWFyIChyZWFyKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFNpbmdsZVRpcmVTdGF0dXMsIHJlYXIpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihUaXJlU3RhdHVzLktFWV9JTk5FUl9SSUdIVF9SRUFSLCByZWFyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U2luZ2xlVGlyZVN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRJbm5lclJpZ2h0UmVhciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChTaW5nbGVUaXJlU3RhdHVzLCBUaXJlU3RhdHVzLktFWV9JTk5FUl9SSUdIVF9SRUFSKTtcbiAgICB9XG59XG5cblRpcmVTdGF0dXMuS0VZX1BSRVNTVVJFX1RFTExUQUxFID0gJ3ByZXNzdXJlVGVsbHRhbGUnO1xuVGlyZVN0YXR1cy5LRVlfTEVGVF9GUk9OVCA9ICdsZWZ0RnJvbnQnO1xuVGlyZVN0YXR1cy5LRVlfUklHSFRfRlJPTlQgPSAncmlnaHRGcm9udCc7XG5UaXJlU3RhdHVzLktFWV9MRUZUX1JFQVIgPSAnbGVmdFJlYXInO1xuVGlyZVN0YXR1cy5LRVlfUklHSFRfUkVBUiA9ICdyaWdodFJlYXInO1xuVGlyZVN0YXR1cy5LRVlfSU5ORVJfTEVGVF9SRUFSID0gJ2lubmVyTGVmdFJlYXInO1xuVGlyZVN0YXR1cy5LRVlfSU5ORVJfUklHSFRfUkVBUiA9ICdpbm5lclJpZ2h0UmVhcic7XG5cbmV4cG9ydCB7IFRpcmVTdGF0dXMgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBBaXJiYWdTdGF0dXMgfSBmcm9tICcuLi9zdHJ1Y3RzL0FpcmJhZ1N0YXR1cy5qcyc7XG5pbXBvcnQgeyBDbHVzdGVyTW9kZVN0YXR1cyB9IGZyb20gJy4uL3N0cnVjdHMvQ2x1c3Rlck1vZGVTdGF0dXMuanMnO1xuaW1wb3J0IHsgVmVoaWNsZURhdGFFdmVudFN0YXR1cyB9IGZyb20gJy4uL2VudW1zL1ZlaGljbGVEYXRhRXZlbnRTdGF0dXMuanMnO1xuaW1wb3J0IHsgRW1lcmdlbmN5RXZlbnQgfSBmcm9tICcuLi9zdHJ1Y3RzL0VtZXJnZW5jeUV2ZW50LmpzJztcbmltcG9ydCB7IFR1cm5TaWduYWwgfSBmcm9tICcuLi9lbnVtcy9UdXJuU2lnbmFsLmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgSGVhZExhbXBTdGF0dXMgfSBmcm9tICcuLi9zdHJ1Y3RzL0hlYWRMYW1wU3RhdHVzLmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IERldmljZVN0YXR1cyB9IGZyb20gJy4uL3N0cnVjdHMvRGV2aWNlU3RhdHVzLmpzJztcbmltcG9ydCB7IFdpcGVyU3RhdHVzIH0gZnJvbSAnLi4vZW51bXMvV2lwZXJTdGF0dXMuanMnO1xuaW1wb3J0IHsgRWxlY3Ryb25pY1BhcmtCcmFrZVN0YXR1cyB9IGZyb20gJy4uL2VudW1zL0VsZWN0cm9uaWNQYXJrQnJha2VTdGF0dXMuanMnO1xuaW1wb3J0IHsgTXlLZXkgfSBmcm9tICcuLi9zdHJ1Y3RzL015S2V5LmpzJztcbmltcG9ydCB7IEdQU0RhdGEgfSBmcm9tICcuLi9zdHJ1Y3RzL0dQU0RhdGEuanMnO1xuaW1wb3J0IHsgUFJOREwgfSBmcm9tICcuLi9lbnVtcy9QUk5ETC5qcyc7XG5pbXBvcnQgeyBGdWVsUmFuZ2UgfSBmcm9tICcuLi9zdHJ1Y3RzL0Z1ZWxSYW5nZS5qcyc7XG5pbXBvcnQgeyBFQ2FsbEluZm8gfSBmcm9tICcuLi9zdHJ1Y3RzL0VDYWxsSW5mby5qcyc7XG5pbXBvcnQgeyBCZWx0U3RhdHVzIH0gZnJvbSAnLi4vc3RydWN0cy9CZWx0U3RhdHVzLmpzJztcbmltcG9ydCB7IENvbXBvbmVudFZvbHVtZVN0YXR1cyB9IGZyb20gJy4uL2VudW1zL0NvbXBvbmVudFZvbHVtZVN0YXR1cy5qcyc7XG5pbXBvcnQgeyBCb2R5SW5mb3JtYXRpb24gfSBmcm9tICcuLi9zdHJ1Y3RzL0JvZHlJbmZvcm1hdGlvbi5qcyc7XG5pbXBvcnQgeyBUaXJlU3RhdHVzIH0gZnJvbSAnLi4vc3RydWN0cy9UaXJlU3RhdHVzLmpzJztcblxuY2xhc3MgR2V0VmVoaWNsZURhdGFSZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkdldFZlaGljbGVEYXRhKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0dQU0RhdGF9IGdwcyAtIFNlZSBHUFNEYXRhXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRHcHMgKGdwcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShHUFNEYXRhLCBncHMpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9HUFMsIGdwcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0dQU0RhdGF9XG4gICAgICovXG4gICAgZ2V0R3BzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEdQU0RhdGEsIEdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0dQUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNwZWVkIC0gVGhlIHZlaGljbGUgc3BlZWQgaW4ga2lsb21ldGVycyBwZXIgaG91clxuICAgICAqIEByZXR1cm4ge0dldFZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0U3BlZWQgKHNwZWVkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1NQRUVELCBzcGVlZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRTcGVlZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9TUEVFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHJwbSAtIFRoZSBudW1iZXIgb2YgcmV2b2x1dGlvbnMgcGVyIG1pbnV0ZSBvZiB0aGUgZW5naW5lXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRScG0gKHJwbSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9SUE0sIHJwbSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRScG0gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfUlBNKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbGV2ZWwgLSBUaGUgZnVlbCBsZXZlbCBpbiB0aGUgdGFuayAocGVyY2VudGFnZSlcbiAgICAgKiBAcmV0dXJuIHtHZXRWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldEZ1ZWxMZXZlbCAobGV2ZWwpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRlVFTF9MRVZFTCwgbGV2ZWwpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0RnVlbExldmVsICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0ZVRUxfTEVWRUwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Q29tcG9uZW50Vm9sdW1lU3RhdHVzfSBsZXZlbF9zdGF0ZSAtIFRoZSBmdWVsIGxldmVsIHN0YXRlXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRGdWVsTGV2ZWxfU3RhdGUgKGxldmVsX3N0YXRlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKENvbXBvbmVudFZvbHVtZVN0YXR1cywgbGV2ZWxfc3RhdGUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9GVUVMX0xFVkVMX1NUQVRFLCBsZXZlbF9zdGF0ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0NvbXBvbmVudFZvbHVtZVN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRGdWVsTGV2ZWxfU3RhdGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQ29tcG9uZW50Vm9sdW1lU3RhdHVzLCBHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9GVUVMX0xFVkVMX1NUQVRFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gY29uc3VtcHRpb24gLSBUaGUgaW5zdGFudGFuZW91cyBmdWVsIGNvbnN1bXB0aW9uIGluIG1pY3JvbGl0cmVzXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRJbnN0YW50RnVlbENvbnN1bXB0aW9uIChjb25zdW1wdGlvbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9JTlNUQU5UX0ZVRUxfQ09OU1VNUFRJT04sIGNvbnN1bXB0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldEluc3RhbnRGdWVsQ29uc3VtcHRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfSU5TVEFOVF9GVUVMX0NPTlNVTVBUSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Z1ZWxSYW5nZVtdfSByYW5nZSAtIFRoZSBlc3RpbWF0ZSByYW5nZSBpbiBLTSB0aGUgdmVoaWNsZSBjYW4gdHJhdmVsIGJhc2VkIG9uIGZ1ZWwgbGV2ZWwgYW5kIGNvbnN1bXB0aW9uXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRGdWVsUmFuZ2UgKHJhbmdlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEZ1ZWxSYW5nZSwgcmFuZ2UsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9GVUVMX1JBTkdFLCByYW5nZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Z1ZWxSYW5nZVtdfVxuICAgICAqL1xuICAgIGdldEZ1ZWxSYW5nZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChGdWVsUmFuZ2UsIEdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0ZVRUxfUkFOR0UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB0ZW1wZXJhdHVyZSAtIFRoZSBleHRlcm5hbCB0ZW1wZXJhdHVyZSBpbiBkZWdyZWVzIGNlbHNpdXNcbiAgICAgKiBAcmV0dXJuIHtHZXRWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldEV4dGVybmFsVGVtcGVyYXR1cmUgKHRlbXBlcmF0dXJlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0VYVEVSTkFMX1RFTVBFUkFUVVJFLCB0ZW1wZXJhdHVyZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRFeHRlcm5hbFRlbXBlcmF0dXJlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0VYVEVSTkFMX1RFTVBFUkFUVVJFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1R1cm5TaWduYWx9IHNpZ25hbCAtIFNlZSBUdXJuU2lnbmFsXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRUdXJuU2lnbmFsIChzaWduYWwpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVHVyblNpZ25hbCwgc2lnbmFsKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfVFVSTl9TSUdOQUwsIHNpZ25hbCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1R1cm5TaWduYWx9XG4gICAgICovXG4gICAgZ2V0VHVyblNpZ25hbCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChUdXJuU2lnbmFsLCBHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9UVVJOX1NJR05BTCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHZpbiAtIFZlaGljbGUgaWRlbnRpZmljYXRpb24gbnVtYmVyXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRWaW4gKHZpbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9WSU4sIHZpbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRWaW4gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfVklOKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1BSTkRMfSBwcm5kbCAtIFNlZSBQUk5ETFxuICAgICAqIEByZXR1cm4ge0dldFZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0UHJuZGwgKHBybmRsKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFBSTkRMLCBwcm5kbCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1BSTkRMLCBwcm5kbCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1BSTkRMfVxuICAgICAqL1xuICAgIGdldFBybmRsICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFBSTkRMLCBHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9QUk5ETCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtUaXJlU3RhdHVzfSBwcmVzc3VyZSAtIFNlZSBUaXJlU3RhdHVzXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRUaXJlUHJlc3N1cmUgKHByZXNzdXJlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFRpcmVTdGF0dXMsIHByZXNzdXJlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfVElSRV9QUkVTU1VSRSwgcHJlc3N1cmUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtUaXJlU3RhdHVzfVxuICAgICAqL1xuICAgIGdldFRpcmVQcmVzc3VyZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChUaXJlU3RhdHVzLCBHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9USVJFX1BSRVNTVVJFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gb2RvbWV0ZXIgLSBPZG9tZXRlciBpbiBrbVxuICAgICAqIEByZXR1cm4ge0dldFZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0T2RvbWV0ZXIgKG9kb21ldGVyKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX09ET01FVEVSLCBvZG9tZXRlcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRPZG9tZXRlciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9PRE9NRVRFUik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCZWx0U3RhdHVzfSBzdGF0dXMgLSBUaGUgc3RhdHVzIG9mIHRoZSBzZWF0IGJlbHRzXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRCZWx0U3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQmVsdFN0YXR1cywgc3RhdHVzKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQkVMVF9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0JlbHRTdGF0dXN9XG4gICAgICovXG4gICAgZ2V0QmVsdFN0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChCZWx0U3RhdHVzLCBHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9CRUxUX1NUQVRVUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb2R5SW5mb3JtYXRpb259IGluZm9ybWF0aW9uIC0gVGhlIGJvZHkgaW5mb3JtYXRpb24gaW5jbHVkaW5nIHBvd2VyIG1vZGVzXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRCb2R5SW5mb3JtYXRpb24gKGluZm9ybWF0aW9uKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEJvZHlJbmZvcm1hdGlvbiwgaW5mb3JtYXRpb24pO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9CT0RZX0lORk9STUFUSU9OLCBpbmZvcm1hdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0JvZHlJbmZvcm1hdGlvbn1cbiAgICAgKi9cbiAgICBnZXRCb2R5SW5mb3JtYXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQm9keUluZm9ybWF0aW9uLCBHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9CT0RZX0lORk9STUFUSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0RldmljZVN0YXR1c30gc3RhdHVzIC0gVGhlIGRldmljZSBzdGF0dXMgaW5jbHVkaW5nIHNpZ25hbCBhbmQgYmF0dGVyeSBzdHJlbmd0aFxuICAgICAqIEByZXR1cm4ge0dldFZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0RGV2aWNlU3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoRGV2aWNlU3RhdHVzLCBzdGF0dXMpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9ERVZJQ0VfU1RBVFVTLCBzdGF0dXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtEZXZpY2VTdGF0dXN9XG4gICAgICovXG4gICAgZ2V0RGV2aWNlU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KERldmljZVN0YXR1cywgR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfREVWSUNFX1NUQVRVUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfSBicmFraW5nIC0gVGhlIHN0YXR1cyBvZiB0aGUgYnJha2UgcGVkYWxcbiAgICAgKiBAcmV0dXJuIHtHZXRWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldERyaXZlckJyYWtpbmcgKGJyYWtpbmcpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFFdmVudFN0YXR1cywgYnJha2luZyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0RSSVZFUl9CUkFLSU5HLCBicmFraW5nKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFFdmVudFN0YXR1c31cbiAgICAgKi9cbiAgICBnZXREcml2ZXJCcmFraW5nICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIEdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0RSSVZFUl9CUkFLSU5HKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1dpcGVyU3RhdHVzfSBzdGF0dXMgLSBUaGUgc3RhdHVzIG9mIHRoZSB3aXBlcnNcbiAgICAgKiBAcmV0dXJuIHtHZXRWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldFdpcGVyU3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoV2lwZXJTdGF0dXMsIHN0YXR1cyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1dJUEVSX1NUQVRVUywgc3RhdHVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7V2lwZXJTdGF0dXN9XG4gICAgICovXG4gICAgZ2V0V2lwZXJTdGF0dXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoV2lwZXJTdGF0dXMsIEdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1dJUEVSX1NUQVRVUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtIZWFkTGFtcFN0YXR1c30gc3RhdHVzIC0gU3RhdHVzIG9mIHRoZSBoZWFkIGxhbXBzXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRIZWFkTGFtcFN0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEhlYWRMYW1wU3RhdHVzLCBzdGF0dXMpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9IRUFEX0xBTVBfU1RBVFVTLCBzdGF0dXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtIZWFkTGFtcFN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRIZWFkTGFtcFN0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChIZWFkTGFtcFN0YXR1cywgR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfSEVBRF9MQU1QX1NUQVRVUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHRvcnF1ZSAtIFRvcnF1ZSB2YWx1ZSBmb3IgZW5naW5lIChpbiBObSkgb24gbm9uLWRpZXNlbCB2YXJpYW50c1xuICAgICAqIEByZXR1cm4ge0dldFZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0RW5naW5lVG9ycXVlICh0b3JxdWUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRU5HSU5FX1RPUlFVRSwgdG9ycXVlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldEVuZ2luZVRvcnF1ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9FTkdJTkVfVE9SUVVFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gcG9zaXRpb24gLSBBY2NlbGVyYXRvciBwZWRhbCBwb3NpdGlvbiAocGVyY2VudGFnZSBkZXByZXNzZWQpXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRBY2NQZWRhbFBvc2l0aW9uIChwb3NpdGlvbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9BQ0NfUEVEQUxfUE9TSVRJT04sIHBvc2l0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldEFjY1BlZGFsUG9zaXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQUNDX1BFREFMX1BPU0lUSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYW5nbGUgLSBDdXJyZW50IGFuZ2xlIG9mIHRoZSBzdGVlcmluZyB3aGVlbCAoaW4gZGVnKVxuICAgICAqIEByZXR1cm4ge0dldFZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0U3RlZXJpbmdXaGVlbEFuZ2xlIChhbmdsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9TVEVFUklOR19XSEVFTF9BTkdMRSwgYW5nbGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0U3RlZXJpbmdXaGVlbEFuZ2xlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1NURUVSSU5HX1dIRUVMX0FOR0xFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbGlmZSAtIFRoZSBlc3RpbWF0ZWQgcGVyY2VudGFnZSBvZiByZW1haW5pbmcgb2lsIGxpZmUgb2YgdGhlIGVuZ2luZS5cbiAgICAgKiBAcmV0dXJuIHtHZXRWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldEVuZ2luZU9pbExpZmUgKGxpZmUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRU5HSU5FX09JTF9MSUZFLCBsaWZlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldEVuZ2luZU9pbExpZmUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRU5HSU5FX09JTF9MSUZFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0VsZWN0cm9uaWNQYXJrQnJha2VTdGF0dXN9IHN0YXR1cyAtIFRoZSBzdGF0dXMgb2YgdGhlIHBhcmsgYnJha2UgYXMgcHJvdmlkZWQgYnkgRWxlY3RyaWMgUGFyayBCcmFrZSAoRVBCKVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtLlxuICAgICAqIEByZXR1cm4ge0dldFZlaGljbGVEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0RWxlY3Ryb25pY1BhcmtCcmFrZVN0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEVsZWN0cm9uaWNQYXJrQnJha2VTdGF0dXMsIHN0YXR1cyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0VMRUNUUk9OSUNfUEFSS19CUkFLRV9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0VsZWN0cm9uaWNQYXJrQnJha2VTdGF0dXN9XG4gICAgICovXG4gICAgZ2V0RWxlY3Ryb25pY1BhcmtCcmFrZVN0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChFbGVjdHJvbmljUGFya0JyYWtlU3RhdHVzLCBHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9FTEVDVFJPTklDX1BBUktfQlJBS0VfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gaWQgLSBQYXJhbWV0ZXIgdXNlZCBieSBjbG91ZCBhcHBzIHRvIGlkZW50aWZ5IGEgaGVhZCB1bml0XG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRDbG91ZEFwcFZlaGljbGVJRCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQ0xPVURfQVBQX1ZFSElDTEVfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldENsb3VkQXBwVmVoaWNsZUlEICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0NMT1VEX0FQUF9WRUhJQ0xFX0lEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0VDYWxsSW5mb30gaW5mbyAtIEVtZXJnZW5jeSBDYWxsIG5vdGlmaWNhdGlvbiBhbmQgY29uZmlybWF0aW9uIGRhdGFcbiAgICAgKiBAcmV0dXJuIHtHZXRWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldEVDYWxsSW5mbyAoaW5mbykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShFQ2FsbEluZm8sIGluZm8pO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9FX0NBTExfSU5GTywgaW5mbyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0VDYWxsSW5mb31cbiAgICAgKi9cbiAgICBnZXRFQ2FsbEluZm8gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoRUNhbGxJbmZvLCBHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9FX0NBTExfSU5GTyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtBaXJiYWdTdGF0dXN9IHN0YXR1cyAtIFRoZSBzdGF0dXMgb2YgdGhlIGFpciBiYWdzXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRBaXJiYWdTdGF0dXMgKHN0YXR1cykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShBaXJiYWdTdGF0dXMsIHN0YXR1cyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0FJUkJBR19TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0FpcmJhZ1N0YXR1c31cbiAgICAgKi9cbiAgICBnZXRBaXJiYWdTdGF0dXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQWlyYmFnU3RhdHVzLCBHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9BSVJCQUdfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0VtZXJnZW5jeUV2ZW50fSBldmVudCAtIEluZm9ybWF0aW9uIHJlbGF0ZWQgdG8gYW4gZW1lcmdlbmN5IGV2ZW50IChhbmQgaWYgaXQgb2NjdXJyZWQpXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRFbWVyZ2VuY3lFdmVudCAoZXZlbnQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoRW1lcmdlbmN5RXZlbnQsIGV2ZW50KTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRU1FUkdFTkNZX0VWRU5ULCBldmVudCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0VtZXJnZW5jeUV2ZW50fVxuICAgICAqL1xuICAgIGdldEVtZXJnZW5jeUV2ZW50ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEVtZXJnZW5jeUV2ZW50LCBHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9FTUVSR0VOQ1lfRVZFTlQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Q2x1c3Rlck1vZGVTdGF0dXN9IHN0YXR1cyAtIFRoZSBzdGF0dXMgbW9kZXMgb2YgdGhlIGNsdXN0ZXJcbiAgICAgKiBAcmV0dXJuIHtHZXRWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldENsdXN0ZXJNb2RlU3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQ2x1c3Rlck1vZGVTdGF0dXMsIHN0YXR1cyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0NMVVNURVJfTU9ERV9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0NsdXN0ZXJNb2RlU3RhdHVzfVxuICAgICAqL1xuICAgIGdldENsdXN0ZXJNb2RlU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KENsdXN0ZXJNb2RlU3RhdHVzLCBHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9DTFVTVEVSX01PREVfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge015S2V5fSBrZXkgLSBJbmZvcm1hdGlvbiByZWxhdGVkIHRvIHRoZSBNeUtleSBmZWF0dXJlXG4gICAgICogQHJldHVybiB7R2V0VmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRNeUtleSAoa2V5KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKE15S2V5LCBrZXkpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9NWV9LRVksIGtleSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge015S2V5fVxuICAgICAqL1xuICAgIGdldE15S2V5ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KE15S2V5LCBHZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9NWV9LRVkpO1xuICAgIH1cbn1cblxuR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfR1BTID0gJ2dwcyc7XG5HZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9TUEVFRCA9ICdzcGVlZCc7XG5HZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9SUE0gPSAncnBtJztcbkdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0ZVRUxfTEVWRUwgPSAnZnVlbExldmVsJztcbkdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0ZVRUxfTEVWRUxfU1RBVEUgPSAnZnVlbExldmVsX1N0YXRlJztcbkdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0lOU1RBTlRfRlVFTF9DT05TVU1QVElPTiA9ICdpbnN0YW50RnVlbENvbnN1bXB0aW9uJztcbkdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0ZVRUxfUkFOR0UgPSAnZnVlbFJhbmdlJztcbkdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0VYVEVSTkFMX1RFTVBFUkFUVVJFID0gJ2V4dGVybmFsVGVtcGVyYXR1cmUnO1xuR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfVFVSTl9TSUdOQUwgPSAndHVyblNpZ25hbCc7XG5HZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9WSU4gPSAndmluJztcbkdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1BSTkRMID0gJ3BybmRsJztcbkdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX1RJUkVfUFJFU1NVUkUgPSAndGlyZVByZXNzdXJlJztcbkdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX09ET01FVEVSID0gJ29kb21ldGVyJztcbkdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0JFTFRfU1RBVFVTID0gJ2JlbHRTdGF0dXMnO1xuR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQk9EWV9JTkZPUk1BVElPTiA9ICdib2R5SW5mb3JtYXRpb24nO1xuR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfREVWSUNFX1NUQVRVUyA9ICdkZXZpY2VTdGF0dXMnO1xuR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRFJJVkVSX0JSQUtJTkcgPSAnZHJpdmVyQnJha2luZyc7XG5HZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9XSVBFUl9TVEFUVVMgPSAnd2lwZXJTdGF0dXMnO1xuR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfSEVBRF9MQU1QX1NUQVRVUyA9ICdoZWFkTGFtcFN0YXR1cyc7XG5HZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9FTkdJTkVfVE9SUVVFID0gJ2VuZ2luZVRvcnF1ZSc7XG5HZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9BQ0NfUEVEQUxfUE9TSVRJT04gPSAnYWNjUGVkYWxQb3NpdGlvbic7XG5HZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9TVEVFUklOR19XSEVFTF9BTkdMRSA9ICdzdGVlcmluZ1doZWVsQW5nbGUnO1xuR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRU5HSU5FX09JTF9MSUZFID0gJ2VuZ2luZU9pbExpZmUnO1xuR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfRUxFQ1RST05JQ19QQVJLX0JSQUtFX1NUQVRVUyA9ICdlbGVjdHJvbmljUGFya0JyYWtlU3RhdHVzJztcbkdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0NMT1VEX0FQUF9WRUhJQ0xFX0lEID0gJ2Nsb3VkQXBwVmVoaWNsZUlEJztcbkdldFZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0VfQ0FMTF9JTkZPID0gJ2VDYWxsSW5mbyc7XG5HZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9BSVJCQUdfU1RBVFVTID0gJ2FpcmJhZ1N0YXR1cyc7XG5HZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9FTUVSR0VOQ1lfRVZFTlQgPSAnZW1lcmdlbmN5RXZlbnQnO1xuR2V0VmVoaWNsZURhdGFSZXNwb25zZS5LRVlfQ0xVU1RFUl9NT0RFX1NUQVRVUyA9ICdjbHVzdGVyTW9kZVN0YXR1cyc7XG5HZXRWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9NWV9LRVkgPSAnbXlLZXknO1xuXG5leHBvcnQgeyBHZXRWZWhpY2xlRGF0YVJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG4vKipcbiAqIE5vbiBwZXJpb2RpYyB2ZWhpY2xlIGRhdGEgcmVhZCByZXF1ZXN0XG4gKi9cbmNsYXNzIFJlYWRESUQgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlJlYWRESUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBuYW1lIC0gTmFtZSBvZiBFQ1UuXG4gICAgICogQHJldHVybiB7UmVhZERJRH1cbiAgICAgKi9cbiAgICBzZXRFY3VOYW1lIChuYW1lKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlYWRESUQuS0VZX0VDVV9OQU1FLCBuYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldEVjdU5hbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmVhZERJRC5LRVlfRUNVX05BTUUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyW119IGxvY2F0aW9uIC0gR2V0IHJhdyBkYXRhIGZyb20gdmVoaWNsZSBkYXRhIERJRCBsb2NhdGlvbihzKVxuICAgICAqIEByZXR1cm4ge1JlYWRESUR9XG4gICAgICovXG4gICAgc2V0RGlkTG9jYXRpb24gKGxvY2F0aW9uKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlYWRESUQuS0VZX0RJRF9MT0NBVElPTiwgbG9jYXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJbXX1cbiAgICAgKi9cbiAgICBnZXREaWRMb2NhdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSZWFkRElELktFWV9ESURfTE9DQVRJT04pO1xuICAgIH1cbn1cblxuUmVhZERJRC5LRVlfRUNVX05BTUUgPSAnZWN1TmFtZSc7XG5SZWFkRElELktFWV9ESURfTE9DQVRJT04gPSAnZGlkTG9jYXRpb24nO1xuXG5leHBvcnQgeyBSZWFkRElEIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IFZlaGljbGVEYXRhUmVzdWx0Q29kZSB9IGZyb20gJy4uL2VudW1zL1ZlaGljbGVEYXRhUmVzdWx0Q29kZS5qcyc7XG5cbi8qKlxuICogSW5kaXZpZHVhbCByZXF1ZXN0ZWQgRElEIHJlc3VsdCBhbmQgZGF0YVxuICovXG5jbGFzcyBESURSZXN1bHQgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVoaWNsZURhdGFSZXN1bHRDb2RlfSBjb2RlIC0gSW5kaXZpZHVhbCBESUQgcmVzdWx0IGNvZGUuXG4gICAgICogQHJldHVybiB7RElEUmVzdWx0fVxuICAgICAqL1xuICAgIHNldFJlc3VsdENvZGUgKGNvZGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFSZXN1bHRDb2RlLCBjb2RlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRElEUmVzdWx0LktFWV9SRVNVTFRfQ09ERSwgY29kZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlaGljbGVEYXRhUmVzdWx0Q29kZX1cbiAgICAgKi9cbiAgICBnZXRSZXN1bHRDb2RlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhUmVzdWx0Q29kZSwgRElEUmVzdWx0LktFWV9SRVNVTFRfQ09ERSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGxvY2F0aW9uIC0gTG9jYXRpb24gb2YgcmF3IGRhdGEgZnJvbSB2ZWhpY2xlIGRhdGEgRElEXG4gICAgICogQHJldHVybiB7RElEUmVzdWx0fVxuICAgICAqL1xuICAgIHNldERpZExvY2F0aW9uIChsb2NhdGlvbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihESURSZXN1bHQuS0VZX0RJRF9MT0NBVElPTiwgbG9jYXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0RGlkTG9jYXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoRElEUmVzdWx0LktFWV9ESURfTE9DQVRJT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIC0gUmF3IERJRC1iYXNlZCBkYXRhIHJldHVybmVkIGZvciByZXF1ZXN0ZWQgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJuIHtESURSZXN1bHR9XG4gICAgICovXG4gICAgc2V0RGF0YSAoZGF0YSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihESURSZXN1bHQuS0VZX0RBVEEsIGRhdGEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0RGF0YSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihESURSZXN1bHQuS0VZX0RBVEEpO1xuICAgIH1cbn1cblxuRElEUmVzdWx0LktFWV9SRVNVTFRfQ09ERSA9ICdyZXN1bHRDb2RlJztcbkRJRFJlc3VsdC5LRVlfRElEX0xPQ0FUSU9OID0gJ2RpZExvY2F0aW9uJztcbkRJRFJlc3VsdC5LRVlfREFUQSA9ICdkYXRhJztcblxuZXhwb3J0IHsgRElEUmVzdWx0IH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgRElEUmVzdWx0IH0gZnJvbSAnLi4vc3RydWN0cy9ESURSZXN1bHQuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbmNsYXNzIFJlYWRESURSZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlJlYWRESUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RElEUmVzdWx0W119IHJlc3VsdCAtIEFycmF5IG9mIHJlcXVlc3RlZCBESUQgcmVzdWx0cyAod2l0aCBkYXRhIGlmIGF2YWlsYWJsZSkuXG4gICAgICogQHJldHVybiB7UmVhZERJRFJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldERpZFJlc3VsdCAocmVzdWx0KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKERJRFJlc3VsdCwgcmVzdWx0LCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVhZERJRFJlc3BvbnNlLktFWV9ESURfUkVTVUxULCByZXN1bHQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtESURSZXN1bHRbXX1cbiAgICAgKi9cbiAgICBnZXREaWRSZXN1bHQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoRElEUmVzdWx0LCBSZWFkRElEUmVzcG9uc2UuS0VZX0RJRF9SRVNVTFQpO1xuICAgIH1cbn1cblxuUmVhZERJRFJlc3BvbnNlLktFWV9ESURfUkVTVUxUID0gJ2RpZFJlc3VsdCc7XG5cbmV4cG9ydCB7IFJlYWRESURSZXNwb25zZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1JlcXVlc3QgfSBmcm9tICcuLi9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcblxuLyoqXG4gKiBWZWhpY2xlIG1vZHVsZSBkaWFnbm9zdGljIHRyb3VibGUgY29kZSByZXF1ZXN0LlxuICovXG5jbGFzcyBHZXREVENzIGV4dGVuZHMgUnBjUmVxdWVzdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5HZXREVENzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbmFtZSAtIE5hbWUgb2YgRUNVLlxuICAgICAqIEByZXR1cm4ge0dldERUQ3N9XG4gICAgICovXG4gICAgc2V0RWN1TmFtZSAobmFtZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXREVENzLktFWV9FQ1VfTkFNRSwgbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRFY3VOYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdldERUQ3MuS0VZX0VDVV9OQU1FKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbWFzayAtIERUQyBNYXNrIEJ5dGUgdG8gYmUgc2VudCBpbiBkaWFnbm9zdGljIHJlcXVlc3QgdG8gbW9kdWxlIC5cbiAgICAgKiBAcmV0dXJuIHtHZXREVENzfVxuICAgICAqL1xuICAgIHNldER0Y01hc2sgKG1hc2spIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0RFRDcy5LRVlfRFRDX01BU0ssIG1hc2spO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0RHRjTWFzayAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXREVENzLktFWV9EVENfTUFTSyk7XG4gICAgfVxufVxuXG5HZXREVENzLktFWV9FQ1VfTkFNRSA9ICdlY3VOYW1lJztcbkdldERUQ3MuS0VZX0RUQ19NQVNLID0gJ2R0Y01hc2snO1xuXG5leHBvcnQgeyBHZXREVENzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbmNsYXNzIEdldERUQ3NSZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkdldERUQ3MpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBoZWFkZXIgLSAyIGJ5dGUgRUNVIEhlYWRlciBmb3IgRFRDIHJlc3BvbnNlIChhcyBkZWZpbmVkIGluIFZIUl9MYXlvdXRfU3BlY2lmaWNhdGlvbl9EVENzLnBkZilcbiAgICAgKiBAcmV0dXJuIHtHZXREVENzUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0RWN1SGVhZGVyIChoZWFkZXIpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0RFRDc1Jlc3BvbnNlLktFWV9FQ1VfSEVBREVSLCBoZWFkZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0RWN1SGVhZGVyICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdldERUQ3NSZXNwb25zZS5LRVlfRUNVX0hFQURFUik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmdbXX0gZHRjIC0gQXJyYXkgb2YgYWxsIHJlcG9ydGVkIERUQ3Mgb24gbW9kdWxlIChlY3VIZWFkZXIgY29udGFpbnMgaW5mb3JtYXRpb24gaWYgbGlzdCBpc1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHRydW5jYXRlZCkuIEVhY2ggRFRDIGlzIHJlcHJlc2VudGVkIGJ5IDQgYnl0ZXMgKDMgYnl0ZXMgb2YgZGF0YSBhbmQgMSBieXRlIHN0YXR1cyBhc1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmluZWQgaW4gVkhSX0xheW91dF9TcGVjaWZpY2F0aW9uX0RUQ3MucGRmKS5cbiAgICAgKiBAcmV0dXJuIHtHZXREVENzUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0RHRjIChkdGMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0RFRDc1Jlc3BvbnNlLktFWV9EVEMsIGR0Yyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ1tdfVxuICAgICAqL1xuICAgIGdldER0YyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXREVENzUmVzcG9uc2UuS0VZX0RUQyk7XG4gICAgfVxufVxuXG5HZXREVENzUmVzcG9uc2UuS0VZX0VDVV9IRUFERVIgPSAnZWN1SGVhZGVyJztcbkdldERUQ3NSZXNwb25zZS5LRVlfRFRDID0gJ2R0Yyc7XG5cbmV4cG9ydCB7IEdldERUQ3NSZXNwb25zZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1JlcXVlc3QgfSBmcm9tICcuLi9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcblxuLyoqXG4gKiBOb24gcGVyaW9kaWMgdmVoaWNsZSBkaWFnbm9zdGljIHJlcXVlc3RcbiAqL1xuY2xhc3MgRGlhZ25vc3RpY01lc3NhZ2UgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkRpYWdub3N0aWNNZXNzYWdlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaWQgLSBOYW1lIG9mIHRhcmdldCBFQ1UuXG4gICAgICogQHJldHVybiB7RGlhZ25vc3RpY01lc3NhZ2V9XG4gICAgICovXG4gICAgc2V0VGFyZ2V0SUQgKGlkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKERpYWdub3N0aWNNZXNzYWdlLktFWV9UQVJHRVRfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFRhcmdldElEICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKERpYWdub3N0aWNNZXNzYWdlLktFWV9UQVJHRVRfSUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBsZW5ndGggLSBMZW5ndGggb2YgbWVzc2FnZSAoaW4gYnl0ZXMpLlxuICAgICAqIEByZXR1cm4ge0RpYWdub3N0aWNNZXNzYWdlfVxuICAgICAqL1xuICAgIHNldE1lc3NhZ2VMZW5ndGggKGxlbmd0aCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihEaWFnbm9zdGljTWVzc2FnZS5LRVlfTUVTU0FHRV9MRU5HVEgsIGxlbmd0aCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRNZXNzYWdlTGVuZ3RoICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKERpYWdub3N0aWNNZXNzYWdlLktFWV9NRVNTQUdFX0xFTkdUSCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJbXX0gZGF0YSAtIEFycmF5IG9mIGJ5dGVzIGNvbXByaXNpbmcgQ0FOIG1lc3NhZ2UuXG4gICAgICogQHJldHVybiB7RGlhZ25vc3RpY01lc3NhZ2V9XG4gICAgICovXG4gICAgc2V0TWVzc2FnZURhdGEgKGRhdGEpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGlhZ25vc3RpY01lc3NhZ2UuS0VZX01FU1NBR0VfREFUQSwgZGF0YSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcltdfVxuICAgICAqL1xuICAgIGdldE1lc3NhZ2VEYXRhICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKERpYWdub3N0aWNNZXNzYWdlLktFWV9NRVNTQUdFX0RBVEEpO1xuICAgIH1cbn1cblxuRGlhZ25vc3RpY01lc3NhZ2UuS0VZX1RBUkdFVF9JRCA9ICd0YXJnZXRJRCc7XG5EaWFnbm9zdGljTWVzc2FnZS5LRVlfTUVTU0FHRV9MRU5HVEggPSAnbWVzc2FnZUxlbmd0aCc7XG5EaWFnbm9zdGljTWVzc2FnZS5LRVlfTUVTU0FHRV9EQVRBID0gJ21lc3NhZ2VEYXRhJztcblxuZXhwb3J0IHsgRGlhZ25vc3RpY01lc3NhZ2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBScGNSZXNwb25zZSB9IGZyb20gJy4uL1JwY1Jlc3BvbnNlLmpzJztcblxuY2xhc3MgRGlhZ25vc3RpY01lc3NhZ2VSZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkRpYWdub3N0aWNNZXNzYWdlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcltdfSByZXN1bHQgLSBBcnJheSBvZiBieXRlcyBjb21wcmlzaW5nIENBTiBtZXNzYWdlIHJlc3VsdC5cbiAgICAgKiBAcmV0dXJuIHtEaWFnbm9zdGljTWVzc2FnZVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldE1lc3NhZ2VEYXRhUmVzdWx0IChyZXN1bHQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGlhZ25vc3RpY01lc3NhZ2VSZXNwb25zZS5LRVlfTUVTU0FHRV9EQVRBX1JFU1VMVCwgcmVzdWx0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyW119XG4gICAgICovXG4gICAgZ2V0TWVzc2FnZURhdGFSZXN1bHQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoRGlhZ25vc3RpY01lc3NhZ2VSZXNwb25zZS5LRVlfTUVTU0FHRV9EQVRBX1JFU1VMVCk7XG4gICAgfVxufVxuXG5EaWFnbm9zdGljTWVzc2FnZVJlc3BvbnNlLktFWV9NRVNTQUdFX0RBVEFfUkVTVUxUID0gJ21lc3NhZ2VEYXRhUmVzdWx0JztcblxuZXhwb3J0IHsgRGlhZ25vc3RpY01lc3NhZ2VSZXNwb25zZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1JlcXVlc3QgfSBmcm9tICcuLi9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFNvZnRCdXR0b24gfSBmcm9tICcuLi9zdHJ1Y3RzL1NvZnRCdXR0b24uanMnO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdWxsIHNjcmVlbiBvdmVybGF5IGNvbnRhaW5pbmcgYSBsYXJnZSBibG9jayBvZiBmb3JtYXR0ZWQgdGV4dCB0aGF0IGNhbiBiZSBzY3JvbGxlZCB3aXRoIHVwIHRvIDhcbiAqIFNvZnRCdXR0b25zIGRlZmluZWRcbiAqL1xuY2xhc3MgU2Nyb2xsYWJsZU1lc3NhZ2UgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlNjcm9sbGFibGVNZXNzYWdlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gYm9keSAtIEJvZHkgb2YgdGV4dCB0aGF0IGNhbiBpbmNsdWRlIG5ld2xpbmVzIGFuZCB0YWJzLlxuICAgICAqIEByZXR1cm4ge1Njcm9sbGFibGVNZXNzYWdlfVxuICAgICAqL1xuICAgIHNldFNjcm9sbGFibGVNZXNzYWdlQm9keSAoYm9keSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTY3JvbGxhYmxlTWVzc2FnZS5LRVlfU0NST0xMQUJMRV9NRVNTQUdFX0JPRFksIGJvZHkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0U2Nyb2xsYWJsZU1lc3NhZ2VCb2R5ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNjcm9sbGFibGVNZXNzYWdlLktFWV9TQ1JPTExBQkxFX01FU1NBR0VfQk9EWSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHRpbWVvdXQgLSBBcHAgZGVmaW5lZCB0aW1lb3V0LiBJbmRpY2F0ZXMgaG93IGxvbmcgb2YgYSB0aW1lb3V0IGZyb20gdGhlIGxhc3QgYWN0aW9uIChpLmUuXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxpbmcgbWVzc2FnZSByZXNldHMgdGltZW91dCkuXG4gICAgICogQHJldHVybiB7U2Nyb2xsYWJsZU1lc3NhZ2V9XG4gICAgICovXG4gICAgc2V0VGltZW91dCAodGltZW91dCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTY3JvbGxhYmxlTWVzc2FnZS5LRVlfVElNRU9VVCwgdGltZW91dCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRUaW1lb3V0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNjcm9sbGFibGVNZXNzYWdlLktFWV9USU1FT1VUKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NvZnRCdXR0b25bXX0gYnV0dG9ucyAtIEFwcCBkZWZpbmVkIFNvZnRCdXR0b25zLiBJZiBvbWl0dGVkIG9uIHN1cHBvcnRlZCBkaXNwbGF5cywgb25seSB0aGUgc3lzdGVtXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZpbmVkIFwiQ2xvc2VcIiBTb2Z0QnV0dG9uIHdpbGwgYmUgZGlzcGxheWVkLlxuICAgICAqIEByZXR1cm4ge1Njcm9sbGFibGVNZXNzYWdlfVxuICAgICAqL1xuICAgIHNldFNvZnRCdXR0b25zIChidXR0b25zKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFNvZnRCdXR0b24sIGJ1dHRvbnMsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTY3JvbGxhYmxlTWVzc2FnZS5LRVlfU09GVF9CVVRUT05TLCBidXR0b25zKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U29mdEJ1dHRvbltdfVxuICAgICAqL1xuICAgIGdldFNvZnRCdXR0b25zICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFNvZnRCdXR0b24sIFNjcm9sbGFibGVNZXNzYWdlLktFWV9TT0ZUX0JVVFRPTlMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBpZCAtIEFuIElEIGZvciB0aGlzIHNwZWNpZmljIFNjcm9sbGFibGVNZXNzYWdlIHRvIGFsbG93IGNhbmNlbGxhdGlvbiB0aHJvdWdoIHRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIGBDYW5jZWxJbnRlcmFjdGlvbmAgUlBDLlxuICAgICAqIEByZXR1cm4ge1Njcm9sbGFibGVNZXNzYWdlfVxuICAgICAqL1xuICAgIHNldENhbmNlbElEIChpZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTY3JvbGxhYmxlTWVzc2FnZS5LRVlfQ0FOQ0VMX0lELCBpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRDYW5jZWxJRCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTY3JvbGxhYmxlTWVzc2FnZS5LRVlfQ0FOQ0VMX0lEKTtcbiAgICB9XG59XG5cblNjcm9sbGFibGVNZXNzYWdlLktFWV9TQ1JPTExBQkxFX01FU1NBR0VfQk9EWSA9ICdzY3JvbGxhYmxlTWVzc2FnZUJvZHknO1xuU2Nyb2xsYWJsZU1lc3NhZ2UuS0VZX1RJTUVPVVQgPSAndGltZW91dCc7XG5TY3JvbGxhYmxlTWVzc2FnZS5LRVlfU09GVF9CVVRUT05TID0gJ3NvZnRCdXR0b25zJztcblNjcm9sbGFibGVNZXNzYWdlLktFWV9DQU5DRUxfSUQgPSAnY2FuY2VsSUQnO1xuXG5leHBvcnQgeyBTY3JvbGxhYmxlTWVzc2FnZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG5jbGFzcyBTY3JvbGxhYmxlTWVzc2FnZVJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuU2Nyb2xsYWJsZU1lc3NhZ2UpO1xuICAgIH1cbn1cblxuXG5leHBvcnQgeyBTY3JvbGxhYmxlTWVzc2FnZVJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdWxsIHNjcmVlbiBvciBwb3AtdXAgb3ZlcmxheSAoZGVwZW5kaW5nIG9uIHBsYXRmb3JtKSB3aXRoIGEgc2luZ2xlIHVzZXIgY29udHJvbGxlZCBzbGlkZXIuXG4gKi9cbmNsYXNzIFNsaWRlciBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuU2xpZGVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gdGlja3MgLSBOdW1iZXIgb2Ygc2VsZWN0YWJsZSBpdGVtcyBvbiBhIGhvcml6b250YWwgYXhpc1xuICAgICAqIEByZXR1cm4ge1NsaWRlcn1cbiAgICAgKi9cbiAgICBzZXROdW1UaWNrcyAodGlja3MpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2xpZGVyLktFWV9OVU1fVElDS1MsIHRpY2tzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldE51bVRpY2tzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNsaWRlci5LRVlfTlVNX1RJQ0tTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gcG9zaXRpb24gLSBJbml0aWFsIHBvc2l0aW9uIG9mIHNsaWRlciBjb250cm9sIChjYW5ub3QgZXhjZWVkIG51bVRpY2tzKVxuICAgICAqIEByZXR1cm4ge1NsaWRlcn1cbiAgICAgKi9cbiAgICBzZXRQb3NpdGlvbiAocG9zaXRpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2xpZGVyLktFWV9QT1NJVElPTiwgcG9zaXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0UG9zaXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2xpZGVyLktFWV9QT1NJVElPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGhlYWRlciAtIFRleHQgaGVhZGVyIHRvIGRpc3BsYXlcbiAgICAgKiBAcmV0dXJuIHtTbGlkZXJ9XG4gICAgICovXG4gICAgc2V0U2xpZGVySGVhZGVyIChoZWFkZXIpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2xpZGVyLktFWV9TTElERVJfSEVBREVSLCBoZWFkZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0U2xpZGVySGVhZGVyICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNsaWRlci5LRVlfU0xJREVSX0hFQURFUik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmdbXX0gZm9vdGVyIC0gVGV4dCBmb290ZXIgdG8gZGlzcGxheSAobWVhbnQgdG8gZGlzcGxheSBtaW4vbWF4IHRocmVzaG9sZCBkZXNjcmlwdG9ycykuIEZvciBhIHN0YXRpY1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQgZm9vdGVyLCBvbmx5IG9uZSBmb290ZXIgc3RyaW5nIHNoYWxsIGJlIHByb3ZpZGVkIGluIHRoZSBhcnJheS4gRm9yIGEgZHluYW1pYyB0ZXh0XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9vdGVyLCB0aGUgbnVtYmVyIG9mIGZvb3RlciB0ZXh0IHN0cmluZyBpbiB0aGUgYXJyYXkgbXVzdCBtYXRjaCB0aGUgbnVtVGlja3MgdmFsdWUuXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgRm9yIGEgZHluYW1pYyB0ZXh0IGZvb3RlciwgdGV4dCBhcnJheSBzdHJpbmcgc2hvdWxkIGNvcnJlbGF0ZSB3aXRoIHBvdGVudGlhbCBzbGlkZXJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbiBpbmRleC4gSWYgb21pdHRlZCBvbiBzdXBwb3J0ZWQgZGlzcGxheXMsIG5vIGZvb3RlciB0ZXh0IHNoYWxsIGJlIGRpc3BsYXllZC5cbiAgICAgKiBAcmV0dXJuIHtTbGlkZXJ9XG4gICAgICovXG4gICAgc2V0U2xpZGVyRm9vdGVyIChmb290ZXIpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2xpZGVyLktFWV9TTElERVJfRk9PVEVSLCBmb290ZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmdbXX1cbiAgICAgKi9cbiAgICBnZXRTbGlkZXJGb290ZXIgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2xpZGVyLktFWV9TTElERVJfRk9PVEVSKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gdGltZW91dCAtIEFwcCBkZWZpbmVkIHRpbWVvdXQuIEluZGljYXRlcyBob3cgbG9uZyBvZiBhIHRpbWVvdXQgZnJvbSB0aGUgbGFzdCBhY3Rpb24gKGkuZS4gc2xpZGluZ1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbCByZXNldHMgdGltZW91dCkuIElmIG9taXR0ZWQsIHRoZSB2YWx1ZSBpcyBzZXQgdG8gMTAwMDAuXG4gICAgICogQHJldHVybiB7U2xpZGVyfVxuICAgICAqL1xuICAgIHNldFRpbWVvdXQgKHRpbWVvdXQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2xpZGVyLktFWV9USU1FT1VULCB0aW1lb3V0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFRpbWVvdXQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2xpZGVyLktFWV9USU1FT1VUKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaWQgLSBBbiBJRCBmb3IgdGhpcyBzcGVjaWZpYyBTbGlkZXIgdG8gYWxsb3cgY2FuY2VsbGF0aW9uIHRocm91Z2ggdGhlIGBDYW5jZWxJbnRlcmFjdGlvbmAgUlBDLlxuICAgICAqIEByZXR1cm4ge1NsaWRlcn1cbiAgICAgKi9cbiAgICBzZXRDYW5jZWxJRCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2xpZGVyLktFWV9DQU5DRUxfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldENhbmNlbElEICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNsaWRlci5LRVlfQ0FOQ0VMX0lEKTtcbiAgICB9XG59XG5cblNsaWRlci5LRVlfTlVNX1RJQ0tTID0gJ251bVRpY2tzJztcblNsaWRlci5LRVlfUE9TSVRJT04gPSAncG9zaXRpb24nO1xuU2xpZGVyLktFWV9TTElERVJfSEVBREVSID0gJ3NsaWRlckhlYWRlcic7XG5TbGlkZXIuS0VZX1NMSURFUl9GT09URVIgPSAnc2xpZGVyRm9vdGVyJztcblNsaWRlci5LRVlfVElNRU9VVCA9ICd0aW1lb3V0JztcblNsaWRlci5LRVlfQ0FOQ0VMX0lEID0gJ2NhbmNlbElEJztcblxuZXhwb3J0IHsgU2xpZGVyIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbmNsYXNzIFNsaWRlclJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuU2xpZGVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gcG9zaXRpb24gLSBDdXJyZW50IHNsaWRlciB2YWx1ZSByZXR1cm5lZCB3aGVuIHNhdmVkIG9yIGNhbmNlbGVkIChhYm9ydGVkKSBUaGlzIHZhbHVlIGlzIG9ubHlcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm5lZCBmb3IgcmVzdWx0Q29kZXMgXCJTQVZFRFwiIG9yIFwiQUJPUlRFRFwiXG4gICAgICogQHJldHVybiB7U2xpZGVyUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0U2xpZGVyUG9zaXRpb24gKHBvc2l0aW9uKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNsaWRlclJlc3BvbnNlLktFWV9TTElERVJfUE9TSVRJT04sIHBvc2l0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFNsaWRlclBvc2l0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNsaWRlclJlc3BvbnNlLktFWV9TTElERVJfUE9TSVRJT04pO1xuICAgIH1cbn1cblxuU2xpZGVyUmVzcG9uc2UuS0VZX1NMSURFUl9QT1NJVElPTiA9ICdzbGlkZXJQb3NpdGlvbic7XG5cbmV4cG9ydCB7IFNsaWRlclJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgU29mdEJ1dHRvbiB9IGZyb20gJy4uL3N0cnVjdHMvU29mdEJ1dHRvbi5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBJbWFnZSB9IGZyb20gJy4uL3N0cnVjdHMvSW1hZ2UuanMnO1xuXG5jbGFzcyBTaG93Q29uc3RhbnRUQlQgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlNob3dDb25zdGFudFRCVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHRleHQxXG4gICAgICogQHJldHVybiB7U2hvd0NvbnN0YW50VEJUfVxuICAgICAqL1xuICAgIHNldE5hdmlnYXRpb25UZXh0MSAodGV4dDEpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2hvd0NvbnN0YW50VEJULktFWV9OQVZJR0FUSU9OX1RFWFRfMSwgdGV4dDEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0TmF2aWdhdGlvblRleHQxICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNob3dDb25zdGFudFRCVC5LRVlfTkFWSUdBVElPTl9URVhUXzEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0MlxuICAgICAqIEByZXR1cm4ge1Nob3dDb25zdGFudFRCVH1cbiAgICAgKi9cbiAgICBzZXROYXZpZ2F0aW9uVGV4dDIgKHRleHQyKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNob3dDb25zdGFudFRCVC5LRVlfTkFWSUdBVElPTl9URVhUXzIsIHRleHQyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldE5hdmlnYXRpb25UZXh0MiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTaG93Q29uc3RhbnRUQlQuS0VZX05BVklHQVRJT05fVEVYVF8yKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXRhXG4gICAgICogQHJldHVybiB7U2hvd0NvbnN0YW50VEJUfVxuICAgICAqL1xuICAgIHNldEV0YSAoZXRhKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNob3dDb25zdGFudFRCVC5LRVlfRVRBLCBldGEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0RXRhICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNob3dDb25zdGFudFRCVC5LRVlfRVRBKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZGVzdGluYXRpb25cbiAgICAgKiBAcmV0dXJuIHtTaG93Q29uc3RhbnRUQlR9XG4gICAgICovXG4gICAgc2V0VGltZVRvRGVzdGluYXRpb24gKGRlc3RpbmF0aW9uKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNob3dDb25zdGFudFRCVC5LRVlfVElNRV9UT19ERVNUSU5BVElPTiwgZGVzdGluYXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0VGltZVRvRGVzdGluYXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2hvd0NvbnN0YW50VEJULktFWV9USU1FX1RPX0RFU1RJTkFUSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZGlzdGFuY2VcbiAgICAgKiBAcmV0dXJuIHtTaG93Q29uc3RhbnRUQlR9XG4gICAgICovXG4gICAgc2V0VG90YWxEaXN0YW5jZSAoZGlzdGFuY2UpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2hvd0NvbnN0YW50VEJULktFWV9UT1RBTF9ESVNUQU5DRSwgZGlzdGFuY2UpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0VG90YWxEaXN0YW5jZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTaG93Q29uc3RhbnRUQlQuS0VZX1RPVEFMX0RJU1RBTkNFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0ltYWdlfSBpY29uXG4gICAgICogQHJldHVybiB7U2hvd0NvbnN0YW50VEJUfVxuICAgICAqL1xuICAgIHNldFR1cm5JY29uIChpY29uKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEltYWdlLCBpY29uKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2hvd0NvbnN0YW50VEJULktFWV9UVVJOX0lDT04sIGljb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtJbWFnZX1cbiAgICAgKi9cbiAgICBnZXRUdXJuSWNvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChJbWFnZSwgU2hvd0NvbnN0YW50VEJULktFWV9UVVJOX0lDT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7SW1hZ2V9IGljb25cbiAgICAgKiBAcmV0dXJuIHtTaG93Q29uc3RhbnRUQlR9XG4gICAgICovXG4gICAgc2V0TmV4dFR1cm5JY29uIChpY29uKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEltYWdlLCBpY29uKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2hvd0NvbnN0YW50VEJULktFWV9ORVhUX1RVUk5fSUNPTiwgaWNvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0ltYWdlfVxuICAgICAqL1xuICAgIGdldE5leHRUdXJuSWNvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChJbWFnZSwgU2hvd0NvbnN0YW50VEJULktFWV9ORVhUX1RVUk5fSUNPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG1hbmV1dmVyIC0gRnJhY3Rpb24gb2YgZGlzdGFuY2UgdGlsbCBuZXh0IG1hbmV1dmVyIChzdGFydGluZyBmcm9tIHdoZW4gQWxlcnRNYW5ldXZlciBpc1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyaWdnZXJlZCkuIFVzZWQgdG8gY2FsY3VsYXRlIHByb2dyZXNzIGJhci5cbiAgICAgKiBAcmV0dXJuIHtTaG93Q29uc3RhbnRUQlR9XG4gICAgICovXG4gICAgc2V0RGlzdGFuY2VUb01hbmV1dmVyIChtYW5ldXZlcikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTaG93Q29uc3RhbnRUQlQuS0VZX0RJU1RBTkNFX1RPX01BTkVVVkVSLCBtYW5ldXZlcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXREaXN0YW5jZVRvTWFuZXV2ZXIgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2hvd0NvbnN0YW50VEJULktFWV9ESVNUQU5DRV9UT19NQU5FVVZFUik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNjYWxlIC0gRGlzdGFuY2UgdGlsbCBuZXh0IG1hbmV1dmVyIChzdGFydGluZyBmcm9tKSBmcm9tIHByZXZpb3VzIG1hbmV1dmVyLiBVc2VkIHRvIGNhbGN1bGF0ZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHByb2dyZXNzIGJhci5cbiAgICAgKiBAcmV0dXJuIHtTaG93Q29uc3RhbnRUQlR9XG4gICAgICovXG4gICAgc2V0RGlzdGFuY2VUb01hbmV1dmVyU2NhbGUgKHNjYWxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNob3dDb25zdGFudFRCVC5LRVlfRElTVEFOQ0VfVE9fTUFORVVWRVJfU0NBTEUsIHNjYWxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldERpc3RhbmNlVG9NYW5ldXZlclNjYWxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNob3dDb25zdGFudFRCVC5LRVlfRElTVEFOQ0VfVE9fTUFORVVWRVJfU0NBTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gY29tcGxldGUgLSBJZiBhbmQgd2hlbiBhIG1hbmV1dmVyIGhhcyBjb21wbGV0ZWQgd2hpbGUgYW4gQWxlcnRNYW5ldXZlciBpcyBhY3RpdmUsIHRoZSBhcHAgbXVzdFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kIHRoaXMgdmFsdWUgc2V0IHRvIFRSVUUgaW4gb3JkZXIgdG8gY2xlYXIgdGhlIEFsZXJ0TWFuZXV2ZXIgb3ZlcmxheS4gSWYgb21pdHRlZFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgdmFsdWUgd2lsbCBiZSBhc3N1bWVkIGFzIEZBTFNFLlxuICAgICAqIEByZXR1cm4ge1Nob3dDb25zdGFudFRCVH1cbiAgICAgKi9cbiAgICBzZXRNYW5ldXZlckNvbXBsZXRlIChjb21wbGV0ZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTaG93Q29uc3RhbnRUQlQuS0VZX01BTkVVVkVSX0NPTVBMRVRFLCBjb21wbGV0ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0TWFuZXV2ZXJDb21wbGV0ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTaG93Q29uc3RhbnRUQlQuS0VZX01BTkVVVkVSX0NPTVBMRVRFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NvZnRCdXR0b25bXX0gYnV0dG9ucyAtIFRocmVlIGR5bmFtaWMgU29mdEJ1dHRvbnMgYXZhaWxhYmxlIChmaXJzdCBTb2Z0QnV0dG9uIGlzIGZpeGVkIHRvIFwiVHVybnNcIikuIElmXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbWl0dGVkIG9uIHN1cHBvcnRlZCBkaXNwbGF5cywgdGhlIGN1cnJlbnRseSBkaXNwbGF5ZWQgU29mdEJ1dHRvbiB2YWx1ZXMgd2lsbCBub3RcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZS5cbiAgICAgKiBAcmV0dXJuIHtTaG93Q29uc3RhbnRUQlR9XG4gICAgICovXG4gICAgc2V0U29mdEJ1dHRvbnMgKGJ1dHRvbnMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoU29mdEJ1dHRvbiwgYnV0dG9ucywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNob3dDb25zdGFudFRCVC5LRVlfU09GVF9CVVRUT05TLCBidXR0b25zKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U29mdEJ1dHRvbltdfVxuICAgICAqL1xuICAgIGdldFNvZnRCdXR0b25zICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFNvZnRCdXR0b24sIFNob3dDb25zdGFudFRCVC5LRVlfU09GVF9CVVRUT05TKTtcbiAgICB9XG59XG5cblNob3dDb25zdGFudFRCVC5LRVlfTkFWSUdBVElPTl9URVhUXzEgPSAnbmF2aWdhdGlvblRleHQxJztcblNob3dDb25zdGFudFRCVC5LRVlfTkFWSUdBVElPTl9URVhUXzIgPSAnbmF2aWdhdGlvblRleHQyJztcblNob3dDb25zdGFudFRCVC5LRVlfRVRBID0gJ2V0YSc7XG5TaG93Q29uc3RhbnRUQlQuS0VZX1RJTUVfVE9fREVTVElOQVRJT04gPSAndGltZVRvRGVzdGluYXRpb24nO1xuU2hvd0NvbnN0YW50VEJULktFWV9UT1RBTF9ESVNUQU5DRSA9ICd0b3RhbERpc3RhbmNlJztcblNob3dDb25zdGFudFRCVC5LRVlfVFVSTl9JQ09OID0gJ3R1cm5JY29uJztcblNob3dDb25zdGFudFRCVC5LRVlfTkVYVF9UVVJOX0lDT04gPSAnbmV4dFR1cm5JY29uJztcblNob3dDb25zdGFudFRCVC5LRVlfRElTVEFOQ0VfVE9fTUFORVVWRVIgPSAnZGlzdGFuY2VUb01hbmV1dmVyJztcblNob3dDb25zdGFudFRCVC5LRVlfRElTVEFOQ0VfVE9fTUFORVVWRVJfU0NBTEUgPSAnZGlzdGFuY2VUb01hbmV1dmVyU2NhbGUnO1xuU2hvd0NvbnN0YW50VEJULktFWV9NQU5FVVZFUl9DT01QTEVURSA9ICdtYW5ldXZlckNvbXBsZXRlJztcblNob3dDb25zdGFudFRCVC5LRVlfU09GVF9CVVRUT05TID0gJ3NvZnRCdXR0b25zJztcblxuZXhwb3J0IHsgU2hvd0NvbnN0YW50VEJUIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbmNsYXNzIFNob3dDb25zdGFudFRCVFJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuU2hvd0NvbnN0YW50VEJUKTtcbiAgICB9XG59XG5cblxuZXhwb3J0IHsgU2hvd0NvbnN0YW50VEJUUmVzcG9uc2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBUVFNDaHVuayB9IGZyb20gJy4uL3N0cnVjdHMvVFRTQ2h1bmsuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgU29mdEJ1dHRvbiB9IGZyb20gJy4uL3N0cnVjdHMvU29mdEJ1dHRvbi5qcyc7XG5cbmNsYXNzIEFsZXJ0TWFuZXV2ZXIgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkFsZXJ0TWFuZXV2ZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VFRTQ2h1bmtbXX0gY2h1bmtzIC0gQW4gYXJyYXkgb2YgdGV4dCBjaHVua3Mgb2YgdHlwZSBUVFNDaHVuay4gU2VlIFRUU0NodW5rXG4gICAgICogQHJldHVybiB7QWxlcnRNYW5ldXZlcn1cbiAgICAgKi9cbiAgICBzZXRUdHNDaHVua3MgKGNodW5rcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShUVFNDaHVuaywgY2h1bmtzLCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQWxlcnRNYW5ldXZlci5LRVlfVFRTX0NIVU5LUywgY2h1bmtzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VFRTQ2h1bmtbXX1cbiAgICAgKi9cbiAgICBnZXRUdHNDaHVua3MgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVFRTQ2h1bmssIEFsZXJ0TWFuZXV2ZXIuS0VZX1RUU19DSFVOS1MpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U29mdEJ1dHRvbltdfSBidXR0b25zIC0gSWYgb21pdHRlZCBvbiBzdXBwb3J0ZWQgZGlzcGxheXMsIG9ubHkgdGhlIHN5c3RlbSBkZWZpbmVkIFwiQ2xvc2VcIiBTb2Z0QnV0dG9uXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFsbCBiZSBkaXNwbGF5ZWQuXG4gICAgICogQHJldHVybiB7QWxlcnRNYW5ldXZlcn1cbiAgICAgKi9cbiAgICBzZXRTb2Z0QnV0dG9ucyAoYnV0dG9ucykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShTb2Z0QnV0dG9uLCBidXR0b25zLCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQWxlcnRNYW5ldXZlci5LRVlfU09GVF9CVVRUT05TLCBidXR0b25zKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U29mdEJ1dHRvbltdfVxuICAgICAqL1xuICAgIGdldFNvZnRCdXR0b25zICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFNvZnRCdXR0b24sIEFsZXJ0TWFuZXV2ZXIuS0VZX1NPRlRfQlVUVE9OUyk7XG4gICAgfVxufVxuXG5BbGVydE1hbmV1dmVyLktFWV9UVFNfQ0hVTktTID0gJ3R0c0NodW5rcyc7XG5BbGVydE1hbmV1dmVyLktFWV9TT0ZUX0JVVFRPTlMgPSAnc29mdEJ1dHRvbnMnO1xuXG5leHBvcnQgeyBBbGVydE1hbmV1dmVyIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbmNsYXNzIEFsZXJ0TWFuZXV2ZXJSZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkFsZXJ0TWFuZXV2ZXIpO1xuICAgIH1cbn1cblxuXG5leHBvcnQgeyBBbGVydE1hbmV1dmVyUmVzcG9uc2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgSW1hZ2UgfSBmcm9tICcuL0ltYWdlLmpzJztcblxuY2xhc3MgVHVybiBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHRleHQgLSBJbmRpdmlkdWFsIHR1cm4gdGV4dC4gTXVzdCBwcm92aWRlIGF0IGxlYXN0IHRleHQgb3IgaWNvbiBmb3IgYSBnaXZlbiB0dXJuLlxuICAgICAqIEByZXR1cm4ge1R1cm59XG4gICAgICovXG4gICAgc2V0TmF2aWdhdGlvblRleHQgKHRleHQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVHVybi5LRVlfTkFWSUdBVElPTl9URVhULCB0ZXh0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldE5hdmlnYXRpb25UZXh0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFR1cm4uS0VZX05BVklHQVRJT05fVEVYVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtJbWFnZX0gaWNvbiAtIEluZGl2aWR1YWwgdHVybiBpY29uLiBNdXN0IHByb3ZpZGUgYXQgbGVhc3QgdGV4dCBvciBpY29uIGZvciBhIGdpdmVuIHR1cm4uXG4gICAgICogQHJldHVybiB7VHVybn1cbiAgICAgKi9cbiAgICBzZXRUdXJuSWNvbiAoaWNvbikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShJbWFnZSwgaWNvbik7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFR1cm4uS0VZX1RVUk5fSUNPTiwgaWNvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0ltYWdlfVxuICAgICAqL1xuICAgIGdldFR1cm5JY29uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEltYWdlLCBUdXJuLktFWV9UVVJOX0lDT04pO1xuICAgIH1cbn1cblxuVHVybi5LRVlfTkFWSUdBVElPTl9URVhUID0gJ25hdmlnYXRpb25UZXh0JztcblR1cm4uS0VZX1RVUk5fSUNPTiA9ICd0dXJuSWNvbic7XG5cbmV4cG9ydCB7IFR1cm4gfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBUdXJuIH0gZnJvbSAnLi4vc3RydWN0cy9UdXJuLmpzJztcbmltcG9ydCB7IFJwY1JlcXVlc3QgfSBmcm9tICcuLi9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFNvZnRCdXR0b24gfSBmcm9tICcuLi9zdHJ1Y3RzL1NvZnRCdXR0b24uanMnO1xuXG5jbGFzcyBVcGRhdGVUdXJuTGlzdCBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuVXBkYXRlVHVybkxpc3QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VHVybltdfSBsaXN0XG4gICAgICogQHJldHVybiB7VXBkYXRlVHVybkxpc3R9XG4gICAgICovXG4gICAgc2V0VHVybkxpc3QgKGxpc3QpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVHVybiwgbGlzdCwgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVwZGF0ZVR1cm5MaXN0LktFWV9UVVJOX0xJU1QsIGxpc3QpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtUdXJuW119XG4gICAgICovXG4gICAgZ2V0VHVybkxpc3QgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVHVybiwgVXBkYXRlVHVybkxpc3QuS0VZX1RVUk5fTElTVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTb2Z0QnV0dG9uW119IGJ1dHRvbnMgLSBJZiBvbWl0dGVkIG9uIHN1cHBvcnRlZCBkaXNwbGF5cywgYXBwLWRlZmluZWQgU29mdEJ1dHRvbiB3aWxsIGJlIGxlZnQgYmxhbmsuXG4gICAgICogQHJldHVybiB7VXBkYXRlVHVybkxpc3R9XG4gICAgICovXG4gICAgc2V0U29mdEJ1dHRvbnMgKGJ1dHRvbnMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoU29mdEJ1dHRvbiwgYnV0dG9ucywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVwZGF0ZVR1cm5MaXN0LktFWV9TT0ZUX0JVVFRPTlMsIGJ1dHRvbnMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTb2Z0QnV0dG9uW119XG4gICAgICovXG4gICAgZ2V0U29mdEJ1dHRvbnMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoU29mdEJ1dHRvbiwgVXBkYXRlVHVybkxpc3QuS0VZX1NPRlRfQlVUVE9OUyk7XG4gICAgfVxufVxuXG5VcGRhdGVUdXJuTGlzdC5LRVlfVFVSTl9MSVNUID0gJ3R1cm5MaXN0JztcblVwZGF0ZVR1cm5MaXN0LktFWV9TT0ZUX0JVVFRPTlMgPSAnc29mdEJ1dHRvbnMnO1xuXG5leHBvcnQgeyBVcGRhdGVUdXJuTGlzdCB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG5jbGFzcyBVcGRhdGVUdXJuTGlzdFJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuVXBkYXRlVHVybkxpc3QpO1xuICAgIH1cbn1cblxuXG5leHBvcnQgeyBVcGRhdGVUdXJuTGlzdFJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgVFRTQ2h1bmsgfSBmcm9tICcuLi9zdHJ1Y3RzL1RUU0NodW5rLmpzJztcbmltcG9ydCB7IExhbmd1YWdlIH0gZnJvbSAnLi4vZW51bXMvTGFuZ3VhZ2UuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG5jbGFzcyBDaGFuZ2VSZWdpc3RyYXRpb24gZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkNoYW5nZVJlZ2lzdHJhdGlvbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBSZXF1ZXN0ZWQgdm9pY2UgZW5naW5lIChWUitUVFMpIGxhbmd1YWdlIHJlZ2lzdHJhdGlvblxuICAgICAqIEByZXR1cm4ge0NoYW5nZVJlZ2lzdHJhdGlvbn1cbiAgICAgKi9cbiAgICBzZXRMYW5ndWFnZSAobGFuZ3VhZ2UpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTGFuZ3VhZ2UsIGxhbmd1YWdlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2hhbmdlUmVnaXN0cmF0aW9uLktFWV9MQU5HVUFHRSwgbGFuZ3VhZ2UpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtMYW5ndWFnZX1cbiAgICAgKi9cbiAgICBnZXRMYW5ndWFnZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChMYW5ndWFnZSwgQ2hhbmdlUmVnaXN0cmF0aW9uLktFWV9MQU5HVUFHRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBSZXF1ZXN0IGRpc3BsYXkgbGFuZ3VhZ2UgcmVnaXN0cmF0aW9uXG4gICAgICogQHJldHVybiB7Q2hhbmdlUmVnaXN0cmF0aW9ufVxuICAgICAqL1xuICAgIHNldEhtaURpc3BsYXlMYW5ndWFnZSAobGFuZ3VhZ2UpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTGFuZ3VhZ2UsIGxhbmd1YWdlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2hhbmdlUmVnaXN0cmF0aW9uLktFWV9ITUlfRElTUExBWV9MQU5HVUFHRSwgbGFuZ3VhZ2UpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtMYW5ndWFnZX1cbiAgICAgKi9cbiAgICBnZXRIbWlEaXNwbGF5TGFuZ3VhZ2UgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTGFuZ3VhZ2UsIENoYW5nZVJlZ2lzdHJhdGlvbi5LRVlfSE1JX0RJU1BMQVlfTEFOR1VBR0UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIC0gUmVxdWVzdCBuZXcgYXBwIG5hbWUgcmVnaXN0cmF0aW9uXG4gICAgICogQHJldHVybiB7Q2hhbmdlUmVnaXN0cmF0aW9ufVxuICAgICAqL1xuICAgIHNldEFwcE5hbWUgKG5hbWUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2hhbmdlUmVnaXN0cmF0aW9uLktFWV9BUFBfTkFNRSwgbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRBcHBOYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKENoYW5nZVJlZ2lzdHJhdGlvbi5LRVlfQVBQX05BTUUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VFRTQ2h1bmtbXX0gbmFtZSAtIFJlcXVlc3QgbmV3IHR0c05hbWUgcmVnaXN0cmF0aW9uXG4gICAgICogQHJldHVybiB7Q2hhbmdlUmVnaXN0cmF0aW9ufVxuICAgICAqL1xuICAgIHNldFR0c05hbWUgKG5hbWUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVFRTQ2h1bmssIG5hbWUsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihDaGFuZ2VSZWdpc3RyYXRpb24uS0VZX1RUU19OQU1FLCBuYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VFRTQ2h1bmtbXX1cbiAgICAgKi9cbiAgICBnZXRUdHNOYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFRUU0NodW5rLCBDaGFuZ2VSZWdpc3RyYXRpb24uS0VZX1RUU19OQU1FKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSAtIFJlcXVlc3QgbmV3IGFwcCBzaG9ydCBuYW1lIHJlZ2lzdHJhdGlvblxuICAgICAqIEByZXR1cm4ge0NoYW5nZVJlZ2lzdHJhdGlvbn1cbiAgICAgKi9cbiAgICBzZXROZ25NZWRpYVNjcmVlbkFwcE5hbWUgKG5hbWUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2hhbmdlUmVnaXN0cmF0aW9uLktFWV9OR05fTUVESUFfU0NSRUVOX0FQUF9OQU1FLCBuYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldE5nbk1lZGlhU2NyZWVuQXBwTmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihDaGFuZ2VSZWdpc3RyYXRpb24uS0VZX05HTl9NRURJQV9TQ1JFRU5fQVBQX05BTUUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nW119IHN5bm9ueW1zIC0gUmVxdWVzdCBuZXcgVlIgc3lub255bXMgcmVnaXN0cmF0aW9uXG4gICAgICogQHJldHVybiB7Q2hhbmdlUmVnaXN0cmF0aW9ufVxuICAgICAqL1xuICAgIHNldFZyU3lub255bXMgKHN5bm9ueW1zKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENoYW5nZVJlZ2lzdHJhdGlvbi5LRVlfVlJfU1lOT05ZTVMsIHN5bm9ueW1zKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nW119XG4gICAgICovXG4gICAgZ2V0VnJTeW5vbnltcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihDaGFuZ2VSZWdpc3RyYXRpb24uS0VZX1ZSX1NZTk9OWU1TKTtcbiAgICB9XG59XG5cbkNoYW5nZVJlZ2lzdHJhdGlvbi5LRVlfTEFOR1VBR0UgPSAnbGFuZ3VhZ2UnO1xuQ2hhbmdlUmVnaXN0cmF0aW9uLktFWV9ITUlfRElTUExBWV9MQU5HVUFHRSA9ICdobWlEaXNwbGF5TGFuZ3VhZ2UnO1xuQ2hhbmdlUmVnaXN0cmF0aW9uLktFWV9BUFBfTkFNRSA9ICdhcHBOYW1lJztcbkNoYW5nZVJlZ2lzdHJhdGlvbi5LRVlfVFRTX05BTUUgPSAndHRzTmFtZSc7XG5DaGFuZ2VSZWdpc3RyYXRpb24uS0VZX05HTl9NRURJQV9TQ1JFRU5fQVBQX05BTUUgPSAnbmduTWVkaWFTY3JlZW5BcHBOYW1lJztcbkNoYW5nZVJlZ2lzdHJhdGlvbi5LRVlfVlJfU1lOT05ZTVMgPSAndnJTeW5vbnltcyc7XG5cbmV4cG9ydCB7IENoYW5nZVJlZ2lzdHJhdGlvbiB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG5jbGFzcyBDaGFuZ2VSZWdpc3RyYXRpb25SZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkNoYW5nZVJlZ2lzdHJhdGlvbik7XG4gICAgfVxufVxuXG5cbmV4cG9ydCB7IENoYW5nZVJlZ2lzdHJhdGlvblJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbi8qKlxuICogR2VuZXJpYyBSZXNwb25zZSBpcyBzZW50LCB3aGVuIHRoZSBuYW1lIG9mIGEgcmVjZWl2ZWQgbXNnIGNhbm5vdCBiZSByZXRyaWV2ZWQuIE9ubHkgdXNlZCBpbiBjYXNlIG9mIGFuIGVycm9yLlxuICogQ3VycmVudGx5LCBvbmx5IHJlc3VsdENvZGUgSU5WQUxJRF9EQVRBIGlzIHVzZWQuXG4gKi9cbmNsYXNzIEdlbmVyaWNSZXNwb25zZVJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuR2VuZXJpY1Jlc3BvbnNlKTtcbiAgICB9XG59XG5cblxuZXhwb3J0IHsgR2VuZXJpY1Jlc3BvbnNlUmVzcG9uc2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBGaWxlVHlwZSB9IGZyb20gJy4uL2VudW1zL0ZpbGVUeXBlLmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcblxuLyoqXG4gKiBVc2VkIHRvIHB1c2ggYSBiaW5hcnkgZGF0YSBvbnRvIHRoZSBtb2R1bGUgZnJvbSBhIG1vYmlsZSBkZXZpY2UsIHN1Y2ggYXMgaWNvbnMgYW5kIGFsYnVtIGFydCBOb3Qgc3VwcG9ydGVkIG9uIGZpcnN0XG4gKiBnZW5lcmF0aW9uIG9mIFNETCBlbmFibGVkIG1vZHVsZXMuIEJpbmFyeSBkYXRhIGlzIGluIGJpbmFyeSBwYXJ0IG9mIGh5YnJpZCBtc2cuXG4gKi9cbmNsYXNzIFB1dEZpbGUgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlB1dEZpbGUpO1xuICAgIH1cblxuICAgIC8vIC0tLS0tLSBOb3QgcGFydCBvZiB0aGUgUlBDIHNwZWMgaXRzZWxmIC0tLS0tXG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGZpbGVEYXRhXG4gICAgICogQHJldHVybiB7UHV0RmlsZX1cbiAgICAgKi9cbiAgICBzZXRGaWxlRGF0YSAoZmlsZURhdGEpIHtcbiAgICAgICAgdGhpcy5zZXRCdWxrRGF0YShmaWxlRGF0YSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtVaW50OEFycmF5fVxuICAgICAqL1xuICAgIGdldEZpbGVEYXRhICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QnVsa0RhdGEoKTtcbiAgICB9XG5cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLSBFTkQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIC0gRmlsZSByZWZlcmVuY2UgbmFtZS5cbiAgICAgKiBAcmV0dXJuIHtQdXRGaWxlfVxuICAgICAqL1xuICAgIHNldEZpbGVOYW1lIChuYW1lKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFB1dEZpbGUuS0VZX0ZJTEVfTkFNRSwgbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRGaWxlTmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihQdXRGaWxlLktFWV9GSUxFX05BTUUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RmlsZVR5cGV9IHR5cGUgLSBTZWxlY3RlZCBmaWxlIHR5cGUuXG4gICAgICogQHJldHVybiB7UHV0RmlsZX1cbiAgICAgKi9cbiAgICBzZXRGaWxlVHlwZSAodHlwZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShGaWxlVHlwZSwgdHlwZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFB1dEZpbGUuS0VZX0ZJTEVfVFlQRSwgdHlwZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0ZpbGVUeXBlfVxuICAgICAqL1xuICAgIGdldEZpbGVUeXBlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEZpbGVUeXBlLCBQdXRGaWxlLktFWV9GSUxFX1RZUEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gZmlsZSAtIEluZGljYXRlcyBpZiB0aGUgZmlsZSBpcyBtZWFudCB0byBwZXJzaXN0IGJldHdlZW4gc2Vzc2lvbnMgLyBpZ25pdGlvbiBjeWNsZXMuIElmIHNldCB0b1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUsIHRoZW4gdGhlIHN5c3RlbSB3aWxsIGFpbSB0byBwZXJzaXN0IHRoaXMgZmlsZSB0aHJvdWdoIHNlc3Npb24gLyBjeWNsZXMuIFdoaWxlIGZpbGVzXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgd2l0aCB0aGlzIGRlc2lnbmF0aW9uIHdpbGwgaGF2ZSBwcmlvcml0eSBvdmVyIG90aGVycywgdGhleSBhcmUgc3ViamVjdCB0byBkZWxldGlvbiBieSB0aGVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBzeXN0ZW0gYXQgYW55IHRpbWUuIEluIHRoZSBldmVudCBvZiBhdXRvbWF0aWMgZGVsZXRpb24gYnkgdGhlIHN5c3RlbSwgdGhlIGFwcCB3aWxsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgcmVjZWl2ZSBhIHJlamVjdGlvbiBhbmQgaGF2ZSB0byByZXNlbmQgdGhlIGZpbGUuIElmIG9taXR0ZWQsIHRoZSB2YWx1ZSB3aWxsIGJlIHNldCB0b1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLlxuICAgICAqIEByZXR1cm4ge1B1dEZpbGV9XG4gICAgICovXG4gICAgc2V0UGVyc2lzdGVudEZpbGUgKGZpbGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUHV0RmlsZS5LRVlfUEVSU0lTVEVOVF9GSUxFLCBmaWxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRQZXJzaXN0ZW50RmlsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihQdXRGaWxlLktFWV9QRVJTSVNURU5UX0ZJTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gZmlsZSAtIEluZGljYXRlcyBpZiB0aGUgZmlsZSBpcyBtZWFudCB0byBiZSBwYXNzZWQgdGhydSBjb3JlIHRvIGVsc2V3aGVyZSBvbiB0aGUgc3lzdGVtLiBJZiBzZXRcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB0byBUUlVFLCB0aGVuIHRoZSBzeXN0ZW0gd2lsbCBpbnN0ZWFkIHBhc3MgdGhlIGRhdGEgdGhydSBhcyBpdCBhcnJpdmVzIHRvIGEgcHJlZGV0ZXJtaW5lZFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGFyZWEgb3V0c2lkZSBvZiBjb3JlLiBJZiBvbWl0dGVkLCB0aGUgdmFsdWUgd2lsbCBiZSBzZXQgdG8gZmFsc2UuXG4gICAgICogQHJldHVybiB7UHV0RmlsZX1cbiAgICAgKi9cbiAgICBzZXRTeXN0ZW1GaWxlIChmaWxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFB1dEZpbGUuS0VZX1NZU1RFTV9GSUxFLCBmaWxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRTeXN0ZW1GaWxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFB1dEZpbGUuS0VZX1NZU1RFTV9GSUxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gb2Zmc2V0IC0gT3B0aW9uYWwgb2Zmc2V0IGluIGJ5dGVzIGZvciByZXN1bWluZyBwYXJ0aWFsIGRhdGEgY2h1bmtzXG4gICAgICogQHJldHVybiB7UHV0RmlsZX1cbiAgICAgKi9cbiAgICBzZXRPZmZzZXQgKG9mZnNldCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihQdXRGaWxlLktFWV9PRkZTRVQsIG9mZnNldCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRPZmZzZXQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUHV0RmlsZS5LRVlfT0ZGU0VUKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoIC0gT3B0aW9uYWwgbGVuZ3RoIGluIGJ5dGVzIGZvciByZXN1bWluZyBwYXJ0aWFsIGRhdGEgY2h1bmtzIElmIG9mZnNldCBpcyBzZXQgdG8gMCwgdGhlblxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggaXMgdGhlIHRvdGFsIGxlbmd0aCBvZiB0aGUgZmlsZSB0byBiZSBkb3dubG9hZGVkXG4gICAgICogQHJldHVybiB7UHV0RmlsZX1cbiAgICAgKi9cbiAgICBzZXRMZW5ndGggKGxlbmd0aCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihQdXRGaWxlLktFWV9MRU5HVEgsIGxlbmd0aCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRMZW5ndGggKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUHV0RmlsZS5LRVlfTEVOR1RIKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gY3JjIC0gQWRkaXRpb25hbCBDUkMzMiBjaGVja3N1bSB0byBwcm90ZWN0IGRhdGEgaW50ZWdyaXR5IHVwIHRvIDUxMiBNYml0c1xuICAgICAqIEByZXR1cm4ge1B1dEZpbGV9XG4gICAgICovXG4gICAgc2V0Q3JjIChjcmMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUHV0RmlsZS5LRVlfQ1JDLCBjcmMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0Q3JjICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFB1dEZpbGUuS0VZX0NSQyk7XG4gICAgfVxufVxuXG5QdXRGaWxlLktFWV9GSUxFX05BTUUgPSAnc3luY0ZpbGVOYW1lJztcblB1dEZpbGUuS0VZX0ZJTEVfVFlQRSA9ICdmaWxlVHlwZSc7XG5QdXRGaWxlLktFWV9QRVJTSVNURU5UX0ZJTEUgPSAncGVyc2lzdGVudEZpbGUnO1xuUHV0RmlsZS5LRVlfU1lTVEVNX0ZJTEUgPSAnc3lzdGVtRmlsZSc7XG5QdXRGaWxlLktFWV9PRkZTRVQgPSAnb2Zmc2V0JztcblB1dEZpbGUuS0VZX0xFTkdUSCA9ICdsZW5ndGgnO1xuUHV0RmlsZS5LRVlfQ1JDID0gJ2NyYyc7XG5cbmV4cG9ydCB7IFB1dEZpbGUgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBScGNSZXNwb25zZSB9IGZyb20gJy4uL1JwY1Jlc3BvbnNlLmpzJztcblxuLyoqXG4gKiBSZXNwb25zZSBpcyBzZW50LCB3aGVuIHRoZSBmaWxlIGRhdGEgd2FzIGNvcGllZCAoc3VjY2VzcyBjYXNlKS4gT3Igd2hlbiBhbiBlcnJvciBvY2N1cnJlZC4gTm90IHN1cHBvcnRlZCBvbiBmaXJzdFxuICogZ2VuZXJhdGlvbiBTREwgZW5hYmxlZCB2ZWhpY2xlcy5cbiAqL1xuY2xhc3MgUHV0RmlsZVJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuUHV0RmlsZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGF2YWlsYWJsZSAtIFByb3ZpZGVzIHRoZSB0b3RhbCBsb2NhbCBzcGFjZSBhdmFpbGFibGUgaW4gU0RMIENvcmUgZm9yIHRoZSByZWdpc3RlcmVkIGFwcC4gSWYgdGhlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZmVyIGhhcyBzeXN0ZW1GaWxlIGVuYWJsZWQsIHRoZW4gdGhlIHZhbHVlIHdpbGwgYmUgc2V0IHRvIDAgYXV0b21hdGljYWxseS5cbiAgICAgKiBAcmV0dXJuIHtQdXRGaWxlUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0U3BhY2VBdmFpbGFibGUgKGF2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihQdXRGaWxlUmVzcG9uc2UuS0VZX1NQQUNFX0FWQUlMQUJMRSwgYXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFNwYWNlQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFB1dEZpbGVSZXNwb25zZS5LRVlfU1BBQ0VfQVZBSUxBQkxFKTtcbiAgICB9XG59XG5cblB1dEZpbGVSZXNwb25zZS5LRVlfU1BBQ0VfQVZBSUxBQkxFID0gJ3NwYWNlQXZhaWxhYmxlJztcblxuZXhwb3J0IHsgUHV0RmlsZVJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgRmlsZVR5cGUgfSBmcm9tICcuLi9lbnVtcy9GaWxlVHlwZS5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5cbi8qKlxuICogVGhpcyByZXF1ZXN0IGlzIHNlbnQgdG8gdGhlIG1vZHVsZSB0byByZXRyaWV2ZSBhIGZpbGVcbiAqL1xuY2xhc3MgR2V0RmlsZSBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuR2V0RmlsZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBGaWxlIG5hbWUgdGhhdCBzaG91bGQgYmUgcmV0cmlldmVkXG4gICAgICogQHJldHVybiB7R2V0RmlsZX1cbiAgICAgKi9cbiAgICBzZXRGaWxlTmFtZSAobmFtZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRGaWxlLktFWV9GSUxFX05BTUUsIG5hbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0RmlsZU5hbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR2V0RmlsZS5LRVlfRklMRV9OQU1FKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gaWQgLSBJRCBvZiB0aGUgc2VydmljZSB0aGF0IHNob3VsZCBoYXZlIHVwbG9hZGVkIHRoZSByZXF1ZXN0ZWQgZmlsZS5cbiAgICAgKiBAcmV0dXJuIHtHZXRGaWxlfVxuICAgICAqL1xuICAgIHNldEFwcFNlcnZpY2VJZCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0RmlsZS5LRVlfQVBQX1NFUlZJQ0VfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldEFwcFNlcnZpY2VJZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXRGaWxlLktFWV9BUFBfU0VSVklDRV9JRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtGaWxlVHlwZX0gdHlwZSAtIFNlbGVjdGVkIGZpbGUgdHlwZS5cbiAgICAgKiBAcmV0dXJuIHtHZXRGaWxlfVxuICAgICAqL1xuICAgIHNldEZpbGVUeXBlICh0eXBlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEZpbGVUeXBlLCB0eXBlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0RmlsZS5LRVlfRklMRV9UWVBFLCB0eXBlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7RmlsZVR5cGV9XG4gICAgICovXG4gICAgZ2V0RmlsZVR5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoRmlsZVR5cGUsIEdldEZpbGUuS0VZX0ZJTEVfVFlQRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG9mZnNldCAtIE9wdGlvbmFsIG9mZnNldCBpbiBieXRlcyBmb3IgcmVzdW1pbmcgcGFydGlhbCBkYXRhIGNodW5rc1xuICAgICAqIEByZXR1cm4ge0dldEZpbGV9XG4gICAgICovXG4gICAgc2V0T2Zmc2V0IChvZmZzZXQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0RmlsZS5LRVlfT0ZGU0VULCBvZmZzZXQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0T2Zmc2V0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdldEZpbGUuS0VZX09GRlNFVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGxlbmd0aCAtIE9wdGlvbmFsIGxlbmd0aCBpbiBieXRlcyBmb3IgcmVzdW1pbmcgcGFydGlhbCBkYXRhIGNodW5rcyBJZiBvZmZzZXQgaXMgc2V0IHRvIDAsIHRoZW5cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoIGlzIHRoZSB0b3RhbCBsZW5ndGggb2YgdGhlIGZpbGUgdG8gYmUgcmV0cmlldmVkXG4gICAgICogQHJldHVybiB7R2V0RmlsZX1cbiAgICAgKi9cbiAgICBzZXRMZW5ndGggKGxlbmd0aCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRGaWxlLktFWV9MRU5HVEgsIGxlbmd0aCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRMZW5ndGggKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR2V0RmlsZS5LRVlfTEVOR1RIKTtcbiAgICB9XG59XG5cbkdldEZpbGUuS0VZX0ZJTEVfTkFNRSA9ICdmaWxlTmFtZSc7XG5HZXRGaWxlLktFWV9BUFBfU0VSVklDRV9JRCA9ICdhcHBTZXJ2aWNlSWQnO1xuR2V0RmlsZS5LRVlfRklMRV9UWVBFID0gJ2ZpbGVUeXBlJztcbkdldEZpbGUuS0VZX09GRlNFVCA9ICdvZmZzZXQnO1xuR2V0RmlsZS5LRVlfTEVOR1RIID0gJ2xlbmd0aCc7XG5cbmV4cG9ydCB7IEdldEZpbGUgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBScGNSZXNwb25zZSB9IGZyb20gJy4uL1JwY1Jlc3BvbnNlLmpzJztcbmltcG9ydCB7IEZpbGVUeXBlIH0gZnJvbSAnLi4vZW51bXMvRmlsZVR5cGUuanMnO1xuXG4vKipcbiAqIFRoaXMgcmVzcG9uc2UgaW5jbHVkZXMgdGhlIGRhdGEgdGhhdCBpcyByZXF1ZXN0ZWQgZnJvbSB0aGUgc3BlY2lmaWMgc2VydmljZVxuICovXG5jbGFzcyBHZXRGaWxlUmVzcG9uc2UgZXh0ZW5kcyBScGNSZXNwb25zZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5HZXRGaWxlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gb2Zmc2V0IC0gT3B0aW9uYWwgb2Zmc2V0IGluIGJ5dGVzIGZvciByZXN1bWluZyBwYXJ0aWFsIGRhdGEgY2h1bmtzXG4gICAgICogQHJldHVybiB7R2V0RmlsZVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldE9mZnNldCAob2Zmc2V0KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldEZpbGVSZXNwb25zZS5LRVlfT0ZGU0VULCBvZmZzZXQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0T2Zmc2V0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdldEZpbGVSZXNwb25zZS5LRVlfT0ZGU0VUKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoIC0gT3B0aW9uYWwgbGVuZ3RoIGluIGJ5dGVzIGZvciByZXN1bWluZyBwYXJ0aWFsIGRhdGEgY2h1bmtzIGlmIG9mZnNldCBpcyBzZXQgdG8gMCwgdGhlblxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggaXMgdGhlIHRvdGFsIGxlbmd0aCBvZiB0aGUgZmlsZSB0byBiZSBkb3dubG9hZGVkXG4gICAgICogQHJldHVybiB7R2V0RmlsZVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldExlbmd0aCAobGVuZ3RoKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldEZpbGVSZXNwb25zZS5LRVlfTEVOR1RILCBsZW5ndGgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0TGVuZ3RoICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdldEZpbGVSZXNwb25zZS5LRVlfTEVOR1RIKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0ZpbGVUeXBlfSB0eXBlIC0gRmlsZSB0eXBlIHRoYXQgaXMgYmVpbmcgc2VudCBpbiByZXNwb25zZS5cbiAgICAgKiBAcmV0dXJuIHtHZXRGaWxlUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0RmlsZVR5cGUgKHR5cGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoRmlsZVR5cGUsIHR5cGUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRGaWxlUmVzcG9uc2UuS0VZX0ZJTEVfVFlQRSwgdHlwZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0ZpbGVUeXBlfVxuICAgICAqL1xuICAgIGdldEZpbGVUeXBlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEZpbGVUeXBlLCBHZXRGaWxlUmVzcG9uc2UuS0VZX0ZJTEVfVFlQRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGNyYyAtIEFkZGl0aW9uYWwgQ1JDMzIgY2hlY2tzdW0gdG8gcHJvdGVjdCBkYXRhIGludGVncml0eSB1cCB0byA1MTIgTWJpdHNcbiAgICAgKiBAcmV0dXJuIHtHZXRGaWxlUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0Q3JjIChjcmMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0RmlsZVJlc3BvbnNlLktFWV9DUkMsIGNyYyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRDcmMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR2V0RmlsZVJlc3BvbnNlLktFWV9DUkMpO1xuICAgIH1cbn1cblxuR2V0RmlsZVJlc3BvbnNlLktFWV9PRkZTRVQgPSAnb2Zmc2V0JztcbkdldEZpbGVSZXNwb25zZS5LRVlfTEVOR1RIID0gJ2xlbmd0aCc7XG5HZXRGaWxlUmVzcG9uc2UuS0VZX0ZJTEVfVFlQRSA9ICdmaWxlVHlwZSc7XG5HZXRGaWxlUmVzcG9uc2UuS0VZX0NSQyA9ICdjcmMnO1xuXG5leHBvcnQgeyBHZXRGaWxlUmVzcG9uc2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5cbi8qKlxuICogVXNlZCB0byBkZWxldGUgYSBmaWxlIHJlc2lkZW50IG9uIHRoZSBtb2R1bGUgaW4gdGhlIGFwcCdzIGxvY2FsIGNhY2hlLiBOb3Qgc3VwcG9ydGVkIG9uIGZpcnN0IGdlbmVyYXRpb24gU0RMIGVuYWJsZWRcbiAqIHZlaGljbGVzLlxuICovXG5jbGFzcyBEZWxldGVGaWxlIGV4dGVuZHMgUnBjUmVxdWVzdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5EZWxldGVGaWxlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSAtIEZpbGUgcmVmZXJlbmNlIG5hbWUuXG4gICAgICogQHJldHVybiB7RGVsZXRlRmlsZX1cbiAgICAgKi9cbiAgICBzZXRTZGxGaWxlTmFtZSAobmFtZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihEZWxldGVGaWxlLktFWV9TRExfRklMRV9OQU1FLCBuYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldFNkbEZpbGVOYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKERlbGV0ZUZpbGUuS0VZX1NETF9GSUxFX05BTUUpO1xuICAgIH1cbn1cblxuRGVsZXRlRmlsZS5LRVlfU0RMX0ZJTEVfTkFNRSA9ICdzeW5jRmlsZU5hbWUnO1xuXG5leHBvcnQgeyBEZWxldGVGaWxlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbi8qKlxuICogUmVzcG9uc2UgaXMgc2VudCwgd2hlbiB0aGUgZmlsZSBkYXRhIHdhcyBkZWxldGVkIChzdWNjZXNzIGNhc2UpLiBPciB3aGVuIGFuIGVycm9yIG9jY3VycmVkLiBOb3Qgc3VwcG9ydGVkIG9uIEZpcnN0XG4gKiBnZW5lcmF0aW9uIFNETCBlbmFibGVkIHZlaGljbGVzLlxuICovXG5jbGFzcyBEZWxldGVGaWxlUmVzcG9uc2UgZXh0ZW5kcyBScGNSZXNwb25zZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5EZWxldGVGaWxlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYXZhaWxhYmxlIC0gUHJvdmlkZXMgdGhlIHRvdGFsIGxvY2FsIHNwYWNlIGF2YWlsYWJsZSBvbiB0aGUgbW9kdWxlIGZvciB0aGUgcmVnaXN0ZXJlZCBhcHAuXG4gICAgICogQHJldHVybiB7RGVsZXRlRmlsZVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldFNwYWNlQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGVsZXRlRmlsZVJlc3BvbnNlLktFWV9TUEFDRV9BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRTcGFjZUF2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihEZWxldGVGaWxlUmVzcG9uc2UuS0VZX1NQQUNFX0FWQUlMQUJMRSk7XG4gICAgfVxufVxuXG5EZWxldGVGaWxlUmVzcG9uc2UuS0VZX1NQQUNFX0FWQUlMQUJMRSA9ICdzcGFjZUF2YWlsYWJsZSc7XG5cbmV4cG9ydCB7IERlbGV0ZUZpbGVSZXNwb25zZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1JlcXVlc3QgfSBmcm9tICcuLi9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcblxuLyoqXG4gKiBSZXF1ZXN0cyB0aGUgY3VycmVudCBsaXN0IG9mIHJlc2lkZW50IGZpbGVuYW1lcyBmb3IgdGhlIHJlZ2lzdGVyZWQgYXBwLiBOb3Qgc3VwcG9ydGVkIG9uIGZpcnN0IGdlbmVyYXRpb24gU0RMXG4gKiBlbmFibGVkIHZlaGljbGVzLlxuICovXG5jbGFzcyBMaXN0RmlsZXMgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkxpc3RGaWxlcyk7XG4gICAgfVxufVxuXG5cbmV4cG9ydCB7IExpc3RGaWxlcyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGN1cnJlbnQgbGlzdCBvZiByZXNpZGVudCBmaWxlbmFtZXMgZm9yIHRoZSByZWdpc3RlcmVkIGFwcCBhbG9uZyB3aXRoIHRoZSBjdXJyZW50IHNwYWNlIGF2YWlsYWJsZSBOb3RcbiAqIHN1cHBvcnRlZCBvbiBGaXJzdCBnZW5lcmF0aW9uIFNETCBlbmFibGVkIHZlaGljbGVzLlxuICovXG5jbGFzcyBMaXN0RmlsZXNSZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkxpc3RGaWxlcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmdbXX0gZmlsZW5hbWVzIC0gQW4gYXJyYXkgb2YgYWxsIGZpbGVuYW1lcyByZXNpZGVudCBvbiB0aGUgbW9kdWxlIGZvciB0aGUgZ2l2ZW4gcmVnaXN0ZXJlZCBhcHAuIElmXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb21pdHRlZCwgdGhlbiBubyBmaWxlcyBjdXJyZW50bHkgcmVzaWRlIG9uIHRoZSBzeXN0ZW0uXG4gICAgICogQHJldHVybiB7TGlzdEZpbGVzUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0RmlsZW5hbWVzIChmaWxlbmFtZXMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTGlzdEZpbGVzUmVzcG9uc2UuS0VZX0ZJTEVOQU1FUywgZmlsZW5hbWVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nW119XG4gICAgICovXG4gICAgZ2V0RmlsZW5hbWVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKExpc3RGaWxlc1Jlc3BvbnNlLktFWV9GSUxFTkFNRVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBhdmFpbGFibGUgLSBQcm92aWRlcyB0aGUgdG90YWwgbG9jYWwgc3BhY2UgYXZhaWxhYmxlIG9uIHRoZSBtb2R1bGUgZm9yIHRoZSByZWdpc3RlcmVkIGFwcC5cbiAgICAgKiBAcmV0dXJuIHtMaXN0RmlsZXNSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRTcGFjZUF2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKExpc3RGaWxlc1Jlc3BvbnNlLktFWV9TUEFDRV9BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRTcGFjZUF2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihMaXN0RmlsZXNSZXNwb25zZS5LRVlfU1BBQ0VfQVZBSUxBQkxFKTtcbiAgICB9XG59XG5cbkxpc3RGaWxlc1Jlc3BvbnNlLktFWV9GSUxFTkFNRVMgPSAnZmlsZW5hbWVzJztcbkxpc3RGaWxlc1Jlc3BvbnNlLktFWV9TUEFDRV9BVkFJTEFCTEUgPSAnc3BhY2VBdmFpbGFibGUnO1xuXG5leHBvcnQgeyBMaXN0RmlsZXNSZXNwb25zZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1JlcXVlc3QgfSBmcm9tICcuLi9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcblxuLyoqXG4gKiBVc2VkIHRvIHNldCBleGlzdGluZyBsb2NhbCBmaWxlIG9uIHRoZSBtb2R1bGUgYXMgdGhlIGFwcCdzIGljb24gTm90IHN1cHBvcnRlZCBvbiBmaXJzdCBnZW5lcmF0aW9uIFNETCBlbmFibGVkXG4gKiB2ZWhpY2xlcy5cbiAqL1xuY2xhc3MgU2V0QXBwSWNvbiBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuU2V0QXBwSWNvbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBGaWxlIHJlZmVyZW5jZSBuYW1lLlxuICAgICAqIEByZXR1cm4ge1NldEFwcEljb259XG4gICAgICovXG4gICAgc2V0RmlsZU5hbWUgKG5hbWUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2V0QXBwSWNvbi5LRVlfRklMRV9OQU1FLCBuYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldEZpbGVOYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNldEFwcEljb24uS0VZX0ZJTEVfTkFNRSk7XG4gICAgfVxufVxuXG5TZXRBcHBJY29uLktFWV9GSUxFX05BTUUgPSAnc3luY0ZpbGVOYW1lJztcblxuZXhwb3J0IHsgU2V0QXBwSWNvbiB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG4vKipcbiAqIFJlc3BvbnNlIGlzIHNlbnQsIHdoZW4gdGhlIGZpbGUgZGF0YSB3YXMgY29waWVkIChzdWNjZXNzIGNhc2UpLiBPciB3aGVuIGFuIGVycm9yIG9jY3VycmVkLiBOb3Qgc3VwcG9ydGVkIG9uIEZpcnN0XG4gKiBnZW5lcmF0aW9uIFNETCBlbmFibGVkIHZlaGljbGVzLlxuICovXG5jbGFzcyBTZXRBcHBJY29uUmVzcG9uc2UgZXh0ZW5kcyBScGNSZXNwb25zZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5TZXRBcHBJY29uKTtcbiAgICB9XG59XG5cblxuZXhwb3J0IHsgU2V0QXBwSWNvblJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgVGVtcGxhdGVDb2xvclNjaGVtZSB9IGZyb20gJy4uL3N0cnVjdHMvVGVtcGxhdGVDb2xvclNjaGVtZS5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5cbi8qKlxuICogVGhpcyBSUEMgaXMgZGVwcmVjYXRlZC4gVXNlIFNob3cgUlBDIHRvIGNoYW5nZSBsYXlvdXQuXG4gKiBAZGVwcmVjYXRlZFxuICovXG5jbGFzcyBTZXREaXNwbGF5TGF5b3V0IGV4dGVuZHMgUnBjUmVxdWVzdCB7XG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlNldERpc3BsYXlMYXlvdXQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGxheW91dCAtIFByZWRlZmluZWQgb3IgZHluYW1pY2FsbHkgY3JlYXRlZCBzY3JlZW4gbGF5b3V0LiBDdXJyZW50bHkgb25seSBwcmVkZWZpbmVkIHNjcmVlblxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBsYXlvdXRzIGFyZSBkZWZpbmVkLlxuICAgICAqIEByZXR1cm4ge1NldERpc3BsYXlMYXlvdXR9XG4gICAgICovXG4gICAgc2V0RGlzcGxheUxheW91dCAobGF5b3V0KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNldERpc3BsYXlMYXlvdXQuS0VZX0RJU1BMQVlfTEFZT1VULCBsYXlvdXQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXREaXNwbGF5TGF5b3V0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNldERpc3BsYXlMYXlvdXQuS0VZX0RJU1BMQVlfTEFZT1VUKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqIEBwYXJhbSB7VGVtcGxhdGVDb2xvclNjaGVtZX0gc2NoZW1lIC0gQSBjb2xvciBzY2hlbWUgZm9yIGFsbCBkaXNwbGF5IGxheW91dCB0ZW1wbGF0ZXMuXG4gICAgICogQHJldHVybiB7U2V0RGlzcGxheUxheW91dH1cbiAgICAgKi9cbiAgICBzZXREYXlDb2xvclNjaGVtZSAoc2NoZW1lKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFRlbXBsYXRlQ29sb3JTY2hlbWUsIHNjaGVtZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNldERpc3BsYXlMYXlvdXQuS0VZX0RBWV9DT0xPUl9TQ0hFTUUsIHNjaGVtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICogQHJldHVybiB7VGVtcGxhdGVDb2xvclNjaGVtZX1cbiAgICAgKi9cbiAgICBnZXREYXlDb2xvclNjaGVtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChUZW1wbGF0ZUNvbG9yU2NoZW1lLCBTZXREaXNwbGF5TGF5b3V0LktFWV9EQVlfQ09MT1JfU0NIRU1FKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqIEBwYXJhbSB7VGVtcGxhdGVDb2xvclNjaGVtZX0gc2NoZW1lIC0gQSBjb2xvciBzY2hlbWUgZm9yIGFsbCBkaXNwbGF5IGxheW91dCB0ZW1wbGF0ZXMuXG4gICAgICogQHJldHVybiB7U2V0RGlzcGxheUxheW91dH1cbiAgICAgKi9cbiAgICBzZXROaWdodENvbG9yU2NoZW1lIChzY2hlbWUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVGVtcGxhdGVDb2xvclNjaGVtZSwgc2NoZW1lKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2V0RGlzcGxheUxheW91dC5LRVlfTklHSFRfQ09MT1JfU0NIRU1FLCBzY2hlbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqIEByZXR1cm4ge1RlbXBsYXRlQ29sb3JTY2hlbWV9XG4gICAgICovXG4gICAgZ2V0TmlnaHRDb2xvclNjaGVtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChUZW1wbGF0ZUNvbG9yU2NoZW1lLCBTZXREaXNwbGF5TGF5b3V0LktFWV9OSUdIVF9DT0xPUl9TQ0hFTUUpO1xuICAgIH1cbn1cblxuU2V0RGlzcGxheUxheW91dC5LRVlfRElTUExBWV9MQVlPVVQgPSAnZGlzcGxheUxheW91dCc7XG5TZXREaXNwbGF5TGF5b3V0LktFWV9EQVlfQ09MT1JfU0NIRU1FID0gJ2RheUNvbG9yU2NoZW1lJztcblNldERpc3BsYXlMYXlvdXQuS0VZX05JR0hUX0NPTE9SX1NDSEVNRSA9ICduaWdodENvbG9yU2NoZW1lJztcblxuZXhwb3J0IHsgU2V0RGlzcGxheUxheW91dCB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgU29mdEJ1dHRvbkNhcGFiaWxpdGllcyB9IGZyb20gJy4uL3N0cnVjdHMvU29mdEJ1dHRvbkNhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBQcmVzZXRCYW5rQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi4vc3RydWN0cy9QcmVzZXRCYW5rQ2FwYWJpbGl0aWVzLmpzJztcbmltcG9ydCB7IERpc3BsYXlDYXBhYmlsaXRpZXMgfSBmcm9tICcuLi9zdHJ1Y3RzL0Rpc3BsYXlDYXBhYmlsaXRpZXMuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgQnV0dG9uQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi4vc3RydWN0cy9CdXR0b25DYXBhYmlsaXRpZXMuanMnO1xuXG4vKipcbiAqIFRoaXMgUlBDIGlzIGRlcHJlY2F0ZWQuIFVzZSBTaG93IFJQQyB0byBjaGFuZ2UgbGF5b3V0LlxuICogQGRlcHJlY2F0ZWRcbiAqL1xuY2xhc3MgU2V0RGlzcGxheUxheW91dFJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5TZXREaXNwbGF5TGF5b3V0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqIEBwYXJhbSB7RGlzcGxheUNhcGFiaWxpdGllc30gY2FwYWJpbGl0aWVzIC0gU2VlIERpc3BsYXlDYXBhYmlsaXRpZXNcbiAgICAgKiBAcmV0dXJuIHtTZXREaXNwbGF5TGF5b3V0UmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0RGlzcGxheUNhcGFiaWxpdGllcyAoY2FwYWJpbGl0aWVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKERpc3BsYXlDYXBhYmlsaXRpZXMsIGNhcGFiaWxpdGllcyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNldERpc3BsYXlMYXlvdXRSZXNwb25zZS5LRVlfRElTUExBWV9DQVBBQklMSVRJRVMsIGNhcGFiaWxpdGllcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICogQHJldHVybiB7RGlzcGxheUNhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBnZXREaXNwbGF5Q2FwYWJpbGl0aWVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KERpc3BsYXlDYXBhYmlsaXRpZXMsIFNldERpc3BsYXlMYXlvdXRSZXNwb25zZS5LRVlfRElTUExBWV9DQVBBQklMSVRJRVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICogQHBhcmFtIHtCdXR0b25DYXBhYmlsaXRpZXNbXX0gY2FwYWJpbGl0aWVzIC0gU2VlIEJ1dHRvbkNhcGFiaWxpdGllc1xuICAgICAqIEByZXR1cm4ge1NldERpc3BsYXlMYXlvdXRSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRCdXR0b25DYXBhYmlsaXRpZXMgKGNhcGFiaWxpdGllcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShCdXR0b25DYXBhYmlsaXRpZXMsIGNhcGFiaWxpdGllcywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNldERpc3BsYXlMYXlvdXRSZXNwb25zZS5LRVlfQlVUVE9OX0NBUEFCSUxJVElFUywgY2FwYWJpbGl0aWVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKiBAcmV0dXJuIHtCdXR0b25DYXBhYmlsaXRpZXNbXX1cbiAgICAgKi9cbiAgICBnZXRCdXR0b25DYXBhYmlsaXRpZXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQnV0dG9uQ2FwYWJpbGl0aWVzLCBTZXREaXNwbGF5TGF5b3V0UmVzcG9uc2UuS0VZX0JVVFRPTl9DQVBBQklMSVRJRVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICogQHBhcmFtIHtTb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzW119IGNhcGFiaWxpdGllcyAtIElmIHJldHVybmVkLCB0aGUgcGxhdGZvcm0gc3VwcG9ydHMgb24tc2NyZWVuIFNvZnRCdXR0b25zOyBzZWVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU29mdEJ1dHRvbkNhcGFiaWxpdGllcy5cbiAgICAgKiBAcmV0dXJuIHtTZXREaXNwbGF5TGF5b3V0UmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0U29mdEJ1dHRvbkNhcGFiaWxpdGllcyAoY2FwYWJpbGl0aWVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFNvZnRCdXR0b25DYXBhYmlsaXRpZXMsIGNhcGFiaWxpdGllcywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNldERpc3BsYXlMYXlvdXRSZXNwb25zZS5LRVlfU09GVF9CVVRUT05fQ0FQQUJJTElUSUVTLCBjYXBhYmlsaXRpZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqIEByZXR1cm4ge1NvZnRCdXR0b25DYXBhYmlsaXRpZXNbXX1cbiAgICAgKi9cbiAgICBnZXRTb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFNvZnRCdXR0b25DYXBhYmlsaXRpZXMsIFNldERpc3BsYXlMYXlvdXRSZXNwb25zZS5LRVlfU09GVF9CVVRUT05fQ0FQQUJJTElUSUVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqIEBwYXJhbSB7UHJlc2V0QmFua0NhcGFiaWxpdGllc30gY2FwYWJpbGl0aWVzIC0gSWYgcmV0dXJuZWQsIHRoZSBwbGF0Zm9ybSBzdXBwb3J0cyBjdXN0b20gb24tc2NyZWVuIFByZXNldHM7IHNlZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJlc2V0QmFua0NhcGFiaWxpdGllcy5cbiAgICAgKiBAcmV0dXJuIHtTZXREaXNwbGF5TGF5b3V0UmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0UHJlc2V0QmFua0NhcGFiaWxpdGllcyAoY2FwYWJpbGl0aWVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFByZXNldEJhbmtDYXBhYmlsaXRpZXMsIGNhcGFiaWxpdGllcyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNldERpc3BsYXlMYXlvdXRSZXNwb25zZS5LRVlfUFJFU0VUX0JBTktfQ0FQQUJJTElUSUVTLCBjYXBhYmlsaXRpZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqIEByZXR1cm4ge1ByZXNldEJhbmtDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgZ2V0UHJlc2V0QmFua0NhcGFiaWxpdGllcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChQcmVzZXRCYW5rQ2FwYWJpbGl0aWVzLCBTZXREaXNwbGF5TGF5b3V0UmVzcG9uc2UuS0VZX1BSRVNFVF9CQU5LX0NBUEFCSUxJVElFUyk7XG4gICAgfVxufVxuXG5TZXREaXNwbGF5TGF5b3V0UmVzcG9uc2UuS0VZX0RJU1BMQVlfQ0FQQUJJTElUSUVTID0gJ2Rpc3BsYXlDYXBhYmlsaXRpZXMnO1xuU2V0RGlzcGxheUxheW91dFJlc3BvbnNlLktFWV9CVVRUT05fQ0FQQUJJTElUSUVTID0gJ2J1dHRvbkNhcGFiaWxpdGllcyc7XG5TZXREaXNwbGF5TGF5b3V0UmVzcG9uc2UuS0VZX1NPRlRfQlVUVE9OX0NBUEFCSUxJVElFUyA9ICdzb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzJztcblNldERpc3BsYXlMYXlvdXRSZXNwb25zZS5LRVlfUFJFU0VUX0JBTktfQ0FQQUJJTElUSUVTID0gJ3ByZXNldEJhbmtDYXBhYmlsaXRpZXMnO1xuXG5leHBvcnQgeyBTZXREaXNwbGF5TGF5b3V0UmVzcG9uc2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBFbnVtZXJhdGlvbiBsaXN0aW5nIHBvc3NpYmxlIGFzeW5jaHJvbm91cyByZXF1ZXN0cy5cbiAqIEB0eXBlZGVmIHtFbnVtfSBSZXF1ZXN0VHlwZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgUmVxdWVzdFR5cGUgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSFRUUCAoKSB7XG4gICAgICAgIHJldHVybiBSZXF1ZXN0VHlwZS5fTUFQLkhUVFA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRklMRV9SRVNVTUUgKCkge1xuICAgICAgICByZXR1cm4gUmVxdWVzdFR5cGUuX01BUC5GSUxFX1JFU1VNRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBBVVRIX1JFUVVFU1QgKCkge1xuICAgICAgICByZXR1cm4gUmVxdWVzdFR5cGUuX01BUC5BVVRIX1JFUVVFU1Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQVVUSF9DSEFMTEVOR0UgKCkge1xuICAgICAgICByZXR1cm4gUmVxdWVzdFR5cGUuX01BUC5BVVRIX0NIQUxMRU5HRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBBVVRIX0FDSyAoKSB7XG4gICAgICAgIHJldHVybiBSZXF1ZXN0VHlwZS5fTUFQLkFVVEhfQUNLO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFBST1BSSUVUQVJZICgpIHtcbiAgICAgICAgcmV0dXJuIFJlcXVlc3RUeXBlLl9NQVAuUFJPUFJJRVRBUlk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUVVFUllfQVBQUyAoKSB7XG4gICAgICAgIHJldHVybiBSZXF1ZXN0VHlwZS5fTUFQLlFVRVJZX0FQUFM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTEFVTkNIX0FQUCAoKSB7XG4gICAgICAgIHJldHVybiBSZXF1ZXN0VHlwZS5fTUFQLkxBVU5DSF9BUFA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTE9DS19TQ1JFRU5fSUNPTl9VUkwgKCkge1xuICAgICAgICByZXR1cm4gUmVxdWVzdFR5cGUuX01BUC5MT0NLX1NDUkVFTl9JQ09OX1VSTDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBUUkFGRklDX01FU1NBR0VfQ0hBTk5FTCAoKSB7XG4gICAgICAgIHJldHVybiBSZXF1ZXN0VHlwZS5fTUFQLlRSQUZGSUNfTUVTU0FHRV9DSEFOTkVMO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IERSSVZFUl9QUk9GSUxFICgpIHtcbiAgICAgICAgcmV0dXJuIFJlcXVlc3RUeXBlLl9NQVAuRFJJVkVSX1BST0ZJTEU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVk9JQ0VfU0VBUkNIICgpIHtcbiAgICAgICAgcmV0dXJuIFJlcXVlc3RUeXBlLl9NQVAuVk9JQ0VfU0VBUkNIO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5BVklHQVRJT04gKCkge1xuICAgICAgICByZXR1cm4gUmVxdWVzdFR5cGUuX01BUC5OQVZJR0FUSU9OO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFBIT05FICgpIHtcbiAgICAgICAgcmV0dXJuIFJlcXVlc3RUeXBlLl9NQVAuUEhPTkU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ0xJTUFURSAoKSB7XG4gICAgICAgIHJldHVybiBSZXF1ZXN0VHlwZS5fTUFQLkNMSU1BVEU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0VUVElOR1MgKCkge1xuICAgICAgICByZXR1cm4gUmVxdWVzdFR5cGUuX01BUC5TRVRUSU5HUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBWRUhJQ0xFX0RJQUdOT1NUSUNTICgpIHtcbiAgICAgICAgcmV0dXJuIFJlcXVlc3RUeXBlLl9NQVAuVkVISUNMRV9ESUFHTk9TVElDUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFTUVSR0VOQ1kgKCkge1xuICAgICAgICByZXR1cm4gUmVxdWVzdFR5cGUuX01BUC5FTUVSR0VOQ1k7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTUVESUEgKCkge1xuICAgICAgICByZXR1cm4gUmVxdWVzdFR5cGUuX01BUC5NRURJQTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBGT1RBICgpIHtcbiAgICAgICAgcmV0dXJuIFJlcXVlc3RUeXBlLl9NQVAuRk9UQTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBPRU1fU1BFQ0lGSUMgKCkge1xuICAgICAgICByZXR1cm4gUmVxdWVzdFR5cGUuX01BUC5PRU1fU1BFQ0lGSUM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSUNPTl9VUkwgKCkge1xuICAgICAgICByZXR1cm4gUmVxdWVzdFR5cGUuX01BUC5JQ09OX1VSTDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBSZXF1ZXN0VHlwZS5fdmFsdWVGb3JLZXkoa2V5LCBSZXF1ZXN0VHlwZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFJlcXVlc3RUeXBlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgUmVxdWVzdFR5cGUuX01BUCk7XG4gICAgfVxufVxuXG5SZXF1ZXN0VHlwZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0hUVFAnOiAnSFRUUCcsXG4gICAgJ0ZJTEVfUkVTVU1FJzogJ0ZJTEVfUkVTVU1FJyxcbiAgICAnQVVUSF9SRVFVRVNUJzogJ0FVVEhfUkVRVUVTVCcsXG4gICAgJ0FVVEhfQ0hBTExFTkdFJzogJ0FVVEhfQ0hBTExFTkdFJyxcbiAgICAnQVVUSF9BQ0snOiAnQVVUSF9BQ0snLFxuICAgICdQUk9QUklFVEFSWSc6ICdQUk9QUklFVEFSWScsXG4gICAgJ1FVRVJZX0FQUFMnOiAnUVVFUllfQVBQUycsXG4gICAgJ0xBVU5DSF9BUFAnOiAnTEFVTkNIX0FQUCcsXG4gICAgJ0xPQ0tfU0NSRUVOX0lDT05fVVJMJzogJ0xPQ0tfU0NSRUVOX0lDT05fVVJMJyxcbiAgICAnVFJBRkZJQ19NRVNTQUdFX0NIQU5ORUwnOiAnVFJBRkZJQ19NRVNTQUdFX0NIQU5ORUwnLFxuICAgICdEUklWRVJfUFJPRklMRSc6ICdEUklWRVJfUFJPRklMRScsXG4gICAgJ1ZPSUNFX1NFQVJDSCc6ICdWT0lDRV9TRUFSQ0gnLFxuICAgICdOQVZJR0FUSU9OJzogJ05BVklHQVRJT04nLFxuICAgICdQSE9ORSc6ICdQSE9ORScsXG4gICAgJ0NMSU1BVEUnOiAnQ0xJTUFURScsXG4gICAgJ1NFVFRJTkdTJzogJ1NFVFRJTkdTJyxcbiAgICAnVkVISUNMRV9ESUFHTk9TVElDUyc6ICdWRUhJQ0xFX0RJQUdOT1NUSUNTJyxcbiAgICAnRU1FUkdFTkNZJzogJ0VNRVJHRU5DWScsXG4gICAgJ01FRElBJzogJ01FRElBJyxcbiAgICAnRk9UQSc6ICdGT1RBJyxcbiAgICAnT0VNX1NQRUNJRklDJzogJ09FTV9TUEVDSUZJQycsXG4gICAgJ0lDT05fVVJMJzogJ0lDT05fVVJMJyxcbn0pO1xuXG5leHBvcnQgeyBSZXF1ZXN0VHlwZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1JlcXVlc3QgfSBmcm9tICcuLi9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IFJlcXVlc3RUeXBlIH0gZnJvbSAnLi4vZW51bXMvUmVxdWVzdFR5cGUuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG4vKipcbiAqIEFuIGFzeW5jaHJvbm91cyByZXF1ZXN0IGZyb20gdGhlIGRldmljZTsgYmluYXJ5IGRhdGEgY2FuIGJlIGluY2x1ZGVkIGluIGh5YnJpZCBwYXJ0IG9mIG1lc3NhZ2UgZm9yIHNvbWUgcmVxdWVzdHNcbiAqIChzdWNoIGFzIEhUVFAsIFByb3ByaWV0YXJ5LCBvciBBdXRoZW50aWNhdGlvbiByZXF1ZXN0cylcbiAqL1xuY2xhc3MgU3lzdGVtUmVxdWVzdCBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuU3lzdGVtUmVxdWVzdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtSZXF1ZXN0VHlwZX0gdHlwZSAtIFRoZSB0eXBlIG9mIHN5c3RlbSByZXF1ZXN0LiBOb3RlIHRoYXQgUHJvcHJpZXRhcnkgcmVxdWVzdHMgc2hvdWxkIGZvcndhcmQgdGhlIGJpbmFyeVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhIHRvIHRoZSBrbm93biBwcm9wcmlldGFyeSBtb2R1bGUgb24gdGhlIHN5c3RlbS5cbiAgICAgKiBAcmV0dXJuIHtTeXN0ZW1SZXF1ZXN0fVxuICAgICAqL1xuICAgIHNldFJlcXVlc3RUeXBlICh0eXBlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFJlcXVlc3RUeXBlLCB0eXBlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3lzdGVtUmVxdWVzdC5LRVlfUkVRVUVTVF9UWVBFLCB0eXBlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7UmVxdWVzdFR5cGV9XG4gICAgICovXG4gICAgZ2V0UmVxdWVzdFR5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoUmVxdWVzdFR5cGUsIFN5c3RlbVJlcXVlc3QuS0VZX1JFUVVFU1RfVFlQRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgLSBUaGlzIHBhcmFtZXRlciBpcyBmaWxsZWQgZm9yIHN1cHBvcnRpbmcgT0VNIHByb3ByaWV0YXJ5IGRhdGEgZXhjaGFuZ2VzLlxuICAgICAqIEByZXR1cm4ge1N5c3RlbVJlcXVlc3R9XG4gICAgICovXG4gICAgc2V0UmVxdWVzdFN1YlR5cGUgKHR5cGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3lzdGVtUmVxdWVzdC5LRVlfUkVRVUVTVF9TVUJfVFlQRSwgdHlwZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRSZXF1ZXN0U3ViVHlwZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTeXN0ZW1SZXF1ZXN0LktFWV9SRVFVRVNUX1NVQl9UWVBFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSAtIEZpbGVuYW1lIG9mIEhUVFAgZGF0YSB0byBzdG9yZSBpbiBwcmVkZWZpbmVkIHN5c3RlbSBzdGFnaW5nIGFyZWEuIE1hbmRhdG9yeSBpZiByZXF1ZXN0VHlwZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgaXMgSFRUUC4gUFJPUFJJRVRBUlkgcmVxdWVzdFR5cGUgc2hvdWxkIGlnbm9yZSB0aGlzIHBhcmFtZXRlci5cbiAgICAgKiBAcmV0dXJuIHtTeXN0ZW1SZXF1ZXN0fVxuICAgICAqL1xuICAgIHNldEZpbGVOYW1lIChuYW1lKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFN5c3RlbVJlcXVlc3QuS0VZX0ZJTEVfTkFNRSwgbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRGaWxlTmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTeXN0ZW1SZXF1ZXN0LktFWV9GSUxFX05BTUUpO1xuICAgIH1cbn1cblxuU3lzdGVtUmVxdWVzdC5LRVlfUkVRVUVTVF9UWVBFID0gJ3JlcXVlc3RUeXBlJztcblN5c3RlbVJlcXVlc3QuS0VZX1JFUVVFU1RfU1VCX1RZUEUgPSAncmVxdWVzdFN1YlR5cGUnO1xuU3lzdGVtUmVxdWVzdC5LRVlfRklMRV9OQU1FID0gJ2ZpbGVOYW1lJztcblxuZXhwb3J0IHsgU3lzdGVtUmVxdWVzdCB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG5jbGFzcyBTeXN0ZW1SZXF1ZXN0UmVzcG9uc2UgZXh0ZW5kcyBScGNSZXNwb25zZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5TeXN0ZW1SZXF1ZXN0KTtcbiAgICB9XG59XG5cblxuZXhwb3J0IHsgU3lzdGVtUmVxdWVzdFJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogVGhlIG1vZGUgaW4gd2hpY2ggdGhlIFNlbmRMb2NhdGlvbiByZXF1ZXN0IGlzIHNlbnRcbiAqIEB0eXBlZGVmIHtFbnVtfSBEZWxpdmVyeU1vZGVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIERlbGl2ZXJ5TW9kZSBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBQUk9NUFQgKCkge1xuICAgICAgICByZXR1cm4gRGVsaXZlcnlNb2RlLl9NQVAuUFJPTVBUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IERFU1RJTkFUSU9OICgpIHtcbiAgICAgICAgcmV0dXJuIERlbGl2ZXJ5TW9kZS5fTUFQLkRFU1RJTkFUSU9OO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFFVRVVFICgpIHtcbiAgICAgICAgcmV0dXJuIERlbGl2ZXJ5TW9kZS5fTUFQLlFVRVVFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIERlbGl2ZXJ5TW9kZS5fdmFsdWVGb3JLZXkoa2V5LCBEZWxpdmVyeU1vZGUuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBEZWxpdmVyeU1vZGUuX2tleUZvclZhbHVlKHZhbHVlLCBEZWxpdmVyeU1vZGUuX01BUCk7XG4gICAgfVxufVxuXG5EZWxpdmVyeU1vZGUuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdQUk9NUFQnOiAnUFJPTVBUJyxcbiAgICAnREVTVElOQVRJT04nOiAnREVTVElOQVRJT04nLFxuICAgICdRVUVVRSc6ICdRVUVVRScsXG59KTtcblxuZXhwb3J0IHsgRGVsaXZlcnlNb2RlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcblxuY2xhc3MgRGF0ZVRpbWUgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBtaWxsaXNlY29uZCAtIE1pbGxpc2Vjb25kc1xuICAgICAqIEByZXR1cm4ge0RhdGVUaW1lfVxuICAgICAqL1xuICAgIHNldE1pbGxpc2Vjb25kIChtaWxsaXNlY29uZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihEYXRlVGltZS5LRVlfTUlMTElTRUNPTkQsIG1pbGxpc2Vjb25kKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldE1pbGxpc2Vjb25kICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKERhdGVUaW1lLktFWV9NSUxMSVNFQ09ORCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlY29uZCAtIFNlY29uZHMgcGFydCBvZiB0aW1lXG4gICAgICogQHJldHVybiB7RGF0ZVRpbWV9XG4gICAgICovXG4gICAgc2V0U2Vjb25kIChzZWNvbmQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGF0ZVRpbWUuS0VZX1NFQ09ORCwgc2Vjb25kKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFNlY29uZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihEYXRlVGltZS5LRVlfU0VDT05EKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbWludXRlIC0gTWludXRlcyBwYXJ0IG9mIHRpbWVcbiAgICAgKiBAcmV0dXJuIHtEYXRlVGltZX1cbiAgICAgKi9cbiAgICBzZXRNaW51dGUgKG1pbnV0ZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihEYXRlVGltZS5LRVlfTUlOVVRFLCBtaW51dGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0TWludXRlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKERhdGVUaW1lLktFWV9NSU5VVEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBob3VyIC0gSG91cnMgcGFydCBvZiB0aW1lLiBOb3RlIHRoYXQgdGhpcyBzdHJ1Y3R1cmUgYWNjZXB0cyB0aW1lIG9ubHkgaW4gMjQgSHIgZm9ybWF0XG4gICAgICogQHJldHVybiB7RGF0ZVRpbWV9XG4gICAgICovXG4gICAgc2V0SG91ciAoaG91cikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihEYXRlVGltZS5LRVlfSE9VUiwgaG91cik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRIb3VyICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKERhdGVUaW1lLktFWV9IT1VSKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZGF5IC0gRGF5IG9mIHRoZSBtb250aFxuICAgICAqIEByZXR1cm4ge0RhdGVUaW1lfVxuICAgICAqL1xuICAgIHNldERheSAoZGF5KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKERhdGVUaW1lLktFWV9EQVksIGRheSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXREYXkgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoRGF0ZVRpbWUuS0VZX0RBWSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG1vbnRoIC0gTW9udGggb2YgdGhlIHllYXJcbiAgICAgKiBAcmV0dXJuIHtEYXRlVGltZX1cbiAgICAgKi9cbiAgICBzZXRNb250aCAobW9udGgpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGF0ZVRpbWUuS0VZX01PTlRILCBtb250aCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRNb250aCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihEYXRlVGltZS5LRVlfTU9OVEgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5ZWFyIC0gVGhlIHllYXIgaW4gWVlZWSBmb3JtYXRcbiAgICAgKiBAcmV0dXJuIHtEYXRlVGltZX1cbiAgICAgKi9cbiAgICBzZXRZZWFyICh5ZWFyKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKERhdGVUaW1lLktFWV9ZRUFSLCB5ZWFyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFllYXIgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoRGF0ZVRpbWUuS0VZX1lFQVIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB0el9ob3VyIC0gVGltZSB6b25lIG9mZnNldCBpbiBIb3VycyB3cnQgVVRDLlxuICAgICAqIEByZXR1cm4ge0RhdGVUaW1lfVxuICAgICAqL1xuICAgIHNldFR6X2hvdXIgKHR6X2hvdXIpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGF0ZVRpbWUuS0VZX1RaX0hPVVIsIHR6X2hvdXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0VHpfaG91ciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihEYXRlVGltZS5LRVlfVFpfSE9VUik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHR6X21pbnV0ZSAtIFRpbWUgem9uZSBvZmZzZXQgaW4gTWluIHdydCBVVEMuXG4gICAgICogQHJldHVybiB7RGF0ZVRpbWV9XG4gICAgICovXG4gICAgc2V0VHpfbWludXRlICh0el9taW51dGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGF0ZVRpbWUuS0VZX1RaX01JTlVURSwgdHpfbWludXRlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFR6X21pbnV0ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihEYXRlVGltZS5LRVlfVFpfTUlOVVRFKTtcbiAgICB9XG59XG5cbkRhdGVUaW1lLktFWV9NSUxMSVNFQ09ORCA9ICdtaWxsaXNlY29uZCc7XG5EYXRlVGltZS5LRVlfU0VDT05EID0gJ3NlY29uZCc7XG5EYXRlVGltZS5LRVlfTUlOVVRFID0gJ21pbnV0ZSc7XG5EYXRlVGltZS5LRVlfSE9VUiA9ICdob3VyJztcbkRhdGVUaW1lLktFWV9EQVkgPSAnZGF5JztcbkRhdGVUaW1lLktFWV9NT05USCA9ICdtb250aCc7XG5EYXRlVGltZS5LRVlfWUVBUiA9ICd5ZWFyJztcbkRhdGVUaW1lLktFWV9UWl9IT1VSID0gJ3R6X2hvdXInO1xuRGF0ZVRpbWUuS0VZX1RaX01JTlVURSA9ICd0el9taW51dGUnO1xuXG5leHBvcnQgeyBEYXRlVGltZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5cbmNsYXNzIE9BU0lTQWRkcmVzcyBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBOYW1lIG9mIHRoZSBjb3VudHJ5IChsb2NhbGl6ZWQpXG4gICAgICogQHJldHVybiB7T0FTSVNBZGRyZXNzfVxuICAgICAqL1xuICAgIHNldENvdW50cnlOYW1lIChuYW1lKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9BU0lTQWRkcmVzcy5LRVlfQ09VTlRSWV9OQU1FLCBuYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldENvdW50cnlOYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE9BU0lTQWRkcmVzcy5LRVlfQ09VTlRSWV9OQU1FKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gY29kZSAtIE5hbWUgb2YgY291bnRyeSAoSVNPIDMxNjYtMilcbiAgICAgKiBAcmV0dXJuIHtPQVNJU0FkZHJlc3N9XG4gICAgICovXG4gICAgc2V0Q291bnRyeUNvZGUgKGNvZGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT0FTSVNBZGRyZXNzLktFWV9DT1VOVFJZX0NPREUsIGNvZGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0Q291bnRyeUNvZGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoT0FTSVNBZGRyZXNzLktFWV9DT1VOVFJZX0NPREUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBjb2RlIC0gKFBMWiwgWklQLCBQSU4sIENBUCBldGMuKVxuICAgICAqIEByZXR1cm4ge09BU0lTQWRkcmVzc31cbiAgICAgKi9cbiAgICBzZXRQb3N0YWxDb2RlIChjb2RlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9BU0lTQWRkcmVzcy5LRVlfUE9TVEFMX0NPREUsIGNvZGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0UG9zdGFsQ29kZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihPQVNJU0FkZHJlc3MuS0VZX1BPU1RBTF9DT0RFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gYXJlYSAtIFBvcnRpb24gb2YgY291bnRyeSAoZS5nLiBzdGF0ZSlcbiAgICAgKiBAcmV0dXJuIHtPQVNJU0FkZHJlc3N9XG4gICAgICovXG4gICAgc2V0QWRtaW5pc3RyYXRpdmVBcmVhIChhcmVhKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9BU0lTQWRkcmVzcy5LRVlfQURNSU5JU1RSQVRJVkVfQVJFQSwgYXJlYSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRBZG1pbmlzdHJhdGl2ZUFyZWEgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoT0FTSVNBZGRyZXNzLktFWV9BRE1JTklTVFJBVElWRV9BUkVBKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gYXJlYSAtIFBvcnRpb24gb2YgZS5nLiBzdGF0ZSAoZS5nLiBjb3VudHkpXG4gICAgICogQHJldHVybiB7T0FTSVNBZGRyZXNzfVxuICAgICAqL1xuICAgIHNldFN1YkFkbWluaXN0cmF0aXZlQXJlYSAoYXJlYSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPQVNJU0FkZHJlc3MuS0VZX1NVQl9BRE1JTklTVFJBVElWRV9BUkVBLCBhcmVhKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldFN1YkFkbWluaXN0cmF0aXZlQXJlYSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihPQVNJU0FkZHJlc3MuS0VZX1NVQl9BRE1JTklTVFJBVElWRV9BUkVBKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbG9jYWxpdHkgLSBIeXBlcm55bSBmb3IgZS5nLiBjaXR5L3ZpbGxhZ2VcbiAgICAgKiBAcmV0dXJuIHtPQVNJU0FkZHJlc3N9XG4gICAgICovXG4gICAgc2V0TG9jYWxpdHkgKGxvY2FsaXR5KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9BU0lTQWRkcmVzcy5LRVlfTE9DQUxJVFksIGxvY2FsaXR5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldExvY2FsaXR5ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE9BU0lTQWRkcmVzcy5LRVlfTE9DQUxJVFkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBsb2NhbGl0eSAtIEh5cGVybnltIGZvciBlLmcuIGRpc3RyaWN0XG4gICAgICogQHJldHVybiB7T0FTSVNBZGRyZXNzfVxuICAgICAqL1xuICAgIHNldFN1YkxvY2FsaXR5IChsb2NhbGl0eSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPQVNJU0FkZHJlc3MuS0VZX1NVQl9MT0NBTElUWSwgbG9jYWxpdHkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0U3ViTG9jYWxpdHkgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoT0FTSVNBZGRyZXNzLktFWV9TVUJfTE9DQUxJVFkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0aG9yb3VnaGZhcmUgLSBIeXBlcm55bSBmb3Igc3RyZWV0LCByb2FkIGV0Yy5cbiAgICAgKiBAcmV0dXJuIHtPQVNJU0FkZHJlc3N9XG4gICAgICovXG4gICAgc2V0VGhvcm91Z2hmYXJlICh0aG9yb3VnaGZhcmUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT0FTSVNBZGRyZXNzLktFWV9USE9ST1VHSEZBUkUsIHRob3JvdWdoZmFyZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRUaG9yb3VnaGZhcmUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoT0FTSVNBZGRyZXNzLktFWV9USE9ST1VHSEZBUkUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0aG9yb3VnaGZhcmUgLSBQb3J0aW9uIG9mIHRob3JvdWdoZmFyZSBlLmcuIGhvdXNlIG51bWJlclxuICAgICAqIEByZXR1cm4ge09BU0lTQWRkcmVzc31cbiAgICAgKi9cbiAgICBzZXRTdWJUaG9yb3VnaGZhcmUgKHRob3JvdWdoZmFyZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPQVNJU0FkZHJlc3MuS0VZX1NVQl9USE9ST1VHSEZBUkUsIHRob3JvdWdoZmFyZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRTdWJUaG9yb3VnaGZhcmUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoT0FTSVNBZGRyZXNzLktFWV9TVUJfVEhPUk9VR0hGQVJFKTtcbiAgICB9XG59XG5cbk9BU0lTQWRkcmVzcy5LRVlfQ09VTlRSWV9OQU1FID0gJ2NvdW50cnlOYW1lJztcbk9BU0lTQWRkcmVzcy5LRVlfQ09VTlRSWV9DT0RFID0gJ2NvdW50cnlDb2RlJztcbk9BU0lTQWRkcmVzcy5LRVlfUE9TVEFMX0NPREUgPSAncG9zdGFsQ29kZSc7XG5PQVNJU0FkZHJlc3MuS0VZX0FETUlOSVNUUkFUSVZFX0FSRUEgPSAnYWRtaW5pc3RyYXRpdmVBcmVhJztcbk9BU0lTQWRkcmVzcy5LRVlfU1VCX0FETUlOSVNUUkFUSVZFX0FSRUEgPSAnc3ViQWRtaW5pc3RyYXRpdmVBcmVhJztcbk9BU0lTQWRkcmVzcy5LRVlfTE9DQUxJVFkgPSAnbG9jYWxpdHknO1xuT0FTSVNBZGRyZXNzLktFWV9TVUJfTE9DQUxJVFkgPSAnc3ViTG9jYWxpdHknO1xuT0FTSVNBZGRyZXNzLktFWV9USE9ST1VHSEZBUkUgPSAndGhvcm91Z2hmYXJlJztcbk9BU0lTQWRkcmVzcy5LRVlfU1VCX1RIT1JPVUdIRkFSRSA9ICdzdWJUaG9yb3VnaGZhcmUnO1xuXG5leHBvcnQgeyBPQVNJU0FkZHJlc3MgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBEZWxpdmVyeU1vZGUgfSBmcm9tICcuLi9lbnVtcy9EZWxpdmVyeU1vZGUuanMnO1xuaW1wb3J0IHsgRGF0ZVRpbWUgfSBmcm9tICcuLi9zdHJ1Y3RzL0RhdGVUaW1lLmpzJztcbmltcG9ydCB7IFJwY1JlcXVlc3QgfSBmcm9tICcuLi9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IE9BU0lTQWRkcmVzcyB9IGZyb20gJy4uL3N0cnVjdHMvT0FTSVNBZGRyZXNzLmpzJztcbmltcG9ydCB7IEltYWdlIH0gZnJvbSAnLi4vc3RydWN0cy9JbWFnZS5qcyc7XG5cbmNsYXNzIFNlbmRMb2NhdGlvbiBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuU2VuZExvY2F0aW9uKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZGVncmVlc1xuICAgICAqIEByZXR1cm4ge1NlbmRMb2NhdGlvbn1cbiAgICAgKi9cbiAgICBzZXRMb25naXR1ZGVEZWdyZWVzIChkZWdyZWVzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNlbmRMb2NhdGlvbi5LRVlfTE9OR0lUVURFX0RFR1JFRVMsIGRlZ3JlZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0TG9uZ2l0dWRlRGVncmVlcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTZW5kTG9jYXRpb24uS0VZX0xPTkdJVFVERV9ERUdSRUVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZGVncmVlc1xuICAgICAqIEByZXR1cm4ge1NlbmRMb2NhdGlvbn1cbiAgICAgKi9cbiAgICBzZXRMYXRpdHVkZURlZ3JlZXMgKGRlZ3JlZXMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2VuZExvY2F0aW9uLktFWV9MQVRJVFVERV9ERUdSRUVTLCBkZWdyZWVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldExhdGl0dWRlRGVncmVlcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTZW5kTG9jYXRpb24uS0VZX0xBVElUVURFX0RFR1JFRVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIC0gTmFtZSAvIHRpdGxlIG9mIGludGVuZGVkIGxvY2F0aW9uXG4gICAgICogQHJldHVybiB7U2VuZExvY2F0aW9ufVxuICAgICAqL1xuICAgIHNldExvY2F0aW9uTmFtZSAobmFtZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZW5kTG9jYXRpb24uS0VZX0xPQ0FUSU9OX05BTUUsIG5hbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0TG9jYXRpb25OYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNlbmRMb2NhdGlvbi5LRVlfTE9DQVRJT05fTkFNRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGRlc2NyaXB0aW9uIC0gRGVzY3JpcHRpb24gaW50ZW5kZWQgbG9jYXRpb24gLyBlc3RhYmxpc2htZW50IChpZiBhcHBsaWNhYmxlKVxuICAgICAqIEByZXR1cm4ge1NlbmRMb2NhdGlvbn1cbiAgICAgKi9cbiAgICBzZXRMb2NhdGlvbkRlc2NyaXB0aW9uIChkZXNjcmlwdGlvbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZW5kTG9jYXRpb24uS0VZX0xPQ0FUSU9OX0RFU0NSSVBUSU9OLCBkZXNjcmlwdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRMb2NhdGlvbkRlc2NyaXB0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNlbmRMb2NhdGlvbi5LRVlfTE9DQVRJT05fREVTQ1JJUFRJT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nW119IGxpbmVzIC0gTG9jYXRpb24gYWRkcmVzcyAoaWYgYXBwbGljYWJsZSlcbiAgICAgKiBAcmV0dXJuIHtTZW5kTG9jYXRpb259XG4gICAgICovXG4gICAgc2V0QWRkcmVzc0xpbmVzIChsaW5lcykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZW5kTG9jYXRpb24uS0VZX0FERFJFU1NfTElORVMsIGxpbmVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nW119XG4gICAgICovXG4gICAgZ2V0QWRkcmVzc0xpbmVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNlbmRMb2NhdGlvbi5LRVlfQUREUkVTU19MSU5FUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG51bWJlciAtIFBob25lIG51bWJlciBvZiBpbnRlbmRlZCBsb2NhdGlvbiAvIGVzdGFibGlzaG1lbnQgKGlmIGFwcGxpY2FibGUpXG4gICAgICogQHJldHVybiB7U2VuZExvY2F0aW9ufVxuICAgICAqL1xuICAgIHNldFBob25lTnVtYmVyIChudW1iZXIpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2VuZExvY2F0aW9uLktFWV9QSE9ORV9OVU1CRVIsIG51bWJlcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRQaG9uZU51bWJlciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTZW5kTG9jYXRpb24uS0VZX1BIT05FX05VTUJFUik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtJbWFnZX0gaW1hZ2UgLSBJbWFnZSAvIGljb24gb2YgaW50ZW5kZWQgbG9jYXRpb24gKGlmIGFwcGxpY2FibGUgYW5kIHN1cHBvcnRlZClcbiAgICAgKiBAcmV0dXJuIHtTZW5kTG9jYXRpb259XG4gICAgICovXG4gICAgc2V0TG9jYXRpb25JbWFnZSAoaW1hZ2UpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoSW1hZ2UsIGltYWdlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2VuZExvY2F0aW9uLktFWV9MT0NBVElPTl9JTUFHRSwgaW1hZ2UpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtJbWFnZX1cbiAgICAgKi9cbiAgICBnZXRMb2NhdGlvbkltYWdlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEltYWdlLCBTZW5kTG9jYXRpb24uS0VZX0xPQ0FUSU9OX0lNQUdFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0RhdGVUaW1lfSBzdGFtcCAtIHRpbWVzdGFtcCBpbiBJU08gODYwMSBmb3JtYXRcbiAgICAgKiBAcmV0dXJuIHtTZW5kTG9jYXRpb259XG4gICAgICovXG4gICAgc2V0VGltZVN0YW1wIChzdGFtcCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShEYXRlVGltZSwgc3RhbXApO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZW5kTG9jYXRpb24uS0VZX1RJTUVfU1RBTVAsIHN0YW1wKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7RGF0ZVRpbWV9XG4gICAgICovXG4gICAgZ2V0VGltZVN0YW1wICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KERhdGVUaW1lLCBTZW5kTG9jYXRpb24uS0VZX1RJTUVfU1RBTVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7T0FTSVNBZGRyZXNzfSBhZGRyZXNzIC0gQWRkcmVzcyB0byBiZSB1c2VkIGZvciBzZXR0aW5nIGRlc3RpbmF0aW9uXG4gICAgICogQHJldHVybiB7U2VuZExvY2F0aW9ufVxuICAgICAqL1xuICAgIHNldEFkZHJlc3MgKGFkZHJlc3MpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoT0FTSVNBZGRyZXNzLCBhZGRyZXNzKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2VuZExvY2F0aW9uLktFWV9BRERSRVNTLCBhZGRyZXNzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7T0FTSVNBZGRyZXNzfVxuICAgICAqL1xuICAgIGdldEFkZHJlc3MgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoT0FTSVNBZGRyZXNzLCBTZW5kTG9jYXRpb24uS0VZX0FERFJFU1MpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RGVsaXZlcnlNb2RlfSBtb2RlIC0gRGVmaW5lcyB0aGUgbW9kZSBvZiBwcm9tcHQgZm9yIHVzZXJcbiAgICAgKiBAcmV0dXJuIHtTZW5kTG9jYXRpb259XG4gICAgICovXG4gICAgc2V0RGVsaXZlcnlNb2RlIChtb2RlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKERlbGl2ZXJ5TW9kZSwgbW9kZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNlbmRMb2NhdGlvbi5LRVlfREVMSVZFUllfTU9ERSwgbW9kZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0RlbGl2ZXJ5TW9kZX1cbiAgICAgKi9cbiAgICBnZXREZWxpdmVyeU1vZGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoRGVsaXZlcnlNb2RlLCBTZW5kTG9jYXRpb24uS0VZX0RFTElWRVJZX01PREUpO1xuICAgIH1cbn1cblxuU2VuZExvY2F0aW9uLktFWV9MT05HSVRVREVfREVHUkVFUyA9ICdsb25naXR1ZGVEZWdyZWVzJztcblNlbmRMb2NhdGlvbi5LRVlfTEFUSVRVREVfREVHUkVFUyA9ICdsYXRpdHVkZURlZ3JlZXMnO1xuU2VuZExvY2F0aW9uLktFWV9MT0NBVElPTl9OQU1FID0gJ2xvY2F0aW9uTmFtZSc7XG5TZW5kTG9jYXRpb24uS0VZX0xPQ0FUSU9OX0RFU0NSSVBUSU9OID0gJ2xvY2F0aW9uRGVzY3JpcHRpb24nO1xuU2VuZExvY2F0aW9uLktFWV9BRERSRVNTX0xJTkVTID0gJ2FkZHJlc3NMaW5lcyc7XG5TZW5kTG9jYXRpb24uS0VZX1BIT05FX05VTUJFUiA9ICdwaG9uZU51bWJlcic7XG5TZW5kTG9jYXRpb24uS0VZX0xPQ0FUSU9OX0lNQUdFID0gJ2xvY2F0aW9uSW1hZ2UnO1xuU2VuZExvY2F0aW9uLktFWV9USU1FX1NUQU1QID0gJ3RpbWVTdGFtcCc7XG5TZW5kTG9jYXRpb24uS0VZX0FERFJFU1MgPSAnYWRkcmVzcyc7XG5TZW5kTG9jYXRpb24uS0VZX0RFTElWRVJZX01PREUgPSAnZGVsaXZlcnlNb2RlJztcblxuZXhwb3J0IHsgU2VuZExvY2F0aW9uIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbmNsYXNzIFNlbmRMb2NhdGlvblJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuU2VuZExvY2F0aW9uKTtcbiAgICB9XG59XG5cblxuZXhwb3J0IHsgU2VuZExvY2F0aW9uUmVzcG9uc2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5cbi8qKlxuICogRGlhbHMgYSBwaG9uZSBudW1iZXIgYW5kIHN3aXRjaGVzIHRvIHBob25lIGFwcGxpY2F0aW9uLlxuICovXG5jbGFzcyBEaWFsTnVtYmVyIGV4dGVuZHMgUnBjUmVxdWVzdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5EaWFsTnVtYmVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbnVtYmVyIC0gUGhvbmUgbnVtYmVyIGlzIGEgc3RyaW5nLCB3aGljaCBjYW4gYmUgdXAgdG8gNDAgY2hhcnMuIEFsbCBjaGFyYWN0ZXJzIHNoYWxsIGJlIHN0cmlwcGVkXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGZyb20gc3RyaW5nIGV4Y2VwdCBkaWdpdHMgMC05IGFuZCAqICMgLCA7ICtcbiAgICAgKiBAcmV0dXJuIHtEaWFsTnVtYmVyfVxuICAgICAqL1xuICAgIHNldE51bWJlciAobnVtYmVyKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKERpYWxOdW1iZXIuS0VZX05VTUJFUiwgbnVtYmVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldE51bWJlciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihEaWFsTnVtYmVyLktFWV9OVU1CRVIpO1xuICAgIH1cbn1cblxuRGlhbE51bWJlci5LRVlfTlVNQkVSID0gJ251bWJlcic7XG5cbmV4cG9ydCB7IERpYWxOdW1iZXIgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBScGNSZXNwb25zZSB9IGZyb20gJy4uL1JwY1Jlc3BvbnNlLmpzJztcblxuY2xhc3MgRGlhbE51bWJlclJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuRGlhbE51bWJlcik7XG4gICAgfVxufVxuXG5cbmV4cG9ydCB7IERpYWxOdW1iZXJSZXNwb25zZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBCdXR0b25QcmVzc01vZGVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIEJ1dHRvblByZXNzTW9kZSBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIGJ1dHRvbiB3YXMgcmVsZWFzZWQsIGFmdGVyIGl0IHdhcyBwcmVzc2VkIGZvciBhIGxvbmcgdGltZSBBY3R1YWwgdGltaW5nIGlzIGRlZmluZWQgYnkgdGhlIGhlYWR1bml0IGFuZCBtYXlcbiAgICAgKiB2YXJ5XG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTE9ORyAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25QcmVzc01vZGUuX01BUC5MT05HO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgYnV0dG9uIHdhcyByZWxlYXNlZCwgYWZ0ZXIgaXQgd2FzIHByZXNzZWQgZm9yIGEgc2hvcnQgdGltZSBBY3R1YWwgdGltaW5nIGlzIGRlZmluZWQgYnkgdGhlIGhlYWR1bml0IGFuZCBtYXlcbiAgICAgKiB2YXJ5XG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0hPUlQgKCkge1xuICAgICAgICByZXR1cm4gQnV0dG9uUHJlc3NNb2RlLl9NQVAuU0hPUlQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gQnV0dG9uUHJlc3NNb2RlLl92YWx1ZUZvcktleShrZXksIEJ1dHRvblByZXNzTW9kZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvblByZXNzTW9kZS5fa2V5Rm9yVmFsdWUodmFsdWUsIEJ1dHRvblByZXNzTW9kZS5fTUFQKTtcbiAgICB9XG59XG5cbkJ1dHRvblByZXNzTW9kZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0xPTkcnOiAnTE9ORycsXG4gICAgJ1NIT1JUJzogJ1NIT1JUJyxcbn0pO1xuXG5leHBvcnQgeyBCdXR0b25QcmVzc01vZGUgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gTW9kdWxlVHlwZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgTW9kdWxlVHlwZSBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDTElNQVRFICgpIHtcbiAgICAgICAgcmV0dXJuIE1vZHVsZVR5cGUuX01BUC5DTElNQVRFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJBRElPICgpIHtcbiAgICAgICAgcmV0dXJuIE1vZHVsZVR5cGUuX01BUC5SQURJTztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTRUFUICgpIHtcbiAgICAgICAgcmV0dXJuIE1vZHVsZVR5cGUuX01BUC5TRUFUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFVRElPICgpIHtcbiAgICAgICAgcmV0dXJuIE1vZHVsZVR5cGUuX01BUC5BVURJTztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBMSUdIVCAoKSB7XG4gICAgICAgIHJldHVybiBNb2R1bGVUeXBlLl9NQVAuTElHSFQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSE1JX1NFVFRJTkdTICgpIHtcbiAgICAgICAgcmV0dXJuIE1vZHVsZVR5cGUuX01BUC5ITUlfU0VUVElOR1M7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gTW9kdWxlVHlwZS5fdmFsdWVGb3JLZXkoa2V5LCBNb2R1bGVUeXBlLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gTW9kdWxlVHlwZS5fa2V5Rm9yVmFsdWUodmFsdWUsIE1vZHVsZVR5cGUuX01BUCk7XG4gICAgfVxufVxuXG5Nb2R1bGVUeXBlLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnQ0xJTUFURSc6ICdDTElNQVRFJyxcbiAgICAnUkFESU8nOiAnUkFESU8nLFxuICAgICdTRUFUJzogJ1NFQVQnLFxuICAgICdBVURJTyc6ICdBVURJTycsXG4gICAgJ0xJR0hUJzogJ0xJR0hUJyxcbiAgICAnSE1JX1NFVFRJTkdTJzogJ0hNSV9TRVRUSU5HUycsXG59KTtcblxuZXhwb3J0IHsgTW9kdWxlVHlwZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEJ1dHRvbk5hbWUgfSBmcm9tICcuLi9lbnVtcy9CdXR0b25OYW1lLmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IEJ1dHRvblByZXNzTW9kZSB9IGZyb20gJy4uL2VudW1zL0J1dHRvblByZXNzTW9kZS5qcyc7XG5pbXBvcnQgeyBNb2R1bGVUeXBlIH0gZnJvbSAnLi4vZW51bXMvTW9kdWxlVHlwZS5qcyc7XG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5cbmNsYXNzIEJ1dHRvblByZXNzIGV4dGVuZHMgUnBjUmVxdWVzdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5CdXR0b25QcmVzcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtNb2R1bGVUeXBlfSB0eXBlIC0gVGhlIG1vZHVsZSB3aGVyZSB0aGUgYnV0dG9uIHNob3VsZCBiZSBwcmVzc2VkXG4gICAgICogQHJldHVybiB7QnV0dG9uUHJlc3N9XG4gICAgICovXG4gICAgc2V0TW9kdWxlVHlwZSAodHlwZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShNb2R1bGVUeXBlLCB0eXBlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQnV0dG9uUHJlc3MuS0VZX01PRFVMRV9UWVBFLCB0eXBlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TW9kdWxlVHlwZX1cbiAgICAgKi9cbiAgICBnZXRNb2R1bGVUeXBlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KE1vZHVsZVR5cGUsIEJ1dHRvblByZXNzLktFWV9NT0RVTEVfVFlQRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGlkIC0gSWQgb2YgYSBtb2R1bGUsIHB1Ymxpc2hlZCBieSBTeXN0ZW0gQ2FwYWJpbGl0eS5cbiAgICAgKiBAcmV0dXJuIHtCdXR0b25QcmVzc31cbiAgICAgKi9cbiAgICBzZXRNb2R1bGVJZCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQnV0dG9uUHJlc3MuS0VZX01PRFVMRV9JRCwgaWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0TW9kdWxlSWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQnV0dG9uUHJlc3MuS0VZX01PRFVMRV9JRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCdXR0b25OYW1lfSBuYW1lIC0gVGhlIG5hbWUgb2Ygc3VwcG9ydGVkIFJDIGNsaW1hdGUgb3IgcmFkaW8gYnV0dG9uLlxuICAgICAqIEByZXR1cm4ge0J1dHRvblByZXNzfVxuICAgICAqL1xuICAgIHNldEJ1dHRvbk5hbWUgKG5hbWUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQnV0dG9uTmFtZSwgbmFtZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEJ1dHRvblByZXNzLktFWV9CVVRUT05fTkFNRSwgbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0J1dHRvbk5hbWV9XG4gICAgICovXG4gICAgZ2V0QnV0dG9uTmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChCdXR0b25OYW1lLCBCdXR0b25QcmVzcy5LRVlfQlVUVE9OX05BTUUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7QnV0dG9uUHJlc3NNb2RlfSBtb2RlIC0gSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBpcyBhIExPTkcgb3IgU0hPUlQgYnV0dG9uIHByZXNzIGV2ZW50LlxuICAgICAqIEByZXR1cm4ge0J1dHRvblByZXNzfVxuICAgICAqL1xuICAgIHNldEJ1dHRvblByZXNzTW9kZSAobW9kZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShCdXR0b25QcmVzc01vZGUsIG1vZGUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihCdXR0b25QcmVzcy5LRVlfQlVUVE9OX1BSRVNTX01PREUsIG1vZGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCdXR0b25QcmVzc01vZGV9XG4gICAgICovXG4gICAgZ2V0QnV0dG9uUHJlc3NNb2RlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEJ1dHRvblByZXNzTW9kZSwgQnV0dG9uUHJlc3MuS0VZX0JVVFRPTl9QUkVTU19NT0RFKTtcbiAgICB9XG59XG5cbkJ1dHRvblByZXNzLktFWV9NT0RVTEVfVFlQRSA9ICdtb2R1bGVUeXBlJztcbkJ1dHRvblByZXNzLktFWV9NT0RVTEVfSUQgPSAnbW9kdWxlSWQnO1xuQnV0dG9uUHJlc3MuS0VZX0JVVFRPTl9OQU1FID0gJ2J1dHRvbk5hbWUnO1xuQnV0dG9uUHJlc3MuS0VZX0JVVFRPTl9QUkVTU19NT0RFID0gJ2J1dHRvblByZXNzTW9kZSc7XG5cbmV4cG9ydCB7IEJ1dHRvblByZXNzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbmNsYXNzIEJ1dHRvblByZXNzUmVzcG9uc2UgZXh0ZW5kcyBScGNSZXNwb25zZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5CdXR0b25QcmVzcyk7XG4gICAgfVxufVxuXG5cbmV4cG9ydCB7IEJ1dHRvblByZXNzUmVzcG9uc2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBNb2R1bGVUeXBlIH0gZnJvbSAnLi4vZW51bXMvTW9kdWxlVHlwZS5qcyc7XG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5cbmNsYXNzIEdldEludGVyaW9yVmVoaWNsZURhdGEgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkdldEludGVyaW9yVmVoaWNsZURhdGEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TW9kdWxlVHlwZX0gdHlwZSAtIFRoZSB0eXBlIG9mIGEgUkMgbW9kdWxlIHRvIHJldHJpZXZlIG1vZHVsZSBkYXRhIGZyb20gdGhlIHZlaGljbGUuIEluIHRoZSBmdXR1cmUsIHRoaXNcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG91bGQgYmUgdGhlIElkZW50aWZpY2F0aW9uIG9mIGEgbW9kdWxlLlxuICAgICAqIEByZXR1cm4ge0dldEludGVyaW9yVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0TW9kdWxlVHlwZSAodHlwZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShNb2R1bGVUeXBlLCB0eXBlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0SW50ZXJpb3JWZWhpY2xlRGF0YS5LRVlfTU9EVUxFX1RZUEUsIHR5cGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtNb2R1bGVUeXBlfVxuICAgICAqL1xuICAgIGdldE1vZHVsZVR5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTW9kdWxlVHlwZSwgR2V0SW50ZXJpb3JWZWhpY2xlRGF0YS5LRVlfTU9EVUxFX1RZUEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBpZCAtIElkIG9mIGEgbW9kdWxlLCBwdWJsaXNoZWQgYnkgU3lzdGVtIENhcGFiaWxpdHkuXG4gICAgICogQHJldHVybiB7R2V0SW50ZXJpb3JWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRNb2R1bGVJZCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0SW50ZXJpb3JWZWhpY2xlRGF0YS5LRVlfTU9EVUxFX0lELCBpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRNb2R1bGVJZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXRJbnRlcmlvclZlaGljbGVEYXRhLktFWV9NT0RVTEVfSUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gc3Vic2NyaWJlIC0gSWYgc3Vic2NyaWJlIGlzIHRydWUsIHRoZSBoZWFkIHVuaXQgd2lsbCByZWdpc3RlciBPbkludGVyaW9yVmVoaWNsZURhdGFcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdGlmaWNhdGlvbnMgZm9yIHRoZSByZXF1ZXN0ZWQgbW9kdWxlIChtb2R1bGVJZCBhbmQgbW9kdWxlVHlwZSkuIElmIHN1YnNjcmliZSBpc1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsIHRoZSBoZWFkIHVuaXQgd2lsbCB1bnJlZ2lzdGVyIE9uSW50ZXJpb3JWZWhpY2xlRGF0YSBub3RpZmljYXRpb25zIGZvciB0aGVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RlZCBtb2R1bGUgKG1vZHVsZUlkIGFuZCBtb2R1bGVUeXBlKS4gSWYgc3Vic2NyaWJlIGlzIG5vdCBpbmNsdWRlZCwgdGhlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJzY3JpcHRpb24gc3RhdHVzIG9mIHRoZSBhcHAgZm9yIHRoZSByZXF1ZXN0ZWQgbW9kdWxlIChtb2R1bGVJZCBhbmQgbW9kdWxlVHlwZSlcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbGwgcmVtYWluIHVuY2hhbmdlZC5cbiAgICAgKiBAcmV0dXJuIHtHZXRJbnRlcmlvclZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldFN1YnNjcmliZSAoc3Vic2NyaWJlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldEludGVyaW9yVmVoaWNsZURhdGEuS0VZX1NVQlNDUklCRSwgc3Vic2NyaWJlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRTdWJzY3JpYmUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR2V0SW50ZXJpb3JWZWhpY2xlRGF0YS5LRVlfU1VCU0NSSUJFKTtcbiAgICB9XG59XG5cbkdldEludGVyaW9yVmVoaWNsZURhdGEuS0VZX01PRFVMRV9UWVBFID0gJ21vZHVsZVR5cGUnO1xuR2V0SW50ZXJpb3JWZWhpY2xlRGF0YS5LRVlfTU9EVUxFX0lEID0gJ21vZHVsZUlkJztcbkdldEludGVyaW9yVmVoaWNsZURhdGEuS0VZX1NVQlNDUklCRSA9ICdzdWJzY3JpYmUnO1xuXG5leHBvcnQgeyBHZXRJbnRlcmlvclZlaGljbGVEYXRhIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYge0VudW19IERpc3BsYXlNb2RlXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBEaXNwbGF5TW9kZSBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBEQVkgKCkge1xuICAgICAgICByZXR1cm4gRGlzcGxheU1vZGUuX01BUC5EQVk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTklHSFQgKCkge1xuICAgICAgICByZXR1cm4gRGlzcGxheU1vZGUuX01BUC5OSUdIVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBBVVRPICgpIHtcbiAgICAgICAgcmV0dXJuIERpc3BsYXlNb2RlLl9NQVAuQVVUTztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBEaXNwbGF5TW9kZS5fdmFsdWVGb3JLZXkoa2V5LCBEaXNwbGF5TW9kZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIERpc3BsYXlNb2RlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgRGlzcGxheU1vZGUuX01BUCk7XG4gICAgfVxufVxuXG5EaXNwbGF5TW9kZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0RBWSc6ICdEQVknLFxuICAgICdOSUdIVCc6ICdOSUdIVCcsXG4gICAgJ0FVVE8nOiAnQVVUTycsXG59KTtcblxuZXhwb3J0IHsgRGlzcGxheU1vZGUgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gRGlzdGFuY2VVbml0XG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBEaXN0YW5jZVVuaXQgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTUlMRVMgKCkge1xuICAgICAgICByZXR1cm4gRGlzdGFuY2VVbml0Ll9NQVAuTUlMRVM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgS0lMT01FVEVSUyAoKSB7XG4gICAgICAgIHJldHVybiBEaXN0YW5jZVVuaXQuX01BUC5LSUxPTUVURVJTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIERpc3RhbmNlVW5pdC5fdmFsdWVGb3JLZXkoa2V5LCBEaXN0YW5jZVVuaXQuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBEaXN0YW5jZVVuaXQuX2tleUZvclZhbHVlKHZhbHVlLCBEaXN0YW5jZVVuaXQuX01BUCk7XG4gICAgfVxufVxuXG5EaXN0YW5jZVVuaXQuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdNSUxFUyc6ICdNSUxFUycsXG4gICAgJ0tJTE9NRVRFUlMnOiAnS0lMT01FVEVSUycsXG59KTtcblxuZXhwb3J0IHsgRGlzdGFuY2VVbml0IH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYge0VudW19IFRlbXBlcmF0dXJlVW5pdFxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgVGVtcGVyYXR1cmVVbml0IGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEZBSFJFTkhFSVQgKCkge1xuICAgICAgICByZXR1cm4gVGVtcGVyYXR1cmVVbml0Ll9NQVAuRkFIUkVOSEVJVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBDRUxTSVVTICgpIHtcbiAgICAgICAgcmV0dXJuIFRlbXBlcmF0dXJlVW5pdC5fTUFQLkNFTFNJVVM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gVGVtcGVyYXR1cmVVbml0Ll92YWx1ZUZvcktleShrZXksIFRlbXBlcmF0dXJlVW5pdC5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFRlbXBlcmF0dXJlVW5pdC5fa2V5Rm9yVmFsdWUodmFsdWUsIFRlbXBlcmF0dXJlVW5pdC5fTUFQKTtcbiAgICB9XG59XG5cblRlbXBlcmF0dXJlVW5pdC5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0ZBSFJFTkhFSVQnOiAnRkFIUkVOSEVJVCcsXG4gICAgJ0NFTFNJVVMnOiAnQ0VMU0lVUycsXG59KTtcblxuZXhwb3J0IHsgVGVtcGVyYXR1cmVVbml0IH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRGlzcGxheU1vZGUgfSBmcm9tICcuLi9lbnVtcy9EaXNwbGF5TW9kZS5qcyc7XG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgRGlzdGFuY2VVbml0IH0gZnJvbSAnLi4vZW51bXMvRGlzdGFuY2VVbml0LmpzJztcbmltcG9ydCB7IFRlbXBlcmF0dXJlVW5pdCB9IGZyb20gJy4uL2VudW1zL1RlbXBlcmF0dXJlVW5pdC5qcyc7XG5cbi8qKlxuICogQ29ycmVzcG9uZHMgdG8gXCJITUlfU0VUVElOR1NcIiBNb2R1bGVUeXBlXG4gKi9cbmNsYXNzIEhNSVNldHRpbmdzQ29udHJvbERhdGEgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RGlzcGxheU1vZGV9IG1vZGVcbiAgICAgKiBAcmV0dXJuIHtITUlTZXR0aW5nc0NvbnRyb2xEYXRhfVxuICAgICAqL1xuICAgIHNldERpc3BsYXlNb2RlIChtb2RlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKERpc3BsYXlNb2RlLCBtb2RlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoSE1JU2V0dGluZ3NDb250cm9sRGF0YS5LRVlfRElTUExBWV9NT0RFLCBtb2RlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7RGlzcGxheU1vZGV9XG4gICAgICovXG4gICAgZ2V0RGlzcGxheU1vZGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoRGlzcGxheU1vZGUsIEhNSVNldHRpbmdzQ29udHJvbERhdGEuS0VZX0RJU1BMQVlfTU9ERSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtUZW1wZXJhdHVyZVVuaXR9IHVuaXRcbiAgICAgKiBAcmV0dXJuIHtITUlTZXR0aW5nc0NvbnRyb2xEYXRhfVxuICAgICAqL1xuICAgIHNldFRlbXBlcmF0dXJlVW5pdCAodW5pdCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShUZW1wZXJhdHVyZVVuaXQsIHVuaXQpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihITUlTZXR0aW5nc0NvbnRyb2xEYXRhLktFWV9URU1QRVJBVFVSRV9VTklULCB1bml0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VGVtcGVyYXR1cmVVbml0fVxuICAgICAqL1xuICAgIGdldFRlbXBlcmF0dXJlVW5pdCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChUZW1wZXJhdHVyZVVuaXQsIEhNSVNldHRpbmdzQ29udHJvbERhdGEuS0VZX1RFTVBFUkFUVVJFX1VOSVQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RGlzdGFuY2VVbml0fSB1bml0XG4gICAgICogQHJldHVybiB7SE1JU2V0dGluZ3NDb250cm9sRGF0YX1cbiAgICAgKi9cbiAgICBzZXREaXN0YW5jZVVuaXQgKHVuaXQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoRGlzdGFuY2VVbml0LCB1bml0KTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoSE1JU2V0dGluZ3NDb250cm9sRGF0YS5LRVlfRElTVEFOQ0VfVU5JVCwgdW5pdCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Rpc3RhbmNlVW5pdH1cbiAgICAgKi9cbiAgICBnZXREaXN0YW5jZVVuaXQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoRGlzdGFuY2VVbml0LCBITUlTZXR0aW5nc0NvbnRyb2xEYXRhLktFWV9ESVNUQU5DRV9VTklUKTtcbiAgICB9XG59XG5cbkhNSVNldHRpbmdzQ29udHJvbERhdGEuS0VZX0RJU1BMQVlfTU9ERSA9ICdkaXNwbGF5TW9kZSc7XG5ITUlTZXR0aW5nc0NvbnRyb2xEYXRhLktFWV9URU1QRVJBVFVSRV9VTklUID0gJ3RlbXBlcmF0dXJlVW5pdCc7XG5ITUlTZXR0aW5nc0NvbnRyb2xEYXRhLktFWV9ESVNUQU5DRV9VTklUID0gJ2Rpc3RhbmNlVW5pdCc7XG5cbmV4cG9ydCB7IEhNSVNldHRpbmdzQ29udHJvbERhdGEgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gUmFkaW9CYW5kXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBSYWRpb0JhbmQgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQU0gKCkge1xuICAgICAgICByZXR1cm4gUmFkaW9CYW5kLl9NQVAuQU07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRk0gKCkge1xuICAgICAgICByZXR1cm4gUmFkaW9CYW5kLl9NQVAuRk07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgWE0gKCkge1xuICAgICAgICByZXR1cm4gUmFkaW9CYW5kLl9NQVAuWE07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gUmFkaW9CYW5kLl92YWx1ZUZvcktleShrZXksIFJhZGlvQmFuZC5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFJhZGlvQmFuZC5fa2V5Rm9yVmFsdWUodmFsdWUsIFJhZGlvQmFuZC5fTUFQKTtcbiAgICB9XG59XG5cblJhZGlvQmFuZC5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0FNJzogJ0FNJyxcbiAgICAnRk0nOiAnRk0nLFxuICAgICdYTSc6ICdYTScsXG59KTtcblxuZXhwb3J0IHsgUmFkaW9CYW5kIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcblxuY2xhc3MgUmRzRGF0YSBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHBzIC0gUHJvZ3JhbSBTZXJ2aWNlIE5hbWVcbiAgICAgKiBAcmV0dXJuIHtSZHNEYXRhfVxuICAgICAqL1xuICAgIHNldFBTIChwcykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZHNEYXRhLktFWV9QUywgcHMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0UFMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmRzRGF0YS5LRVlfUFMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBydCAtIFJhZGlvIFRleHRcbiAgICAgKiBAcmV0dXJuIHtSZHNEYXRhfVxuICAgICAqL1xuICAgIHNldFJUIChydCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZHNEYXRhLktFWV9SVCwgcnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0UlQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmRzRGF0YS5LRVlfUlQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBjdCAtIFRoZSBjbG9jayB0ZXh0IGluIFVUQyBmb3JtYXQgYXMgWVlZWS1NTS1ERFRoaDptbTpzcy5zVFpEXG4gICAgICogQHJldHVybiB7UmRzRGF0YX1cbiAgICAgKi9cbiAgICBzZXRDVCAoY3QpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmRzRGF0YS5LRVlfQ1QsIGN0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldENUICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFJkc0RhdGEuS0VZX0NUKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gcGkgLSBQcm9ncmFtIElkZW50aWZpY2F0aW9uIC0gdGhlIGNhbGwgc2lnbiBmb3IgdGhlIHJhZGlvIHN0YXRpb25cbiAgICAgKiBAcmV0dXJuIHtSZHNEYXRhfVxuICAgICAqL1xuICAgIHNldFBJIChwaSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZHNEYXRhLktFWV9QSSwgcGkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0UEkgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmRzRGF0YS5LRVlfUEkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBwdHkgLSBUaGUgcHJvZ3JhbSB0eXBlIC0gVGhlIHJlZ2lvbiBzaG91bGQgYmUgdXNlZCB0byBkaWZmZXJlbnRpYXRlIGJldHdlZW4gRVUgYW5kIE5vcnRoIEFtZXJpY2FcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgcHJvZ3JhbSB0eXBlc1xuICAgICAqIEByZXR1cm4ge1Jkc0RhdGF9XG4gICAgICovXG4gICAgc2V0UFRZIChwdHkpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmRzRGF0YS5LRVlfUFRZLCBwdHkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0UFRZICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFJkc0RhdGEuS0VZX1BUWSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSB0cCAtIFRyYWZmaWMgUHJvZ3JhbSBJZGVudGlmaWNhdGlvbiAtIElkZW50aWZpZXMgYSBzdGF0aW9uIHRoYXQgb2ZmZXJzIHRyYWZmaWNcbiAgICAgKiBAcmV0dXJuIHtSZHNEYXRhfVxuICAgICAqL1xuICAgIHNldFRQICh0cCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZHNEYXRhLktFWV9UUCwgdHApO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFRQICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFJkc0RhdGEuS0VZX1RQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHRhIC0gVHJhZmZpYyBBbm5vdW5jZW1lbnQgSWRlbnRpZmljYXRpb24gLSBJbmRpY2F0ZXMgYW4gb25nb2luZyB0cmFmZmljIGFubm91bmNlbWVudFxuICAgICAqIEByZXR1cm4ge1Jkc0RhdGF9XG4gICAgICovXG4gICAgc2V0VEEgKHRhKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJkc0RhdGEuS0VZX1RBLCB0YSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0VEEgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmRzRGF0YS5LRVlfVEEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSByZWcgLSBSZWdpb25cbiAgICAgKiBAcmV0dXJuIHtSZHNEYXRhfVxuICAgICAqL1xuICAgIHNldFJFRyAocmVnKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJkc0RhdGEuS0VZX1JFRywgcmVnKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldFJFRyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSZHNEYXRhLktFWV9SRUcpO1xuICAgIH1cbn1cblxuUmRzRGF0YS5LRVlfUFMgPSAnUFMnO1xuUmRzRGF0YS5LRVlfUlQgPSAnUlQnO1xuUmRzRGF0YS5LRVlfQ1QgPSAnQ1QnO1xuUmRzRGF0YS5LRVlfUEkgPSAnUEknO1xuUmRzRGF0YS5LRVlfUFRZID0gJ1BUWSc7XG5SZHNEYXRhLktFWV9UUCA9ICdUUCc7XG5SZHNEYXRhLktFWV9UQSA9ICdUQSc7XG5SZHNEYXRhLktFWV9SRUcgPSAnUkVHJztcblxuZXhwb3J0IHsgUmRzRGF0YSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBSYWRpb1N0YXRlXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBSYWRpb1N0YXRlIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFDUVVJUklORyAoKSB7XG4gICAgICAgIHJldHVybiBSYWRpb1N0YXRlLl9NQVAuQUNRVUlSSU5HO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFDUVVJUkVEICgpIHtcbiAgICAgICAgcmV0dXJuIFJhZGlvU3RhdGUuX01BUC5BQ1FVSVJFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBNVUxUSUNBU1QgKCkge1xuICAgICAgICByZXR1cm4gUmFkaW9TdGF0ZS5fTUFQLk1VTFRJQ0FTVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOT1RfRk9VTkQgKCkge1xuICAgICAgICByZXR1cm4gUmFkaW9TdGF0ZS5fTUFQLk5PVF9GT1VORDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBSYWRpb1N0YXRlLl92YWx1ZUZvcktleShrZXksIFJhZGlvU3RhdGUuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBSYWRpb1N0YXRlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgUmFkaW9TdGF0ZS5fTUFQKTtcbiAgICB9XG59XG5cblJhZGlvU3RhdGUuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdBQ1FVSVJJTkcnOiAnQUNRVUlSSU5HJyxcbiAgICAnQUNRVUlSRUQnOiAnQUNRVUlSRUQnLFxuICAgICdNVUxUSUNBU1QnOiAnTVVMVElDQVNUJyxcbiAgICAnTk9UX0ZPVU5EJzogJ05PVF9GT1VORCcsXG59KTtcblxuZXhwb3J0IHsgUmFkaW9TdGF0ZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5cbmNsYXNzIFN0YXRpb25JRE51bWJlciBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGNvZGUgLSBCaW5hcnkgUmVwcmVzZW50YXRpb24gb2YgSVRVIENvdW50cnkgQ29kZS4gVVNBIENvZGUgaXMgMDAxLlxuICAgICAqIEByZXR1cm4ge1N0YXRpb25JRE51bWJlcn1cbiAgICAgKi9cbiAgICBzZXRDb3VudHJ5Q29kZSAoY29kZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdGF0aW9uSUROdW1iZXIuS0VZX0NPVU5UUllfQ09ERSwgY29kZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRDb3VudHJ5Q29kZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTdGF0aW9uSUROdW1iZXIuS0VZX0NPVU5UUllfQ09ERSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGlkIC0gQmluYXJ5IHJlcHJlc2VudGF0aW9uIG9mIHVuaXF1ZSBmYWNpbGl0eSBJRCBhc3NpZ25lZCBieSB0aGUgRkNDOyBGQ0MgY29udHJvbGxlZCBmb3IgVS5TLlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIHRlcnJpdG9yeVxuICAgICAqIEByZXR1cm4ge1N0YXRpb25JRE51bWJlcn1cbiAgICAgKi9cbiAgICBzZXRGY2NGYWNpbGl0eUlkIChpZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTdGF0aW9uSUROdW1iZXIuS0VZX0ZDQ19GQUNJTElUWV9JRCwgaWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0RmNjRmFjaWxpdHlJZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTdGF0aW9uSUROdW1iZXIuS0VZX0ZDQ19GQUNJTElUWV9JRCk7XG4gICAgfVxufVxuXG5TdGF0aW9uSUROdW1iZXIuS0VZX0NPVU5UUllfQ09ERSA9ICdjb3VudHJ5Q29kZSc7XG5TdGF0aW9uSUROdW1iZXIuS0VZX0ZDQ19GQUNJTElUWV9JRCA9ICdmY2NGYWNpbGl0eUlkJztcblxuZXhwb3J0IHsgU3RhdGlvbklETnVtYmVyIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgR1BTRGF0YSB9IGZyb20gJy4vR1BTRGF0YS5qcyc7XG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgU3RhdGlvbklETnVtYmVyIH0gZnJvbSAnLi9TdGF0aW9uSUROdW1iZXIuanMnO1xuXG5jbGFzcyBTaXNEYXRhIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSAtIElkZW50aWZpZXMgdGhlIDQtYWxwaGEtY2hhcmFjdGVyIHN0YXRpb24gY2FsbCBzaWduIHBsdXMgYW4gb3B0aW9uYWwgKC1GTSkgZXh0ZW5zaW9uXG4gICAgICogQHJldHVybiB7U2lzRGF0YX1cbiAgICAgKi9cbiAgICBzZXRTdGF0aW9uU2hvcnROYW1lIChuYW1lKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNpc0RhdGEuS0VZX1NUQVRJT05fU0hPUlRfTkFNRSwgbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRTdGF0aW9uU2hvcnROYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNpc0RhdGEuS0VZX1NUQVRJT05fU0hPUlRfTkFNRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdGF0aW9uSUROdW1iZXJ9IG51bWJlciAtIFVzZWQgZm9yIG5ldHdvcmsgQXBwbGljYXRpb24uIENvbnNpc3RzIG9mIENvdW50cnkgQ29kZSBhbmQgRkNDIEZhY2lsaXR5IElELlxuICAgICAqIEByZXR1cm4ge1Npc0RhdGF9XG4gICAgICovXG4gICAgc2V0U3RhdGlvbklETnVtYmVyIChudW1iZXIpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoU3RhdGlvbklETnVtYmVyLCBudW1iZXIpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTaXNEYXRhLktFWV9TVEFUSU9OX0lETlVNQkVSLCBudW1iZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdGF0aW9uSUROdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0U3RhdGlvbklETnVtYmVyICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFN0YXRpb25JRE51bWJlciwgU2lzRGF0YS5LRVlfU1RBVElPTl9JRE5VTUJFUik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBJZGVudGlmaWVzIHRoZSBzdGF0aW9uIGNhbGwgc2lnbiBvciBvdGhlciBpZGVudGlmeWluZyBpbmZvcm1hdGlvbiBpbiB0aGUgbG9uZyBmb3JtYXQuXG4gICAgICogQHJldHVybiB7U2lzRGF0YX1cbiAgICAgKi9cbiAgICBzZXRTdGF0aW9uTG9uZ05hbWUgKG5hbWUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2lzRGF0YS5LRVlfU1RBVElPTl9MT05HX05BTUUsIG5hbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0U3RhdGlvbkxvbmdOYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNpc0RhdGEuS0VZX1NUQVRJT05fTE9OR19OQU1FKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0dQU0RhdGF9IGxvY2F0aW9uIC0gUHJvdmlkZXMgdGhlIDMtZGltZW5zaW9uYWwgZ2VvZ3JhcGhpYyBzdGF0aW9uIGxvY2F0aW9uLlxuICAgICAqIEByZXR1cm4ge1Npc0RhdGF9XG4gICAgICovXG4gICAgc2V0U3RhdGlvbkxvY2F0aW9uIChsb2NhdGlvbikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShHUFNEYXRhLCBsb2NhdGlvbik7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNpc0RhdGEuS0VZX1NUQVRJT05fTE9DQVRJT04sIGxvY2F0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7R1BTRGF0YX1cbiAgICAgKi9cbiAgICBnZXRTdGF0aW9uTG9jYXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoR1BTRGF0YSwgU2lzRGF0YS5LRVlfU1RBVElPTl9MT0NBVElPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgLSBNYXkgYmUgdXNlZCB0byBjb252ZXkgdGV4dHVhbCBpbmZvcm1hdGlvbiBvZiBnZW5lcmFsIGludGVyZXN0IHRvIHRoZSBjb25zdW1lciBzdWNoIGFzXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICB3ZWF0aGVyIGZvcmVjYXN0cyBvciBwdWJsaWMgc2VydmljZSBhbm5vdW5jZW1lbnRzLiBJbmNsdWRlcyBhIGhpZ2ggcHJpb3JpdHkgZGVsaXZlcnlcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmUgdG8gY29udmV5IGVtZXJnZW5jaWVzIHRoYXQgbWF5IGJlIGluIHRoZSBsaXN0ZW5pbmcgYXJlYS5cbiAgICAgKiBAcmV0dXJuIHtTaXNEYXRhfVxuICAgICAqL1xuICAgIHNldFN0YXRpb25NZXNzYWdlIChtZXNzYWdlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNpc0RhdGEuS0VZX1NUQVRJT05fTUVTU0FHRSwgbWVzc2FnZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRTdGF0aW9uTWVzc2FnZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTaXNEYXRhLktFWV9TVEFUSU9OX01FU1NBR0UpO1xuICAgIH1cbn1cblxuU2lzRGF0YS5LRVlfU1RBVElPTl9TSE9SVF9OQU1FID0gJ3N0YXRpb25TaG9ydE5hbWUnO1xuU2lzRGF0YS5LRVlfU1RBVElPTl9JRE5VTUJFUiA9ICdzdGF0aW9uSUROdW1iZXInO1xuU2lzRGF0YS5LRVlfU1RBVElPTl9MT05HX05BTUUgPSAnc3RhdGlvbkxvbmdOYW1lJztcblNpc0RhdGEuS0VZX1NUQVRJT05fTE9DQVRJT04gPSAnc3RhdGlvbkxvY2F0aW9uJztcblNpc0RhdGEuS0VZX1NUQVRJT05fTUVTU0FHRSA9ICdzdGF0aW9uTWVzc2FnZSc7XG5cbmV4cG9ydCB7IFNpc0RhdGEgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBSYWRpb0JhbmQgfSBmcm9tICcuLi9lbnVtcy9SYWRpb0JhbmQuanMnO1xuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IFJkc0RhdGEgfSBmcm9tICcuL1Jkc0RhdGEuanMnO1xuaW1wb3J0IHsgUmFkaW9TdGF0ZSB9IGZyb20gJy4uL2VudW1zL1JhZGlvU3RhdGUuanMnO1xuaW1wb3J0IHsgU2lzRGF0YSB9IGZyb20gJy4vU2lzRGF0YS5qcyc7XG5cbmNsYXNzIFJhZGlvQ29udHJvbERhdGEgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBpbnRlZ2VyIC0gVGhlIGludGVnZXIgcGFydCBvZiB0aGUgZnJlcXVlbmN5IGllIGZvciAxMDEuNyB0aGlzIHZhbHVlIHNob3VsZCBiZSAxMDFcbiAgICAgKiBAcmV0dXJuIHtSYWRpb0NvbnRyb2xEYXRhfVxuICAgICAqL1xuICAgIHNldEZyZXF1ZW5jeUludGVnZXIgKGludGVnZXIpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmFkaW9Db250cm9sRGF0YS5LRVlfRlJFUVVFTkNZX0lOVEVHRVIsIGludGVnZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0RnJlcXVlbmN5SW50ZWdlciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSYWRpb0NvbnRyb2xEYXRhLktFWV9GUkVRVUVOQ1lfSU5URUdFUik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGZyYWN0aW9uIC0gVGhlIGZyYWN0aW9uYWwgcGFydCBvZiB0aGUgZnJlcXVlbmN5IGZvciAxMDEuNyBpcyA3XG4gICAgICogQHJldHVybiB7UmFkaW9Db250cm9sRGF0YX1cbiAgICAgKi9cbiAgICBzZXRGcmVxdWVuY3lGcmFjdGlvbiAoZnJhY3Rpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmFkaW9Db250cm9sRGF0YS5LRVlfRlJFUVVFTkNZX0ZSQUNUSU9OLCBmcmFjdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRGcmVxdWVuY3lGcmFjdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSYWRpb0NvbnRyb2xEYXRhLktFWV9GUkVRVUVOQ1lfRlJBQ1RJT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7UmFkaW9CYW5kfSBiYW5kXG4gICAgICogQHJldHVybiB7UmFkaW9Db250cm9sRGF0YX1cbiAgICAgKi9cbiAgICBzZXRCYW5kIChiYW5kKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFJhZGlvQmFuZCwgYmFuZCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJhZGlvQ29udHJvbERhdGEuS0VZX0JBTkQsIGJhbmQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtSYWRpb0JhbmR9XG4gICAgICovXG4gICAgZ2V0QmFuZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChSYWRpb0JhbmQsIFJhZGlvQ29udHJvbERhdGEuS0VZX0JBTkQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7UmRzRGF0YX0gZGF0YVxuICAgICAqIEByZXR1cm4ge1JhZGlvQ29udHJvbERhdGF9XG4gICAgICovXG4gICAgc2V0UmRzRGF0YSAoZGF0YSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShSZHNEYXRhLCBkYXRhKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmFkaW9Db250cm9sRGF0YS5LRVlfUkRTX0RBVEEsIGRhdGEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtSZHNEYXRhfVxuICAgICAqL1xuICAgIGdldFJkc0RhdGEgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoUmRzRGF0YSwgUmFkaW9Db250cm9sRGF0YS5LRVlfUkRTX0RBVEEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gZW5hYmxlIC0gVHJ1ZSBpZiB0aGUgaGQgcmFkaW8gaXMgb24sIGZhbHNlIGlmIHRoZSByYWRpbyBpcyBvZmZcbiAgICAgKiBAcmV0dXJuIHtSYWRpb0NvbnRyb2xEYXRhfVxuICAgICAqL1xuICAgIHNldEhkUmFkaW9FbmFibGUgKGVuYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSYWRpb0NvbnRyb2xEYXRhLktFWV9IRF9SQURJT19FTkFCTEUsIGVuYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0SGRSYWRpb0VuYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSYWRpb0NvbnRyb2xEYXRhLktFWV9IRF9SQURJT19FTkFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBkcyAtIE51bWJlciBvZiBIRCBzdWItY2hhbm5lbHMgaWYgYXZhaWxhYmxlXG4gICAgICogQHJldHVybiB7UmFkaW9Db250cm9sRGF0YX1cbiAgICAgKi9cbiAgICBzZXRBdmFpbGFibGVIRHMgKGRzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJhZGlvQ29udHJvbERhdGEuS0VZX0FWQUlMQUJMRV9IRFMsIGRzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldEF2YWlsYWJsZUhEcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSYWRpb0NvbnRyb2xEYXRhLktFWV9BVkFJTEFCTEVfSERTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcltdfSBjaGFubmVscyAtIFRoZSBsaXN0IG9mIGF2YWlsYWJsZSBIRCBzdWItY2hhbm5lbCBpbmRleGVzLiBFbXB0eSBsaXN0IG1lYW5zIG5vIEhkIGNoYW5uZWwgaXNcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF2YWlsYWJsZS4gUmVhZC1vbmx5LlxuICAgICAqIEByZXR1cm4ge1JhZGlvQ29udHJvbERhdGF9XG4gICAgICovXG4gICAgc2V0QXZhaWxhYmxlSGRDaGFubmVscyAoY2hhbm5lbHMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmFkaW9Db250cm9sRGF0YS5LRVlfQVZBSUxBQkxFX0hEX0NIQU5ORUxTLCBjaGFubmVscyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcltdfVxuICAgICAqL1xuICAgIGdldEF2YWlsYWJsZUhkQ2hhbm5lbHMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmFkaW9Db250cm9sRGF0YS5LRVlfQVZBSUxBQkxFX0hEX0NIQU5ORUxTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gY2hhbm5lbCAtIEN1cnJlbnQgSEQgc3ViLWNoYW5uZWwgaWYgYXZhaWxhYmxlXG4gICAgICogQHJldHVybiB7UmFkaW9Db250cm9sRGF0YX1cbiAgICAgKi9cbiAgICBzZXRIZENoYW5uZWwgKGNoYW5uZWwpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmFkaW9Db250cm9sRGF0YS5LRVlfSERfQ0hBTk5FTCwgY2hhbm5lbCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRIZENoYW5uZWwgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmFkaW9Db250cm9sRGF0YS5LRVlfSERfQ0hBTk5FTCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHN0cmVuZ3RoXG4gICAgICogQHJldHVybiB7UmFkaW9Db250cm9sRGF0YX1cbiAgICAgKi9cbiAgICBzZXRTaWduYWxTdHJlbmd0aCAoc3RyZW5ndGgpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmFkaW9Db250cm9sRGF0YS5LRVlfU0lHTkFMX1NUUkVOR1RILCBzdHJlbmd0aCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRTaWduYWxTdHJlbmd0aCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSYWRpb0NvbnRyb2xEYXRhLktFWV9TSUdOQUxfU1RSRU5HVEgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB0aHJlc2hvbGQgLSBJZiB0aGUgc2lnbmFsIHN0cmVuZ3RoIGZhbGxzIGJlbG93IHRoZSBzZXQgdmFsdWUgZm9yIHRoaXMgcGFyYW1ldGVyLCB0aGUgcmFkaW8gd2lsbFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0dW5lIHRvIGFuIGFsdGVybmF0aXZlIGZyZXF1ZW5jeVxuICAgICAqIEByZXR1cm4ge1JhZGlvQ29udHJvbERhdGF9XG4gICAgICovXG4gICAgc2V0U2lnbmFsQ2hhbmdlVGhyZXNob2xkICh0aHJlc2hvbGQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmFkaW9Db250cm9sRGF0YS5LRVlfU0lHTkFMX0NIQU5HRV9USFJFU0hPTEQsIHRocmVzaG9sZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRTaWduYWxDaGFuZ2VUaHJlc2hvbGQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmFkaW9Db250cm9sRGF0YS5LRVlfU0lHTkFMX0NIQU5HRV9USFJFU0hPTEQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gZW5hYmxlIC0gVHJ1ZSBpZiB0aGUgcmFkaW8gaXMgb24sIGZhbHNlIGlmIHRoZSByYWRpbyBpcyBvZmYuIElmIHNldCB0byBmYWxzZSwgbm8gb3RoZXIgZGF0YSB3aWxsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICBiZSBpbmNsdWRlZC5cbiAgICAgKiBAcmV0dXJuIHtSYWRpb0NvbnRyb2xEYXRhfVxuICAgICAqL1xuICAgIHNldFJhZGlvRW5hYmxlIChlbmFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmFkaW9Db250cm9sRGF0YS5LRVlfUkFESU9fRU5BQkxFLCBlbmFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFJhZGlvRW5hYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFJhZGlvQ29udHJvbERhdGEuS0VZX1JBRElPX0VOQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtSYWRpb1N0YXRlfSBzdGF0ZVxuICAgICAqIEByZXR1cm4ge1JhZGlvQ29udHJvbERhdGF9XG4gICAgICovXG4gICAgc2V0U3RhdGUgKHN0YXRlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFJhZGlvU3RhdGUsIHN0YXRlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmFkaW9Db250cm9sRGF0YS5LRVlfU1RBVEUsIHN0YXRlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7UmFkaW9TdGF0ZX1cbiAgICAgKi9cbiAgICBnZXRTdGF0ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChSYWRpb1N0YXRlLCBSYWRpb0NvbnRyb2xEYXRhLktFWV9TVEFURSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTaXNEYXRhfSBkYXRhIC0gUmVhZC1vbmx5IFN0YXRpb24gSW5mb3JtYXRpb24gU2VydmljZSAoU0lTKSBkYXRhIHByb3ZpZGVzIGJhc2ljIGluZm9ybWF0aW9uIGFib3V0IHRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRpb24gc3VjaCBhcyBjYWxsIHNpZ24sIGFzIHdlbGwgYXMgaW5mb3JtYXRpb24gbm90IGRpc3BsYXlhYmxlIHRvIHRoZSBjb25zdW1lciBzdWNoIGFzXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgdGhlIHN0YXRpb24gaWRlbnRpZmljYXRpb24gbnVtYmVyXG4gICAgICogQHJldHVybiB7UmFkaW9Db250cm9sRGF0YX1cbiAgICAgKi9cbiAgICBzZXRTaXNEYXRhIChkYXRhKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFNpc0RhdGEsIGRhdGEpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSYWRpb0NvbnRyb2xEYXRhLktFWV9TSVNfREFUQSwgZGF0YSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1Npc0RhdGF9XG4gICAgICovXG4gICAgZ2V0U2lzRGF0YSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChTaXNEYXRhLCBSYWRpb0NvbnRyb2xEYXRhLktFWV9TSVNfREFUQSk7XG4gICAgfVxufVxuXG5SYWRpb0NvbnRyb2xEYXRhLktFWV9GUkVRVUVOQ1lfSU5URUdFUiA9ICdmcmVxdWVuY3lJbnRlZ2VyJztcblJhZGlvQ29udHJvbERhdGEuS0VZX0ZSRVFVRU5DWV9GUkFDVElPTiA9ICdmcmVxdWVuY3lGcmFjdGlvbic7XG5SYWRpb0NvbnRyb2xEYXRhLktFWV9CQU5EID0gJ2JhbmQnO1xuUmFkaW9Db250cm9sRGF0YS5LRVlfUkRTX0RBVEEgPSAncmRzRGF0YSc7XG5SYWRpb0NvbnRyb2xEYXRhLktFWV9IRF9SQURJT19FTkFCTEUgPSAnaGRSYWRpb0VuYWJsZSc7XG5SYWRpb0NvbnRyb2xEYXRhLktFWV9BVkFJTEFCTEVfSERTID0gJ2F2YWlsYWJsZUhEcyc7XG5SYWRpb0NvbnRyb2xEYXRhLktFWV9BVkFJTEFCTEVfSERfQ0hBTk5FTFMgPSAnYXZhaWxhYmxlSGRDaGFubmVscyc7XG5SYWRpb0NvbnRyb2xEYXRhLktFWV9IRF9DSEFOTkVMID0gJ2hkQ2hhbm5lbCc7XG5SYWRpb0NvbnRyb2xEYXRhLktFWV9TSUdOQUxfU1RSRU5HVEggPSAnc2lnbmFsU3RyZW5ndGgnO1xuUmFkaW9Db250cm9sRGF0YS5LRVlfU0lHTkFMX0NIQU5HRV9USFJFU0hPTEQgPSAnc2lnbmFsQ2hhbmdlVGhyZXNob2xkJztcblJhZGlvQ29udHJvbERhdGEuS0VZX1JBRElPX0VOQUJMRSA9ICdyYWRpb0VuYWJsZSc7XG5SYWRpb0NvbnRyb2xEYXRhLktFWV9TVEFURSA9ICdzdGF0ZSc7XG5SYWRpb0NvbnRyb2xEYXRhLktFWV9TSVNfREFUQSA9ICdzaXNEYXRhJztcblxuZXhwb3J0IHsgUmFkaW9Db250cm9sRGF0YSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBUZW1wZXJhdHVyZVVuaXQgfSBmcm9tICcuLi9lbnVtcy9UZW1wZXJhdHVyZVVuaXQuanMnO1xuXG5jbGFzcyBUZW1wZXJhdHVyZSBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtUZW1wZXJhdHVyZVVuaXR9IHVuaXQgLSBUZW1wZXJhdHVyZSBVbml0XG4gICAgICogQHJldHVybiB7VGVtcGVyYXR1cmV9XG4gICAgICovXG4gICAgc2V0VW5pdCAodW5pdCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShUZW1wZXJhdHVyZVVuaXQsIHVuaXQpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihUZW1wZXJhdHVyZS5LRVlfVU5JVCwgdW5pdCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1RlbXBlcmF0dXJlVW5pdH1cbiAgICAgKi9cbiAgICBnZXRVbml0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFRlbXBlcmF0dXJlVW5pdCwgVGVtcGVyYXR1cmUuS0VZX1VOSVQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB2YWx1ZSAtIFRlbXBlcmF0dXJlIFZhbHVlIGluIFRlbXBlcmF0dXJlVW5pdCBzcGVjaWZpZWQgdW5pdC4gUmFuZ2UgZGVwZW5kcyBvbiBPRU0gYW5kIGlzIG5vdFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrZWQgYnkgU0RMLlxuICAgICAqIEByZXR1cm4ge1RlbXBlcmF0dXJlfVxuICAgICAqL1xuICAgIHNldFZhbHVlICh2YWx1ZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihUZW1wZXJhdHVyZS5LRVlfVkFMVUUsIHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFZhbHVlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFRlbXBlcmF0dXJlLktFWV9WQUxVRSk7XG4gICAgfVxufVxuXG5UZW1wZXJhdHVyZS5LRVlfVU5JVCA9ICd1bml0JztcblRlbXBlcmF0dXJlLktFWV9WQUxVRSA9ICd2YWx1ZSc7XG5cbmV4cG9ydCB7IFRlbXBlcmF0dXJlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYge0VudW19IFZlbnRpbGF0aW9uTW9kZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgVmVudGlsYXRpb25Nb2RlIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFVQUEVSICgpIHtcbiAgICAgICAgcmV0dXJuIFZlbnRpbGF0aW9uTW9kZS5fTUFQLlVQUEVSO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IExPV0VSICgpIHtcbiAgICAgICAgcmV0dXJuIFZlbnRpbGF0aW9uTW9kZS5fTUFQLkxPV0VSO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEJPVEggKCkge1xuICAgICAgICByZXR1cm4gVmVudGlsYXRpb25Nb2RlLl9NQVAuQk9USDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOT05FICgpIHtcbiAgICAgICAgcmV0dXJuIFZlbnRpbGF0aW9uTW9kZS5fTUFQLk5PTkU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gVmVudGlsYXRpb25Nb2RlLl92YWx1ZUZvcktleShrZXksIFZlbnRpbGF0aW9uTW9kZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFZlbnRpbGF0aW9uTW9kZS5fa2V5Rm9yVmFsdWUodmFsdWUsIFZlbnRpbGF0aW9uTW9kZS5fTUFQKTtcbiAgICB9XG59XG5cblZlbnRpbGF0aW9uTW9kZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1VQUEVSJzogJ1VQUEVSJyxcbiAgICAnTE9XRVInOiAnTE9XRVInLFxuICAgICdCT1RIJzogJ0JPVEgnLFxuICAgICdOT05FJzogJ05PTkUnLFxufSk7XG5cbmV4cG9ydCB7IFZlbnRpbGF0aW9uTW9kZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBEZWZyb3N0Wm9uZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgRGVmcm9zdFpvbmUgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRlJPTlQgKCkge1xuICAgICAgICByZXR1cm4gRGVmcm9zdFpvbmUuX01BUC5GUk9OVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSRUFSICgpIHtcbiAgICAgICAgcmV0dXJuIERlZnJvc3Rab25lLl9NQVAuUkVBUjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBBTEwgKCkge1xuICAgICAgICByZXR1cm4gRGVmcm9zdFpvbmUuX01BUC5BTEw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTk9ORSAoKSB7XG4gICAgICAgIHJldHVybiBEZWZyb3N0Wm9uZS5fTUFQLk5PTkU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gRGVmcm9zdFpvbmUuX3ZhbHVlRm9yS2V5KGtleSwgRGVmcm9zdFpvbmUuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBEZWZyb3N0Wm9uZS5fa2V5Rm9yVmFsdWUodmFsdWUsIERlZnJvc3Rab25lLl9NQVApO1xuICAgIH1cbn1cblxuRGVmcm9zdFpvbmUuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdGUk9OVCc6ICdGUk9OVCcsXG4gICAgJ1JFQVInOiAnUkVBUicsXG4gICAgJ0FMTCc6ICdBTEwnLFxuICAgICdOT05FJzogJ05PTkUnLFxufSk7XG5cbmV4cG9ydCB7IERlZnJvc3Rab25lIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgVGVtcGVyYXR1cmUgfSBmcm9tICcuL1RlbXBlcmF0dXJlLmpzJztcbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBWZW50aWxhdGlvbk1vZGUgfSBmcm9tICcuLi9lbnVtcy9WZW50aWxhdGlvbk1vZGUuanMnO1xuaW1wb3J0IHsgRGVmcm9zdFpvbmUgfSBmcm9tICcuLi9lbnVtcy9EZWZyb3N0Wm9uZS5qcyc7XG5cbmNsYXNzIENsaW1hdGVDb250cm9sRGF0YSBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNwZWVkXG4gICAgICogQHJldHVybiB7Q2xpbWF0ZUNvbnRyb2xEYXRhfVxuICAgICAqL1xuICAgIHNldEZhblNwZWVkIChzcGVlZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihDbGltYXRlQ29udHJvbERhdGEuS0VZX0ZBTl9TUEVFRCwgc3BlZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0RmFuU3BlZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xEYXRhLktFWV9GQU5fU1BFRUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VGVtcGVyYXR1cmV9IHRlbXBlcmF0dXJlXG4gICAgICogQHJldHVybiB7Q2xpbWF0ZUNvbnRyb2xEYXRhfVxuICAgICAqL1xuICAgIHNldEN1cnJlbnRUZW1wZXJhdHVyZSAodGVtcGVyYXR1cmUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVGVtcGVyYXR1cmUsIHRlbXBlcmF0dXJlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xEYXRhLktFWV9DVVJSRU5UX1RFTVBFUkFUVVJFLCB0ZW1wZXJhdHVyZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1RlbXBlcmF0dXJlfVxuICAgICAqL1xuICAgIGdldEN1cnJlbnRUZW1wZXJhdHVyZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChUZW1wZXJhdHVyZSwgQ2xpbWF0ZUNvbnRyb2xEYXRhLktFWV9DVVJSRU5UX1RFTVBFUkFUVVJFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1RlbXBlcmF0dXJlfSB0ZW1wZXJhdHVyZVxuICAgICAqIEByZXR1cm4ge0NsaW1hdGVDb250cm9sRGF0YX1cbiAgICAgKi9cbiAgICBzZXREZXNpcmVkVGVtcGVyYXR1cmUgKHRlbXBlcmF0dXJlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFRlbXBlcmF0dXJlLCB0ZW1wZXJhdHVyZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENsaW1hdGVDb250cm9sRGF0YS5LRVlfREVTSVJFRF9URU1QRVJBVFVSRSwgdGVtcGVyYXR1cmUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtUZW1wZXJhdHVyZX1cbiAgICAgKi9cbiAgICBnZXREZXNpcmVkVGVtcGVyYXR1cmUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVGVtcGVyYXR1cmUsIENsaW1hdGVDb250cm9sRGF0YS5LRVlfREVTSVJFRF9URU1QRVJBVFVSRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBlbmFibGVcbiAgICAgKiBAcmV0dXJuIHtDbGltYXRlQ29udHJvbERhdGF9XG4gICAgICovXG4gICAgc2V0QWNFbmFibGUgKGVuYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihDbGltYXRlQ29udHJvbERhdGEuS0VZX0FDX0VOQUJMRSwgZW5hYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRBY0VuYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihDbGltYXRlQ29udHJvbERhdGEuS0VZX0FDX0VOQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBlbmFibGVcbiAgICAgKiBAcmV0dXJuIHtDbGltYXRlQ29udHJvbERhdGF9XG4gICAgICovXG4gICAgc2V0Q2lyY3VsYXRlQWlyRW5hYmxlIChlbmFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xEYXRhLktFWV9DSVJDVUxBVEVfQUlSX0VOQUJMRSwgZW5hYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRDaXJjdWxhdGVBaXJFbmFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xEYXRhLktFWV9DSVJDVUxBVEVfQUlSX0VOQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBlbmFibGVcbiAgICAgKiBAcmV0dXJuIHtDbGltYXRlQ29udHJvbERhdGF9XG4gICAgICovXG4gICAgc2V0QXV0b01vZGVFbmFibGUgKGVuYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihDbGltYXRlQ29udHJvbERhdGEuS0VZX0FVVE9fTU9ERV9FTkFCTEUsIGVuYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0QXV0b01vZGVFbmFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xEYXRhLktFWV9BVVRPX01PREVfRU5BQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0RlZnJvc3Rab25lfSB6b25lXG4gICAgICogQHJldHVybiB7Q2xpbWF0ZUNvbnRyb2xEYXRhfVxuICAgICAqL1xuICAgIHNldERlZnJvc3Rab25lICh6b25lKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKERlZnJvc3Rab25lLCB6b25lKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xEYXRhLktFWV9ERUZST1NUX1pPTkUsIHpvbmUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtEZWZyb3N0Wm9uZX1cbiAgICAgKi9cbiAgICBnZXREZWZyb3N0Wm9uZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChEZWZyb3N0Wm9uZSwgQ2xpbWF0ZUNvbnRyb2xEYXRhLktFWV9ERUZST1NUX1pPTkUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gZW5hYmxlXG4gICAgICogQHJldHVybiB7Q2xpbWF0ZUNvbnRyb2xEYXRhfVxuICAgICAqL1xuICAgIHNldER1YWxNb2RlRW5hYmxlIChlbmFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xEYXRhLktFWV9EVUFMX01PREVfRU5BQkxFLCBlbmFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldER1YWxNb2RlRW5hYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKENsaW1hdGVDb250cm9sRGF0YS5LRVlfRFVBTF9NT0RFX0VOQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBlbmFibGVcbiAgICAgKiBAcmV0dXJuIHtDbGltYXRlQ29udHJvbERhdGF9XG4gICAgICovXG4gICAgc2V0QWNNYXhFbmFibGUgKGVuYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihDbGltYXRlQ29udHJvbERhdGEuS0VZX0FDX01BWF9FTkFCTEUsIGVuYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0QWNNYXhFbmFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xEYXRhLktFWV9BQ19NQVhfRU5BQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlbnRpbGF0aW9uTW9kZX0gbW9kZVxuICAgICAqIEByZXR1cm4ge0NsaW1hdGVDb250cm9sRGF0YX1cbiAgICAgKi9cbiAgICBzZXRWZW50aWxhdGlvbk1vZGUgKG1vZGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVudGlsYXRpb25Nb2RlLCBtb2RlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xEYXRhLktFWV9WRU5USUxBVElPTl9NT0RFLCBtb2RlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVudGlsYXRpb25Nb2RlfVxuICAgICAqL1xuICAgIGdldFZlbnRpbGF0aW9uTW9kZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWZW50aWxhdGlvbk1vZGUsIENsaW1hdGVDb250cm9sRGF0YS5LRVlfVkVOVElMQVRJT05fTU9ERSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBlbmFibGUgLSB2YWx1ZSBmYWxzZSBtZWFucyBkaXNhYmxlZC90dXJuIG9mZiwgdmFsdWUgdHJ1ZSBtZWFucyBlbmFibGVkL3R1cm4gb24uXG4gICAgICogQHJldHVybiB7Q2xpbWF0ZUNvbnRyb2xEYXRhfVxuICAgICAqL1xuICAgIHNldEhlYXRlZFN0ZWVyaW5nV2hlZWxFbmFibGUgKGVuYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihDbGltYXRlQ29udHJvbERhdGEuS0VZX0hFQVRFRF9TVEVFUklOR19XSEVFTF9FTkFCTEUsIGVuYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0SGVhdGVkU3RlZXJpbmdXaGVlbEVuYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihDbGltYXRlQ29udHJvbERhdGEuS0VZX0hFQVRFRF9TVEVFUklOR19XSEVFTF9FTkFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gZW5hYmxlIC0gdmFsdWUgZmFsc2UgbWVhbnMgZGlzYWJsZWQsIHZhbHVlIHRydWUgbWVhbnMgZW5hYmxlZC5cbiAgICAgKiBAcmV0dXJuIHtDbGltYXRlQ29udHJvbERhdGF9XG4gICAgICovXG4gICAgc2V0SGVhdGVkV2luZHNoaWVsZEVuYWJsZSAoZW5hYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENsaW1hdGVDb250cm9sRGF0YS5LRVlfSEVBVEVEX1dJTkRTSElFTERfRU5BQkxFLCBlbmFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEhlYXRlZFdpbmRzaGllbGRFbmFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xEYXRhLktFWV9IRUFURURfV0lORFNISUVMRF9FTkFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gZW5hYmxlIC0gdmFsdWUgZmFsc2UgbWVhbnMgZGlzYWJsZWQsIHZhbHVlIHRydWUgbWVhbnMgZW5hYmxlZC5cbiAgICAgKiBAcmV0dXJuIHtDbGltYXRlQ29udHJvbERhdGF9XG4gICAgICovXG4gICAgc2V0SGVhdGVkUmVhcldpbmRvd0VuYWJsZSAoZW5hYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENsaW1hdGVDb250cm9sRGF0YS5LRVlfSEVBVEVEX1JFQVJfV0lORE9XX0VOQUJMRSwgZW5hYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRIZWF0ZWRSZWFyV2luZG93RW5hYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKENsaW1hdGVDb250cm9sRGF0YS5LRVlfSEVBVEVEX1JFQVJfV0lORE9XX0VOQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBlbmFibGUgLSB2YWx1ZSBmYWxzZSBtZWFucyBkaXNhYmxlZCwgdmFsdWUgdHJ1ZSBtZWFucyBlbmFibGVkLlxuICAgICAqIEByZXR1cm4ge0NsaW1hdGVDb250cm9sRGF0YX1cbiAgICAgKi9cbiAgICBzZXRIZWF0ZWRNaXJyb3JzRW5hYmxlIChlbmFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xEYXRhLktFWV9IRUFURURfTUlSUk9SU19FTkFCTEUsIGVuYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0SGVhdGVkTWlycm9yc0VuYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihDbGltYXRlQ29udHJvbERhdGEuS0VZX0hFQVRFRF9NSVJST1JTX0VOQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBlbmFibGUgLSBUcnVlIGlmIHRoZSBjbGltYXRlIG1vZHVsZSBpcyBvbiwgZmFsc2UgaWYgdGhlIGNsaW1hdGUgbW9kdWxlIGlzIG9mZlxuICAgICAqIEByZXR1cm4ge0NsaW1hdGVDb250cm9sRGF0YX1cbiAgICAgKi9cbiAgICBzZXRDbGltYXRlRW5hYmxlIChlbmFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xEYXRhLktFWV9DTElNQVRFX0VOQUJMRSwgZW5hYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRDbGltYXRlRW5hYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKENsaW1hdGVDb250cm9sRGF0YS5LRVlfQ0xJTUFURV9FTkFCTEUpO1xuICAgIH1cbn1cblxuQ2xpbWF0ZUNvbnRyb2xEYXRhLktFWV9GQU5fU1BFRUQgPSAnZmFuU3BlZWQnO1xuQ2xpbWF0ZUNvbnRyb2xEYXRhLktFWV9DVVJSRU5UX1RFTVBFUkFUVVJFID0gJ2N1cnJlbnRUZW1wZXJhdHVyZSc7XG5DbGltYXRlQ29udHJvbERhdGEuS0VZX0RFU0lSRURfVEVNUEVSQVRVUkUgPSAnZGVzaXJlZFRlbXBlcmF0dXJlJztcbkNsaW1hdGVDb250cm9sRGF0YS5LRVlfQUNfRU5BQkxFID0gJ2FjRW5hYmxlJztcbkNsaW1hdGVDb250cm9sRGF0YS5LRVlfQ0lSQ1VMQVRFX0FJUl9FTkFCTEUgPSAnY2lyY3VsYXRlQWlyRW5hYmxlJztcbkNsaW1hdGVDb250cm9sRGF0YS5LRVlfQVVUT19NT0RFX0VOQUJMRSA9ICdhdXRvTW9kZUVuYWJsZSc7XG5DbGltYXRlQ29udHJvbERhdGEuS0VZX0RFRlJPU1RfWk9ORSA9ICdkZWZyb3N0Wm9uZSc7XG5DbGltYXRlQ29udHJvbERhdGEuS0VZX0RVQUxfTU9ERV9FTkFCTEUgPSAnZHVhbE1vZGVFbmFibGUnO1xuQ2xpbWF0ZUNvbnRyb2xEYXRhLktFWV9BQ19NQVhfRU5BQkxFID0gJ2FjTWF4RW5hYmxlJztcbkNsaW1hdGVDb250cm9sRGF0YS5LRVlfVkVOVElMQVRJT05fTU9ERSA9ICd2ZW50aWxhdGlvbk1vZGUnO1xuQ2xpbWF0ZUNvbnRyb2xEYXRhLktFWV9IRUFURURfU1RFRVJJTkdfV0hFRUxfRU5BQkxFID0gJ2hlYXRlZFN0ZWVyaW5nV2hlZWxFbmFibGUnO1xuQ2xpbWF0ZUNvbnRyb2xEYXRhLktFWV9IRUFURURfV0lORFNISUVMRF9FTkFCTEUgPSAnaGVhdGVkV2luZHNoaWVsZEVuYWJsZSc7XG5DbGltYXRlQ29udHJvbERhdGEuS0VZX0hFQVRFRF9SRUFSX1dJTkRPV19FTkFCTEUgPSAnaGVhdGVkUmVhcldpbmRvd0VuYWJsZSc7XG5DbGltYXRlQ29udHJvbERhdGEuS0VZX0hFQVRFRF9NSVJST1JTX0VOQUJMRSA9ICdoZWF0ZWRNaXJyb3JzRW5hYmxlJztcbkNsaW1hdGVDb250cm9sRGF0YS5LRVlfQ0xJTUFURV9FTkFCTEUgPSAnY2xpbWF0ZUVuYWJsZSc7XG5cbmV4cG9ydCB7IENsaW1hdGVDb250cm9sRGF0YSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5cbi8qKlxuICogRGVmaW5lcyB0aGUgZWFjaCBFcXVhbGl6ZXIgY2hhbm5lbCBzZXR0aW5ncy5cbiAqL1xuY2xhc3MgRXF1YWxpemVyU2V0dGluZ3MgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBpZFxuICAgICAqIEByZXR1cm4ge0VxdWFsaXplclNldHRpbmdzfVxuICAgICAqL1xuICAgIHNldENoYW5uZWxJZCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRXF1YWxpemVyU2V0dGluZ3MuS0VZX0NIQU5ORUxfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldENoYW5uZWxJZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihFcXVhbGl6ZXJTZXR0aW5ncy5LRVlfQ0hBTk5FTF9JRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSByZWFkLW9ubHkgY2hhbm5lbCAvIGZyZXF1ZW5jeSBuYW1lIChlLmkuIFwiVHJlYmxlLCBNaWRyYW5nZSwgQmFzc1wiIG9yIFwiMTI1IEh6XCIpXG4gICAgICogQHJldHVybiB7RXF1YWxpemVyU2V0dGluZ3N9XG4gICAgICovXG4gICAgc2V0Q2hhbm5lbE5hbWUgKG5hbWUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRXF1YWxpemVyU2V0dGluZ3MuS0VZX0NIQU5ORUxfTkFNRSwgbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRDaGFubmVsTmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihFcXVhbGl6ZXJTZXR0aW5ncy5LRVlfQ0hBTk5FTF9OQU1FKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc2V0dGluZyAtIFJlZmxlY3RzIHRoZSBzZXR0aW5nLCBmcm9tIDAlLTEwMCUuXG4gICAgICogQHJldHVybiB7RXF1YWxpemVyU2V0dGluZ3N9XG4gICAgICovXG4gICAgc2V0Q2hhbm5lbFNldHRpbmcgKHNldHRpbmcpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRXF1YWxpemVyU2V0dGluZ3MuS0VZX0NIQU5ORUxfU0VUVElORywgc2V0dGluZyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRDaGFubmVsU2V0dGluZyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihFcXVhbGl6ZXJTZXR0aW5ncy5LRVlfQ0hBTk5FTF9TRVRUSU5HKTtcbiAgICB9XG59XG5cbkVxdWFsaXplclNldHRpbmdzLktFWV9DSEFOTkVMX0lEID0gJ2NoYW5uZWxJZCc7XG5FcXVhbGl6ZXJTZXR0aW5ncy5LRVlfQ0hBTk5FTF9OQU1FID0gJ2NoYW5uZWxOYW1lJztcbkVxdWFsaXplclNldHRpbmdzLktFWV9DSEFOTkVMX1NFVFRJTkcgPSAnY2hhbm5lbFNldHRpbmcnO1xuXG5leHBvcnQgeyBFcXVhbGl6ZXJTZXR0aW5ncyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBQcmltYXJ5QXVkaW9Tb3VyY2UgfSBmcm9tICcuLi9lbnVtcy9QcmltYXJ5QXVkaW9Tb3VyY2UuanMnO1xuaW1wb3J0IHsgRXF1YWxpemVyU2V0dGluZ3MgfSBmcm9tICcuL0VxdWFsaXplclNldHRpbmdzLmpzJztcblxuY2xhc3MgQXVkaW9Db250cm9sRGF0YSBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtQcmltYXJ5QXVkaW9Tb3VyY2V9IHNvdXJjZSAtIEluIGEgZ2V0dGVyIHJlc3BvbnNlIG9yIGEgbm90aWZpY2F0aW9uLCBpdCBpcyB0aGUgY3VycmVudCBwcmltYXJ5IGF1ZGlvXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZSBvZiB0aGUgc3lzdGVtLiBJbiBhIHNldHRlciByZXF1ZXN0LCBpdCBpcyB0aGUgdGFyZ2V0IGF1ZGlvIHNvdXJjZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0IHRoZSBzeXN0ZW0gc2hhbGwgc3dpdGNoIHRvLiBJZiB0aGUgdmFsdWUgaXMgTU9CSUxFX0FQUCwgdGhlIHN5c3RlbVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFsbCBzd2l0Y2ggdG8gdGhlIG1vYmlsZSBtZWRpYSBhcHAgdGhhdCBpc3N1ZXMgdGhlIHNldHRlciBSUEMuXG4gICAgICogQHJldHVybiB7QXVkaW9Db250cm9sRGF0YX1cbiAgICAgKi9cbiAgICBzZXRTb3VyY2UgKHNvdXJjZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShQcmltYXJ5QXVkaW9Tb3VyY2UsIHNvdXJjZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEF1ZGlvQ29udHJvbERhdGEuS0VZX1NPVVJDRSwgc291cmNlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7UHJpbWFyeUF1ZGlvU291cmNlfVxuICAgICAqL1xuICAgIGdldFNvdXJjZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChQcmltYXJ5QXVkaW9Tb3VyY2UsIEF1ZGlvQ29udHJvbERhdGEuS0VZX1NPVVJDRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBjb250ZXh0IC0gVGhpcyBwYXJhbWV0ZXIgc2hhbGwgbm90IGJlIHByZXNlbnQgaW4gYW55IGdldHRlciByZXNwb25zZXMgb3Igbm90aWZpY2F0aW9ucy4gVGhpc1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlciBpcyBvcHRpb25hbCBpbiBhIHNldHRlciByZXF1ZXN0LiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBmYWxzZSBpZiBpdCBpcyBub3RcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmNsdWRlZC4gSWYgaXQgaXMgZmFsc2UsIHRoZSBzeXN0ZW0gbm90IG9ubHkgY2hhbmdlcyB0aGUgYXVkaW8gc291cmNlIGJ1dCBhbHNvIGJyaW5nc1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBkZWZhdWx0IGFwcGxpY2F0aW9uIG9yIHN5c3RlbSBVSSBhc3NvY2lhdGVkIHdpdGggdGhlIGF1ZGlvIHNvdXJjZSB0byBmb3JlZ3JvdW5kLlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmIGl0IGlzIHRydWUsIHRoZSBzeXN0ZW0gb25seSBjaGFuZ2VzIHRoZSBhdWRpbyBzb3VyY2UsIGJ1dCBrZWVwcyB0aGUgY3VycmVudFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGxpY2F0aW9uIGluIGZvcmVncm91bmQuXG4gICAgICogQHJldHVybiB7QXVkaW9Db250cm9sRGF0YX1cbiAgICAgKi9cbiAgICBzZXRLZWVwQ29udGV4dCAoY29udGV4dCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBdWRpb0NvbnRyb2xEYXRhLktFWV9LRUVQX0NPTlRFWFQsIGNvbnRleHQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEtlZXBDb250ZXh0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEF1ZGlvQ29udHJvbERhdGEuS0VZX0tFRVBfQ09OVEVYVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHZvbHVtZSAtIFJlZmxlY3RzIHRoZSB2b2x1bWUgb2YgYXVkaW8sIGZyb20gMCUtMTAwJS5cbiAgICAgKiBAcmV0dXJuIHtBdWRpb0NvbnRyb2xEYXRhfVxuICAgICAqL1xuICAgIHNldFZvbHVtZSAodm9sdW1lKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEF1ZGlvQ29udHJvbERhdGEuS0VZX1ZPTFVNRSwgdm9sdW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFZvbHVtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihBdWRpb0NvbnRyb2xEYXRhLktFWV9WT0xVTUUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RXF1YWxpemVyU2V0dGluZ3NbXX0gc2V0dGluZ3MgLSBEZWZpbmVzIHRoZSBsaXN0IG9mIHN1cHBvcnRlZCBjaGFubmVscyAoYmFuZCkgYW5kIHRoZWlyIGN1cnJlbnQvZGVzaXJlZFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR0aW5ncyBvbiBITUlcbiAgICAgKiBAcmV0dXJuIHtBdWRpb0NvbnRyb2xEYXRhfVxuICAgICAqL1xuICAgIHNldEVxdWFsaXplclNldHRpbmdzIChzZXR0aW5ncykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShFcXVhbGl6ZXJTZXR0aW5ncywgc2V0dGluZ3MsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBdWRpb0NvbnRyb2xEYXRhLktFWV9FUVVBTElaRVJfU0VUVElOR1MsIHNldHRpbmdzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7RXF1YWxpemVyU2V0dGluZ3NbXX1cbiAgICAgKi9cbiAgICBnZXRFcXVhbGl6ZXJTZXR0aW5ncyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChFcXVhbGl6ZXJTZXR0aW5ncywgQXVkaW9Db250cm9sRGF0YS5LRVlfRVFVQUxJWkVSX1NFVFRJTkdTKTtcbiAgICB9XG59XG5cbkF1ZGlvQ29udHJvbERhdGEuS0VZX1NPVVJDRSA9ICdzb3VyY2UnO1xuQXVkaW9Db250cm9sRGF0YS5LRVlfS0VFUF9DT05URVhUID0gJ2tlZXBDb250ZXh0JztcbkF1ZGlvQ29udHJvbERhdGEuS0VZX1ZPTFVNRSA9ICd2b2x1bWUnO1xuQXVkaW9Db250cm9sRGF0YS5LRVlfRVFVQUxJWkVSX1NFVFRJTkdTID0gJ2VxdWFsaXplclNldHRpbmdzJztcblxuZXhwb3J0IHsgQXVkaW9Db250cm9sRGF0YSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIExpc3QgcG9zc2libGUgY3VzaGlvbnMgb2YgYSBtdWx0aS1jb250b3VyIG1hc3NhZ2Ugc2VhdC5cbiAqIEB0eXBlZGVmIHtFbnVtfSBNYXNzYWdlQ3VzaGlvblxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgTWFzc2FnZUN1c2hpb24gZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVE9QX0xVTUJBUiAoKSB7XG4gICAgICAgIHJldHVybiBNYXNzYWdlQ3VzaGlvbi5fTUFQLlRPUF9MVU1CQVI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTUlERExFX0xVTUJBUiAoKSB7XG4gICAgICAgIHJldHVybiBNYXNzYWdlQ3VzaGlvbi5fTUFQLk1JRERMRV9MVU1CQVI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQk9UVE9NX0xVTUJBUiAoKSB7XG4gICAgICAgIHJldHVybiBNYXNzYWdlQ3VzaGlvbi5fTUFQLkJPVFRPTV9MVU1CQVI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQkFDS19CT0xTVEVSUyAoKSB7XG4gICAgICAgIHJldHVybiBNYXNzYWdlQ3VzaGlvbi5fTUFQLkJBQ0tfQk9MU1RFUlM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0VBVF9CT0xTVEVSUyAoKSB7XG4gICAgICAgIHJldHVybiBNYXNzYWdlQ3VzaGlvbi5fTUFQLlNFQVRfQk9MU1RFUlM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gTWFzc2FnZUN1c2hpb24uX3ZhbHVlRm9yS2V5KGtleSwgTWFzc2FnZUN1c2hpb24uX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBNYXNzYWdlQ3VzaGlvbi5fa2V5Rm9yVmFsdWUodmFsdWUsIE1hc3NhZ2VDdXNoaW9uLl9NQVApO1xuICAgIH1cbn1cblxuTWFzc2FnZUN1c2hpb24uX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdUT1BfTFVNQkFSJzogJ1RPUF9MVU1CQVInLFxuICAgICdNSURETEVfTFVNQkFSJzogJ01JRERMRV9MVU1CQVInLFxuICAgICdCT1RUT01fTFVNQkFSJzogJ0JPVFRPTV9MVU1CQVInLFxuICAgICdCQUNLX0JPTFNURVJTJzogJ0JBQ0tfQk9MU1RFUlMnLFxuICAgICdTRUFUX0JPTFNURVJTJzogJ1NFQVRfQk9MU1RFUlMnLFxufSk7XG5cbmV4cG9ydCB7IE1hc3NhZ2VDdXNoaW9uIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IE1hc3NhZ2VDdXNoaW9uIH0gZnJvbSAnLi4vZW51bXMvTWFzc2FnZUN1c2hpb24uanMnO1xuXG4vKipcbiAqIFRoZSBpbnRlbnNpdHkgb3IgZmlybW5lc3Mgb2YgYSBjdXNoaW9uLlxuICovXG5jbGFzcyBNYXNzYWdlQ3VzaGlvbkZpcm1uZXNzIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge01hc3NhZ2VDdXNoaW9ufSBjdXNoaW9uIC0gTGlzdCBwb3NzaWJsZSBjdXNoaW9ucyBvZiBhIG11bHRpLWNvbnRvdXIgbWFzc2FnZSBzZWF0LlxuICAgICAqIEByZXR1cm4ge01hc3NhZ2VDdXNoaW9uRmlybW5lc3N9XG4gICAgICovXG4gICAgc2V0Q3VzaGlvbiAoY3VzaGlvbikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShNYXNzYWdlQ3VzaGlvbiwgY3VzaGlvbik7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE1hc3NhZ2VDdXNoaW9uRmlybW5lc3MuS0VZX0NVU0hJT04sIGN1c2hpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtNYXNzYWdlQ3VzaGlvbn1cbiAgICAgKi9cbiAgICBnZXRDdXNoaW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KE1hc3NhZ2VDdXNoaW9uLCBNYXNzYWdlQ3VzaGlvbkZpcm1uZXNzLktFWV9DVVNISU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZmlybW5lc3NcbiAgICAgKiBAcmV0dXJuIHtNYXNzYWdlQ3VzaGlvbkZpcm1uZXNzfVxuICAgICAqL1xuICAgIHNldEZpcm1uZXNzIChmaXJtbmVzcykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihNYXNzYWdlQ3VzaGlvbkZpcm1uZXNzLktFWV9GSVJNTkVTUywgZmlybW5lc3MpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0RmlybW5lc3MgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoTWFzc2FnZUN1c2hpb25GaXJtbmVzcy5LRVlfRklSTU5FU1MpO1xuICAgIH1cbn1cblxuTWFzc2FnZUN1c2hpb25GaXJtbmVzcy5LRVlfQ1VTSElPTiA9ICdjdXNoaW9uJztcbk1hc3NhZ2VDdXNoaW9uRmlybW5lc3MuS0VZX0ZJUk1ORVNTID0gJ2Zpcm1uZXNzJztcblxuZXhwb3J0IHsgTWFzc2FnZUN1c2hpb25GaXJtbmVzcyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIExpc3QgcG9zc2libGUgc2VhdHMgdGhhdCBpcyBhIHJlbW90ZSBjb250cm9sbGFibGUgc2VhdC5cbiAqIEBkZXByZWNhdGVkXG4gKiBAdHlwZWRlZiB7RW51bX0gU3VwcG9ydGVkU2VhdFxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgU3VwcG9ydGVkU2VhdCBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRFJJVkVSICgpIHtcbiAgICAgICAgcmV0dXJuIFN1cHBvcnRlZFNlYXQuX01BUC5EUklWRVI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBGUk9OVF9QQVNTRU5HRVIgKCkge1xuICAgICAgICByZXR1cm4gU3VwcG9ydGVkU2VhdC5fTUFQLkZST05UX1BBU1NFTkdFUjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBTdXBwb3J0ZWRTZWF0Ll92YWx1ZUZvcktleShrZXksIFN1cHBvcnRlZFNlYXQuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBTdXBwb3J0ZWRTZWF0Ll9rZXlGb3JWYWx1ZSh2YWx1ZSwgU3VwcG9ydGVkU2VhdC5fTUFQKTtcbiAgICB9XG59XG5cblN1cHBvcnRlZFNlYXQuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdEUklWRVInOiAnRFJJVkVSJyxcbiAgICAnRlJPTlRfUEFTU0VOR0VSJzogJ0ZST05UX1BBU1NFTkdFUicsXG59KTtcblxuZXhwb3J0IHsgU3VwcG9ydGVkU2VhdCB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBTZWF0TWVtb3J5QWN0aW9uVHlwZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgU2VhdE1lbW9yeUFjdGlvblR5cGUgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2F2ZSBjdXJyZW50IHNlYXQgcG9zdGlvbnMgYW5kIHNldHRpbmdzIHRvIHNlYXQgbWVtb3J5LlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNBVkUgKCkge1xuICAgICAgICByZXR1cm4gU2VhdE1lbW9yeUFjdGlvblR5cGUuX01BUC5TQVZFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc3RvcmUgLyBhcHBseSB0aGUgc2VhdCBtZW1vcnkgc2V0dGluZ3MgdG8gdGhlIGN1cnJlbnQgc2VhdC5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSRVNUT1JFICgpIHtcbiAgICAgICAgcmV0dXJuIFNlYXRNZW1vcnlBY3Rpb25UeXBlLl9NQVAuUkVTVE9SRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBObyBhY3Rpb24gdG8gYmUgcGVyZm9ybWVkLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5PTkUgKCkge1xuICAgICAgICByZXR1cm4gU2VhdE1lbW9yeUFjdGlvblR5cGUuX01BUC5OT05FO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFNlYXRNZW1vcnlBY3Rpb25UeXBlLl92YWx1ZUZvcktleShrZXksIFNlYXRNZW1vcnlBY3Rpb25UeXBlLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gU2VhdE1lbW9yeUFjdGlvblR5cGUuX2tleUZvclZhbHVlKHZhbHVlLCBTZWF0TWVtb3J5QWN0aW9uVHlwZS5fTUFQKTtcbiAgICB9XG59XG5cblNlYXRNZW1vcnlBY3Rpb25UeXBlLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnU0FWRSc6ICdTQVZFJyxcbiAgICAnUkVTVE9SRSc6ICdSRVNUT1JFJyxcbiAgICAnTk9ORSc6ICdOT05FJyxcbn0pO1xuXG5leHBvcnQgeyBTZWF0TWVtb3J5QWN0aW9uVHlwZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBTZWF0TWVtb3J5QWN0aW9uVHlwZSB9IGZyb20gJy4uL2VudW1zL1NlYXRNZW1vcnlBY3Rpb25UeXBlLmpzJztcblxuY2xhc3MgU2VhdE1lbW9yeUFjdGlvbiBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGlkXG4gICAgICogQHJldHVybiB7U2VhdE1lbW9yeUFjdGlvbn1cbiAgICAgKi9cbiAgICBzZXRJZCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2VhdE1lbW9yeUFjdGlvbi5LRVlfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldElkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNlYXRNZW1vcnlBY3Rpb24uS0VZX0lEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbGFiZWxcbiAgICAgKiBAcmV0dXJuIHtTZWF0TWVtb3J5QWN0aW9ufVxuICAgICAqL1xuICAgIHNldExhYmVsIChsYWJlbCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZWF0TWVtb3J5QWN0aW9uLktFWV9MQUJFTCwgbGFiZWwpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0TGFiZWwgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2VhdE1lbW9yeUFjdGlvbi5LRVlfTEFCRUwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2VhdE1lbW9yeUFjdGlvblR5cGV9IGFjdGlvblxuICAgICAqIEByZXR1cm4ge1NlYXRNZW1vcnlBY3Rpb259XG4gICAgICovXG4gICAgc2V0QWN0aW9uIChhY3Rpb24pIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoU2VhdE1lbW9yeUFjdGlvblR5cGUsIGFjdGlvbik7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNlYXRNZW1vcnlBY3Rpb24uS0VZX0FDVElPTiwgYWN0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U2VhdE1lbW9yeUFjdGlvblR5cGV9XG4gICAgICovXG4gICAgZ2V0QWN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFNlYXRNZW1vcnlBY3Rpb25UeXBlLCBTZWF0TWVtb3J5QWN0aW9uLktFWV9BQ1RJT04pO1xuICAgIH1cbn1cblxuU2VhdE1lbW9yeUFjdGlvbi5LRVlfSUQgPSAnaWQnO1xuU2VhdE1lbW9yeUFjdGlvbi5LRVlfTEFCRUwgPSAnbGFiZWwnO1xuU2VhdE1lbW9yeUFjdGlvbi5LRVlfQUNUSU9OID0gJ2FjdGlvbic7XG5cbmV4cG9ydCB7IFNlYXRNZW1vcnlBY3Rpb24gfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBMaXN0IHBvc3NpYmxlIHpvbmVzIG9mIGEgbXVsdGktY29udG91ciBtYXNzYWdlIHNlYXQuXG4gKiBAdHlwZWRlZiB7RW51bX0gTWFzc2FnZVpvbmVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIE1hc3NhZ2Vab25lIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYWNrIG9mIGEgbXVsdGktY29udG91ciBtYXNzYWdlIHNlYXQuIG9yIFNFQVRfQkFDS1xuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IExVTUJBUiAoKSB7XG4gICAgICAgIHJldHVybiBNYXNzYWdlWm9uZS5fTUFQLkxVTUJBUjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYm90dG9tIGEgbXVsdGktY29udG91ciBtYXNzYWdlIHNlYXQuIG9yIFNFQVRfQk9UVE9NXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU0VBVF9DVVNISU9OICgpIHtcbiAgICAgICAgcmV0dXJuIE1hc3NhZ2Vab25lLl9NQVAuU0VBVF9DVVNISU9OO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIE1hc3NhZ2Vab25lLl92YWx1ZUZvcktleShrZXksIE1hc3NhZ2Vab25lLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gTWFzc2FnZVpvbmUuX2tleUZvclZhbHVlKHZhbHVlLCBNYXNzYWdlWm9uZS5fTUFQKTtcbiAgICB9XG59XG5cbk1hc3NhZ2Vab25lLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnTFVNQkFSJzogJ0xVTUJBUicsXG4gICAgJ1NFQVRfQ1VTSElPTic6ICdTRUFUX0NVU0hJT04nLFxufSk7XG5cbmV4cG9ydCB7IE1hc3NhZ2Vab25lIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogTGlzdCBwb3NzaWJsZSBtb2RlcyBvZiBhIG1hc3NhZ2Ugem9uZS5cbiAqIEB0eXBlZGVmIHtFbnVtfSBNYXNzYWdlTW9kZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgTWFzc2FnZU1vZGUgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgT0ZGICgpIHtcbiAgICAgICAgcmV0dXJuIE1hc3NhZ2VNb2RlLl9NQVAuT0ZGO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IExPVyAoKSB7XG4gICAgICAgIHJldHVybiBNYXNzYWdlTW9kZS5fTUFQLkxPVztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBISUdIICgpIHtcbiAgICAgICAgcmV0dXJuIE1hc3NhZ2VNb2RlLl9NQVAuSElHSDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBNYXNzYWdlTW9kZS5fdmFsdWVGb3JLZXkoa2V5LCBNYXNzYWdlTW9kZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIE1hc3NhZ2VNb2RlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgTWFzc2FnZU1vZGUuX01BUCk7XG4gICAgfVxufVxuXG5NYXNzYWdlTW9kZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ09GRic6ICdPRkYnLFxuICAgICdMT1cnOiAnTE9XJyxcbiAgICAnSElHSCc6ICdISUdIJyxcbn0pO1xuXG5leHBvcnQgeyBNYXNzYWdlTW9kZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBNYXNzYWdlWm9uZSB9IGZyb20gJy4uL2VudW1zL01hc3NhZ2Vab25lLmpzJztcbmltcG9ydCB7IE1hc3NhZ2VNb2RlIH0gZnJvbSAnLi4vZW51bXMvTWFzc2FnZU1vZGUuanMnO1xuXG4vKipcbiAqIFNwZWNpZnkgdGhlIG1vZGUgb2YgYSBtYXNzYWdlIHpvbmUuXG4gKi9cbmNsYXNzIE1hc3NhZ2VNb2RlRGF0YSBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtNYXNzYWdlWm9uZX0gem9uZSAtIExpc3QgcG9zc2libGUgem9uZXMgb2YgYSBtdWx0aS1jb250b3VyIG1hc3NhZ2Ugc2VhdC5cbiAgICAgKiBAcmV0dXJuIHtNYXNzYWdlTW9kZURhdGF9XG4gICAgICovXG4gICAgc2V0TWFzc2FnZVpvbmUgKHpvbmUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTWFzc2FnZVpvbmUsIHpvbmUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihNYXNzYWdlTW9kZURhdGEuS0VZX01BU1NBR0VfWk9ORSwgem9uZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge01hc3NhZ2Vab25lfVxuICAgICAqL1xuICAgIGdldE1hc3NhZ2Vab25lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KE1hc3NhZ2Vab25lLCBNYXNzYWdlTW9kZURhdGEuS0VZX01BU1NBR0VfWk9ORSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtNYXNzYWdlTW9kZX0gbW9kZSAtIExpc3QgcG9zc2libGUgbW9kZXMgb2YgYSBtYXNzYWdlIHpvbmUuXG4gICAgICogQHJldHVybiB7TWFzc2FnZU1vZGVEYXRhfVxuICAgICAqL1xuICAgIHNldE1hc3NhZ2VNb2RlIChtb2RlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKE1hc3NhZ2VNb2RlLCBtb2RlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTWFzc2FnZU1vZGVEYXRhLktFWV9NQVNTQUdFX01PREUsIG1vZGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtNYXNzYWdlTW9kZX1cbiAgICAgKi9cbiAgICBnZXRNYXNzYWdlTW9kZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChNYXNzYWdlTW9kZSwgTWFzc2FnZU1vZGVEYXRhLktFWV9NQVNTQUdFX01PREUpO1xuICAgIH1cbn1cblxuTWFzc2FnZU1vZGVEYXRhLktFWV9NQVNTQUdFX1pPTkUgPSAnbWFzc2FnZVpvbmUnO1xuTWFzc2FnZU1vZGVEYXRhLktFWV9NQVNTQUdFX01PREUgPSAnbWFzc2FnZU1vZGUnO1xuXG5leHBvcnQgeyBNYXNzYWdlTW9kZURhdGEgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBNYXNzYWdlQ3VzaGlvbkZpcm1uZXNzIH0gZnJvbSAnLi9NYXNzYWdlQ3VzaGlvbkZpcm1uZXNzLmpzJztcbmltcG9ydCB7IFN1cHBvcnRlZFNlYXQgfSBmcm9tICcuLi9lbnVtcy9TdXBwb3J0ZWRTZWF0LmpzJztcbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBTZWF0TWVtb3J5QWN0aW9uIH0gZnJvbSAnLi9TZWF0TWVtb3J5QWN0aW9uLmpzJztcbmltcG9ydCB7IE1hc3NhZ2VNb2RlRGF0YSB9IGZyb20gJy4vTWFzc2FnZU1vZGVEYXRhLmpzJztcblxuLyoqXG4gKiBTZWF0IGNvbnRyb2wgZGF0YSBjb3JyZXNwb25kcyB0byBcIlNFQVRcIiBNb2R1bGVUeXBlLlxuICovXG5jbGFzcyBTZWF0Q29udHJvbERhdGEgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3VwcG9ydGVkU2VhdH0gaWQgLSBMaXN0IHBvc3NpYmxlIHNlYXRzIHRoYXQgaXMgYSByZW1vdGUgY29udHJvbGxhYmxlIHNlYXQuXG4gICAgICogQHJldHVybiB7U2VhdENvbnRyb2xEYXRhfVxuICAgICAqL1xuICAgIHNldElkIChpZCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShTdXBwb3J0ZWRTZWF0LCBpZCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNlYXRDb250cm9sRGF0YS5LRVlfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3VwcG9ydGVkU2VhdH1cbiAgICAgKi9cbiAgICBnZXRJZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChTdXBwb3J0ZWRTZWF0LCBTZWF0Q29udHJvbERhdGEuS0VZX0lEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGVuYWJsZWRcbiAgICAgKiBAcmV0dXJuIHtTZWF0Q29udHJvbERhdGF9XG4gICAgICovXG4gICAgc2V0SGVhdGluZ0VuYWJsZWQgKGVuYWJsZWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2VhdENvbnRyb2xEYXRhLktFWV9IRUFUSU5HX0VOQUJMRUQsIGVuYWJsZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEhlYXRpbmdFbmFibGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNlYXRDb250cm9sRGF0YS5LRVlfSEVBVElOR19FTkFCTEVEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGVuYWJsZWRcbiAgICAgKiBAcmV0dXJuIHtTZWF0Q29udHJvbERhdGF9XG4gICAgICovXG4gICAgc2V0Q29vbGluZ0VuYWJsZWQgKGVuYWJsZWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2VhdENvbnRyb2xEYXRhLktFWV9DT09MSU5HX0VOQUJMRUQsIGVuYWJsZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldENvb2xpbmdFbmFibGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNlYXRDb250cm9sRGF0YS5LRVlfQ09PTElOR19FTkFCTEVEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbGV2ZWxcbiAgICAgKiBAcmV0dXJuIHtTZWF0Q29udHJvbERhdGF9XG4gICAgICovXG4gICAgc2V0SGVhdGluZ0xldmVsIChsZXZlbCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZWF0Q29udHJvbERhdGEuS0VZX0hFQVRJTkdfTEVWRUwsIGxldmVsKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldEhlYXRpbmdMZXZlbCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTZWF0Q29udHJvbERhdGEuS0VZX0hFQVRJTkdfTEVWRUwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBsZXZlbFxuICAgICAqIEByZXR1cm4ge1NlYXRDb250cm9sRGF0YX1cbiAgICAgKi9cbiAgICBzZXRDb29saW5nTGV2ZWwgKGxldmVsKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNlYXRDb250cm9sRGF0YS5LRVlfQ09PTElOR19MRVZFTCwgbGV2ZWwpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0Q29vbGluZ0xldmVsICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNlYXRDb250cm9sRGF0YS5LRVlfQ09PTElOR19MRVZFTCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHBvc2l0aW9uXG4gICAgICogQHJldHVybiB7U2VhdENvbnRyb2xEYXRhfVxuICAgICAqL1xuICAgIHNldEhvcml6b250YWxQb3NpdGlvbiAocG9zaXRpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2VhdENvbnRyb2xEYXRhLktFWV9IT1JJWk9OVEFMX1BPU0lUSU9OLCBwb3NpdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRIb3Jpem9udGFsUG9zaXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2VhdENvbnRyb2xEYXRhLktFWV9IT1JJWk9OVEFMX1BPU0lUSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gcG9zaXRpb25cbiAgICAgKiBAcmV0dXJuIHtTZWF0Q29udHJvbERhdGF9XG4gICAgICovXG4gICAgc2V0VmVydGljYWxQb3NpdGlvbiAocG9zaXRpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2VhdENvbnRyb2xEYXRhLktFWV9WRVJUSUNBTF9QT1NJVElPTiwgcG9zaXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0VmVydGljYWxQb3NpdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTZWF0Q29udHJvbERhdGEuS0VZX1ZFUlRJQ0FMX1BPU0lUSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gcG9zaXRpb25cbiAgICAgKiBAcmV0dXJuIHtTZWF0Q29udHJvbERhdGF9XG4gICAgICovXG4gICAgc2V0RnJvbnRWZXJ0aWNhbFBvc2l0aW9uIChwb3NpdGlvbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZWF0Q29udHJvbERhdGEuS0VZX0ZST05UX1ZFUlRJQ0FMX1BPU0lUSU9OLCBwb3NpdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRGcm9udFZlcnRpY2FsUG9zaXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2VhdENvbnRyb2xEYXRhLktFWV9GUk9OVF9WRVJUSUNBTF9QT1NJVElPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHBvc2l0aW9uXG4gICAgICogQHJldHVybiB7U2VhdENvbnRyb2xEYXRhfVxuICAgICAqL1xuICAgIHNldEJhY2tWZXJ0aWNhbFBvc2l0aW9uIChwb3NpdGlvbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZWF0Q29udHJvbERhdGEuS0VZX0JBQ0tfVkVSVElDQUxfUE9TSVRJT04sIHBvc2l0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldEJhY2tWZXJ0aWNhbFBvc2l0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNlYXRDb250cm9sRGF0YS5LRVlfQkFDS19WRVJUSUNBTF9QT1NJVElPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGFuZ2xlXG4gICAgICogQHJldHVybiB7U2VhdENvbnRyb2xEYXRhfVxuICAgICAqL1xuICAgIHNldEJhY2tUaWx0QW5nbGUgKGFuZ2xlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNlYXRDb250cm9sRGF0YS5LRVlfQkFDS19USUxUX0FOR0xFLCBhbmdsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRCYWNrVGlsdEFuZ2xlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNlYXRDb250cm9sRGF0YS5LRVlfQkFDS19USUxUX0FOR0xFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gcG9zaXRpb25cbiAgICAgKiBAcmV0dXJuIHtTZWF0Q29udHJvbERhdGF9XG4gICAgICovXG4gICAgc2V0SGVhZFN1cHBvcnRIb3Jpem9udGFsUG9zaXRpb24gKHBvc2l0aW9uKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNlYXRDb250cm9sRGF0YS5LRVlfSEVBRF9TVVBQT1JUX0hPUklaT05UQUxfUE9TSVRJT04sIHBvc2l0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldEhlYWRTdXBwb3J0SG9yaXpvbnRhbFBvc2l0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNlYXRDb250cm9sRGF0YS5LRVlfSEVBRF9TVVBQT1JUX0hPUklaT05UQUxfUE9TSVRJT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBwb3NpdGlvblxuICAgICAqIEByZXR1cm4ge1NlYXRDb250cm9sRGF0YX1cbiAgICAgKi9cbiAgICBzZXRIZWFkU3VwcG9ydFZlcnRpY2FsUG9zaXRpb24gKHBvc2l0aW9uKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNlYXRDb250cm9sRGF0YS5LRVlfSEVBRF9TVVBQT1JUX1ZFUlRJQ0FMX1BPU0lUSU9OLCBwb3NpdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRIZWFkU3VwcG9ydFZlcnRpY2FsUG9zaXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2VhdENvbnRyb2xEYXRhLktFWV9IRUFEX1NVUFBPUlRfVkVSVElDQUxfUE9TSVRJT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gZW5hYmxlZFxuICAgICAqIEByZXR1cm4ge1NlYXRDb250cm9sRGF0YX1cbiAgICAgKi9cbiAgICBzZXRNYXNzYWdlRW5hYmxlZCAoZW5hYmxlZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZWF0Q29udHJvbERhdGEuS0VZX01BU1NBR0VfRU5BQkxFRCwgZW5hYmxlZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0TWFzc2FnZUVuYWJsZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2VhdENvbnRyb2xEYXRhLktFWV9NQVNTQUdFX0VOQUJMRUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TWFzc2FnZU1vZGVEYXRhW119IG1vZGUgLSBTcGVjaWZ5IHRoZSBtb2RlIG9mIGEgbWFzc2FnZSB6b25lLlxuICAgICAqIEByZXR1cm4ge1NlYXRDb250cm9sRGF0YX1cbiAgICAgKi9cbiAgICBzZXRNYXNzYWdlTW9kZSAobW9kZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShNYXNzYWdlTW9kZURhdGEsIG1vZGUsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZWF0Q29udHJvbERhdGEuS0VZX01BU1NBR0VfTU9ERSwgbW9kZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge01hc3NhZ2VNb2RlRGF0YVtdfVxuICAgICAqL1xuICAgIGdldE1hc3NhZ2VNb2RlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KE1hc3NhZ2VNb2RlRGF0YSwgU2VhdENvbnRyb2xEYXRhLktFWV9NQVNTQUdFX01PREUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TWFzc2FnZUN1c2hpb25GaXJtbmVzc1tdfSBmaXJtbmVzcyAtIFRoZSBpbnRlbnNpdHkgb3IgZmlybW5lc3Mgb2YgYSBjdXNoaW9uLlxuICAgICAqIEByZXR1cm4ge1NlYXRDb250cm9sRGF0YX1cbiAgICAgKi9cbiAgICBzZXRNYXNzYWdlQ3VzaGlvbkZpcm1uZXNzIChmaXJtbmVzcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShNYXNzYWdlQ3VzaGlvbkZpcm1uZXNzLCBmaXJtbmVzcywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNlYXRDb250cm9sRGF0YS5LRVlfTUFTU0FHRV9DVVNISU9OX0ZJUk1ORVNTLCBmaXJtbmVzcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge01hc3NhZ2VDdXNoaW9uRmlybW5lc3NbXX1cbiAgICAgKi9cbiAgICBnZXRNYXNzYWdlQ3VzaGlvbkZpcm1uZXNzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KE1hc3NhZ2VDdXNoaW9uRmlybW5lc3MsIFNlYXRDb250cm9sRGF0YS5LRVlfTUFTU0FHRV9DVVNISU9OX0ZJUk1ORVNTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NlYXRNZW1vcnlBY3Rpb259IG1lbW9yeVxuICAgICAqIEByZXR1cm4ge1NlYXRDb250cm9sRGF0YX1cbiAgICAgKi9cbiAgICBzZXRNZW1vcnkgKG1lbW9yeSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShTZWF0TWVtb3J5QWN0aW9uLCBtZW1vcnkpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZWF0Q29udHJvbERhdGEuS0VZX01FTU9SWSwgbWVtb3J5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U2VhdE1lbW9yeUFjdGlvbn1cbiAgICAgKi9cbiAgICBnZXRNZW1vcnkgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoU2VhdE1lbW9yeUFjdGlvbiwgU2VhdENvbnRyb2xEYXRhLktFWV9NRU1PUlkpO1xuICAgIH1cbn1cblxuU2VhdENvbnRyb2xEYXRhLktFWV9JRCA9ICdpZCc7XG5TZWF0Q29udHJvbERhdGEuS0VZX0hFQVRJTkdfRU5BQkxFRCA9ICdoZWF0aW5nRW5hYmxlZCc7XG5TZWF0Q29udHJvbERhdGEuS0VZX0NPT0xJTkdfRU5BQkxFRCA9ICdjb29saW5nRW5hYmxlZCc7XG5TZWF0Q29udHJvbERhdGEuS0VZX0hFQVRJTkdfTEVWRUwgPSAnaGVhdGluZ0xldmVsJztcblNlYXRDb250cm9sRGF0YS5LRVlfQ09PTElOR19MRVZFTCA9ICdjb29saW5nTGV2ZWwnO1xuU2VhdENvbnRyb2xEYXRhLktFWV9IT1JJWk9OVEFMX1BPU0lUSU9OID0gJ2hvcml6b250YWxQb3NpdGlvbic7XG5TZWF0Q29udHJvbERhdGEuS0VZX1ZFUlRJQ0FMX1BPU0lUSU9OID0gJ3ZlcnRpY2FsUG9zaXRpb24nO1xuU2VhdENvbnRyb2xEYXRhLktFWV9GUk9OVF9WRVJUSUNBTF9QT1NJVElPTiA9ICdmcm9udFZlcnRpY2FsUG9zaXRpb24nO1xuU2VhdENvbnRyb2xEYXRhLktFWV9CQUNLX1ZFUlRJQ0FMX1BPU0lUSU9OID0gJ2JhY2tWZXJ0aWNhbFBvc2l0aW9uJztcblNlYXRDb250cm9sRGF0YS5LRVlfQkFDS19USUxUX0FOR0xFID0gJ2JhY2tUaWx0QW5nbGUnO1xuU2VhdENvbnRyb2xEYXRhLktFWV9IRUFEX1NVUFBPUlRfSE9SSVpPTlRBTF9QT1NJVElPTiA9ICdoZWFkU3VwcG9ydEhvcml6b250YWxQb3NpdGlvbic7XG5TZWF0Q29udHJvbERhdGEuS0VZX0hFQURfU1VQUE9SVF9WRVJUSUNBTF9QT1NJVElPTiA9ICdoZWFkU3VwcG9ydFZlcnRpY2FsUG9zaXRpb24nO1xuU2VhdENvbnRyb2xEYXRhLktFWV9NQVNTQUdFX0VOQUJMRUQgPSAnbWFzc2FnZUVuYWJsZWQnO1xuU2VhdENvbnRyb2xEYXRhLktFWV9NQVNTQUdFX01PREUgPSAnbWFzc2FnZU1vZGUnO1xuU2VhdENvbnRyb2xEYXRhLktFWV9NQVNTQUdFX0NVU0hJT05fRklSTU5FU1MgPSAnbWFzc2FnZUN1c2hpb25GaXJtbmVzcyc7XG5TZWF0Q29udHJvbERhdGEuS0VZX01FTU9SWSA9ICdtZW1vcnknO1xuXG5leHBvcnQgeyBTZWF0Q29udHJvbERhdGEgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gTGlnaHRTdGF0dXNcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIExpZ2h0U3RhdHVzIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE9OICgpIHtcbiAgICAgICAgcmV0dXJuIExpZ2h0U3RhdHVzLl9NQVAuT047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgT0ZGICgpIHtcbiAgICAgICAgcmV0dXJuIExpZ2h0U3RhdHVzLl9NQVAuT0ZGO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJBTVBfVVAgKCkge1xuICAgICAgICByZXR1cm4gTGlnaHRTdGF0dXMuX01BUC5SQU1QX1VQO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJBTVBfRE9XTiAoKSB7XG4gICAgICAgIHJldHVybiBMaWdodFN0YXR1cy5fTUFQLlJBTVBfRE9XTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBVTktOT1dOICgpIHtcbiAgICAgICAgcmV0dXJuIExpZ2h0U3RhdHVzLl9NQVAuVU5LTk9XTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBJTlZBTElEICgpIHtcbiAgICAgICAgcmV0dXJuIExpZ2h0U3RhdHVzLl9NQVAuSU5WQUxJRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBMaWdodFN0YXR1cy5fdmFsdWVGb3JLZXkoa2V5LCBMaWdodFN0YXR1cy5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIExpZ2h0U3RhdHVzLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgTGlnaHRTdGF0dXMuX01BUCk7XG4gICAgfVxufVxuXG5MaWdodFN0YXR1cy5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ09OJzogJ09OJyxcbiAgICAnT0ZGJzogJ09GRicsXG4gICAgJ1JBTVBfVVAnOiAnUkFNUF9VUCcsXG4gICAgJ1JBTVBfRE9XTic6ICdSQU1QX0RPV04nLFxuICAgICdVTktOT1dOJzogJ1VOS05PV04nLFxuICAgICdJTlZBTElEJzogJ0lOVkFMSUQnLFxufSk7XG5cbmV4cG9ydCB7IExpZ2h0U3RhdHVzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYge0VudW19IExpZ2h0TmFtZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgTGlnaHROYW1lIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEZST05UX0xFRlRfSElHSF9CRUFNICgpIHtcbiAgICAgICAgcmV0dXJuIExpZ2h0TmFtZS5fTUFQLkZST05UX0xFRlRfSElHSF9CRUFNO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEZST05UX1JJR0hUX0hJR0hfQkVBTSAoKSB7XG4gICAgICAgIHJldHVybiBMaWdodE5hbWUuX01BUC5GUk9OVF9SSUdIVF9ISUdIX0JFQU07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRlJPTlRfTEVGVF9MT1dfQkVBTSAoKSB7XG4gICAgICAgIHJldHVybiBMaWdodE5hbWUuX01BUC5GUk9OVF9MRUZUX0xPV19CRUFNO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEZST05UX1JJR0hUX0xPV19CRUFNICgpIHtcbiAgICAgICAgcmV0dXJuIExpZ2h0TmFtZS5fTUFQLkZST05UX1JJR0hUX0xPV19CRUFNO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEZST05UX0xFRlRfUEFSS0lOR19MSUdIVCAoKSB7XG4gICAgICAgIHJldHVybiBMaWdodE5hbWUuX01BUC5GUk9OVF9MRUZUX1BBUktJTkdfTElHSFQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRlJPTlRfUklHSFRfUEFSS0lOR19MSUdIVCAoKSB7XG4gICAgICAgIHJldHVybiBMaWdodE5hbWUuX01BUC5GUk9OVF9SSUdIVF9QQVJLSU5HX0xJR0hUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEZST05UX0xFRlRfRk9HX0xJR0hUICgpIHtcbiAgICAgICAgcmV0dXJuIExpZ2h0TmFtZS5fTUFQLkZST05UX0xFRlRfRk9HX0xJR0hUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEZST05UX1JJR0hUX0ZPR19MSUdIVCAoKSB7XG4gICAgICAgIHJldHVybiBMaWdodE5hbWUuX01BUC5GUk9OVF9SSUdIVF9GT0dfTElHSFQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRlJPTlRfTEVGVF9EQVlUSU1FX1JVTk5JTkdfTElHSFQgKCkge1xuICAgICAgICByZXR1cm4gTGlnaHROYW1lLl9NQVAuRlJPTlRfTEVGVF9EQVlUSU1FX1JVTk5JTkdfTElHSFQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRlJPTlRfUklHSFRfREFZVElNRV9SVU5OSU5HX0xJR0hUICgpIHtcbiAgICAgICAgcmV0dXJuIExpZ2h0TmFtZS5fTUFQLkZST05UX1JJR0hUX0RBWVRJTUVfUlVOTklOR19MSUdIVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBGUk9OVF9MRUZUX1RVUk5fTElHSFQgKCkge1xuICAgICAgICByZXR1cm4gTGlnaHROYW1lLl9NQVAuRlJPTlRfTEVGVF9UVVJOX0xJR0hUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEZST05UX1JJR0hUX1RVUk5fTElHSFQgKCkge1xuICAgICAgICByZXR1cm4gTGlnaHROYW1lLl9NQVAuRlJPTlRfUklHSFRfVFVSTl9MSUdIVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSRUFSX0xFRlRfRk9HX0xJR0hUICgpIHtcbiAgICAgICAgcmV0dXJuIExpZ2h0TmFtZS5fTUFQLlJFQVJfTEVGVF9GT0dfTElHSFQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUkVBUl9SSUdIVF9GT0dfTElHSFQgKCkge1xuICAgICAgICByZXR1cm4gTGlnaHROYW1lLl9NQVAuUkVBUl9SSUdIVF9GT0dfTElHSFQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUkVBUl9MRUZUX1RBSUxfTElHSFQgKCkge1xuICAgICAgICByZXR1cm4gTGlnaHROYW1lLl9NQVAuUkVBUl9MRUZUX1RBSUxfTElHSFQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUkVBUl9SSUdIVF9UQUlMX0xJR0hUICgpIHtcbiAgICAgICAgcmV0dXJuIExpZ2h0TmFtZS5fTUFQLlJFQVJfUklHSFRfVEFJTF9MSUdIVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSRUFSX0xFRlRfQlJBS0VfTElHSFQgKCkge1xuICAgICAgICByZXR1cm4gTGlnaHROYW1lLl9NQVAuUkVBUl9MRUZUX0JSQUtFX0xJR0hUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJFQVJfUklHSFRfQlJBS0VfTElHSFQgKCkge1xuICAgICAgICByZXR1cm4gTGlnaHROYW1lLl9NQVAuUkVBUl9SSUdIVF9CUkFLRV9MSUdIVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSRUFSX0xFRlRfVFVSTl9MSUdIVCAoKSB7XG4gICAgICAgIHJldHVybiBMaWdodE5hbWUuX01BUC5SRUFSX0xFRlRfVFVSTl9MSUdIVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSRUFSX1JJR0hUX1RVUk5fTElHSFQgKCkge1xuICAgICAgICByZXR1cm4gTGlnaHROYW1lLl9NQVAuUkVBUl9SSUdIVF9UVVJOX0xJR0hUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJFQVJfUkVHSVNUUkFUSU9OX1BMQVRFX0xJR0hUICgpIHtcbiAgICAgICAgcmV0dXJuIExpZ2h0TmFtZS5fTUFQLlJFQVJfUkVHSVNUUkFUSU9OX1BMQVRFX0xJR0hUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEluY2x1ZGUgYWxsIGhpZ2ggYmVhbSBsaWdodHM6IGZyb250X2xlZnQgYW5kIGZyb250X3JpZ2h0LlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEhJR0hfQkVBTVMgKCkge1xuICAgICAgICByZXR1cm4gTGlnaHROYW1lLl9NQVAuSElHSF9CRUFNUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbmNsdWRlIGFsbCBsb3cgYmVhbSBsaWdodHM6IGZyb250X2xlZnQgYW5kIGZyb250X3JpZ2h0LlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IExPV19CRUFNUyAoKSB7XG4gICAgICAgIHJldHVybiBMaWdodE5hbWUuX01BUC5MT1dfQkVBTVM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW5jbHVkZSBhbGwgZm9nIGxpZ2h0czogZnJvbnRfbGVmdCwgZnJvbnRfcmlnaHQsIHJlYXJfbGVmdCBhbmQgcmVhcl9yaWdodC5cbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBGT0dfTElHSFRTICgpIHtcbiAgICAgICAgcmV0dXJuIExpZ2h0TmFtZS5fTUFQLkZPR19MSUdIVFM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW5jbHVkZSBhbGwgZGF5dGltZSBydW5uaW5nIGxpZ2h0czogZnJvbnRfbGVmdCBhbmQgZnJvbnRfcmlnaHQuXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUlVOTklOR19MSUdIVFMgKCkge1xuICAgICAgICByZXR1cm4gTGlnaHROYW1lLl9NQVAuUlVOTklOR19MSUdIVFM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW5jbHVkZSBhbGwgcGFya2luZyBsaWdodHM6IGZyb250X2xlZnQgYW5kIGZyb250X3JpZ2h0LlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFBBUktJTkdfTElHSFRTICgpIHtcbiAgICAgICAgcmV0dXJuIExpZ2h0TmFtZS5fTUFQLlBBUktJTkdfTElHSFRTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEluY2x1ZGUgYWxsIGJyYWtlIGxpZ2h0czogcmVhcl9sZWZ0IGFuZCByZWFyX3JpZ2h0LlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEJSQUtFX0xJR0hUUyAoKSB7XG4gICAgICAgIHJldHVybiBMaWdodE5hbWUuX01BUC5CUkFLRV9MSUdIVFM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUkVBUl9SRVZFUlNJTkdfTElHSFRTICgpIHtcbiAgICAgICAgcmV0dXJuIExpZ2h0TmFtZS5fTUFQLlJFQVJfUkVWRVJTSU5HX0xJR0hUUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTSURFX01BUktFUl9MSUdIVFMgKCkge1xuICAgICAgICByZXR1cm4gTGlnaHROYW1lLl9NQVAuU0lERV9NQVJLRVJfTElHSFRTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEluY2x1ZGUgYWxsIGxlZnQgdHVybiBzaWduYWwgbGlnaHRzOiBmcm9udF9sZWZ0LCByZWFyX2xlZnQsIGxlZnRfc2lkZSBhbmQgbWlycm9yX21vdW50ZWQuXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTEVGVF9UVVJOX0xJR0hUUyAoKSB7XG4gICAgICAgIHJldHVybiBMaWdodE5hbWUuX01BUC5MRUZUX1RVUk5fTElHSFRTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEluY2x1ZGUgYWxsIHJpZ2h0IHR1cm4gc2lnbmFsIGxpZ2h0czogZnJvbnRfcmlnaHQsIHJlYXJfcmlnaHQsIHJpZ2h0X3NpZGUgYW5kIG1pcnJvcl9tb3VudGVkLlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJJR0hUX1RVUk5fTElHSFRTICgpIHtcbiAgICAgICAgcmV0dXJuIExpZ2h0TmFtZS5fTUFQLlJJR0hUX1RVUk5fTElHSFRTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEluY2x1ZGUgYWxsIGhhemFyZCBsaWdodHM6IGZyb250X2xlZnQsIGZyb250X3JpZ2h0LCByZWFyX2xlZnQgYW5kIHJlYXJfcmlnaHQuXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSEFaQVJEX0xJR0hUUyAoKSB7XG4gICAgICAgIHJldHVybiBMaWdodE5hbWUuX01BUC5IQVpBUkRfTElHSFRTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhcmdvIGxhbXBzIGlsbHVtaW5hdGUgdGhlIGNhcmdvIGFyZWEuXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUkVBUl9DQVJHT19MSUdIVFMgKCkge1xuICAgICAgICByZXR1cm4gTGlnaHROYW1lLl9NQVAuUkVBUl9DQVJHT19MSUdIVFM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJ1Y2sgYmVkIGxhbXBzIGxpZ2h0IHVwIHRoZSBiZWQgb2YgdGhlIHRydWNrLlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJFQVJfVFJVQ0tfQkVEX0xJR0hUUyAoKSB7XG4gICAgICAgIHJldHVybiBMaWdodE5hbWUuX01BUC5SRUFSX1RSVUNLX0JFRF9MSUdIVFM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJhaWxlciBsaWdodHMgYXJlIGxhbXBzIG1vdW50ZWQgb24gYSB0cmFpbGVyIGhpdGNoLlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJFQVJfVFJBSUxFUl9MSUdIVFMgKCkge1xuICAgICAgICByZXR1cm4gTGlnaHROYW1lLl9NQVAuUkVBUl9UUkFJTEVSX0xJR0hUUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJdCBpcyB0aGUgc3BvdGxpZ2h0cyBtb3VudGVkIG9uIHRoZSBsZWZ0IHNpZGUgb2YgYSB2ZWhpY2xlLlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IExFRlRfU1BPVF9MSUdIVFMgKCkge1xuICAgICAgICByZXR1cm4gTGlnaHROYW1lLl9NQVAuTEVGVF9TUE9UX0xJR0hUUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJdCBpcyB0aGUgc3BvdGxpZ2h0cyBtb3VudGVkIG9uIHRoZSByaWdodCBzaWRlIG9mIGEgdmVoaWNsZS5cbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSSUdIVF9TUE9UX0xJR0hUUyAoKSB7XG4gICAgICAgIHJldHVybiBMaWdodE5hbWUuX01BUC5SSUdIVF9TUE9UX0xJR0hUUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQdWRkbGUgbGFtcHMgaWxsdW1pbmF0ZSB0aGUgZ3JvdW5kIGJlc2lkZSB0aGUgZG9vciBhcyB0aGUgY3VzdG9tZXIgaXMgb3BlbmluZyBvciBhcHByb2FjaGluZyB0aGUgZG9vci5cbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBMRUZUX1BVRERMRV9MSUdIVFMgKCkge1xuICAgICAgICByZXR1cm4gTGlnaHROYW1lLl9NQVAuTEVGVF9QVURETEVfTElHSFRTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFB1ZGRsZSBsYW1wcyBpbGx1bWluYXRlIHRoZSBncm91bmQgYmVzaWRlIHRoZSBkb29yIGFzIHRoZSBjdXN0b21lciBpcyBvcGVuaW5nIG9yIGFwcHJvYWNoaW5nIHRoZSBkb29yLlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJJR0hUX1BVRERMRV9MSUdIVFMgKCkge1xuICAgICAgICByZXR1cm4gTGlnaHROYW1lLl9NQVAuUklHSFRfUFVERExFX0xJR0hUUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBBTUJJRU5UX0xJR0hUUyAoKSB7XG4gICAgICAgIHJldHVybiBMaWdodE5hbWUuX01BUC5BTUJJRU5UX0xJR0hUUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBPVkVSSEVBRF9MSUdIVFMgKCkge1xuICAgICAgICByZXR1cm4gTGlnaHROYW1lLl9NQVAuT1ZFUkhFQURfTElHSFRTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJFQURJTkdfTElHSFRTICgpIHtcbiAgICAgICAgcmV0dXJuIExpZ2h0TmFtZS5fTUFQLlJFQURJTkdfTElHSFRTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFRSVU5LX0xJR0hUUyAoKSB7XG4gICAgICAgIHJldHVybiBMaWdodE5hbWUuX01BUC5UUlVOS19MSUdIVFM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW5jbHVkZSBleHRlcmlvciBsaWdodHMgbG9jYXRlZCBpbiBmcm9udCBvZiB0aGUgdmVoaWNsZS4gRm9yIGV4YW1wbGUsIGZvZyBsaWdodHMgYW5kIGxvdyBiZWFtcy5cbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFWFRFUklPUl9GUk9OVF9MSUdIVFMgKCkge1xuICAgICAgICByZXR1cm4gTGlnaHROYW1lLl9NQVAuRVhURVJJT1JfRlJPTlRfTElHSFRTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEluY2x1ZGUgZXh0ZXJpb3IgbGlnaHRzIGxvY2F0ZWQgYXQgdGhlIGJhY2sgb2YgdGhlIHZlaGljbGUuIEZvciBleGFtcGxlLCBsaWNlbnNlIHBsYXRlIGxpZ2h0cywgcmV2ZXJzZSBsaWdodHMsXG4gICAgICogY2FyZ28gbGlnaHRzLCBiZWQgbGlnaHRzIGFuZCB0cmFpbGVyIGFzc2lzdCBsaWdodHMuXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRVhURVJJT1JfUkVBUl9MSUdIVFMgKCkge1xuICAgICAgICByZXR1cm4gTGlnaHROYW1lLl9NQVAuRVhURVJJT1JfUkVBUl9MSUdIVFM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW5jbHVkZSBleHRlcmlvciBsaWdodHMgbG9jYXRlZCBhdCB0aGUgbGVmdCBzaWRlIG9mIHRoZSB2ZWhpY2xlLiBGb3IgZXhhbXBsZSwgbGVmdCBwdWRkbGUgbGlnaHRzIGFuZCBzcG90XG4gICAgICogbGlnaHRzLlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEVYVEVSSU9SX0xFRlRfTElHSFRTICgpIHtcbiAgICAgICAgcmV0dXJuIExpZ2h0TmFtZS5fTUFQLkVYVEVSSU9SX0xFRlRfTElHSFRTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEluY2x1ZGUgZXh0ZXJpb3IgbGlnaHRzIGxvY2F0ZWQgYXQgdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIHZlaGljbGUuIEZvciBleGFtcGxlLCByaWdodCBwdWRkbGUgbGlnaHRzIGFuZCBzcG90XG4gICAgICogbGlnaHRzLlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEVYVEVSSU9SX1JJR0hUX0xJR0hUUyAoKSB7XG4gICAgICAgIHJldHVybiBMaWdodE5hbWUuX01BUC5FWFRFUklPUl9SSUdIVF9MSUdIVFM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW5jbHVkZSBhbGwgZXh0ZXJpb3IgbGlnaHRzIGFyb3VuZCB0aGUgdmVoaWNsZS5cbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFWFRFUklPUl9BTExfTElHSFRTICgpIHtcbiAgICAgICAgcmV0dXJuIExpZ2h0TmFtZS5fTUFQLkVYVEVSSU9SX0FMTF9MSUdIVFM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gTGlnaHROYW1lLl92YWx1ZUZvcktleShrZXksIExpZ2h0TmFtZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIExpZ2h0TmFtZS5fa2V5Rm9yVmFsdWUodmFsdWUsIExpZ2h0TmFtZS5fTUFQKTtcbiAgICB9XG59XG5cbkxpZ2h0TmFtZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0ZST05UX0xFRlRfSElHSF9CRUFNJzogMCxcbiAgICAnRlJPTlRfUklHSFRfSElHSF9CRUFNJzogMSxcbiAgICAnRlJPTlRfTEVGVF9MT1dfQkVBTSc6IDIsXG4gICAgJ0ZST05UX1JJR0hUX0xPV19CRUFNJzogMyxcbiAgICAnRlJPTlRfTEVGVF9QQVJLSU5HX0xJR0hUJzogNCxcbiAgICAnRlJPTlRfUklHSFRfUEFSS0lOR19MSUdIVCc6IDUsXG4gICAgJ0ZST05UX0xFRlRfRk9HX0xJR0hUJzogNixcbiAgICAnRlJPTlRfUklHSFRfRk9HX0xJR0hUJzogNyxcbiAgICAnRlJPTlRfTEVGVF9EQVlUSU1FX1JVTk5JTkdfTElHSFQnOiA4LFxuICAgICdGUk9OVF9SSUdIVF9EQVlUSU1FX1JVTk5JTkdfTElHSFQnOiA5LFxuICAgICdGUk9OVF9MRUZUX1RVUk5fTElHSFQnOiAxMCxcbiAgICAnRlJPTlRfUklHSFRfVFVSTl9MSUdIVCc6IDExLFxuICAgICdSRUFSX0xFRlRfRk9HX0xJR0hUJzogMTIsXG4gICAgJ1JFQVJfUklHSFRfRk9HX0xJR0hUJzogMTMsXG4gICAgJ1JFQVJfTEVGVF9UQUlMX0xJR0hUJzogMTQsXG4gICAgJ1JFQVJfUklHSFRfVEFJTF9MSUdIVCc6IDE1LFxuICAgICdSRUFSX0xFRlRfQlJBS0VfTElHSFQnOiAxNixcbiAgICAnUkVBUl9SSUdIVF9CUkFLRV9MSUdIVCc6IDE3LFxuICAgICdSRUFSX0xFRlRfVFVSTl9MSUdIVCc6IDE4LFxuICAgICdSRUFSX1JJR0hUX1RVUk5fTElHSFQnOiAxOSxcbiAgICAnUkVBUl9SRUdJU1RSQVRJT05fUExBVEVfTElHSFQnOiAyMCxcbiAgICAnSElHSF9CRUFNUyc6IDUwMSxcbiAgICAnTE9XX0JFQU1TJzogNTAyLFxuICAgICdGT0dfTElHSFRTJzogNTAzLFxuICAgICdSVU5OSU5HX0xJR0hUUyc6IDUwNCxcbiAgICAnUEFSS0lOR19MSUdIVFMnOiA1MDUsXG4gICAgJ0JSQUtFX0xJR0hUUyc6IDUwNixcbiAgICAnUkVBUl9SRVZFUlNJTkdfTElHSFRTJzogNTA3LFxuICAgICdTSURFX01BUktFUl9MSUdIVFMnOiA1MDgsXG4gICAgJ0xFRlRfVFVSTl9MSUdIVFMnOiA1MDksXG4gICAgJ1JJR0hUX1RVUk5fTElHSFRTJzogNTEwLFxuICAgICdIQVpBUkRfTElHSFRTJzogNTExLFxuICAgICdSRUFSX0NBUkdPX0xJR0hUUyc6IDUxMixcbiAgICAnUkVBUl9UUlVDS19CRURfTElHSFRTJzogNTEzLFxuICAgICdSRUFSX1RSQUlMRVJfTElHSFRTJzogNTE0LFxuICAgICdMRUZUX1NQT1RfTElHSFRTJzogNTE1LFxuICAgICdSSUdIVF9TUE9UX0xJR0hUUyc6IDUxNixcbiAgICAnTEVGVF9QVURETEVfTElHSFRTJzogNTE3LFxuICAgICdSSUdIVF9QVURETEVfTElHSFRTJzogNTE4LFxuICAgICdBTUJJRU5UX0xJR0hUUyc6IDgwMSxcbiAgICAnT1ZFUkhFQURfTElHSFRTJzogODAyLFxuICAgICdSRUFESU5HX0xJR0hUUyc6IDgwMyxcbiAgICAnVFJVTktfTElHSFRTJzogODA0LFxuICAgICdFWFRFUklPUl9GUk9OVF9MSUdIVFMnOiA5MDEsXG4gICAgJ0VYVEVSSU9SX1JFQVJfTElHSFRTJzogOTAyLFxuICAgICdFWFRFUklPUl9MRUZUX0xJR0hUUyc6IDkwMyxcbiAgICAnRVhURVJJT1JfUklHSFRfTElHSFRTJzogOTA0LFxuICAgICdFWFRFUklPUl9BTExfTElHSFRTJzogOTA1LFxufSk7XG5cbmV4cG9ydCB7IExpZ2h0TmFtZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBMaWdodFN0YXR1cyB9IGZyb20gJy4uL2VudW1zL0xpZ2h0U3RhdHVzLmpzJztcbmltcG9ydCB7IExpZ2h0TmFtZSB9IGZyb20gJy4uL2VudW1zL0xpZ2h0TmFtZS5qcyc7XG5pbXBvcnQgeyBSR0JDb2xvciB9IGZyb20gJy4vUkdCQ29sb3IuanMnO1xuXG5jbGFzcyBMaWdodFN0YXRlIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0xpZ2h0TmFtZX0gaWQgLSBUaGUgbmFtZSBvZiBhIGxpZ2h0IG9yIGEgZ3JvdXAgb2YgbGlnaHRzLlxuICAgICAqIEByZXR1cm4ge0xpZ2h0U3RhdGV9XG4gICAgICovXG4gICAgc2V0SWQgKGlkKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKExpZ2h0TmFtZSwgaWQpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihMaWdodFN0YXRlLktFWV9JRCwgaWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtMaWdodE5hbWV9XG4gICAgICovXG4gICAgZ2V0SWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTGlnaHROYW1lLCBMaWdodFN0YXRlLktFWV9JRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtMaWdodFN0YXR1c30gc3RhdHVzXG4gICAgICogQHJldHVybiB7TGlnaHRTdGF0ZX1cbiAgICAgKi9cbiAgICBzZXRTdGF0dXMgKHN0YXR1cykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShMaWdodFN0YXR1cywgc3RhdHVzKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTGlnaHRTdGF0ZS5LRVlfU1RBVFVTLCBzdGF0dXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtMaWdodFN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRTdGF0dXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTGlnaHRTdGF0dXMsIExpZ2h0U3RhdGUuS0VZX1NUQVRVUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGRlbnNpdHlcbiAgICAgKiBAcmV0dXJuIHtMaWdodFN0YXRlfVxuICAgICAqL1xuICAgIHNldERlbnNpdHkgKGRlbnNpdHkpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTGlnaHRTdGF0ZS5LRVlfREVOU0lUWSwgZGVuc2l0eSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXREZW5zaXR5ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKExpZ2h0U3RhdGUuS0VZX0RFTlNJVFkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7UkdCQ29sb3J9IGNvbG9yXG4gICAgICogQHJldHVybiB7TGlnaHRTdGF0ZX1cbiAgICAgKi9cbiAgICBzZXRDb2xvciAoY29sb3IpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoUkdCQ29sb3IsIGNvbG9yKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTGlnaHRTdGF0ZS5LRVlfQ09MT1IsIGNvbG9yKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7UkdCQ29sb3J9XG4gICAgICovXG4gICAgZ2V0Q29sb3IgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoUkdCQ29sb3IsIExpZ2h0U3RhdGUuS0VZX0NPTE9SKTtcbiAgICB9XG59XG5cbkxpZ2h0U3RhdGUuS0VZX0lEID0gJ2lkJztcbkxpZ2h0U3RhdGUuS0VZX1NUQVRVUyA9ICdzdGF0dXMnO1xuTGlnaHRTdGF0ZS5LRVlfREVOU0lUWSA9ICdkZW5zaXR5JztcbkxpZ2h0U3RhdGUuS0VZX0NPTE9SID0gJ2NvbG9yJztcblxuZXhwb3J0IHsgTGlnaHRTdGF0ZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBMaWdodFN0YXRlIH0gZnJvbSAnLi9MaWdodFN0YXRlLmpzJztcblxuY2xhc3MgTGlnaHRDb250cm9sRGF0YSBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtMaWdodFN0YXRlW119IHN0YXRlIC0gQW4gYXJyYXkgb2YgTGlnaHROYW1lcyBhbmQgdGhlaXIgY3VycmVudCBvciBkZXNpcmVkIHN0YXR1cy4gTm8gY2hhbmdlIHRvIHRoZSBzdGF0dXNcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZiB0aGUgTGlnaHROYW1lcyB0aGF0IGFyZSBub3QgbGlzdGVkIGluIHRoZSBhcnJheS5cbiAgICAgKiBAcmV0dXJuIHtMaWdodENvbnRyb2xEYXRhfVxuICAgICAqL1xuICAgIHNldExpZ2h0U3RhdGUgKHN0YXRlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKExpZ2h0U3RhdGUsIHN0YXRlLCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTGlnaHRDb250cm9sRGF0YS5LRVlfTElHSFRfU1RBVEUsIHN0YXRlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TGlnaHRTdGF0ZVtdfVxuICAgICAqL1xuICAgIGdldExpZ2h0U3RhdGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTGlnaHRTdGF0ZSwgTGlnaHRDb250cm9sRGF0YS5LRVlfTElHSFRfU1RBVEUpO1xuICAgIH1cbn1cblxuTGlnaHRDb250cm9sRGF0YS5LRVlfTElHSFRfU1RBVEUgPSAnbGlnaHRTdGF0ZSc7XG5cbmV4cG9ydCB7IExpZ2h0Q29udHJvbERhdGEgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBITUlTZXR0aW5nc0NvbnRyb2xEYXRhIH0gZnJvbSAnLi9ITUlTZXR0aW5nc0NvbnRyb2xEYXRhLmpzJztcbmltcG9ydCB7IFJhZGlvQ29udHJvbERhdGEgfSBmcm9tICcuL1JhZGlvQ29udHJvbERhdGEuanMnO1xuaW1wb3J0IHsgTW9kdWxlVHlwZSB9IGZyb20gJy4uL2VudW1zL01vZHVsZVR5cGUuanMnO1xuaW1wb3J0IHsgQ2xpbWF0ZUNvbnRyb2xEYXRhIH0gZnJvbSAnLi9DbGltYXRlQ29udHJvbERhdGEuanMnO1xuaW1wb3J0IHsgQXVkaW9Db250cm9sRGF0YSB9IGZyb20gJy4vQXVkaW9Db250cm9sRGF0YS5qcyc7XG5pbXBvcnQgeyBTZWF0Q29udHJvbERhdGEgfSBmcm9tICcuL1NlYXRDb250cm9sRGF0YS5qcyc7XG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgTGlnaHRDb250cm9sRGF0YSB9IGZyb20gJy4vTGlnaHRDb250cm9sRGF0YS5qcyc7XG5cbi8qKlxuICogVGhlIG1vZHVsZVR5cGUgaW5kaWNhdGVzIHdoaWNoIHR5cGUgb2YgZGF0YSBzaG91bGQgYmUgY2hhbmdlZCBhbmQgaWRlbnRpZmllcyB3aGljaCBkYXRhIG9iamVjdCBleGlzdHMgaW4gdGhpc1xuICogc3RydWN0LiBGb3IgZXhhbXBsZSwgaWYgdGhlIG1vZHVsZVR5cGUgaXMgQ0xJTUFURSB0aGVuIGEgXCJjbGltYXRlQ29udHJvbERhdGFcIiBzaG91bGQgZXhpc3RcbiAqL1xuY2xhc3MgTW9kdWxlRGF0YSBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtNb2R1bGVUeXBlfSB0eXBlXG4gICAgICogQHJldHVybiB7TW9kdWxlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRNb2R1bGVUeXBlICh0eXBlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKE1vZHVsZVR5cGUsIHR5cGUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihNb2R1bGVEYXRhLktFWV9NT0RVTEVfVFlQRSwgdHlwZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge01vZHVsZVR5cGV9XG4gICAgICovXG4gICAgZ2V0TW9kdWxlVHlwZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChNb2R1bGVUeXBlLCBNb2R1bGVEYXRhLktFWV9NT0RVTEVfVFlQRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGlkIC0gSWQgb2YgYSBtb2R1bGUsIHB1Ymxpc2hlZCBieSBTeXN0ZW0gQ2FwYWJpbGl0eS5cbiAgICAgKiBAcmV0dXJuIHtNb2R1bGVEYXRhfVxuICAgICAqL1xuICAgIHNldE1vZHVsZUlkIChpZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihNb2R1bGVEYXRhLktFWV9NT0RVTEVfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldE1vZHVsZUlkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE1vZHVsZURhdGEuS0VZX01PRFVMRV9JRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtSYWRpb0NvbnRyb2xEYXRhfSBkYXRhXG4gICAgICogQHJldHVybiB7TW9kdWxlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRSYWRpb0NvbnRyb2xEYXRhIChkYXRhKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFJhZGlvQ29udHJvbERhdGEsIGRhdGEpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihNb2R1bGVEYXRhLktFWV9SQURJT19DT05UUk9MX0RBVEEsIGRhdGEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtSYWRpb0NvbnRyb2xEYXRhfVxuICAgICAqL1xuICAgIGdldFJhZGlvQ29udHJvbERhdGEgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoUmFkaW9Db250cm9sRGF0YSwgTW9kdWxlRGF0YS5LRVlfUkFESU9fQ09OVFJPTF9EQVRBKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0NsaW1hdGVDb250cm9sRGF0YX0gZGF0YVxuICAgICAqIEByZXR1cm4ge01vZHVsZURhdGF9XG4gICAgICovXG4gICAgc2V0Q2xpbWF0ZUNvbnRyb2xEYXRhIChkYXRhKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKENsaW1hdGVDb250cm9sRGF0YSwgZGF0YSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE1vZHVsZURhdGEuS0VZX0NMSU1BVEVfQ09OVFJPTF9EQVRBLCBkYXRhKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Q2xpbWF0ZUNvbnRyb2xEYXRhfVxuICAgICAqL1xuICAgIGdldENsaW1hdGVDb250cm9sRGF0YSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChDbGltYXRlQ29udHJvbERhdGEsIE1vZHVsZURhdGEuS0VZX0NMSU1BVEVfQ09OVFJPTF9EQVRBKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NlYXRDb250cm9sRGF0YX0gZGF0YSAtIFNlYXQgY29udHJvbCBkYXRhIGNvcnJlc3BvbmRzIHRvIFwiU0VBVFwiIE1vZHVsZVR5cGUuXG4gICAgICogQHJldHVybiB7TW9kdWxlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRTZWF0Q29udHJvbERhdGEgKGRhdGEpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoU2VhdENvbnRyb2xEYXRhLCBkYXRhKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTW9kdWxlRGF0YS5LRVlfU0VBVF9DT05UUk9MX0RBVEEsIGRhdGEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTZWF0Q29udHJvbERhdGF9XG4gICAgICovXG4gICAgZ2V0U2VhdENvbnRyb2xEYXRhICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFNlYXRDb250cm9sRGF0YSwgTW9kdWxlRGF0YS5LRVlfU0VBVF9DT05UUk9MX0RBVEEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7QXVkaW9Db250cm9sRGF0YX0gZGF0YVxuICAgICAqIEByZXR1cm4ge01vZHVsZURhdGF9XG4gICAgICovXG4gICAgc2V0QXVkaW9Db250cm9sRGF0YSAoZGF0YSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShBdWRpb0NvbnRyb2xEYXRhLCBkYXRhKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTW9kdWxlRGF0YS5LRVlfQVVESU9fQ09OVFJPTF9EQVRBLCBkYXRhKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7QXVkaW9Db250cm9sRGF0YX1cbiAgICAgKi9cbiAgICBnZXRBdWRpb0NvbnRyb2xEYXRhICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEF1ZGlvQ29udHJvbERhdGEsIE1vZHVsZURhdGEuS0VZX0FVRElPX0NPTlRST0xfREFUQSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtMaWdodENvbnRyb2xEYXRhfSBkYXRhXG4gICAgICogQHJldHVybiB7TW9kdWxlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRMaWdodENvbnRyb2xEYXRhIChkYXRhKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKExpZ2h0Q29udHJvbERhdGEsIGRhdGEpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihNb2R1bGVEYXRhLktFWV9MSUdIVF9DT05UUk9MX0RBVEEsIGRhdGEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtMaWdodENvbnRyb2xEYXRhfVxuICAgICAqL1xuICAgIGdldExpZ2h0Q29udHJvbERhdGEgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTGlnaHRDb250cm9sRGF0YSwgTW9kdWxlRGF0YS5LRVlfTElHSFRfQ09OVFJPTF9EQVRBKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0hNSVNldHRpbmdzQ29udHJvbERhdGF9IGRhdGEgLSBDb3JyZXNwb25kcyB0byBcIkhNSV9TRVRUSU5HU1wiIE1vZHVsZVR5cGVcbiAgICAgKiBAcmV0dXJuIHtNb2R1bGVEYXRhfVxuICAgICAqL1xuICAgIHNldEhtaVNldHRpbmdzQ29udHJvbERhdGEgKGRhdGEpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoSE1JU2V0dGluZ3NDb250cm9sRGF0YSwgZGF0YSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE1vZHVsZURhdGEuS0VZX0hNSV9TRVRUSU5HU19DT05UUk9MX0RBVEEsIGRhdGEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtITUlTZXR0aW5nc0NvbnRyb2xEYXRhfVxuICAgICAqL1xuICAgIGdldEhtaVNldHRpbmdzQ29udHJvbERhdGEgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoSE1JU2V0dGluZ3NDb250cm9sRGF0YSwgTW9kdWxlRGF0YS5LRVlfSE1JX1NFVFRJTkdTX0NPTlRST0xfREFUQSk7XG4gICAgfVxufVxuXG5Nb2R1bGVEYXRhLktFWV9NT0RVTEVfVFlQRSA9ICdtb2R1bGVUeXBlJztcbk1vZHVsZURhdGEuS0VZX01PRFVMRV9JRCA9ICdtb2R1bGVJZCc7XG5Nb2R1bGVEYXRhLktFWV9SQURJT19DT05UUk9MX0RBVEEgPSAncmFkaW9Db250cm9sRGF0YSc7XG5Nb2R1bGVEYXRhLktFWV9DTElNQVRFX0NPTlRST0xfREFUQSA9ICdjbGltYXRlQ29udHJvbERhdGEnO1xuTW9kdWxlRGF0YS5LRVlfU0VBVF9DT05UUk9MX0RBVEEgPSAnc2VhdENvbnRyb2xEYXRhJztcbk1vZHVsZURhdGEuS0VZX0FVRElPX0NPTlRST0xfREFUQSA9ICdhdWRpb0NvbnRyb2xEYXRhJztcbk1vZHVsZURhdGEuS0VZX0xJR0hUX0NPTlRST0xfREFUQSA9ICdsaWdodENvbnRyb2xEYXRhJztcbk1vZHVsZURhdGEuS0VZX0hNSV9TRVRUSU5HU19DT05UUk9MX0RBVEEgPSAnaG1pU2V0dGluZ3NDb250cm9sRGF0YSc7XG5cbmV4cG9ydCB7IE1vZHVsZURhdGEgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBNb2R1bGVEYXRhIH0gZnJvbSAnLi4vc3RydWN0cy9Nb2R1bGVEYXRhLmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG5jbGFzcyBHZXRJbnRlcmlvclZlaGljbGVEYXRhUmVzcG9uc2UgZXh0ZW5kcyBScGNSZXNwb25zZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5HZXRJbnRlcmlvclZlaGljbGVEYXRhKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge01vZHVsZURhdGF9IGRhdGEgLSBUaGUgbW9kdWxlVHlwZSBpbmRpY2F0ZXMgd2hpY2ggdHlwZSBvZiBkYXRhIHNob3VsZCBiZSBjaGFuZ2VkIGFuZCBpZGVudGlmaWVzIHdoaWNoXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSBvYmplY3QgZXhpc3RzIGluIHRoaXMgc3RydWN0LiBGb3IgZXhhbXBsZSwgaWYgdGhlIG1vZHVsZVR5cGUgaXMgQ0xJTUFURSB0aGVuIGFcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImNsaW1hdGVDb250cm9sRGF0YVwiIHNob3VsZCBleGlzdFxuICAgICAqIEByZXR1cm4ge0dldEludGVyaW9yVmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRNb2R1bGVEYXRhIChkYXRhKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKE1vZHVsZURhdGEsIGRhdGEpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRJbnRlcmlvclZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX01PRFVMRV9EQVRBLCBkYXRhKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TW9kdWxlRGF0YX1cbiAgICAgKi9cbiAgICBnZXRNb2R1bGVEYXRhICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KE1vZHVsZURhdGEsIEdldEludGVyaW9yVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfTU9EVUxFX0RBVEEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gc3Vic2NyaWJlZCAtIEl0IGlzIGEgY29uZGl0aW9uYWwtbWFuZGF0b3J5IHBhcmFtZXRlcjogbXVzdCBiZSByZXR1cm5lZCBpbiBjYXNlIFwic3Vic2NyaWJlXCJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXIgd2FzIHByZXNlbnQgaW4gdGhlIHJlbGF0ZWQgcmVxdWVzdC4gaWYgXCJ0cnVlXCIgLSB0aGUgXCJtb2R1bGVUeXBlXCIgZnJvbVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QgaXMgc3VjY2Vzc2Z1bGx5IHN1YnNjcmliZWQgYW5kIHRoZSBoZWFkIHVuaXQgd2lsbCBzZW5kXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25JbnRlcmlvclZlaGljbGVEYXRhIG5vdGlmaWNhdGlvbnMgZm9yIHRoZSBtb2R1bGVUeXBlLiBpZiBcImZhbHNlXCIgLSB0aGVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIm1vZHVsZVR5cGVcIiBmcm9tIHJlcXVlc3QgaXMgZWl0aGVyIHVuc3Vic2NyaWJlZCBvciBmYWlsZWQgdG8gc3Vic2NyaWJlLlxuICAgICAqIEByZXR1cm4ge0dldEludGVyaW9yVmVoaWNsZURhdGFSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRJc1N1YnNjcmliZWQgKHN1YnNjcmliZWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0SW50ZXJpb3JWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9JU19TVUJTQ1JJQkVELCBzdWJzY3JpYmVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRJc1N1YnNjcmliZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR2V0SW50ZXJpb3JWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9JU19TVUJTQ1JJQkVEKTtcbiAgICB9XG59XG5cbkdldEludGVyaW9yVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfTU9EVUxFX0RBVEEgPSAnbW9kdWxlRGF0YSc7XG5HZXRJbnRlcmlvclZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX0lTX1NVQlNDUklCRUQgPSAnaXNTdWJzY3JpYmVkJztcblxuZXhwb3J0IHsgR2V0SW50ZXJpb3JWZWhpY2xlRGF0YVJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgTW9kdWxlVHlwZSB9IGZyb20gJy4uL2VudW1zL01vZHVsZVR5cGUuanMnO1xuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG5jbGFzcyBHZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudCBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuR2V0SW50ZXJpb3JWZWhpY2xlRGF0YUNvbnNlbnQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TW9kdWxlVHlwZX0gdHlwZSAtIFRoZSBtb2R1bGUgdHlwZSB0aGF0IHRoZSBhcHAgcmVxdWVzdHMgdG8gY29udHJvbC5cbiAgICAgKiBAcmV0dXJuIHtHZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudH1cbiAgICAgKi9cbiAgICBzZXRNb2R1bGVUeXBlICh0eXBlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKE1vZHVsZVR5cGUsIHR5cGUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudC5LRVlfTU9EVUxFX1RZUEUsIHR5cGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtNb2R1bGVUeXBlfVxuICAgICAqL1xuICAgIGdldE1vZHVsZVR5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTW9kdWxlVHlwZSwgR2V0SW50ZXJpb3JWZWhpY2xlRGF0YUNvbnNlbnQuS0VZX01PRFVMRV9UWVBFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ1tdfSBpZHMgLSBJZHMgb2YgYSBtb2R1bGUgb2Ygc2FtZSB0eXBlLCBwdWJsaXNoZWQgYnkgU3lzdGVtIENhcGFiaWxpdHkuXG4gICAgICogQHJldHVybiB7R2V0SW50ZXJpb3JWZWhpY2xlRGF0YUNvbnNlbnR9XG4gICAgICovXG4gICAgc2V0TW9kdWxlSWRzIChpZHMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoR2V0SW50ZXJpb3JWZWhpY2xlRGF0YUNvbnNlbnQuS0VZX01PRFVMRV9JRFMsIGlkcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ1tdfVxuICAgICAqL1xuICAgIGdldE1vZHVsZUlkcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudC5LRVlfTU9EVUxFX0lEUyk7XG4gICAgfVxufVxuXG5HZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudC5LRVlfTU9EVUxFX1RZUEUgPSAnbW9kdWxlVHlwZSc7XG5HZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudC5LRVlfTU9EVUxFX0lEUyA9ICdtb2R1bGVJZHMnO1xuXG5leHBvcnQgeyBHZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudCB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG5jbGFzcyBHZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudFJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuR2V0SW50ZXJpb3JWZWhpY2xlRGF0YUNvbnNlbnQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbltdfSBhbGxvd2VkIC0gVGhpcyBhcnJheSBoYXMgdGhlIHNhbWUgc2l6ZSBhcyBcIm1vZHVsZUlkc1wiIGluIHRoZSByZXF1ZXN0IGFuZCBlYWNoIGVsZW1lbnRcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcnJlc3BvbmRzIHRvIG9uZSBtb2R1bGVJZCBJZiB0cnVlLCBTREwgZ3JhbnRzIHRoZSBwZXJtaXNzaW9uIGZvciB0aGUgcmVxdWVzdGVkXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2R1bGUgSWYgZmFsc2UsIFNETCBkZW5pZXMgdGhlIHBlcm1pc3Npb24gZm9yIHRoZSByZXF1ZXN0ZWQgbW9kdWxlLlxuICAgICAqIEByZXR1cm4ge0dldEludGVyaW9yVmVoaWNsZURhdGFDb25zZW50UmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0QWxsb3dlZCAoYWxsb3dlZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudFJlc3BvbnNlLktFWV9BTExPV0VELCBhbGxvd2VkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbltdfVxuICAgICAqL1xuICAgIGdldEFsbG93ZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoR2V0SW50ZXJpb3JWZWhpY2xlRGF0YUNvbnNlbnRSZXNwb25zZS5LRVlfQUxMT1dFRCk7XG4gICAgfVxufVxuXG5HZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudFJlc3BvbnNlLktFWV9BTExPV0VEID0gJ2FsbG93ZWQnO1xuXG5leHBvcnQgeyBHZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudFJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgTW9kdWxlVHlwZSB9IGZyb20gJy4uL2VudW1zL01vZHVsZVR5cGUuanMnO1xuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG5jbGFzcyBSZWxlYXNlSW50ZXJpb3JWZWhpY2xlRGF0YU1vZHVsZSBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuUmVsZWFzZUludGVyaW9yVmVoaWNsZURhdGFNb2R1bGUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TW9kdWxlVHlwZX0gdHlwZVxuICAgICAqIEByZXR1cm4ge1JlbGVhc2VJbnRlcmlvclZlaGljbGVEYXRhTW9kdWxlfVxuICAgICAqL1xuICAgIHNldE1vZHVsZVR5cGUgKHR5cGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTW9kdWxlVHlwZSwgdHlwZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlbGVhc2VJbnRlcmlvclZlaGljbGVEYXRhTW9kdWxlLktFWV9NT0RVTEVfVFlQRSwgdHlwZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge01vZHVsZVR5cGV9XG4gICAgICovXG4gICAgZ2V0TW9kdWxlVHlwZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChNb2R1bGVUeXBlLCBSZWxlYXNlSW50ZXJpb3JWZWhpY2xlRGF0YU1vZHVsZS5LRVlfTU9EVUxFX1RZUEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBpZCAtIElkIG9mIGEgbW9kdWxlLCBwdWJsaXNoZWQgYnkgU3lzdGVtIENhcGFiaWxpdHkuXG4gICAgICogQHJldHVybiB7UmVsZWFzZUludGVyaW9yVmVoaWNsZURhdGFNb2R1bGV9XG4gICAgICovXG4gICAgc2V0TW9kdWxlSWQgKGlkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlbGVhc2VJbnRlcmlvclZlaGljbGVEYXRhTW9kdWxlLktFWV9NT0RVTEVfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldE1vZHVsZUlkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFJlbGVhc2VJbnRlcmlvclZlaGljbGVEYXRhTW9kdWxlLktFWV9NT0RVTEVfSUQpO1xuICAgIH1cbn1cblxuUmVsZWFzZUludGVyaW9yVmVoaWNsZURhdGFNb2R1bGUuS0VZX01PRFVMRV9UWVBFID0gJ21vZHVsZVR5cGUnO1xuUmVsZWFzZUludGVyaW9yVmVoaWNsZURhdGFNb2R1bGUuS0VZX01PRFVMRV9JRCA9ICdtb2R1bGVJZCc7XG5cbmV4cG9ydCB7IFJlbGVhc2VJbnRlcmlvclZlaGljbGVEYXRhTW9kdWxlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbmNsYXNzIFJlbGVhc2VJbnRlcmlvclZlaGljbGVEYXRhTW9kdWxlUmVzcG9uc2UgZXh0ZW5kcyBScGNSZXNwb25zZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5SZWxlYXNlSW50ZXJpb3JWZWhpY2xlRGF0YU1vZHVsZSk7XG4gICAgfVxufVxuXG5cbmV4cG9ydCB7IFJlbGVhc2VJbnRlcmlvclZlaGljbGVEYXRhTW9kdWxlUmVzcG9uc2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBNb2R1bGVEYXRhIH0gZnJvbSAnLi4vc3RydWN0cy9Nb2R1bGVEYXRhLmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcblxuY2xhc3MgU2V0SW50ZXJpb3JWZWhpY2xlRGF0YSBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuU2V0SW50ZXJpb3JWZWhpY2xlRGF0YSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtNb2R1bGVEYXRhfSBkYXRhIC0gVGhlIG1vZHVsZSBkYXRhIHRvIHNldCBmb3IgdGhlIHJlcXVlc3RlZCBSQyBtb2R1bGUuXG4gICAgICogQHJldHVybiB7U2V0SW50ZXJpb3JWZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRNb2R1bGVEYXRhIChkYXRhKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKE1vZHVsZURhdGEsIGRhdGEpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZXRJbnRlcmlvclZlaGljbGVEYXRhLktFWV9NT0RVTEVfREFUQSwgZGF0YSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge01vZHVsZURhdGF9XG4gICAgICovXG4gICAgZ2V0TW9kdWxlRGF0YSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChNb2R1bGVEYXRhLCBTZXRJbnRlcmlvclZlaGljbGVEYXRhLktFWV9NT0RVTEVfREFUQSk7XG4gICAgfVxufVxuXG5TZXRJbnRlcmlvclZlaGljbGVEYXRhLktFWV9NT0RVTEVfREFUQSA9ICdtb2R1bGVEYXRhJztcblxuZXhwb3J0IHsgU2V0SW50ZXJpb3JWZWhpY2xlRGF0YSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IE1vZHVsZURhdGEgfSBmcm9tICcuLi9zdHJ1Y3RzL01vZHVsZURhdGEuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbi8qKlxuICogVXNlZCB0byBzZXQgdGhlIHZhbHVlcyBvZiBvbmUgcmVtb3RlIGNvbnRyb2wgbW9kdWxlXG4gKi9cbmNsYXNzIFNldEludGVyaW9yVmVoaWNsZURhdGFSZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlNldEludGVyaW9yVmVoaWNsZURhdGEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TW9kdWxlRGF0YX0gZGF0YSAtIFRoZSBtb2R1bGVUeXBlIGluZGljYXRlcyB3aGljaCB0eXBlIG9mIGRhdGEgc2hvdWxkIGJlIGNoYW5nZWQgYW5kIGlkZW50aWZpZXMgd2hpY2hcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhIG9iamVjdCBleGlzdHMgaW4gdGhpcyBzdHJ1Y3QuIEZvciBleGFtcGxlLCBpZiB0aGUgbW9kdWxlVHlwZSBpcyBDTElNQVRFIHRoZW4gYVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiY2xpbWF0ZUNvbnRyb2xEYXRhXCIgc2hvdWxkIGV4aXN0XG4gICAgICogQHJldHVybiB7U2V0SW50ZXJpb3JWZWhpY2xlRGF0YVJlc3BvbnNlfVxuICAgICAqL1xuICAgIHNldE1vZHVsZURhdGEgKGRhdGEpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTW9kdWxlRGF0YSwgZGF0YSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNldEludGVyaW9yVmVoaWNsZURhdGFSZXNwb25zZS5LRVlfTU9EVUxFX0RBVEEsIGRhdGEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtNb2R1bGVEYXRhfVxuICAgICAqL1xuICAgIGdldE1vZHVsZURhdGEgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTW9kdWxlRGF0YSwgU2V0SW50ZXJpb3JWZWhpY2xlRGF0YVJlc3BvbnNlLktFWV9NT0RVTEVfREFUQSk7XG4gICAgfVxufVxuXG5TZXRJbnRlcmlvclZlaGljbGVEYXRhUmVzcG9uc2UuS0VZX01PRFVMRV9EQVRBID0gJ21vZHVsZURhdGEnO1xuXG5leHBvcnQgeyBTZXRJbnRlcmlvclZlaGljbGVEYXRhUmVzcG9uc2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5cbi8qKlxuICogVG8gc3Vic2NyaWJlIGluIGdldHRpbmcgY2hhbmdlcyBmb3IgV2F5cG9pbnRzL2Rlc3RpbmF0aW9uc1xuICovXG5jbGFzcyBTdWJzY3JpYmVXYXlQb2ludHMgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlN1YnNjcmliZVdheVBvaW50cyk7XG4gICAgfVxufVxuXG5cbmV4cG9ydCB7IFN1YnNjcmliZVdheVBvaW50cyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG5jbGFzcyBTdWJzY3JpYmVXYXlQb2ludHNSZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlN1YnNjcmliZVdheVBvaW50cyk7XG4gICAgfVxufVxuXG5cbmV4cG9ydCB7IFN1YnNjcmliZVdheVBvaW50c1Jlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogRGVzY3JpYmVzIHdoYXQga2luZCBvZiB3YXlwb2ludCBpcyByZXF1ZXN0ZWQvcHJvdmlkZWQuXG4gKiBAdHlwZWRlZiB7RW51bX0gV2F5UG9pbnRUeXBlXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBXYXlQb2ludFR5cGUgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQUxMICgpIHtcbiAgICAgICAgcmV0dXJuIFdheVBvaW50VHlwZS5fTUFQLkFMTDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBERVNUSU5BVElPTiAoKSB7XG4gICAgICAgIHJldHVybiBXYXlQb2ludFR5cGUuX01BUC5ERVNUSU5BVElPTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBXYXlQb2ludFR5cGUuX3ZhbHVlRm9yS2V5KGtleSwgV2F5UG9pbnRUeXBlLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gV2F5UG9pbnRUeXBlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgV2F5UG9pbnRUeXBlLl9NQVApO1xuICAgIH1cbn1cblxuV2F5UG9pbnRUeXBlLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnQUxMJzogJ0FMTCcsXG4gICAgJ0RFU1RJTkFUSU9OJzogJ0RFU1RJTkFUSU9OJyxcbn0pO1xuXG5leHBvcnQgeyBXYXlQb2ludFR5cGUgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBXYXlQb2ludFR5cGUgfSBmcm9tICcuLi9lbnVtcy9XYXlQb2ludFR5cGUuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG4vKipcbiAqIFJlcXVlc3QgZm9yIGdldHRpbmcgd2F5cG9pbnQvZGVzdGluYXRpb24gZGF0YS5cbiAqL1xuY2xhc3MgR2V0V2F5UG9pbnRzIGV4dGVuZHMgUnBjUmVxdWVzdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5HZXRXYXlQb2ludHMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7V2F5UG9pbnRUeXBlfSB0eXBlIC0gVG8gcmVxdWVzdCBmb3IgZWl0aGVyIHRoZSBkZXN0aW5hdGlvbiBvbmx5IG9yIGZvciBhbGwgd2F5cG9pbnRzIGluY2x1ZGluZ1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzdGluYXRpb25cbiAgICAgKiBAcmV0dXJuIHtHZXRXYXlQb2ludHN9XG4gICAgICovXG4gICAgc2V0V2F5UG9pbnRUeXBlICh0eXBlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFdheVBvaW50VHlwZSwgdHlwZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldFdheVBvaW50cy5LRVlfV0FZX1BPSU5UX1RZUEUsIHR5cGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtXYXlQb2ludFR5cGV9XG4gICAgICovXG4gICAgZ2V0V2F5UG9pbnRUeXBlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFdheVBvaW50VHlwZSwgR2V0V2F5UG9pbnRzLktFWV9XQVlfUE9JTlRfVFlQRSk7XG4gICAgfVxufVxuXG5HZXRXYXlQb2ludHMuS0VZX1dBWV9QT0lOVF9UWVBFID0gJ3dheVBvaW50VHlwZSc7XG5cbmV4cG9ydCB7IEdldFdheVBvaW50cyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5cbmNsYXNzIENvb3JkaW5hdGUgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBkZWdyZWVzIC0gTGF0aXR1ZGUgb2YgdGhlIGxvY2F0aW9uLlxuICAgICAqIEByZXR1cm4ge0Nvb3JkaW5hdGV9XG4gICAgICovXG4gICAgc2V0TGF0aXR1ZGVEZWdyZWVzIChkZWdyZWVzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENvb3JkaW5hdGUuS0VZX0xBVElUVURFX0RFR1JFRVMsIGRlZ3JlZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0TGF0aXR1ZGVEZWdyZWVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKENvb3JkaW5hdGUuS0VZX0xBVElUVURFX0RFR1JFRVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBkZWdyZWVzIC0gTG9uZ2l0dWRlIG9mIHRoZSBsb2NhdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtDb29yZGluYXRlfVxuICAgICAqL1xuICAgIHNldExvbmdpdHVkZURlZ3JlZXMgKGRlZ3JlZXMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ29vcmRpbmF0ZS5LRVlfTE9OR0lUVURFX0RFR1JFRVMsIGRlZ3JlZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0TG9uZ2l0dWRlRGVncmVlcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihDb29yZGluYXRlLktFWV9MT05HSVRVREVfREVHUkVFUyk7XG4gICAgfVxufVxuXG5Db29yZGluYXRlLktFWV9MQVRJVFVERV9ERUdSRUVTID0gJ2xhdGl0dWRlRGVncmVlcyc7XG5Db29yZGluYXRlLktFWV9MT05HSVRVREVfREVHUkVFUyA9ICdsb25naXR1ZGVEZWdyZWVzJztcblxuZXhwb3J0IHsgQ29vcmRpbmF0ZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IENvb3JkaW5hdGUgfSBmcm9tICcuL0Nvb3JkaW5hdGUuanMnO1xuaW1wb3J0IHsgSW1hZ2UgfSBmcm9tICcuL0ltYWdlLmpzJztcbmltcG9ydCB7IE9BU0lTQWRkcmVzcyB9IGZyb20gJy4vT0FTSVNBZGRyZXNzLmpzJztcbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5cbmNsYXNzIExvY2F0aW9uRGV0YWlscyBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtDb29yZGluYXRlfSBjb29yZGluYXRlIC0gTGF0aXR1ZGUvTG9uZ2l0dWRlIG9mIHRoZSBsb2NhdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtMb2NhdGlvbkRldGFpbHN9XG4gICAgICovXG4gICAgc2V0Q29vcmRpbmF0ZSAoY29vcmRpbmF0ZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShDb29yZGluYXRlLCBjb29yZGluYXRlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTG9jYXRpb25EZXRhaWxzLktFWV9DT09SRElOQVRFLCBjb29yZGluYXRlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Q29vcmRpbmF0ZX1cbiAgICAgKi9cbiAgICBnZXRDb29yZGluYXRlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KENvb3JkaW5hdGUsIExvY2F0aW9uRGV0YWlscy5LRVlfQ09PUkRJTkFURSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBOYW1lIG9mIGxvY2F0aW9uLlxuICAgICAqIEByZXR1cm4ge0xvY2F0aW9uRGV0YWlsc31cbiAgICAgKi9cbiAgICBzZXRMb2NhdGlvbk5hbWUgKG5hbWUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTG9jYXRpb25EZXRhaWxzLktFWV9MT0NBVElPTl9OQU1FLCBuYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldExvY2F0aW9uTmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihMb2NhdGlvbkRldGFpbHMuS0VZX0xPQ0FUSU9OX05BTUUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nW119IGxpbmVzIC0gTG9jYXRpb24gYWRkcmVzcyBmb3IgZGlzcGxheSBwdXJwb3NlcyBvbmx5XG4gICAgICogQHJldHVybiB7TG9jYXRpb25EZXRhaWxzfVxuICAgICAqL1xuICAgIHNldEFkZHJlc3NMaW5lcyAobGluZXMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTG9jYXRpb25EZXRhaWxzLktFWV9BRERSRVNTX0xJTkVTLCBsaW5lcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ1tdfVxuICAgICAqL1xuICAgIGdldEFkZHJlc3NMaW5lcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihMb2NhdGlvbkRldGFpbHMuS0VZX0FERFJFU1NfTElORVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBkZXNjcmlwdGlvbiAtIERlc2NyaXB0aW9uIGludGVuZGVkIGxvY2F0aW9uIC8gZXN0YWJsaXNobWVudCAoaWYgYXBwbGljYWJsZSlcbiAgICAgKiBAcmV0dXJuIHtMb2NhdGlvbkRldGFpbHN9XG4gICAgICovXG4gICAgc2V0TG9jYXRpb25EZXNjcmlwdGlvbiAoZGVzY3JpcHRpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTG9jYXRpb25EZXRhaWxzLktFWV9MT0NBVElPTl9ERVNDUklQVElPTiwgZGVzY3JpcHRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0TG9jYXRpb25EZXNjcmlwdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihMb2NhdGlvbkRldGFpbHMuS0VZX0xPQ0FUSU9OX0RFU0NSSVBUSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbnVtYmVyIC0gUGhvbmUgbnVtYmVyIG9mIGxvY2F0aW9uIC8gZXN0YWJsaXNobWVudC5cbiAgICAgKiBAcmV0dXJuIHtMb2NhdGlvbkRldGFpbHN9XG4gICAgICovXG4gICAgc2V0UGhvbmVOdW1iZXIgKG51bWJlcikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihMb2NhdGlvbkRldGFpbHMuS0VZX1BIT05FX05VTUJFUiwgbnVtYmVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldFBob25lTnVtYmVyICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKExvY2F0aW9uRGV0YWlscy5LRVlfUEhPTkVfTlVNQkVSKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0ltYWdlfSBpbWFnZSAtIEltYWdlIC8gaWNvbiBvZiBpbnRlbmRlZCBsb2NhdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtMb2NhdGlvbkRldGFpbHN9XG4gICAgICovXG4gICAgc2V0TG9jYXRpb25JbWFnZSAoaW1hZ2UpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoSW1hZ2UsIGltYWdlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTG9jYXRpb25EZXRhaWxzLktFWV9MT0NBVElPTl9JTUFHRSwgaW1hZ2UpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtJbWFnZX1cbiAgICAgKi9cbiAgICBnZXRMb2NhdGlvbkltYWdlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEltYWdlLCBMb2NhdGlvbkRldGFpbHMuS0VZX0xPQ0FUSU9OX0lNQUdFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge09BU0lTQWRkcmVzc30gYWRkcmVzcyAtIEFkZHJlc3MgdG8gYmUgdXNlZCBieSBuYXZpZ2F0aW9uIGVuZ2luZXMgZm9yIHNlYXJjaFxuICAgICAqIEByZXR1cm4ge0xvY2F0aW9uRGV0YWlsc31cbiAgICAgKi9cbiAgICBzZXRTZWFyY2hBZGRyZXNzIChhZGRyZXNzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKE9BU0lTQWRkcmVzcywgYWRkcmVzcyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKExvY2F0aW9uRGV0YWlscy5LRVlfU0VBUkNIX0FERFJFU1MsIGFkZHJlc3MpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtPQVNJU0FkZHJlc3N9XG4gICAgICovXG4gICAgZ2V0U2VhcmNoQWRkcmVzcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChPQVNJU0FkZHJlc3MsIExvY2F0aW9uRGV0YWlscy5LRVlfU0VBUkNIX0FERFJFU1MpO1xuICAgIH1cbn1cblxuTG9jYXRpb25EZXRhaWxzLktFWV9DT09SRElOQVRFID0gJ2Nvb3JkaW5hdGUnO1xuTG9jYXRpb25EZXRhaWxzLktFWV9MT0NBVElPTl9OQU1FID0gJ2xvY2F0aW9uTmFtZSc7XG5Mb2NhdGlvbkRldGFpbHMuS0VZX0FERFJFU1NfTElORVMgPSAnYWRkcmVzc0xpbmVzJztcbkxvY2F0aW9uRGV0YWlscy5LRVlfTE9DQVRJT05fREVTQ1JJUFRJT04gPSAnbG9jYXRpb25EZXNjcmlwdGlvbic7XG5Mb2NhdGlvbkRldGFpbHMuS0VZX1BIT05FX05VTUJFUiA9ICdwaG9uZU51bWJlcic7XG5Mb2NhdGlvbkRldGFpbHMuS0VZX0xPQ0FUSU9OX0lNQUdFID0gJ2xvY2F0aW9uSW1hZ2UnO1xuTG9jYXRpb25EZXRhaWxzLktFWV9TRUFSQ0hfQUREUkVTUyA9ICdzZWFyY2hBZGRyZXNzJztcblxuZXhwb3J0IHsgTG9jYXRpb25EZXRhaWxzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgTG9jYXRpb25EZXRhaWxzIH0gZnJvbSAnLi4vc3RydWN0cy9Mb2NhdGlvbkRldGFpbHMuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbmNsYXNzIEdldFdheVBvaW50c1Jlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuR2V0V2F5UG9pbnRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0xvY2F0aW9uRGV0YWlsc1tdfSBwb2ludHMgLSBTZWUgTG9jYXRpb25EZXRhaWxzXG4gICAgICogQHJldHVybiB7R2V0V2F5UG9pbnRzUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0V2F5UG9pbnRzIChwb2ludHMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTG9jYXRpb25EZXRhaWxzLCBwb2ludHMsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRXYXlQb2ludHNSZXNwb25zZS5LRVlfV0FZX1BPSU5UUywgcG9pbnRzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TG9jYXRpb25EZXRhaWxzW119XG4gICAgICovXG4gICAgZ2V0V2F5UG9pbnRzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KExvY2F0aW9uRGV0YWlscywgR2V0V2F5UG9pbnRzUmVzcG9uc2UuS0VZX1dBWV9QT0lOVFMpO1xuICAgIH1cbn1cblxuR2V0V2F5UG9pbnRzUmVzcG9uc2UuS0VZX1dBWV9QT0lOVFMgPSAnd2F5UG9pbnRzJztcblxuZXhwb3J0IHsgR2V0V2F5UG9pbnRzUmVzcG9uc2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5cbi8qKlxuICogUmVxdWVzdCB0byB1bnN1YnNjcmliZSBmcm9tIFdheVBvaW50cyBhbmQgRGVzdGluYXRpb25cbiAqL1xuY2xhc3MgVW5zdWJzY3JpYmVXYXlQb2ludHMgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlVuc3Vic2NyaWJlV2F5UG9pbnRzKTtcbiAgICB9XG59XG5cblxuZXhwb3J0IHsgVW5zdWJzY3JpYmVXYXlQb2ludHMgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBMb2NhdGlvbkRldGFpbHMgfSBmcm9tICcuLi9zdHJ1Y3RzL0xvY2F0aW9uRGV0YWlscy5qcyc7XG5pbXBvcnQgeyBScGNSZXNwb25zZSB9IGZyb20gJy4uL1JwY1Jlc3BvbnNlLmpzJztcblxuY2xhc3MgVW5zdWJzY3JpYmVXYXlQb2ludHNSZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlVuc3Vic2NyaWJlV2F5UG9pbnRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0xvY2F0aW9uRGV0YWlsc1tdfSBwb2ludHMgLSBTZWUgTG9jYXRpb25EZXRhaWxzXG4gICAgICogQHJldHVybiB7VW5zdWJzY3JpYmVXYXlQb2ludHNSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRXYXlQb2ludHMgKHBvaW50cykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShMb2NhdGlvbkRldGFpbHMsIHBvaW50cywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFVuc3Vic2NyaWJlV2F5UG9pbnRzUmVzcG9uc2UuS0VZX1dBWV9QT0lOVFMsIHBvaW50cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0xvY2F0aW9uRGV0YWlsc1tdfVxuICAgICAqL1xuICAgIGdldFdheVBvaW50cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChMb2NhdGlvbkRldGFpbHMsIFVuc3Vic2NyaWJlV2F5UG9pbnRzUmVzcG9uc2UuS0VZX1dBWV9QT0lOVFMpO1xuICAgIH1cbn1cblxuVW5zdWJzY3JpYmVXYXlQb2ludHNSZXNwb25zZS5LRVlfV0FZX1BPSU5UUyA9ICd3YXlQb2ludHMnO1xuXG5leHBvcnQgeyBVbnN1YnNjcmliZVdheVBvaW50c1Jlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogRW51bWVyYXRpb25zIG9mIGFsbCBhdmFpbGFibGUgc3lzdGVtIGNhcGFiaWxpdHkgdHlwZXNcbiAqIEB0eXBlZGVmIHtFbnVtfSBTeXN0ZW1DYXBhYmlsaXR5VHlwZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgU3lzdGVtQ2FwYWJpbGl0eVR5cGUgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTkFWSUdBVElPTiAoKSB7XG4gICAgICAgIHJldHVybiBTeXN0ZW1DYXBhYmlsaXR5VHlwZS5fTUFQLk5BVklHQVRJT047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUEhPTkVfQ0FMTCAoKSB7XG4gICAgICAgIHJldHVybiBTeXN0ZW1DYXBhYmlsaXR5VHlwZS5fTUFQLlBIT05FX0NBTEw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVklERU9fU1RSRUFNSU5HICgpIHtcbiAgICAgICAgcmV0dXJuIFN5c3RlbUNhcGFiaWxpdHlUeXBlLl9NQVAuVklERU9fU1RSRUFNSU5HO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJFTU9URV9DT05UUk9MICgpIHtcbiAgICAgICAgcmV0dXJuIFN5c3RlbUNhcGFiaWxpdHlUeXBlLl9NQVAuUkVNT1RFX0NPTlRST0w7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQVBQX1NFUlZJQ0VTICgpIHtcbiAgICAgICAgcmV0dXJuIFN5c3RlbUNhcGFiaWxpdHlUeXBlLl9NQVAuQVBQX1NFUlZJQ0VTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFNFQVRfTE9DQVRJT04gKCkge1xuICAgICAgICByZXR1cm4gU3lzdGVtQ2FwYWJpbGl0eVR5cGUuX01BUC5TRUFUX0xPQ0FUSU9OO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IERJU1BMQVlTICgpIHtcbiAgICAgICAgcmV0dXJuIFN5c3RlbUNhcGFiaWxpdHlUeXBlLl9NQVAuRElTUExBWVM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gU3lzdGVtQ2FwYWJpbGl0eVR5cGUuX3ZhbHVlRm9yS2V5KGtleSwgU3lzdGVtQ2FwYWJpbGl0eVR5cGUuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBTeXN0ZW1DYXBhYmlsaXR5VHlwZS5fa2V5Rm9yVmFsdWUodmFsdWUsIFN5c3RlbUNhcGFiaWxpdHlUeXBlLl9NQVApO1xuICAgIH1cbn1cblxuU3lzdGVtQ2FwYWJpbGl0eVR5cGUuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdOQVZJR0FUSU9OJzogJ05BVklHQVRJT04nLFxuICAgICdQSE9ORV9DQUxMJzogJ1BIT05FX0NBTEwnLFxuICAgICdWSURFT19TVFJFQU1JTkcnOiAnVklERU9fU1RSRUFNSU5HJyxcbiAgICAnUkVNT1RFX0NPTlRST0wnOiAnUkVNT1RFX0NPTlRST0wnLFxuICAgICdBUFBfU0VSVklDRVMnOiAnQVBQX1NFUlZJQ0VTJyxcbiAgICAnU0VBVF9MT0NBVElPTic6ICdTRUFUX0xPQ0FUSU9OJyxcbiAgICAnRElTUExBWVMnOiAnRElTUExBWVMnLFxufSk7XG5cbmV4cG9ydCB7IFN5c3RlbUNhcGFiaWxpdHlUeXBlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgU3lzdGVtQ2FwYWJpbGl0eVR5cGUgfSBmcm9tICcuLi9lbnVtcy9TeXN0ZW1DYXBhYmlsaXR5VHlwZS5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5cbi8qKlxuICogUmVxdWVzdCBmb3IgZXhwYW5kZWQgaW5mb3JtYXRpb24gYWJvdXQgYSBzdXBwb3J0ZWQgc3lzdGVtL0hNSSBjYXBhYmlsaXR5XG4gKi9cbmNsYXNzIEdldFN5c3RlbUNhcGFiaWxpdHkgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkdldFN5c3RlbUNhcGFiaWxpdHkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3lzdGVtQ2FwYWJpbGl0eVR5cGV9IHR5cGUgLSBUaGUgdHlwZSBvZiBzeXN0ZW0gY2FwYWJpbGl0eSB0byBnZXQgbW9yZSBpbmZvcm1hdGlvbiBvblxuICAgICAqIEByZXR1cm4ge0dldFN5c3RlbUNhcGFiaWxpdHl9XG4gICAgICovXG4gICAgc2V0U3lzdGVtQ2FwYWJpbGl0eVR5cGUgKHR5cGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoU3lzdGVtQ2FwYWJpbGl0eVR5cGUsIHR5cGUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRTeXN0ZW1DYXBhYmlsaXR5LktFWV9TWVNURU1fQ0FQQUJJTElUWV9UWVBFLCB0eXBlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3lzdGVtQ2FwYWJpbGl0eVR5cGV9XG4gICAgICovXG4gICAgZ2V0U3lzdGVtQ2FwYWJpbGl0eVR5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoU3lzdGVtQ2FwYWJpbGl0eVR5cGUsIEdldFN5c3RlbUNhcGFiaWxpdHkuS0VZX1NZU1RFTV9DQVBBQklMSVRZX1RZUEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gc3Vic2NyaWJlIC0gRmxhZyB0byBzdWJzY3JpYmUgdG8gdXBkYXRlcyBvZiB0aGUgc3VwcGxpZWQgc2VydmljZSBjYXBhYmlsaXR5IHR5cGUuIElmIHRydWUsIHRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdGVyIHdpbGwgYmUgc3Vic2NyaWJlZC4gSWYgZmFsc2UsIHRoZSByZXF1ZXN0ZXIgd2lsbCBub3QgYmUgc3Vic2NyaWJlZCBhbmQgYmVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZWQgYXMgYSBzdWJzY3JpYmVyIGlmIGl0IHdhcyBwcmV2aW91c2x5IHN1YnNjcmliZWQuXG4gICAgICogQHJldHVybiB7R2V0U3lzdGVtQ2FwYWJpbGl0eX1cbiAgICAgKi9cbiAgICBzZXRTdWJzY3JpYmUgKHN1YnNjcmliZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRTeXN0ZW1DYXBhYmlsaXR5LktFWV9TVUJTQ1JJQkUsIHN1YnNjcmliZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0U3Vic2NyaWJlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdldFN5c3RlbUNhcGFiaWxpdHkuS0VZX1NVQlNDUklCRSk7XG4gICAgfVxufVxuXG5HZXRTeXN0ZW1DYXBhYmlsaXR5LktFWV9TWVNURU1fQ0FQQUJJTElUWV9UWVBFID0gJ3N5c3RlbUNhcGFiaWxpdHlUeXBlJztcbkdldFN5c3RlbUNhcGFiaWxpdHkuS0VZX1NVQlNDUklCRSA9ICdzdWJzY3JpYmUnO1xuXG5leHBvcnQgeyBHZXRTeXN0ZW1DYXBhYmlsaXR5IH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogRW51bSBmb3IgZWFjaCB0eXBlIG9mIHZpZGVvIHN0cmVhbWluZyBjb2RlYy5cbiAqIEB0eXBlZGVmIHtFbnVtfSBWaWRlb1N0cmVhbWluZ0NvZGVjXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBWaWRlb1N0cmVhbWluZ0NvZGVjIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgYmxvY2stb3JpZW50ZWQgbW90aW9uLWNvbXBlbnNhdGlvbi1iYXNlZCB2aWRlbyBjb21wcmVzc2lvbiBzdGFuZGFyZC4gQXMgb2YgMjAxNCBpdCBpcyBvbmUgb2YgdGhlIG1vc3RcbiAgICAgKiBjb21tb25seSB1c2VkIGZvcm1hdHMgZm9yIHRoZSByZWNvcmRpbmcsIGNvbXByZXNzaW9uLCBhbmQgZGlzdHJpYnV0aW9uIG9mIHZpZGVvIGNvbnRlbnQuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSDI2NCAoKSB7XG4gICAgICAgIHJldHVybiBWaWRlb1N0cmVhbWluZ0NvZGVjLl9NQVAuSDI2NDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIaWdoIEVmZmljaWVuY3kgVmlkZW8gQ29kaW5nIChIRVZDKSwgYWxzbyBrbm93biBhcyBILjI2NSBhbmQgTVBFRy1IIFBhcnQgMiwgaXMgYSB2aWRlbyBjb21wcmVzc2lvbiBzdGFuZGFyZCxcbiAgICAgKiBvbmUgb2Ygc2V2ZXJhbCBwb3RlbnRpYWwgc3VjY2Vzc29ycyB0byB0aGUgd2lkZWx5IHVzZWQgQVZDIChILjI2NCBvciBNUEVHLTQgUGFydCAxMCkuIEluIGNvbXBhcmlzb24gdG8gQVZDLFxuICAgICAqIEhFVkMgb2ZmZXJzIGFib3V0IGRvdWJsZSB0aGUgZGF0YSBjb21wcmVzc2lvbiByYXRpbyBhdCB0aGUgc2FtZSBsZXZlbCBvZiB2aWRlbyBxdWFsaXR5LCBvciBzdWJzdGFudGlhbGx5XG4gICAgICogaW1wcm92ZWQgdmlkZW8gcXVhbGl0eSBhdCB0aGUgc2FtZSBiaXQgcmF0ZS4gSXQgc3VwcG9ydHMgcmVzb2x1dGlvbnMgdXAgdG8gODE5Mng0MzIwLCBpbmNsdWRpbmcgOEsgVUhELlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEgyNjUgKCkge1xuICAgICAgICByZXR1cm4gVmlkZW9TdHJlYW1pbmdDb2RlYy5fTUFQLkgyNjU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlb3JhIGlzIGRlcml2ZWQgZnJvbSB0aGUgZm9ybWVybHkgcHJvcHJpZXRhcnkgVlAzIGNvZGVjLCByZWxlYXNlZCBpbnRvIHRoZSBwdWJsaWMgZG9tYWluIGJ5IE9uMiBUZWNobm9sb2dpZXMuXG4gICAgICogSXQgaXMgYnJvYWRseSBjb21wYXJhYmxlIGluIGRlc2lnbiBhbmQgYml0cmF0ZSBlZmZpY2llbmN5IHRvIE1QRUctNCBQYXJ0IDIsIGVhcmx5IHZlcnNpb25zIG9mIFdpbmRvd3MgTWVkaWFcbiAgICAgKiBWaWRlbywgYW5kIFJlYWxWaWRlbyB3aGlsZSBsYWNraW5nIHNvbWUgb2YgdGhlIGZlYXR1cmVzIHByZXNlbnQgaW4gc29tZSBvZiB0aGVzZSBvdGhlciBjb2RlY3MuIEl0IGlzIGNvbXBhcmFibGVcbiAgICAgKiBpbiBvcGVuIHN0YW5kYXJkcyBwaGlsb3NvcGh5IHRvIHRoZSBCQkMncyBEaXJhYyBjb2RlYy5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBUaGVvcmEgKCkge1xuICAgICAgICByZXR1cm4gVmlkZW9TdHJlYW1pbmdDb2RlYy5fTUFQLlRoZW9yYTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBWUDggY2FuIGJlIG11bHRpcGxleGVkIGludG8gdGhlIE1hdHJvc2thLWJhc2VkIGNvbnRhaW5lciBmb3JtYXQgV2ViTSBhbG9uZyB3aXRoIFZvcmJpcyBhbmQgT3B1cyBhdWRpby4gVGhlXG4gICAgICogaW1hZ2UgZm9ybWF0IFdlYlAgaXMgYmFzZWQgb24gVlA4J3MgaW50cmEtZnJhbWUgY29kaW5nLiBWUDgncyBkaXJlY3Qgc3VjY2Vzc29yLCBWUDksIGFuZCB0aGUgZW1lcmdpbmcgcm95YWx0eS1cbiAgICAgKiBmcmVlIGludGVybmV0IHZpZGVvIGZvcm1hdCBBVjEgZnJvbSB0aGUgQWxsaWFuY2UgZm9yIE9wZW4gTWVkaWEgKEFPTWVkaWEpIGFyZSBiYXNlZCBvbiBWUDguXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVlA4ICgpIHtcbiAgICAgICAgcmV0dXJuIFZpZGVvU3RyZWFtaW5nQ29kZWMuX01BUC5WUDg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2ltaWxhciB0byBWUDgsIGJ1dCBWUDkgaXMgY3VzdG9taXplZCBmb3IgdmlkZW8gcmVzb2x1dGlvbnMgYmV5b25kIGhpZ2gtZGVmaW5pdGlvbiB2aWRlbyAoVUhEKSBhbmQgYWxzbyBlbmFibGVzXG4gICAgICogbG9zc2xlc3MgY29tcHJlc3Npb24uXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVlA5ICgpIHtcbiAgICAgICAgcmV0dXJuIFZpZGVvU3RyZWFtaW5nQ29kZWMuX01BUC5WUDk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gVmlkZW9TdHJlYW1pbmdDb2RlYy5fdmFsdWVGb3JLZXkoa2V5LCBWaWRlb1N0cmVhbWluZ0NvZGVjLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gVmlkZW9TdHJlYW1pbmdDb2RlYy5fa2V5Rm9yVmFsdWUodmFsdWUsIFZpZGVvU3RyZWFtaW5nQ29kZWMuX01BUCk7XG4gICAgfVxufVxuXG5WaWRlb1N0cmVhbWluZ0NvZGVjLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnSDI2NCc6ICdIMjY0JyxcbiAgICAnSDI2NSc6ICdIMjY1JyxcbiAgICAnVGhlb3JhJzogJ1RoZW9yYScsXG4gICAgJ1ZQOCc6ICdWUDgnLFxuICAgICdWUDknOiAnVlA5Jyxcbn0pO1xuXG5leHBvcnQgeyBWaWRlb1N0cmVhbWluZ0NvZGVjIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogRW51bSBmb3IgZWFjaCB0eXBlIG9mIHZpZGVvIHN0cmVhbWluZyBwcm90b2NvbCB0eXBlLlxuICogQHR5cGVkZWYge0VudW19IFZpZGVvU3RyZWFtaW5nUHJvdG9jb2xcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIFZpZGVvU3RyZWFtaW5nUHJvdG9jb2wgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmF3IHN0cmVhbSBieXRlcyB0aGF0IGNvbnRhaW5zIG5vIHRpbWVzdGFtcCBkYXRhIGFuZCBpcyB0aGUgbG93ZXN0IHN1cHBvcnRlZCB2aWRlbyBzdHJlYW1pbmdcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSQVcgKCkge1xuICAgICAgICByZXR1cm4gVmlkZW9TdHJlYW1pbmdQcm90b2NvbC5fTUFQLlJBVztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSVFAgZmFjaWxpdGF0ZXMgdGhlIHRyYW5zZmVyIG9mIHJlYWwtdGltZSBkYXRhLiBJbmZvcm1hdGlvbiBwcm92aWRlZCBieSB0aGlzIHByb3RvY29sIGluY2x1ZGUgdGltZXN0YW1wcyAoZm9yXG4gICAgICogc3luY2hyb25pemF0aW9uKSwgc2VxdWVuY2UgbnVtYmVycyAoZm9yIHBhY2tldCBsb3NzIGFuZCByZW9yZGVyaW5nIGRldGVjdGlvbikgYW5kIHRoZSBwYXlsb2FkIGZvcm1hdCB3aGljaFxuICAgICAqIGluZGljYXRlcyB0aGUgZW5jb2RlZCBmb3JtYXQgb2YgdGhlIGRhdGEuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUlRQICgpIHtcbiAgICAgICAgcmV0dXJuIFZpZGVvU3RyZWFtaW5nUHJvdG9jb2wuX01BUC5SVFA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIHRyYW5zbWlzc2lvbiBvZiBzdHJlYW1pbmcgZGF0YSBpdHNlbGYgaXMgbm90IGEgdGFzayBvZiBSVFNQLiBNb3N0IFJUU1Agc2VydmVycyB1c2UgdGhlIFJlYWwtdGltZSBUcmFuc3BvcnRcbiAgICAgKiBQcm90b2NvbCAoUlRQKSBpbiBjb25qdW5jdGlvbiB3aXRoIFJlYWwtdGltZSBDb250cm9sIFByb3RvY29sIChSVENQKSBmb3IgbWVkaWEgc3RyZWFtIGRlbGl2ZXJ5LiBIb3dldmVyLCBzb21lXG4gICAgICogdmVuZG9ycyBpbXBsZW1lbnQgcHJvcHJpZXRhcnkgdHJhbnNwb3J0IHByb3RvY29scy5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSVFNQICgpIHtcbiAgICAgICAgcmV0dXJuIFZpZGVvU3RyZWFtaW5nUHJvdG9jb2wuX01BUC5SVFNQO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlYWwtVGltZSBNZXNzYWdpbmcgUHJvdG9jb2wgKFJUTVApIHdhcyBpbml0aWFsbHkgYSBwcm9wcmlldGFyeSBwcm90b2NvbCBkZXZlbG9wZWQgYnkgTWFjcm9tZWRpYSBmb3Igc3RyZWFtaW5nXG4gICAgICogYXVkaW8sIHZpZGVvIGFuZCBkYXRhIG92ZXIgdGhlIEludGVybmV0LCBiZXR3ZWVuIGEgRmxhc2ggcGxheWVyIGFuZCBhIHNlcnZlci4gTWFjcm9tZWRpYSBpcyBub3cgb3duZWQgYnkgQWRvYmUsXG4gICAgICogd2hpY2ggaGFzIHJlbGVhc2VkIGFuIGluY29tcGxldGUgdmVyc2lvbiBvZiB0aGUgc3BlY2lmaWNhdGlvbiBvZiB0aGUgcHJvdG9jb2wgZm9yIHB1YmxpYyB1c2UuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUlRNUCAoKSB7XG4gICAgICAgIHJldHVybiBWaWRlb1N0cmVhbWluZ1Byb3RvY29sLl9NQVAuUlRNUDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgV2ViTSBjb250YWluZXIgaXMgYmFzZWQgb24gYSBwcm9maWxlIG9mIE1hdHJvc2thLiBXZWJNIGluaXRpYWxseSBzdXBwb3J0ZWQgVlA4IHZpZGVvIGFuZCBWb3JiaXMgYXVkaW9cbiAgICAgKiBzdHJlYW1zLiBJbiAyMDEzIGl0IHdhcyB1cGRhdGVkIHRvIGFjY29tbW9kYXRlIFZQOSB2aWRlbyBhbmQgT3B1cyBhdWRpby5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBXRUJNICgpIHtcbiAgICAgICAgcmV0dXJuIFZpZGVvU3RyZWFtaW5nUHJvdG9jb2wuX01BUC5XRUJNO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFZpZGVvU3RyZWFtaW5nUHJvdG9jb2wuX3ZhbHVlRm9yS2V5KGtleSwgVmlkZW9TdHJlYW1pbmdQcm90b2NvbC5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFZpZGVvU3RyZWFtaW5nUHJvdG9jb2wuX2tleUZvclZhbHVlKHZhbHVlLCBWaWRlb1N0cmVhbWluZ1Byb3RvY29sLl9NQVApO1xuICAgIH1cbn1cblxuVmlkZW9TdHJlYW1pbmdQcm90b2NvbC5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1JBVyc6ICdSQVcnLFxuICAgICdSVFAnOiAnUlRQJyxcbiAgICAnUlRTUCc6ICdSVFNQJyxcbiAgICAnUlRNUCc6ICdSVE1QJyxcbiAgICAnV0VCTSc6ICdXRUJNJyxcbn0pO1xuXG5leHBvcnQgeyBWaWRlb1N0cmVhbWluZ1Byb3RvY29sIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IFZpZGVvU3RyZWFtaW5nQ29kZWMgfSBmcm9tICcuLi9lbnVtcy9WaWRlb1N0cmVhbWluZ0NvZGVjLmpzJztcbmltcG9ydCB7IFZpZGVvU3RyZWFtaW5nUHJvdG9jb2wgfSBmcm9tICcuLi9lbnVtcy9WaWRlb1N0cmVhbWluZ1Byb3RvY29sLmpzJztcblxuLyoqXG4gKiBWaWRlbyBzdHJlYW1pbmcgZm9ybWF0cyBhbmQgdGhlaXIgc3BlY2lmaWNhdGlvbnMuXG4gKi9cbmNsYXNzIFZpZGVvU3RyZWFtaW5nRm9ybWF0IGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZpZGVvU3RyZWFtaW5nUHJvdG9jb2x9IHByb3RvY29sIC0gUHJvdG9jb2wgdHlwZSwgc2VlIFZpZGVvU3RyZWFtaW5nUHJvdG9jb2xcbiAgICAgKiBAcmV0dXJuIHtWaWRlb1N0cmVhbWluZ0Zvcm1hdH1cbiAgICAgKi9cbiAgICBzZXRQcm90b2NvbCAocHJvdG9jb2wpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmlkZW9TdHJlYW1pbmdQcm90b2NvbCwgcHJvdG9jb2wpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihWaWRlb1N0cmVhbWluZ0Zvcm1hdC5LRVlfUFJPVE9DT0wsIHByb3RvY29sKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmlkZW9TdHJlYW1pbmdQcm90b2NvbH1cbiAgICAgKi9cbiAgICBnZXRQcm90b2NvbCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChWaWRlb1N0cmVhbWluZ1Byb3RvY29sLCBWaWRlb1N0cmVhbWluZ0Zvcm1hdC5LRVlfUFJPVE9DT0wpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmlkZW9TdHJlYW1pbmdDb2RlY30gY29kZWMgLSBDb2RlYyB0eXBlLCBzZWUgVmlkZW9TdHJlYW1pbmdDb2RlY1xuICAgICAqIEByZXR1cm4ge1ZpZGVvU3RyZWFtaW5nRm9ybWF0fVxuICAgICAqL1xuICAgIHNldENvZGVjIChjb2RlYykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWaWRlb1N0cmVhbWluZ0NvZGVjLCBjb2RlYyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFZpZGVvU3RyZWFtaW5nRm9ybWF0LktFWV9DT0RFQywgY29kZWMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWaWRlb1N0cmVhbWluZ0NvZGVjfVxuICAgICAqL1xuICAgIGdldENvZGVjICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZpZGVvU3RyZWFtaW5nQ29kZWMsIFZpZGVvU3RyZWFtaW5nRm9ybWF0LktFWV9DT0RFQyk7XG4gICAgfVxufVxuXG5WaWRlb1N0cmVhbWluZ0Zvcm1hdC5LRVlfUFJPVE9DT0wgPSAncHJvdG9jb2wnO1xuVmlkZW9TdHJlYW1pbmdGb3JtYXQuS0VZX0NPREVDID0gJ2NvZGVjJztcblxuZXhwb3J0IHsgVmlkZW9TdHJlYW1pbmdGb3JtYXQgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgSW1hZ2VSZXNvbHV0aW9uIH0gZnJvbSAnLi9JbWFnZVJlc29sdXRpb24uanMnO1xuaW1wb3J0IHsgVmlkZW9TdHJlYW1pbmdGb3JtYXQgfSBmcm9tICcuL1ZpZGVvU3RyZWFtaW5nRm9ybWF0LmpzJztcblxuLyoqXG4gKiBDb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCB0aGlzIHN5c3RlbSdzIHZpZGVvIHN0cmVhbWluZyBjYXBhYmlsaXRpZXMuXG4gKi9cbmNsYXNzIFZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eSBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtJbWFnZVJlc29sdXRpb259IHJlc29sdXRpb24gLSBUaGUgcHJlZmVycmVkIHJlc29sdXRpb24gb2YgYSB2aWRlbyBzdHJlYW0gZm9yIGRlY29kaW5nIGFuZCByZW5kZXJpbmcgb25cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhNSS5cbiAgICAgKiBAcmV0dXJuIHtWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHl9XG4gICAgICovXG4gICAgc2V0UHJlZmVycmVkUmVzb2x1dGlvbiAocmVzb2x1dGlvbikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShJbWFnZVJlc29sdXRpb24sIHJlc29sdXRpb24pO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHkuS0VZX1BSRUZFUlJFRF9SRVNPTFVUSU9OLCByZXNvbHV0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7SW1hZ2VSZXNvbHV0aW9ufVxuICAgICAqL1xuICAgIGdldFByZWZlcnJlZFJlc29sdXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoSW1hZ2VSZXNvbHV0aW9uLCBWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHkuS0VZX1BSRUZFUlJFRF9SRVNPTFVUSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYml0cmF0ZSAtIFRoZSBtYXhpbXVtIGJpdHJhdGUgb2YgdmlkZW8gc3RyZWFtIHRoYXQgaXMgc3VwcG9ydGVkLCBpbiBrYnBzLlxuICAgICAqIEByZXR1cm4ge1ZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eX1cbiAgICAgKi9cbiAgICBzZXRNYXhCaXRyYXRlIChiaXRyYXRlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eS5LRVlfTUFYX0JJVFJBVEUsIGJpdHJhdGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0TWF4Qml0cmF0ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHkuS0VZX01BWF9CSVRSQVRFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZpZGVvU3RyZWFtaW5nRm9ybWF0W119IGZvcm1hdHMgLSBEZXRhaWxlZCBpbmZvcm1hdGlvbiBvbiBlYWNoIGZvcm1hdCBzdXBwb3J0ZWQgYnkgdGhpcyBzeXN0ZW0sIGluIGl0c1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZlcnJlZCBvcmRlciAoaS5lLiB0aGUgZmlyc3QgZWxlbWVudCBpbiB0aGUgYXJyYXkgaXMgbW9zdCBwcmVmZXJhYmxlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gdGhlIHN5c3RlbSkuIEVhY2ggb2JqZWN0IHdpbGwgY29udGFpbiBhIFZpZGVvU3RyZWFtaW5nRm9ybWF0IHRoYXRcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmliZXMgd2hhdCBjYW4gYmUgZXhwZWN0ZWQuXG4gICAgICogQHJldHVybiB7VmlkZW9TdHJlYW1pbmdDYXBhYmlsaXR5fVxuICAgICAqL1xuICAgIHNldFN1cHBvcnRlZEZvcm1hdHMgKGZvcm1hdHMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmlkZW9TdHJlYW1pbmdGb3JtYXQsIGZvcm1hdHMsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHkuS0VZX1NVUFBPUlRFRF9GT1JNQVRTLCBmb3JtYXRzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmlkZW9TdHJlYW1pbmdGb3JtYXRbXX1cbiAgICAgKi9cbiAgICBnZXRTdXBwb3J0ZWRGb3JtYXRzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZpZGVvU3RyZWFtaW5nRm9ybWF0LCBWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHkuS0VZX1NVUFBPUlRFRF9GT1JNQVRTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHN1cHBvcnRlZCAtIFRydWUgaWYgdGhlIHN5c3RlbSBjYW4gdXRpbGl6ZSB0aGUgaGFwdGljIHNwYXRpYWwgZGF0YSBmcm9tIHRoZSBzb3VyY2UgYmVpbmdcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbWVkLiBJZiBub3QgaW5jbHVkZWQsIGl0IGNhbiBiZSBhc3N1bWVkIHRoZSBtb2R1bGUgZG9lc24ndCBzdXBwb3J0IGhhcHRpY1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BhdGlhbCBkYXRhJy5cbiAgICAgKiBAcmV0dXJuIHtWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHl9XG4gICAgICovXG4gICAgc2V0SGFwdGljU3BhdGlhbERhdGFTdXBwb3J0ZWQgKHN1cHBvcnRlZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHkuS0VZX0hBUFRJQ19TUEFUSUFMX0RBVEFfU1VQUE9SVEVELCBzdXBwb3J0ZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEhhcHRpY1NwYXRpYWxEYXRhU3VwcG9ydGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eS5LRVlfSEFQVElDX1NQQVRJQUxfREFUQV9TVVBQT1JURUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzaXplIC0gVGhlIGRpYWdvbmFsIHNjcmVlbiBzaXplIGluIGluY2hlcy5cbiAgICAgKiBAcmV0dXJuIHtWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHl9XG4gICAgICovXG4gICAgc2V0RGlhZ29uYWxTY3JlZW5TaXplIChzaXplKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eS5LRVlfRElBR09OQUxfU0NSRUVOX1NJWkUsIHNpemUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0RGlhZ29uYWxTY3JlZW5TaXplICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eS5LRVlfRElBR09OQUxfU0NSRUVOX1NJWkUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBpbmNoIC0gUFBJIGlzIHRoZSBkaWFnb25hbCByZXNvbHV0aW9uIGluIHBpeGVscyBkaXZpZGVkIGJ5IHRoZSBkaWFnb25hbCBzY3JlZW4gc2l6ZSBpbiBpbmNoZXMuXG4gICAgICogQHJldHVybiB7VmlkZW9TdHJlYW1pbmdDYXBhYmlsaXR5fVxuICAgICAqL1xuICAgIHNldFBpeGVsUGVySW5jaCAoaW5jaCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHkuS0VZX1BJWEVMX1BFUl9JTkNILCBpbmNoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFBpeGVsUGVySW5jaCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHkuS0VZX1BJWEVMX1BFUl9JTkNIKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc2NhbGUgLSBUaGUgc2NhbGluZyBmYWN0b3IgdGhlIGFwcCBzaG91bGQgdXNlIHRvIGNoYW5nZSB0aGUgc2l6ZSBvZiB0aGUgcHJvamVjdGluZyB2aWV3LlxuICAgICAqIEByZXR1cm4ge1ZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eX1cbiAgICAgKi9cbiAgICBzZXRTY2FsZSAoc2NhbGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVmlkZW9TdHJlYW1pbmdDYXBhYmlsaXR5LktFWV9TQ0FMRSwgc2NhbGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0U2NhbGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoVmlkZW9TdHJlYW1pbmdDYXBhYmlsaXR5LktFWV9TQ0FMRSk7XG4gICAgfVxufVxuXG5WaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHkuS0VZX1BSRUZFUlJFRF9SRVNPTFVUSU9OID0gJ3ByZWZlcnJlZFJlc29sdXRpb24nO1xuVmlkZW9TdHJlYW1pbmdDYXBhYmlsaXR5LktFWV9NQVhfQklUUkFURSA9ICdtYXhCaXRyYXRlJztcblZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eS5LRVlfU1VQUE9SVEVEX0ZPUk1BVFMgPSAnc3VwcG9ydGVkRm9ybWF0cyc7XG5WaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHkuS0VZX0hBUFRJQ19TUEFUSUFMX0RBVEFfU1VQUE9SVEVEID0gJ2hhcHRpY1NwYXRpYWxEYXRhU3VwcG9ydGVkJztcblZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eS5LRVlfRElBR09OQUxfU0NSRUVOX1NJWkUgPSAnZGlhZ29uYWxTY3JlZW5TaXplJztcblZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eS5LRVlfUElYRUxfUEVSX0lOQ0ggPSAncGl4ZWxQZXJJbmNoJztcblZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eS5LRVlfU0NBTEUgPSAnc2NhbGUnO1xuXG5leHBvcnQgeyBWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHkgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuXG4vKipcbiAqIEV4dGVuZGVkIGNhcGFiaWxpdGllcyBvZiB0aGUgbW9kdWxlJ3MgcGhvbmUgZmVhdHVyZVxuICovXG5jbGFzcyBQaG9uZUNhcGFiaWxpdHkgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gZW5hYmxlZCAtIElmIHRoZSBtb2R1bGUgaGFzIHRoZSBhYmlsaXR5IHRvIHBlcmZvcm0gZGlhbCBudW1iZXJcbiAgICAgKiBAcmV0dXJuIHtQaG9uZUNhcGFiaWxpdHl9XG4gICAgICovXG4gICAgc2V0RGlhbE51bWJlckVuYWJsZWQgKGVuYWJsZWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUGhvbmVDYXBhYmlsaXR5LktFWV9ESUFMX05VTUJFUl9FTkFCTEVELCBlbmFibGVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXREaWFsTnVtYmVyRW5hYmxlZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihQaG9uZUNhcGFiaWxpdHkuS0VZX0RJQUxfTlVNQkVSX0VOQUJMRUQpO1xuICAgIH1cbn1cblxuUGhvbmVDYXBhYmlsaXR5LktFWV9ESUFMX05VTUJFUl9FTkFCTEVEID0gJ2RpYWxOdW1iZXJFbmFibGVkJztcblxuZXhwb3J0IHsgUGhvbmVDYXBhYmlsaXR5IH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgV2luZG93VHlwZSB9IGZyb20gJy4uL2VudW1zL1dpbmRvd1R5cGUuanMnO1xuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcblxuY2xhc3MgV2luZG93VHlwZUNhcGFiaWxpdGllcyBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtXaW5kb3dUeXBlfSB0eXBlXG4gICAgICogQHJldHVybiB7V2luZG93VHlwZUNhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRUeXBlICh0eXBlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFdpbmRvd1R5cGUsIHR5cGUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihXaW5kb3dUeXBlQ2FwYWJpbGl0aWVzLktFWV9UWVBFLCB0eXBlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7V2luZG93VHlwZX1cbiAgICAgKi9cbiAgICBnZXRUeXBlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFdpbmRvd1R5cGUsIFdpbmRvd1R5cGVDYXBhYmlsaXRpZXMuS0VZX1RZUEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB3aW5kb3dzXG4gICAgICogQHJldHVybiB7V2luZG93VHlwZUNhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRNYXhpbXVtTnVtYmVyT2ZXaW5kb3dzICh3aW5kb3dzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdpbmRvd1R5cGVDYXBhYmlsaXRpZXMuS0VZX01BWElNVU1fTlVNQkVSX09GX1dJTkRPV1MsIHdpbmRvd3MpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0TWF4aW11bU51bWJlck9mV2luZG93cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihXaW5kb3dUeXBlQ2FwYWJpbGl0aWVzLktFWV9NQVhJTVVNX05VTUJFUl9PRl9XSU5ET1dTKTtcbiAgICB9XG59XG5cbldpbmRvd1R5cGVDYXBhYmlsaXRpZXMuS0VZX1RZUEUgPSAndHlwZSc7XG5XaW5kb3dUeXBlQ2FwYWJpbGl0aWVzLktFWV9NQVhJTVVNX05VTUJFUl9PRl9XSU5ET1dTID0gJ21heGltdW1OdW1iZXJPZldpbmRvd3MnO1xuXG5leHBvcnQgeyBXaW5kb3dUeXBlQ2FwYWJpbGl0aWVzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgSW1hZ2VGaWVsZCB9IGZyb20gJy4vSW1hZ2VGaWVsZC5qcyc7XG5pbXBvcnQgeyBUZXh0RmllbGQgfSBmcm9tICcuL1RleHRGaWVsZC5qcyc7XG5pbXBvcnQgeyBJbWFnZVR5cGUgfSBmcm9tICcuLi9lbnVtcy9JbWFnZVR5cGUuanMnO1xuaW1wb3J0IHsgTWVudUxheW91dCB9IGZyb20gJy4uL2VudW1zL01lbnVMYXlvdXQuanMnO1xuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IEJ1dHRvbkNhcGFiaWxpdGllcyB9IGZyb20gJy4vQnV0dG9uQ2FwYWJpbGl0aWVzLmpzJztcbmltcG9ydCB7IFNvZnRCdXR0b25DYXBhYmlsaXRpZXMgfSBmcm9tICcuL1NvZnRCdXR0b25DYXBhYmlsaXRpZXMuanMnO1xuXG5jbGFzcyBXaW5kb3dDYXBhYmlsaXR5IGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaWQgLSBUaGUgc3BlY2lmaWVkIElEIG9mIHRoZSB3aW5kb3cuIFRoaXMgSUQgaXMgZWl0aGVyIG9uZSB1c2VkIHdoZW4gc2VuZGluZyB0aGUgQ3JlYXRlV2luZG93XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdCwgb3Igb25lIG9mIHRoZSBwcmVkZWZpbmVkIHdpbmRvdyBJRCB2YWx1ZXMgZnJvbSB0aGUgZW51bSBQcmVkZWZpbmVkV2luZG93cy4gSWZcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBvbW1pdGVkLCB2YWx1ZSBpcyBhc3N1bWVkIHRvIGJlIHRoZSBtYWluIHdpbmRvdyBvbiB0aGUgbWFpbiBkaXNwbGF5LlxuICAgICAqIEByZXR1cm4ge1dpbmRvd0NhcGFiaWxpdHl9XG4gICAgICovXG4gICAgc2V0V2luZG93SUQgKGlkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdpbmRvd0NhcGFiaWxpdHkuS0VZX1dJTkRPV19JRCwgaWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0V2luZG93SUQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoV2luZG93Q2FwYWJpbGl0eS5LRVlfV0lORE9XX0lEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1RleHRGaWVsZFtdfSBmaWVsZHMgLSBBIHNldCBvZiBhbGwgZmllbGRzIHRoYXQgc3VwcG9ydCB0ZXh0IGRhdGEuIFNlZSBUZXh0RmllbGRcbiAgICAgKiBAcmV0dXJuIHtXaW5kb3dDYXBhYmlsaXR5fVxuICAgICAqL1xuICAgIHNldFRleHRGaWVsZHMgKGZpZWxkcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShUZXh0RmllbGQsIGZpZWxkcywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdpbmRvd0NhcGFiaWxpdHkuS0VZX1RFWFRfRklFTERTLCBmaWVsZHMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtUZXh0RmllbGRbXX1cbiAgICAgKi9cbiAgICBnZXRUZXh0RmllbGRzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFRleHRGaWVsZCwgV2luZG93Q2FwYWJpbGl0eS5LRVlfVEVYVF9GSUVMRFMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7SW1hZ2VGaWVsZFtdfSBmaWVsZHMgLSBBIHNldCBvZiBhbGwgZmllbGRzIHRoYXQgc3VwcG9ydCBpbWFnZXMuIFNlZSBJbWFnZUZpZWxkXG4gICAgICogQHJldHVybiB7V2luZG93Q2FwYWJpbGl0eX1cbiAgICAgKi9cbiAgICBzZXRJbWFnZUZpZWxkcyAoZmllbGRzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEltYWdlRmllbGQsIGZpZWxkcywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdpbmRvd0NhcGFiaWxpdHkuS0VZX0lNQUdFX0ZJRUxEUywgZmllbGRzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7SW1hZ2VGaWVsZFtdfVxuICAgICAqL1xuICAgIGdldEltYWdlRmllbGRzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEltYWdlRmllbGQsIFdpbmRvd0NhcGFiaWxpdHkuS0VZX0lNQUdFX0ZJRUxEUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtJbWFnZVR5cGVbXX0gc3VwcG9ydGVkIC0gUHJvdmlkZXMgaW5mb3JtYXRpb24gYWJvdXQgaW1hZ2UgdHlwZXMgc3VwcG9ydGVkIGJ5IHRoZSBzeXN0ZW0uXG4gICAgICogQHJldHVybiB7V2luZG93Q2FwYWJpbGl0eX1cbiAgICAgKi9cbiAgICBzZXRJbWFnZVR5cGVTdXBwb3J0ZWQgKHN1cHBvcnRlZCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShJbWFnZVR5cGUsIHN1cHBvcnRlZCwgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdpbmRvd0NhcGFiaWxpdHkuS0VZX0lNQUdFX1RZUEVfU1VQUE9SVEVELCBzdXBwb3J0ZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtJbWFnZVR5cGVbXX1cbiAgICAgKi9cbiAgICBnZXRJbWFnZVR5cGVTdXBwb3J0ZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoSW1hZ2VUeXBlLCBXaW5kb3dDYXBhYmlsaXR5LktFWV9JTUFHRV9UWVBFX1NVUFBPUlRFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmdbXX0gYXZhaWxhYmxlIC0gQSBzZXQgb2YgYWxsIHdpbmRvdyB0ZW1wbGF0ZXMgYXZhaWxhYmxlIG9uIHRoZSBoZWFkIHVuaXQuXG4gICAgICogQHJldHVybiB7V2luZG93Q2FwYWJpbGl0eX1cbiAgICAgKi9cbiAgICBzZXRUZW1wbGF0ZXNBdmFpbGFibGUgKGF2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihXaW5kb3dDYXBhYmlsaXR5LktFWV9URU1QTEFURVNfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmdbXX1cbiAgICAgKi9cbiAgICBnZXRUZW1wbGF0ZXNBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoV2luZG93Q2FwYWJpbGl0eS5LRVlfVEVNUExBVEVTX0FWQUlMQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGF2YWlsYWJsZSAtIFRoZSBudW1iZXIgb2Ygb24td2luZG93IGN1c3RvbSBwcmVzZXRzIGF2YWlsYWJsZSAoaWYgYW55KTsgb3RoZXJ3aXNlIG9taXR0ZWQuXG4gICAgICogQHJldHVybiB7V2luZG93Q2FwYWJpbGl0eX1cbiAgICAgKi9cbiAgICBzZXROdW1DdXN0b21QcmVzZXRzQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoV2luZG93Q2FwYWJpbGl0eS5LRVlfTlVNX0NVU1RPTV9QUkVTRVRTX0FWQUlMQUJMRSwgYXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldE51bUN1c3RvbVByZXNldHNBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoV2luZG93Q2FwYWJpbGl0eS5LRVlfTlVNX0NVU1RPTV9QUkVTRVRTX0FWQUlMQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCdXR0b25DYXBhYmlsaXRpZXNbXX0gY2FwYWJpbGl0aWVzIC0gVGhlIG51bWJlciBvZiBidXR0b25zIGFuZCB0aGUgY2FwYWJpbGl0aWVzIG9mIGVhY2ggb24td2luZG93IGJ1dHRvbi5cbiAgICAgKiBAcmV0dXJuIHtXaW5kb3dDYXBhYmlsaXR5fVxuICAgICAqL1xuICAgIHNldEJ1dHRvbkNhcGFiaWxpdGllcyAoY2FwYWJpbGl0aWVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEJ1dHRvbkNhcGFiaWxpdGllcywgY2FwYWJpbGl0aWVzLCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoV2luZG93Q2FwYWJpbGl0eS5LRVlfQlVUVE9OX0NBUEFCSUxJVElFUywgY2FwYWJpbGl0aWVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7QnV0dG9uQ2FwYWJpbGl0aWVzW119XG4gICAgICovXG4gICAgZ2V0QnV0dG9uQ2FwYWJpbGl0aWVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEJ1dHRvbkNhcGFiaWxpdGllcywgV2luZG93Q2FwYWJpbGl0eS5LRVlfQlVUVE9OX0NBUEFCSUxJVElFUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzW119IGNhcGFiaWxpdGllcyAtIFRoZSBudW1iZXIgb2Ygc29mdCBidXR0b25zIGF2YWlsYWJsZSBvbi13aW5kb3cgYW5kIHRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXBhYmlsaXRpZXMgZm9yIGVhY2ggYnV0dG9uLlxuICAgICAqIEByZXR1cm4ge1dpbmRvd0NhcGFiaWxpdHl9XG4gICAgICovXG4gICAgc2V0U29mdEJ1dHRvbkNhcGFiaWxpdGllcyAoY2FwYWJpbGl0aWVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFNvZnRCdXR0b25DYXBhYmlsaXRpZXMsIGNhcGFiaWxpdGllcywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdpbmRvd0NhcGFiaWxpdHkuS0VZX1NPRlRfQlVUVE9OX0NBUEFCSUxJVElFUywgY2FwYWJpbGl0aWVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U29mdEJ1dHRvbkNhcGFiaWxpdGllc1tdfVxuICAgICAqL1xuICAgIGdldFNvZnRCdXR0b25DYXBhYmlsaXRpZXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoU29mdEJ1dHRvbkNhcGFiaWxpdGllcywgV2luZG93Q2FwYWJpbGl0eS5LRVlfU09GVF9CVVRUT05fQ0FQQUJJTElUSUVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge01lbnVMYXlvdXRbXX0gYXZhaWxhYmxlIC0gQW4gYXJyYXkgb2YgYXZhaWxhYmxlIG1lbnUgbGF5b3V0cy4gSWYgdGhpcyBwYXJhbWV0ZXIgaXMgbm90IHByb3ZpZGVkLCBvbmx5IHRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgTElTVGAgbGF5b3V0IGlzIGFzc3VtZWQgdG8gYmUgYXZhaWxhYmxlXG4gICAgICogQHJldHVybiB7V2luZG93Q2FwYWJpbGl0eX1cbiAgICAgKi9cbiAgICBzZXRNZW51TGF5b3V0c0F2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKE1lbnVMYXlvdXQsIGF2YWlsYWJsZSwgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdpbmRvd0NhcGFiaWxpdHkuS0VZX01FTlVfTEFZT1VUU19BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge01lbnVMYXlvdXRbXX1cbiAgICAgKi9cbiAgICBnZXRNZW51TGF5b3V0c0F2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChNZW51TGF5b3V0LCBXaW5kb3dDYXBhYmlsaXR5LktFWV9NRU5VX0xBWU9VVFNfQVZBSUxBQkxFKTtcbiAgICB9XG59XG5cbldpbmRvd0NhcGFiaWxpdHkuS0VZX1dJTkRPV19JRCA9ICd3aW5kb3dJRCc7XG5XaW5kb3dDYXBhYmlsaXR5LktFWV9URVhUX0ZJRUxEUyA9ICd0ZXh0RmllbGRzJztcbldpbmRvd0NhcGFiaWxpdHkuS0VZX0lNQUdFX0ZJRUxEUyA9ICdpbWFnZUZpZWxkcyc7XG5XaW5kb3dDYXBhYmlsaXR5LktFWV9JTUFHRV9UWVBFX1NVUFBPUlRFRCA9ICdpbWFnZVR5cGVTdXBwb3J0ZWQnO1xuV2luZG93Q2FwYWJpbGl0eS5LRVlfVEVNUExBVEVTX0FWQUlMQUJMRSA9ICd0ZW1wbGF0ZXNBdmFpbGFibGUnO1xuV2luZG93Q2FwYWJpbGl0eS5LRVlfTlVNX0NVU1RPTV9QUkVTRVRTX0FWQUlMQUJMRSA9ICdudW1DdXN0b21QcmVzZXRzQXZhaWxhYmxlJztcbldpbmRvd0NhcGFiaWxpdHkuS0VZX0JVVFRPTl9DQVBBQklMSVRJRVMgPSAnYnV0dG9uQ2FwYWJpbGl0aWVzJztcbldpbmRvd0NhcGFiaWxpdHkuS0VZX1NPRlRfQlVUVE9OX0NBUEFCSUxJVElFUyA9ICdzb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzJztcbldpbmRvd0NhcGFiaWxpdHkuS0VZX01FTlVfTEFZT1VUU19BVkFJTEFCTEUgPSAnbWVudUxheW91dHNBdmFpbGFibGUnO1xuXG5leHBvcnQgeyBXaW5kb3dDYXBhYmlsaXR5IH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgV2luZG93VHlwZUNhcGFiaWxpdGllcyB9IGZyb20gJy4vV2luZG93VHlwZUNhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBXaW5kb3dDYXBhYmlsaXR5IH0gZnJvbSAnLi9XaW5kb3dDYXBhYmlsaXR5LmpzJztcbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5cbmNsYXNzIERpc3BsYXlDYXBhYmlsaXR5IGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICAgICAqIEByZXR1cm4ge0Rpc3BsYXlDYXBhYmlsaXR5fVxuICAgICAqL1xuICAgIHNldERpc3BsYXlOYW1lIChuYW1lKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKERpc3BsYXlDYXBhYmlsaXR5LktFWV9ESVNQTEFZX05BTUUsIG5hbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0RGlzcGxheU5hbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoRGlzcGxheUNhcGFiaWxpdHkuS0VZX0RJU1BMQVlfTkFNRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtXaW5kb3dUeXBlQ2FwYWJpbGl0aWVzW119IHN1cHBvcnRlZCAtIEluZm9ybXMgdGhlIGFwcGxpY2F0aW9uIGhvdyBtYW55IHdpbmRvd3MgdGhlIGFwcCBpcyBhbGxvd2VkIHRvXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZSBwZXIgdHlwZS5cbiAgICAgKiBAcmV0dXJuIHtEaXNwbGF5Q2FwYWJpbGl0eX1cbiAgICAgKi9cbiAgICBzZXRXaW5kb3dUeXBlU3VwcG9ydGVkIChzdXBwb3J0ZWQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoV2luZG93VHlwZUNhcGFiaWxpdGllcywgc3VwcG9ydGVkLCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoRGlzcGxheUNhcGFiaWxpdHkuS0VZX1dJTkRPV19UWVBFX1NVUFBPUlRFRCwgc3VwcG9ydGVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7V2luZG93VHlwZUNhcGFiaWxpdGllc1tdfVxuICAgICAqL1xuICAgIGdldFdpbmRvd1R5cGVTdXBwb3J0ZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoV2luZG93VHlwZUNhcGFiaWxpdGllcywgRGlzcGxheUNhcGFiaWxpdHkuS0VZX1dJTkRPV19UWVBFX1NVUFBPUlRFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtXaW5kb3dDYXBhYmlsaXR5W119IGNhcGFiaWxpdGllcyAtIENvbnRhaW5zIGEgbGlzdCBvZiBjYXBhYmlsaXRpZXMgb2YgYWxsIHdpbmRvd3MgcmVsYXRlZCB0byB0aGUgYXBwLlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPbmNlIHRoZSBhcHAgaGFzIHJlZ2lzdGVyZWQgdGhlIGNhcGFiaWxpdGllcyBvZiBhbGwgd2luZG93cyBhcmVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdmlkZWQuIEdldFN5c3RlbUNhcGFiaWxpdHkgc3RpbGwgYWxsb3dzIHJlcXVlc3Rpbmcgd2luZG93XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcGFiaWxpdGllcyBvZiBhbGwgd2luZG93cy4gQWZ0ZXIgcmVnaXN0cmF0aW9uLCBvbmx5IHdpbmRvd3Mgd2l0aFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXBhYmlsaXRpZXMgY2hhbmdlZCB3aWxsIGJlIGluY2x1ZGVkLiBGb2xsb3dpbmcgY2FzZXMgd2lsbCBjYXVzZSBvbmx5XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFmZmVjdGVkIHdpbmRvd3MgdG8gYmUgaW5jbHVkZWQ6IDEuIEFwcCBjcmVhdGVzIGEgbmV3IHdpbmRvdy4gQWZ0ZXJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIHdpbmRvdyBpcyBjcmVhdGVkLCBhIHN5c3RlbSBjYXBhYmlsaXR5IG5vdGlmaWNhdGlvbiB3aWxsIGJlIHNlbnRcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVsYXRlZCBvbmx5IHRvIHRoZSBjcmVhdGVkIHdpbmRvdy4gMi4gQXBwIHNldHMgYSBuZXcgbGF5b3V0IHRvIHRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cuIFRoZSBuZXcgbGF5b3V0IGNoYW5nZXMgd2luZG93IGNhcGFiaWx0aWVzLiBUaGUgbm90aWZpY2F0aW9uXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbGwgcmVmbGVjdCB0aG9zZSBjaGFuZ2VzIHRvIHRoZSBzaW5nbGUgd2luZG93LlxuICAgICAqIEByZXR1cm4ge0Rpc3BsYXlDYXBhYmlsaXR5fVxuICAgICAqL1xuICAgIHNldFdpbmRvd0NhcGFiaWxpdGllcyAoY2FwYWJpbGl0aWVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFdpbmRvd0NhcGFiaWxpdHksIGNhcGFiaWxpdGllcywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKERpc3BsYXlDYXBhYmlsaXR5LktFWV9XSU5ET1dfQ0FQQUJJTElUSUVTLCBjYXBhYmlsaXRpZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtXaW5kb3dDYXBhYmlsaXR5W119XG4gICAgICovXG4gICAgZ2V0V2luZG93Q2FwYWJpbGl0aWVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFdpbmRvd0NhcGFiaWxpdHksIERpc3BsYXlDYXBhYmlsaXR5LktFWV9XSU5ET1dfQ0FQQUJJTElUSUVTKTtcbiAgICB9XG59XG5cbkRpc3BsYXlDYXBhYmlsaXR5LktFWV9ESVNQTEFZX05BTUUgPSAnZGlzcGxheU5hbWUnO1xuRGlzcGxheUNhcGFiaWxpdHkuS0VZX1dJTkRPV19UWVBFX1NVUFBPUlRFRCA9ICd3aW5kb3dUeXBlU3VwcG9ydGVkJztcbkRpc3BsYXlDYXBhYmlsaXR5LktFWV9XSU5ET1dfQ0FQQUJJTElUSUVTID0gJ3dpbmRvd0NhcGFiaWxpdGllcyc7XG5cbmV4cG9ydCB7IERpc3BsYXlDYXBhYmlsaXR5IH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IE1vZHVsZUluZm8gfSBmcm9tICcuL01vZHVsZUluZm8uanMnO1xuXG5jbGFzcyBBdWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIC0gVGhlIHNob3J0IGZyaWVuZGx5IG5hbWUgb2YgdGhlIGxpZ2h0IGNvbnRyb2wgbW9kdWxlLiBJdCBzaG91bGQgbm90IGJlIHVzZWQgdG8gaWRlbnRpZnkgYVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgbW9kdWxlIGJ5IG1vYmlsZSBhcHBsaWNhdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtBdWRpb0NvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0TW9kdWxlTmFtZSAobmFtZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBdWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX01PRFVMRV9OQU1FLCBuYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldE1vZHVsZU5hbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQXVkaW9Db250cm9sQ2FwYWJpbGl0aWVzLktFWV9NT0RVTEVfTkFNRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtNb2R1bGVJbmZvfSBpbmZvIC0gSW5mb3JtYXRpb24gYWJvdXQgYSBSQyBtb2R1bGUsIGluY2x1ZGluZyBpdHMgaWQuXG4gICAgICogQHJldHVybiB7QXVkaW9Db250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldE1vZHVsZUluZm8gKGluZm8pIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTW9kdWxlSW5mbywgaW5mbyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEF1ZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfTU9EVUxFX0lORk8sIGluZm8pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtNb2R1bGVJbmZvfVxuICAgICAqL1xuICAgIGdldE1vZHVsZUluZm8gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTW9kdWxlSW5mbywgQXVkaW9Db250cm9sQ2FwYWJpbGl0aWVzLktFWV9NT0RVTEVfSU5GTyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhdmFpbGFibGUgLSBBdmFpbGFiaWxpdHkgb2YgdGhlIGNvbnRyb2wgb2YgYXVkaW8gc291cmNlLlxuICAgICAqIEByZXR1cm4ge0F1ZGlvQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRTb3VyY2VBdmFpbGFibGUgKGF2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBdWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX1NPVVJDRV9BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0U291cmNlQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEF1ZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfU09VUkNFX0FWQUlMQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhdmFpbGFibGUgLSBBdmFpbGFiaWxpdHkgb2YgdGhlIGtlZXBDb250ZXh0IHBhcmFtZXRlci5cbiAgICAgKiBAcmV0dXJuIHtBdWRpb0NvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0S2VlcENvbnRleHRBdmFpbGFibGUgKGF2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBdWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0tFRVBfQ09OVEVYVF9BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0S2VlcENvbnRleHRBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQXVkaW9Db250cm9sQ2FwYWJpbGl0aWVzLktFWV9LRUVQX0NPTlRFWFRfQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGF2YWlsYWJsZSAtIEF2YWlsYWJpbGl0eSBvZiB0aGUgY29udHJvbCBvZiBhdWRpbyB2b2x1bWUuXG4gICAgICogQHJldHVybiB7QXVkaW9Db250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldFZvbHVtZUF2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEF1ZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfVk9MVU1FX0FWQUlMQUJMRSwgYXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRWb2x1bWVBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQXVkaW9Db250cm9sQ2FwYWJpbGl0aWVzLktFWV9WT0xVTUVfQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGF2YWlsYWJsZSAtIEF2YWlsYWJpbGl0eSBvZiB0aGUgY29udHJvbCBvZiBFcXVhbGl6ZXIgU2V0dGluZ3MuXG4gICAgICogQHJldHVybiB7QXVkaW9Db250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldEVxdWFsaXplckF2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEF1ZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfRVFVQUxJWkVSX0FWQUlMQUJMRSwgYXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRFcXVhbGl6ZXJBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQXVkaW9Db250cm9sQ2FwYWJpbGl0aWVzLktFWV9FUVVBTElaRVJfQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaWQgLSBNdXN0IGJlIGluY2x1ZGVkIGlmIGVxdWFsaXplckF2YWlsYWJsZT10cnVlLCBhbmQgYXNzdW1lIGFsbCBJRHMgc3RhcnRpbmcgZnJvbSAxIHRvIHRoaXNcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSBhcmUgdmFsaWRcbiAgICAgKiBAcmV0dXJuIHtBdWRpb0NvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0RXF1YWxpemVyTWF4Q2hhbm5lbElkIChpZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBdWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0VRVUFMSVpFUl9NQVhfQ0hBTk5FTF9JRCwgaWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0RXF1YWxpemVyTWF4Q2hhbm5lbElkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEF1ZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfRVFVQUxJWkVSX01BWF9DSEFOTkVMX0lEKTtcbiAgICB9XG59XG5cbkF1ZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfTU9EVUxFX05BTUUgPSAnbW9kdWxlTmFtZSc7XG5BdWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX01PRFVMRV9JTkZPID0gJ21vZHVsZUluZm8nO1xuQXVkaW9Db250cm9sQ2FwYWJpbGl0aWVzLktFWV9TT1VSQ0VfQVZBSUxBQkxFID0gJ3NvdXJjZUF2YWlsYWJsZSc7XG5BdWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0tFRVBfQ09OVEVYVF9BVkFJTEFCTEUgPSAna2VlcENvbnRleHRBdmFpbGFibGUnO1xuQXVkaW9Db250cm9sQ2FwYWJpbGl0aWVzLktFWV9WT0xVTUVfQVZBSUxBQkxFID0gJ3ZvbHVtZUF2YWlsYWJsZSc7XG5BdWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0VRVUFMSVpFUl9BVkFJTEFCTEUgPSAnZXF1YWxpemVyQXZhaWxhYmxlJztcbkF1ZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfRVFVQUxJWkVSX01BWF9DSEFOTkVMX0lEID0gJ2VxdWFsaXplck1heENoYW5uZWxJZCc7XG5cbmV4cG9ydCB7IEF1ZGlvQ29udHJvbENhcGFiaWxpdGllcyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBMaWdodE5hbWUgfSBmcm9tICcuLi9lbnVtcy9MaWdodE5hbWUuanMnO1xuXG5jbGFzcyBMaWdodENhcGFiaWxpdGllcyBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtMaWdodE5hbWV9IG5hbWVcbiAgICAgKiBAcmV0dXJuIHtMaWdodENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXROYW1lIChuYW1lKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKExpZ2h0TmFtZSwgbmFtZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKExpZ2h0Q2FwYWJpbGl0aWVzLktFWV9OQU1FLCBuYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TGlnaHROYW1lfVxuICAgICAqL1xuICAgIGdldE5hbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTGlnaHROYW1lLCBMaWdodENhcGFiaWxpdGllcy5LRVlfTkFNRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhdmFpbGFibGUgLSBJbmRpY2F0ZXMgaWYgdGhlIHN0YXR1cyAoT04vT0ZGKSBjYW4gYmUgc2V0IHJlbW90ZWx5LiBBcHAgc2hhbGwgbm90IHVzZSByZWFkLW9ubHlcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcyAoUkFNUF9VUC9SQU1QX0RPV04vVU5LTk9XTi9JTlZBTElEKSBpbiBhIHNldEludGVyaW9yVmVoaWNsZURhdGEgcmVxdWVzdC5cbiAgICAgKiBAcmV0dXJuIHtMaWdodENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRTdGF0dXNBdmFpbGFibGUgKGF2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihMaWdodENhcGFiaWxpdGllcy5LRVlfU1RBVFVTX0FWQUlMQUJMRSwgYXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRTdGF0dXNBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoTGlnaHRDYXBhYmlsaXRpZXMuS0VZX1NUQVRVU19BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlIC0gSW5kaWNhdGVzIGlmIHRoZSBsaWdodCdzIGRlbnNpdHkgY2FuIGJlIHNldCByZW1vdGVseSAoc2ltaWxhciB0byBhIGRpbW1lcikuXG4gICAgICogQHJldHVybiB7TGlnaHRDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0RGVuc2l0eUF2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKExpZ2h0Q2FwYWJpbGl0aWVzLktFWV9ERU5TSVRZX0FWQUlMQUJMRSwgYXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXREZW5zaXR5QXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKExpZ2h0Q2FwYWJpbGl0aWVzLktFWV9ERU5TSVRZX0FWQUlMQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhdmFpbGFibGUgLSBJbmRpY2F0ZXMgaWYgdGhlIGxpZ2h0J3MgY29sb3IgY2FuIGJlIHNldCByZW1vdGVseSBieSB1c2luZyB0aGUgc1JHQiBjb2xvciBzcGFjZS5cbiAgICAgKiBAcmV0dXJuIHtMaWdodENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRSZ2JDb2xvclNwYWNlQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTGlnaHRDYXBhYmlsaXRpZXMuS0VZX1JHQl9DT0xPUl9TUEFDRV9BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0UmdiQ29sb3JTcGFjZUF2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihMaWdodENhcGFiaWxpdGllcy5LRVlfUkdCX0NPTE9SX1NQQUNFX0FWQUlMQUJMRSk7XG4gICAgfVxufVxuXG5MaWdodENhcGFiaWxpdGllcy5LRVlfTkFNRSA9ICduYW1lJztcbkxpZ2h0Q2FwYWJpbGl0aWVzLktFWV9TVEFUVVNfQVZBSUxBQkxFID0gJ3N0YXR1c0F2YWlsYWJsZSc7XG5MaWdodENhcGFiaWxpdGllcy5LRVlfREVOU0lUWV9BVkFJTEFCTEUgPSAnZGVuc2l0eUF2YWlsYWJsZSc7XG5MaWdodENhcGFiaWxpdGllcy5LRVlfUkdCX0NPTE9SX1NQQUNFX0FWQUlMQUJMRSA9ICdyZ2JDb2xvclNwYWNlQXZhaWxhYmxlJztcblxuZXhwb3J0IHsgTGlnaHRDYXBhYmlsaXRpZXMgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgTGlnaHRDYXBhYmlsaXRpZXMgfSBmcm9tICcuL0xpZ2h0Q2FwYWJpbGl0aWVzLmpzJztcbmltcG9ydCB7IE1vZHVsZUluZm8gfSBmcm9tICcuL01vZHVsZUluZm8uanMnO1xuXG5jbGFzcyBMaWdodENvbnRyb2xDYXBhYmlsaXRpZXMgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIC0gVGhlIHNob3J0IGZyaWVuZGx5IG5hbWUgb2YgdGhlIGxpZ2h0IGNvbnRyb2wgbW9kdWxlLiBJdCBzaG91bGQgbm90IGJlIHVzZWQgdG8gaWRlbnRpZnkgYVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgbW9kdWxlIGJ5IG1vYmlsZSBhcHBsaWNhdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtMaWdodENvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0TW9kdWxlTmFtZSAobmFtZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihMaWdodENvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX01PRFVMRV9OQU1FLCBuYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldE1vZHVsZU5hbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoTGlnaHRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9NT0RVTEVfTkFNRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtNb2R1bGVJbmZvfSBpbmZvIC0gSW5mb3JtYXRpb24gYWJvdXQgYSBSQyBtb2R1bGUsIGluY2x1ZGluZyBpdHMgaWQuXG4gICAgICogQHJldHVybiB7TGlnaHRDb250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldE1vZHVsZUluZm8gKGluZm8pIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTW9kdWxlSW5mbywgaW5mbyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKExpZ2h0Q29udHJvbENhcGFiaWxpdGllcy5LRVlfTU9EVUxFX0lORk8sIGluZm8pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtNb2R1bGVJbmZvfVxuICAgICAqL1xuICAgIGdldE1vZHVsZUluZm8gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTW9kdWxlSW5mbywgTGlnaHRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9NT0RVTEVfSU5GTyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtMaWdodENhcGFiaWxpdGllc1tdfSBsaWdodHMgLSBBbiBhcnJheSBvZiBhdmFpbGFibGUgTGlnaHRDYXBhYmlsaXRpZXMgdGhhdCBhcmUgY29udHJvbGxhYmxlLlxuICAgICAqIEByZXR1cm4ge0xpZ2h0Q29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRTdXBwb3J0ZWRMaWdodHMgKGxpZ2h0cykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShMaWdodENhcGFiaWxpdGllcywgbGlnaHRzLCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTGlnaHRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9TVVBQT1JURURfTElHSFRTLCBsaWdodHMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtMaWdodENhcGFiaWxpdGllc1tdfVxuICAgICAqL1xuICAgIGdldFN1cHBvcnRlZExpZ2h0cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChMaWdodENhcGFiaWxpdGllcywgTGlnaHRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9TVVBQT1JURURfTElHSFRTKTtcbiAgICB9XG59XG5cbkxpZ2h0Q29udHJvbENhcGFiaWxpdGllcy5LRVlfTU9EVUxFX05BTUUgPSAnbW9kdWxlTmFtZSc7XG5MaWdodENvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX01PRFVMRV9JTkZPID0gJ21vZHVsZUluZm8nO1xuTGlnaHRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9TVVBQT1JURURfTElHSFRTID0gJ3N1cHBvcnRlZExpZ2h0cyc7XG5cbmV4cG9ydCB7IExpZ2h0Q29udHJvbENhcGFiaWxpdGllcyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBEZWZyb3N0Wm9uZSB9IGZyb20gJy4uL2VudW1zL0RlZnJvc3Rab25lLmpzJztcbmltcG9ydCB7IFZlbnRpbGF0aW9uTW9kZSB9IGZyb20gJy4uL2VudW1zL1ZlbnRpbGF0aW9uTW9kZS5qcyc7XG5pbXBvcnQgeyBNb2R1bGVJbmZvIH0gZnJvbSAnLi9Nb2R1bGVJbmZvLmpzJztcblxuLyoqXG4gKiBDb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCBhIGNsaW1hdGUgY29udHJvbCBtb2R1bGUncyBjYXBhYmlsaXRpZXMuXG4gKi9cbmNsYXNzIENsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSAtIFRoZSBzaG9ydCBmcmllbmRseSBuYW1lIG9mIHRoZSBjbGltYXRlIGNvbnRyb2wgbW9kdWxlLiBJdCBzaG91bGQgbm90IGJlIHVzZWQgdG8gaWRlbnRpZnkgYVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgbW9kdWxlIGJ5IG1vYmlsZSBhcHBsaWNhdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtDbGltYXRlQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRNb2R1bGVOYW1lIChuYW1lKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9NT0RVTEVfTkFNRSwgbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRNb2R1bGVOYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKENsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9NT0RVTEVfTkFNRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtNb2R1bGVJbmZvfSBpbmZvIC0gSW5mb3JtYXRpb24gYWJvdXQgYSBSQyBtb2R1bGUsIGluY2x1ZGluZyBpdHMgaWQuXG4gICAgICogQHJldHVybiB7Q2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0TW9kdWxlSW5mbyAoaW5mbykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShNb2R1bGVJbmZvLCBpbmZvKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX01PRFVMRV9JTkZPLCBpbmZvKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TW9kdWxlSW5mb31cbiAgICAgKi9cbiAgICBnZXRNb2R1bGVJbmZvICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KE1vZHVsZUluZm8sIENsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9NT0RVTEVfSU5GTyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhdmFpbGFibGUgLSBBdmFpbGFiaWxpdHkgb2YgdGhlIHJlYWRpbmcgb2YgY3VycmVudCB0ZW1wZXJhdHVyZS4gVHJ1ZTogQXZhaWxhYmxlLCBGYWxzZTogTm90XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdmFpbGFibGUsIE5vdCBwcmVzZW50OiBOb3QgQXZhaWxhYmxlLlxuICAgICAqIEByZXR1cm4ge0NsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldEN1cnJlbnRUZW1wZXJhdHVyZUF2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9DVVJSRU5UX1RFTVBFUkFUVVJFX0FWQUlMQUJMRSwgYXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRDdXJyZW50VGVtcGVyYXR1cmVBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0NVUlJFTlRfVEVNUEVSQVRVUkVfQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGF2YWlsYWJsZSAtIEF2YWlsYWJpbGl0eSBvZiB0aGUgY29udHJvbCBvZiBmYW4gc3BlZWQuIFRydWU6IEF2YWlsYWJsZSwgRmFsc2U6IE5vdCBBdmFpbGFibGUsIE5vdFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlc2VudDogTm90IEF2YWlsYWJsZS5cbiAgICAgKiBAcmV0dXJuIHtDbGltYXRlQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRGYW5TcGVlZEF2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9GQU5fU1BFRURfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEZhblNwZWVkQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKENsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9GQU5fU1BFRURfQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGF2YWlsYWJsZSAtIEF2YWlsYWJpbGl0eSBvZiB0aGUgY29udHJvbCBvZiBkZXNpcmVkIHRlbXBlcmF0dXJlLiBUcnVlOiBBdmFpbGFibGUsIEZhbHNlOiBOb3RcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF2YWlsYWJsZSwgTm90IHByZXNlbnQ6IE5vdCBBdmFpbGFibGUuXG4gICAgICogQHJldHVybiB7Q2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0RGVzaXJlZFRlbXBlcmF0dXJlQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0RFU0lSRURfVEVNUEVSQVRVUkVfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldERlc2lyZWRUZW1wZXJhdHVyZUF2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihDbGltYXRlQ29udHJvbENhcGFiaWxpdGllcy5LRVlfREVTSVJFRF9URU1QRVJBVFVSRV9BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlIC0gQXZhaWxhYmlsaXR5IG9mIHRoZSBjb250cm9sIG9mIHR1cm4gb24vb2ZmIEFDLiBUcnVlOiBBdmFpbGFibGUsIEZhbHNlOiBOb3RcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF2YWlsYWJsZSwgTm90IHByZXNlbnQ6IE5vdCBBdmFpbGFibGUuXG4gICAgICogQHJldHVybiB7Q2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0QWNFbmFibGVBdmFpbGFibGUgKGF2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihDbGltYXRlQ29udHJvbENhcGFiaWxpdGllcy5LRVlfQUNfRU5BQkxFX0FWQUlMQUJMRSwgYXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRBY0VuYWJsZUF2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihDbGltYXRlQ29udHJvbENhcGFiaWxpdGllcy5LRVlfQUNfRU5BQkxFX0FWQUlMQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhdmFpbGFibGUgLSBBdmFpbGFiaWxpdHkgb2YgdGhlIGNvbnRyb2wgb2YgZW5hYmxlL2Rpc2FibGUgYWlyIGNvbmRpdGlvbmluZyBpcyBPTiBvbiB0aGUgbWF4aW11bVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWwuIFRydWU6IEF2YWlsYWJsZSwgRmFsc2U6IE5vdCBBdmFpbGFibGUsIE5vdCBwcmVzZW50OiBOb3QgQXZhaWxhYmxlLlxuICAgICAqIEByZXR1cm4ge0NsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldEFjTWF4RW5hYmxlQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0FDX01BWF9FTkFCTEVfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEFjTWF4RW5hYmxlQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKENsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9BQ19NQVhfRU5BQkxFX0FWQUlMQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhdmFpbGFibGUgLSBBdmFpbGFiaWxpdHkgb2YgdGhlIGNvbnRyb2wgb2YgZW5hYmxlL2Rpc2FibGUgY2lyY3VsYXRlIEFpciBtb2RlLiBUcnVlOiBBdmFpbGFibGUsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGYWxzZTogTm90IEF2YWlsYWJsZSwgTm90IHByZXNlbnQ6IE5vdCBBdmFpbGFibGUuXG4gICAgICogQHJldHVybiB7Q2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0Q2lyY3VsYXRlQWlyRW5hYmxlQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0NJUkNVTEFURV9BSVJfRU5BQkxFX0FWQUlMQUJMRSwgYXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRDaXJjdWxhdGVBaXJFbmFibGVBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0NJUkNVTEFURV9BSVJfRU5BQkxFX0FWQUlMQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhdmFpbGFibGUgLSBBdmFpbGFiaWxpdHkgb2YgdGhlIGNvbnRyb2wgb2YgZW5hYmxlL2Rpc2FibGUgYXV0byBtb2RlLiBUcnVlOiBBdmFpbGFibGUsIEZhbHNlOiBOb3RcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF2YWlsYWJsZSwgTm90IHByZXNlbnQ6IE5vdCBBdmFpbGFibGUuXG4gICAgICogQHJldHVybiB7Q2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0QXV0b01vZGVFbmFibGVBdmFpbGFibGUgKGF2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihDbGltYXRlQ29udHJvbENhcGFiaWxpdGllcy5LRVlfQVVUT19NT0RFX0VOQUJMRV9BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0QXV0b01vZGVFbmFibGVBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0FVVE9fTU9ERV9FTkFCTEVfQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGF2YWlsYWJsZSAtIEF2YWlsYWJpbGl0eSBvZiB0aGUgY29udHJvbCBvZiBlbmFibGUvZGlzYWJsZSBkdWFsIG1vZGUuIFRydWU6IEF2YWlsYWJsZSwgRmFsc2U6IE5vdFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXZhaWxhYmxlLCBOb3QgcHJlc2VudDogTm90IEF2YWlsYWJsZS5cbiAgICAgKiBAcmV0dXJuIHtDbGltYXRlQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXREdWFsTW9kZUVuYWJsZUF2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9EVUFMX01PREVfRU5BQkxFX0FWQUlMQUJMRSwgYXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXREdWFsTW9kZUVuYWJsZUF2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihDbGltYXRlQ29udHJvbENhcGFiaWxpdGllcy5LRVlfRFVBTF9NT0RFX0VOQUJMRV9BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlIC0gQXZhaWxhYmlsaXR5IG9mIHRoZSBjb250cm9sIG9mIGRlZnJvc3Qgem9uZXMuIFRydWU6IEF2YWlsYWJsZSwgRmFsc2U6IE5vdCBBdmFpbGFibGUsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb3QgcHJlc2VudDogTm90IEF2YWlsYWJsZS5cbiAgICAgKiBAcmV0dXJuIHtDbGltYXRlQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXREZWZyb3N0Wm9uZUF2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9ERUZST1NUX1pPTkVfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldERlZnJvc3Rab25lQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKENsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9ERUZST1NUX1pPTkVfQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0RlZnJvc3Rab25lW119IHpvbmUgLSBBIHNldCBvZiBhbGwgZGVmcm9zdCB6b25lcyB0aGF0IGFyZSBjb250cm9sbGFibGUuXG4gICAgICogQHJldHVybiB7Q2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0RGVmcm9zdFpvbmUgKHpvbmUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoRGVmcm9zdFpvbmUsIHpvbmUsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihDbGltYXRlQ29udHJvbENhcGFiaWxpdGllcy5LRVlfREVGUk9TVF9aT05FLCB6b25lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7RGVmcm9zdFpvbmVbXX1cbiAgICAgKi9cbiAgICBnZXREZWZyb3N0Wm9uZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChEZWZyb3N0Wm9uZSwgQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0RFRlJPU1RfWk9ORSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhdmFpbGFibGUgLSBBdmFpbGFiaWxpdHkgb2YgdGhlIGNvbnRyb2wgb2YgYWlyIHZlbnRpbGF0aW9uIG1vZGUuIFRydWU6IEF2YWlsYWJsZSwgRmFsc2U6IE5vdFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXZhaWxhYmxlLCBOb3QgcHJlc2VudDogTm90IEF2YWlsYWJsZS5cbiAgICAgKiBAcmV0dXJuIHtDbGltYXRlQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRWZW50aWxhdGlvbk1vZGVBdmFpbGFibGUgKGF2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihDbGltYXRlQ29udHJvbENhcGFiaWxpdGllcy5LRVlfVkVOVElMQVRJT05fTU9ERV9BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0VmVudGlsYXRpb25Nb2RlQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKENsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9WRU5USUxBVElPTl9NT0RFX0FWQUlMQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZW50aWxhdGlvbk1vZGVbXX0gbW9kZSAtIEEgc2V0IG9mIGFsbCB2ZW50aWxhdGlvbiBtb2RlcyB0aGF0IGFyZSBjb250cm9sbGFibGUuXG4gICAgICogQHJldHVybiB7Q2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0VmVudGlsYXRpb25Nb2RlIChtb2RlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFZlbnRpbGF0aW9uTW9kZSwgbW9kZSwgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9WRU5USUxBVElPTl9NT0RFLCBtb2RlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVudGlsYXRpb25Nb2RlW119XG4gICAgICovXG4gICAgZ2V0VmVudGlsYXRpb25Nb2RlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlbnRpbGF0aW9uTW9kZSwgQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX1ZFTlRJTEFUSU9OX01PREUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlIC0gQXZhaWxhYmlsaXR5IG9mIHRoZSBjb250cm9sIChlbmFibGUvZGlzYWJsZSkgb2YgaGVhdGVkIFN0ZWVyaW5nIFdoZWVsLiBUcnVlOlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXZhaWxhYmxlLCBGYWxzZTogTm90IEF2YWlsYWJsZSwgTm90IHByZXNlbnQ6IE5vdCBBdmFpbGFibGUuXG4gICAgICogQHJldHVybiB7Q2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0SGVhdGVkU3RlZXJpbmdXaGVlbEF2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9IRUFURURfU1RFRVJJTkdfV0hFRUxfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEhlYXRlZFN0ZWVyaW5nV2hlZWxBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0hFQVRFRF9TVEVFUklOR19XSEVFTF9BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlIC0gQXZhaWxhYmlsaXR5IG9mIHRoZSBjb250cm9sIChlbmFibGUvZGlzYWJsZSkgb2YgaGVhdGVkIFdpbmRzaGllbGQuIFRydWU6IEF2YWlsYWJsZSxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZhbHNlOiBOb3QgQXZhaWxhYmxlLCBOb3QgcHJlc2VudDogTm90IEF2YWlsYWJsZS5cbiAgICAgKiBAcmV0dXJuIHtDbGltYXRlQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRIZWF0ZWRXaW5kc2hpZWxkQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0hFQVRFRF9XSU5EU0hJRUxEX0FWQUlMQUJMRSwgYXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRIZWF0ZWRXaW5kc2hpZWxkQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKENsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9IRUFURURfV0lORFNISUVMRF9BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlIC0gQXZhaWxhYmlsaXR5IG9mIHRoZSBjb250cm9sIChlbmFibGUvZGlzYWJsZSkgb2YgaGVhdGVkIFJlYXIgV2luZG93LiBUcnVlOiBBdmFpbGFibGUsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGYWxzZTogTm90IEF2YWlsYWJsZSwgTm90IHByZXNlbnQ6IE5vdCBBdmFpbGFibGUuXG4gICAgICogQHJldHVybiB7Q2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0SGVhdGVkUmVhcldpbmRvd0F2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9IRUFURURfUkVBUl9XSU5ET1dfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEhlYXRlZFJlYXJXaW5kb3dBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0hFQVRFRF9SRUFSX1dJTkRPV19BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlIC0gQXZhaWxhYmlsaXR5IG9mIHRoZSBjb250cm9sIChlbmFibGUvZGlzYWJsZSkgb2YgaGVhdGVkIE1pcnJvcnMuIFRydWU6IEF2YWlsYWJsZSxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZhbHNlOiBOb3QgQXZhaWxhYmxlLCBOb3QgcHJlc2VudDogTm90IEF2YWlsYWJsZS5cbiAgICAgKiBAcmV0dXJuIHtDbGltYXRlQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRIZWF0ZWRNaXJyb3JzQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0hFQVRFRF9NSVJST1JTX0FWQUlMQUJMRSwgYXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRIZWF0ZWRNaXJyb3JzQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKENsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9IRUFURURfTUlSUk9SU19BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlIC0gQXZhaWxhYmlsaXR5IG9mIHRoZSBjb250cm9sIG9mIGVuYWJsZS9kaXNhYmxlIGNsaW1hdGUgY29udHJvbC4gVHJ1ZTogQXZhaWxhYmxlLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmFsc2U6IE5vdCBBdmFpbGFibGUsIE5vdCBwcmVzZW50OiBOb3QgQXZhaWxhYmxlLlxuICAgICAqIEByZXR1cm4ge0NsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldENsaW1hdGVFbmFibGVBdmFpbGFibGUgKGF2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihDbGltYXRlQ29udHJvbENhcGFiaWxpdGllcy5LRVlfQ0xJTUFURV9FTkFCTEVfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldENsaW1hdGVFbmFibGVBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0NMSU1BVEVfRU5BQkxFX0FWQUlMQUJMRSk7XG4gICAgfVxufVxuXG5DbGltYXRlQ29udHJvbENhcGFiaWxpdGllcy5LRVlfTU9EVUxFX05BTUUgPSAnbW9kdWxlTmFtZSc7XG5DbGltYXRlQ29udHJvbENhcGFiaWxpdGllcy5LRVlfTU9EVUxFX0lORk8gPSAnbW9kdWxlSW5mbyc7XG5DbGltYXRlQ29udHJvbENhcGFiaWxpdGllcy5LRVlfQ1VSUkVOVF9URU1QRVJBVFVSRV9BVkFJTEFCTEUgPSAnY3VycmVudFRlbXBlcmF0dXJlQXZhaWxhYmxlJztcbkNsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9GQU5fU1BFRURfQVZBSUxBQkxFID0gJ2ZhblNwZWVkQXZhaWxhYmxlJztcbkNsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9ERVNJUkVEX1RFTVBFUkFUVVJFX0FWQUlMQUJMRSA9ICdkZXNpcmVkVGVtcGVyYXR1cmVBdmFpbGFibGUnO1xuQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0FDX0VOQUJMRV9BVkFJTEFCTEUgPSAnYWNFbmFibGVBdmFpbGFibGUnO1xuQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0FDX01BWF9FTkFCTEVfQVZBSUxBQkxFID0gJ2FjTWF4RW5hYmxlQXZhaWxhYmxlJztcbkNsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9DSVJDVUxBVEVfQUlSX0VOQUJMRV9BVkFJTEFCTEUgPSAnY2lyY3VsYXRlQWlyRW5hYmxlQXZhaWxhYmxlJztcbkNsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9BVVRPX01PREVfRU5BQkxFX0FWQUlMQUJMRSA9ICdhdXRvTW9kZUVuYWJsZUF2YWlsYWJsZSc7XG5DbGltYXRlQ29udHJvbENhcGFiaWxpdGllcy5LRVlfRFVBTF9NT0RFX0VOQUJMRV9BVkFJTEFCTEUgPSAnZHVhbE1vZGVFbmFibGVBdmFpbGFibGUnO1xuQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0RFRlJPU1RfWk9ORV9BVkFJTEFCTEUgPSAnZGVmcm9zdFpvbmVBdmFpbGFibGUnO1xuQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0RFRlJPU1RfWk9ORSA9ICdkZWZyb3N0Wm9uZSc7XG5DbGltYXRlQ29udHJvbENhcGFiaWxpdGllcy5LRVlfVkVOVElMQVRJT05fTU9ERV9BVkFJTEFCTEUgPSAndmVudGlsYXRpb25Nb2RlQXZhaWxhYmxlJztcbkNsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9WRU5USUxBVElPTl9NT0RFID0gJ3ZlbnRpbGF0aW9uTW9kZSc7XG5DbGltYXRlQ29udHJvbENhcGFiaWxpdGllcy5LRVlfSEVBVEVEX1NURUVSSU5HX1dIRUVMX0FWQUlMQUJMRSA9ICdoZWF0ZWRTdGVlcmluZ1doZWVsQXZhaWxhYmxlJztcbkNsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9IRUFURURfV0lORFNISUVMRF9BVkFJTEFCTEUgPSAnaGVhdGVkV2luZHNoaWVsZEF2YWlsYWJsZSc7XG5DbGltYXRlQ29udHJvbENhcGFiaWxpdGllcy5LRVlfSEVBVEVEX1JFQVJfV0lORE9XX0FWQUlMQUJMRSA9ICdoZWF0ZWRSZWFyV2luZG93QXZhaWxhYmxlJztcbkNsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9IRUFURURfTUlSUk9SU19BVkFJTEFCTEUgPSAnaGVhdGVkTWlycm9yc0F2YWlsYWJsZSc7XG5DbGltYXRlQ29udHJvbENhcGFiaWxpdGllcy5LRVlfQ0xJTUFURV9FTkFCTEVfQVZBSUxBQkxFID0gJ2NsaW1hdGVFbmFibGVBdmFpbGFibGUnO1xuXG5leHBvcnQgeyBDbGltYXRlQ29udHJvbENhcGFiaWxpdGllcyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBNb2R1bGVJbmZvIH0gZnJvbSAnLi9Nb2R1bGVJbmZvLmpzJztcblxuY2xhc3MgU2VhdENvbnRyb2xDYXBhYmlsaXRpZXMgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIC0gVGhlIHNob3J0IGZyaWVuZGx5IG5hbWUgb2YgdGhlIGxpZ2h0IGNvbnRyb2wgbW9kdWxlLiBJdCBzaG91bGQgbm90IGJlIHVzZWQgdG8gaWRlbnRpZnkgYVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgbW9kdWxlIGJ5IG1vYmlsZSBhcHBsaWNhdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtTZWF0Q29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRNb2R1bGVOYW1lIChuYW1lKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9NT0RVTEVfTkFNRSwgbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRNb2R1bGVOYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9NT0RVTEVfTkFNRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtNb2R1bGVJbmZvfSBpbmZvIC0gSW5mb3JtYXRpb24gYWJvdXQgYSBSQyBtb2R1bGUsIGluY2x1ZGluZyBpdHMgaWQuXG4gICAgICogQHJldHVybiB7U2VhdENvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0TW9kdWxlSW5mbyAoaW5mbykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShNb2R1bGVJbmZvLCBpbmZvKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2VhdENvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX01PRFVMRV9JTkZPLCBpbmZvKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TW9kdWxlSW5mb31cbiAgICAgKi9cbiAgICBnZXRNb2R1bGVJbmZvICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KE1vZHVsZUluZm8sIFNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9NT0RVTEVfSU5GTyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhdmFpbGFibGVcbiAgICAgKiBAcmV0dXJuIHtTZWF0Q29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRIZWF0aW5nRW5hYmxlZEF2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9IRUFUSU5HX0VOQUJMRURfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEhlYXRpbmdFbmFibGVkQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9IRUFUSU5HX0VOQUJMRURfQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGF2YWlsYWJsZVxuICAgICAqIEByZXR1cm4ge1NlYXRDb250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldENvb2xpbmdFbmFibGVkQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2VhdENvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0NPT0xJTkdfRU5BQkxFRF9BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0Q29vbGluZ0VuYWJsZWRBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2VhdENvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0NPT0xJTkdfRU5BQkxFRF9BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlXG4gICAgICogQHJldHVybiB7U2VhdENvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0SGVhdGluZ0xldmVsQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2VhdENvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0hFQVRJTkdfTEVWRUxfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEhlYXRpbmdMZXZlbEF2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTZWF0Q29udHJvbENhcGFiaWxpdGllcy5LRVlfSEVBVElOR19MRVZFTF9BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlXG4gICAgICogQHJldHVybiB7U2VhdENvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0Q29vbGluZ0xldmVsQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2VhdENvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0NPT0xJTkdfTEVWRUxfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldENvb2xpbmdMZXZlbEF2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTZWF0Q29udHJvbENhcGFiaWxpdGllcy5LRVlfQ09PTElOR19MRVZFTF9BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlXG4gICAgICogQHJldHVybiB7U2VhdENvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0SG9yaXpvbnRhbFBvc2l0aW9uQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2VhdENvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0hPUklaT05UQUxfUE9TSVRJT05fQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEhvcml6b250YWxQb3NpdGlvbkF2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTZWF0Q29udHJvbENhcGFiaWxpdGllcy5LRVlfSE9SSVpPTlRBTF9QT1NJVElPTl9BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlXG4gICAgICogQHJldHVybiB7U2VhdENvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0VmVydGljYWxQb3NpdGlvbkF2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9WRVJUSUNBTF9QT1NJVElPTl9BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0VmVydGljYWxQb3NpdGlvbkF2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTZWF0Q29udHJvbENhcGFiaWxpdGllcy5LRVlfVkVSVElDQUxfUE9TSVRJT05fQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGF2YWlsYWJsZVxuICAgICAqIEByZXR1cm4ge1NlYXRDb250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldEZyb250VmVydGljYWxQb3NpdGlvbkF2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9GUk9OVF9WRVJUSUNBTF9QT1NJVElPTl9BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0RnJvbnRWZXJ0aWNhbFBvc2l0aW9uQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9GUk9OVF9WRVJUSUNBTF9QT1NJVElPTl9BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlXG4gICAgICogQHJldHVybiB7U2VhdENvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0QmFja1ZlcnRpY2FsUG9zaXRpb25BdmFpbGFibGUgKGF2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZWF0Q29udHJvbENhcGFiaWxpdGllcy5LRVlfQkFDS19WRVJUSUNBTF9QT1NJVElPTl9BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0QmFja1ZlcnRpY2FsUG9zaXRpb25BdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2VhdENvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0JBQ0tfVkVSVElDQUxfUE9TSVRJT05fQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGF2YWlsYWJsZVxuICAgICAqIEByZXR1cm4ge1NlYXRDb250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldEJhY2tUaWx0QW5nbGVBdmFpbGFibGUgKGF2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZWF0Q29udHJvbENhcGFiaWxpdGllcy5LRVlfQkFDS19USUxUX0FOR0xFX0FWQUlMQUJMRSwgYXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRCYWNrVGlsdEFuZ2xlQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9CQUNLX1RJTFRfQU5HTEVfQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGF2YWlsYWJsZVxuICAgICAqIEByZXR1cm4ge1NlYXRDb250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldEhlYWRTdXBwb3J0SG9yaXpvbnRhbFBvc2l0aW9uQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2VhdENvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0hFQURfU1VQUE9SVF9IT1JJWk9OVEFMX1BPU0lUSU9OX0FWQUlMQUJMRSwgYXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRIZWFkU3VwcG9ydEhvcml6b250YWxQb3NpdGlvbkF2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTZWF0Q29udHJvbENhcGFiaWxpdGllcy5LRVlfSEVBRF9TVVBQT1JUX0hPUklaT05UQUxfUE9TSVRJT05fQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGF2YWlsYWJsZVxuICAgICAqIEByZXR1cm4ge1NlYXRDb250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldEhlYWRTdXBwb3J0VmVydGljYWxQb3NpdGlvbkF2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9IRUFEX1NVUFBPUlRfVkVSVElDQUxfUE9TSVRJT05fQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEhlYWRTdXBwb3J0VmVydGljYWxQb3NpdGlvbkF2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTZWF0Q29udHJvbENhcGFiaWxpdGllcy5LRVlfSEVBRF9TVVBQT1JUX1ZFUlRJQ0FMX1BPU0lUSU9OX0FWQUlMQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhdmFpbGFibGVcbiAgICAgKiBAcmV0dXJuIHtTZWF0Q29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRNYXNzYWdlRW5hYmxlZEF2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9NQVNTQUdFX0VOQUJMRURfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldE1hc3NhZ2VFbmFibGVkQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9NQVNTQUdFX0VOQUJMRURfQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGF2YWlsYWJsZVxuICAgICAqIEByZXR1cm4ge1NlYXRDb250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldE1hc3NhZ2VNb2RlQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2VhdENvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX01BU1NBR0VfTU9ERV9BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0TWFzc2FnZU1vZGVBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2VhdENvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX01BU1NBR0VfTU9ERV9BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlXG4gICAgICogQHJldHVybiB7U2VhdENvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0TWFzc2FnZUN1c2hpb25GaXJtbmVzc0F2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9NQVNTQUdFX0NVU0hJT05fRklSTU5FU1NfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldE1hc3NhZ2VDdXNoaW9uRmlybW5lc3NBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2VhdENvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX01BU1NBR0VfQ1VTSElPTl9GSVJNTkVTU19BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlXG4gICAgICogQHJldHVybiB7U2VhdENvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0TWVtb3J5QXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2VhdENvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX01FTU9SWV9BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0TWVtb3J5QXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9NRU1PUllfQVZBSUxBQkxFKTtcbiAgICB9XG59XG5cblNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9NT0RVTEVfTkFNRSA9ICdtb2R1bGVOYW1lJztcblNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9NT0RVTEVfSU5GTyA9ICdtb2R1bGVJbmZvJztcblNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9IRUFUSU5HX0VOQUJMRURfQVZBSUxBQkxFID0gJ2hlYXRpbmdFbmFibGVkQXZhaWxhYmxlJztcblNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9DT09MSU5HX0VOQUJMRURfQVZBSUxBQkxFID0gJ2Nvb2xpbmdFbmFibGVkQXZhaWxhYmxlJztcblNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9IRUFUSU5HX0xFVkVMX0FWQUlMQUJMRSA9ICdoZWF0aW5nTGV2ZWxBdmFpbGFibGUnO1xuU2VhdENvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0NPT0xJTkdfTEVWRUxfQVZBSUxBQkxFID0gJ2Nvb2xpbmdMZXZlbEF2YWlsYWJsZSc7XG5TZWF0Q29udHJvbENhcGFiaWxpdGllcy5LRVlfSE9SSVpPTlRBTF9QT1NJVElPTl9BVkFJTEFCTEUgPSAnaG9yaXpvbnRhbFBvc2l0aW9uQXZhaWxhYmxlJztcblNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9WRVJUSUNBTF9QT1NJVElPTl9BVkFJTEFCTEUgPSAndmVydGljYWxQb3NpdGlvbkF2YWlsYWJsZSc7XG5TZWF0Q29udHJvbENhcGFiaWxpdGllcy5LRVlfRlJPTlRfVkVSVElDQUxfUE9TSVRJT05fQVZBSUxBQkxFID0gJ2Zyb250VmVydGljYWxQb3NpdGlvbkF2YWlsYWJsZSc7XG5TZWF0Q29udHJvbENhcGFiaWxpdGllcy5LRVlfQkFDS19WRVJUSUNBTF9QT1NJVElPTl9BVkFJTEFCTEUgPSAnYmFja1ZlcnRpY2FsUG9zaXRpb25BdmFpbGFibGUnO1xuU2VhdENvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0JBQ0tfVElMVF9BTkdMRV9BVkFJTEFCTEUgPSAnYmFja1RpbHRBbmdsZUF2YWlsYWJsZSc7XG5TZWF0Q29udHJvbENhcGFiaWxpdGllcy5LRVlfSEVBRF9TVVBQT1JUX0hPUklaT05UQUxfUE9TSVRJT05fQVZBSUxBQkxFID0gJ2hlYWRTdXBwb3J0SG9yaXpvbnRhbFBvc2l0aW9uQXZhaWxhYmxlJztcblNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9IRUFEX1NVUFBPUlRfVkVSVElDQUxfUE9TSVRJT05fQVZBSUxBQkxFID0gJ2hlYWRTdXBwb3J0VmVydGljYWxQb3NpdGlvbkF2YWlsYWJsZSc7XG5TZWF0Q29udHJvbENhcGFiaWxpdGllcy5LRVlfTUFTU0FHRV9FTkFCTEVEX0FWQUlMQUJMRSA9ICdtYXNzYWdlRW5hYmxlZEF2YWlsYWJsZSc7XG5TZWF0Q29udHJvbENhcGFiaWxpdGllcy5LRVlfTUFTU0FHRV9NT0RFX0FWQUlMQUJMRSA9ICdtYXNzYWdlTW9kZUF2YWlsYWJsZSc7XG5TZWF0Q29udHJvbENhcGFiaWxpdGllcy5LRVlfTUFTU0FHRV9DVVNISU9OX0ZJUk1ORVNTX0FWQUlMQUJMRSA9ICdtYXNzYWdlQ3VzaGlvbkZpcm1uZXNzQXZhaWxhYmxlJztcblNlYXRDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9NRU1PUllfQVZBSUxBQkxFID0gJ21lbW9yeUF2YWlsYWJsZSc7XG5cbmV4cG9ydCB7IFNlYXRDb250cm9sQ2FwYWJpbGl0aWVzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IE1vZHVsZUluZm8gfSBmcm9tICcuL01vZHVsZUluZm8uanMnO1xuXG4vKipcbiAqIENvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGEgcmFkaW8gY29udHJvbCBtb2R1bGUncyBjYXBhYmlsaXRpZXMuXG4gKi9cbmNsYXNzIFJhZGlvQ29udHJvbENhcGFiaWxpdGllcyBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBUaGUgc2hvcnQgZnJpZW5kbHkgbmFtZSBvZiB0aGUgY2xpbWF0ZSBjb250cm9sIG1vZHVsZS4gSXQgc2hvdWxkIG5vdCBiZSB1c2VkIHRvIGlkZW50aWZ5IGFcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIG1vZHVsZSBieSBtb2JpbGUgYXBwbGljYXRpb24uXG4gICAgICogQHJldHVybiB7UmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldE1vZHVsZU5hbWUgKG5hbWUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzLktFWV9NT0RVTEVfTkFNRSwgbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRNb2R1bGVOYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFJhZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfTU9EVUxFX05BTUUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TW9kdWxlSW5mb30gaW5mbyAtIEluZm9ybWF0aW9uIGFib3V0IGEgUkMgbW9kdWxlLCBpbmNsdWRpbmcgaXRzIGlkLlxuICAgICAqIEByZXR1cm4ge1JhZGlvQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRNb2R1bGVJbmZvIChpbmZvKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKE1vZHVsZUluZm8sIGluZm8pO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX01PRFVMRV9JTkZPLCBpbmZvKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TW9kdWxlSW5mb31cbiAgICAgKi9cbiAgICBnZXRNb2R1bGVJbmZvICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KE1vZHVsZUluZm8sIFJhZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfTU9EVUxFX0lORk8pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlIC0gQXZhaWxhYmlsaXR5IG9mIHRoZSBjb250cm9sIG9mIGVuYWJsZS9kaXNhYmxlIHJhZGlvLiBUcnVlOiBBdmFpbGFibGUsIEZhbHNlOiBOb3RcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF2YWlsYWJsZSwgTm90IHByZXNlbnQ6IE5vdCBBdmFpbGFibGUuXG4gICAgICogQHJldHVybiB7UmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldFJhZGlvRW5hYmxlQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzLktFWV9SQURJT19FTkFCTEVfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFJhZGlvRW5hYmxlQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFJhZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfUkFESU9fRU5BQkxFX0FWQUlMQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhdmFpbGFibGUgLSBBdmFpbGFiaWxpdHkgb2YgdGhlIGNvbnRyb2wgb2YgcmFkaW8gYmFuZC4gVHJ1ZTogQXZhaWxhYmxlLCBGYWxzZTogTm90IEF2YWlsYWJsZSxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vdCBwcmVzZW50OiBOb3QgQXZhaWxhYmxlLlxuICAgICAqIEByZXR1cm4ge1JhZGlvQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRSYWRpb0JhbmRBdmFpbGFibGUgKGF2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX1JBRElPX0JBTkRfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFJhZGlvQmFuZEF2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX1JBRElPX0JBTkRfQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGF2YWlsYWJsZSAtIEF2YWlsYWJpbGl0eSBvZiB0aGUgY29udHJvbCBvZiByYWRpbyBmcmVxdWVuY3kuIFRydWU6IEF2YWlsYWJsZSwgRmFsc2U6IE5vdFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXZhaWxhYmxlLCBOb3QgcHJlc2VudDogTm90IEF2YWlsYWJsZS5cbiAgICAgKiBAcmV0dXJuIHtSYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0UmFkaW9GcmVxdWVuY3lBdmFpbGFibGUgKGF2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX1JBRElPX0ZSRVFVRU5DWV9BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0UmFkaW9GcmVxdWVuY3lBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzLktFWV9SQURJT19GUkVRVUVOQ1lfQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGF2YWlsYWJsZSAtIEF2YWlsYWJpbGl0eSBvZiB0aGUgY29udHJvbCBvZiBIRCByYWRpbyBjaGFubmVsLiBUcnVlOiBBdmFpbGFibGUsIEZhbHNlOiBOb3RcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF2YWlsYWJsZSwgTm90IHByZXNlbnQ6IE5vdCBBdmFpbGFibGUuXG4gICAgICogQHJldHVybiB7UmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldEhkQ2hhbm5lbEF2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJhZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfSERfQ0hBTk5FTF9BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0SGRDaGFubmVsQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFJhZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfSERfQ0hBTk5FTF9BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlIC0gQXZhaWxhYmlsaXR5IG9mIHRoZSBnZXR0aW5nIFJhZGlvIERhdGEgU3lzdGVtIChSRFMpIGRhdGEuIFRydWU6IEF2YWlsYWJsZSwgRmFsc2U6XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb3QgQXZhaWxhYmxlLCBOb3QgcHJlc2VudDogTm90IEF2YWlsYWJsZS5cbiAgICAgKiBAcmV0dXJuIHtSYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0UmRzRGF0YUF2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJhZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfUkRTX0RBVEFfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFJkc0RhdGFBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzLktFWV9SRFNfREFUQV9BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlIC0gQXZhaWxhYmlsaXR5IG9mIHRoZSBnZXR0aW5nIHRoZSBudW1iZXIgb2YgYXZhaWxhYmxlIEhEIGNoYW5uZWxzLiBUcnVlOiBBdmFpbGFibGUsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGYWxzZTogTm90IEF2YWlsYWJsZSwgTm90IHByZXNlbnQ6IE5vdCBBdmFpbGFibGUuXG4gICAgICogQHJldHVybiB7UmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldEF2YWlsYWJsZUhEc0F2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJhZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfQVZBSUxBQkxFX0hEU19BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0QXZhaWxhYmxlSERzQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFJhZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfQVZBSUxBQkxFX0hEU19BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlIC0gQXZhaWxhYmlsaXR5IG9mIHRoZSBsaXN0IG9mIGF2YWlsYWJsZSBIRCBzdWItY2hhbm5lbCBpbmRleGVzLiBUcnVlOiBBdmFpbGFibGUsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGYWxzZTogTm90IEF2YWlsYWJsZSwgTm90IHByZXNlbnQ6IE5vdCBBdmFpbGFibGUuXG4gICAgICogQHJldHVybiB7UmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldEF2YWlsYWJsZUhkQ2hhbm5lbHNBdmFpbGFibGUgKGF2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0FWQUlMQUJMRV9IRF9DSEFOTkVMU19BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0QXZhaWxhYmxlSGRDaGFubmVsc0F2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0FWQUlMQUJMRV9IRF9DSEFOTkVMU19BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlIC0gQXZhaWxhYmlsaXR5IG9mIHRoZSBnZXR0aW5nIHRoZSBSYWRpbyBzdGF0ZS4gVHJ1ZTogQXZhaWxhYmxlLCBGYWxzZTogTm90IEF2YWlsYWJsZSxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vdCBwcmVzZW50OiBOb3QgQXZhaWxhYmxlLlxuICAgICAqIEByZXR1cm4ge1JhZGlvQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRTdGF0ZUF2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJhZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfU1RBVEVfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFN0YXRlQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFJhZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfU1RBVEVfQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGF2YWlsYWJsZSAtIEF2YWlsYWJpbGl0eSBvZiB0aGUgZ2V0dGluZyB0aGUgc2lnbmFsIHN0cmVuZ3RoLiBUcnVlOiBBdmFpbGFibGUsIEZhbHNlOiBOb3RcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF2YWlsYWJsZSwgTm90IHByZXNlbnQ6IE5vdCBBdmFpbGFibGUuXG4gICAgICogQHJldHVybiB7UmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldFNpZ25hbFN0cmVuZ3RoQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzLktFWV9TSUdOQUxfU1RSRU5HVEhfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFNpZ25hbFN0cmVuZ3RoQXZhaWxhYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFJhZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfU0lHTkFMX1NUUkVOR1RIX0FWQUlMQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhdmFpbGFibGUgLSBBdmFpbGFiaWxpdHkgb2YgdGhlIGdldHRpbmcgdGhlIHNpZ25hbCBDaGFuZ2UgVGhyZXNob2xkLiBUcnVlOiBBdmFpbGFibGUsIEZhbHNlOiBOb3RcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF2YWlsYWJsZSwgTm90IHByZXNlbnQ6IE5vdCBBdmFpbGFibGUuXG4gICAgICogQHJldHVybiB7UmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldFNpZ25hbENoYW5nZVRocmVzaG9sZEF2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJhZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfU0lHTkFMX0NIQU5HRV9USFJFU0hPTERfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFNpZ25hbENoYW5nZVRocmVzaG9sZEF2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX1NJR05BTF9DSEFOR0VfVEhSRVNIT0xEX0FWQUlMQUJMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBhdmFpbGFibGUgLSBBdmFpbGFiaWxpdHkgb2YgdGhlIGdldHRpbmcgSEQgcmFkaW8gU3RhdGlvbiBJbmZvcm1hdGlvbiBTZXJ2aWNlIChTSVMpIGRhdGEuIFRydWU6XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdmFpbGFibGUsIEZhbHNlOiBOb3QgQXZhaWxhYmxlLCBOb3QgcHJlc2VudDogTm90IEF2YWlsYWJsZS5cbiAgICAgKiBAcmV0dXJuIHtSYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0U2lzRGF0YUF2YWlsYWJsZSAoYXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJhZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfU0lTX0RBVEFfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFNpc0RhdGFBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzLktFWV9TSVNfREFUQV9BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlIC0gQXZhaWxhYmlsaXR5IG9mIHRoZSBjb250cm9sIG9mIGVuYWJsZS9kaXNhYmxlIEhEIHJhZGlvLiBUcnVlOiBBdmFpbGFibGUsIEZhbHNlOiBOb3RcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF2YWlsYWJsZSwgTm90IHByZXNlbnQ6IE5vdCBBdmFpbGFibGUuXG4gICAgICogQHJldHVybiB7UmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldEhkUmFkaW9FbmFibGVBdmFpbGFibGUgKGF2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0hEX1JBRElPX0VOQUJMRV9BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0SGRSYWRpb0VuYWJsZUF2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0hEX1JBRElPX0VOQUJMRV9BVkFJTEFCTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYXZhaWxhYmxlIC0gQXZhaWxhYmlsaXR5IG9mIHNpcml1cyBYTSByYWRpby4gVHJ1ZTogQXZhaWxhYmxlLCBGYWxzZTogTm90IEF2YWlsYWJsZSwgTm90IHByZXNlbnQ6XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb3QgQXZhaWxhYmxlLlxuICAgICAqIEByZXR1cm4ge1JhZGlvQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRTaXJpdXN4bVJhZGlvQXZhaWxhYmxlIChhdmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzLktFWV9TSVJJVVNYTV9SQURJT19BVkFJTEFCTEUsIGF2YWlsYWJsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0U2lyaXVzeG1SYWRpb0F2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX1NJUklVU1hNX1JBRElPX0FWQUlMQUJMRSk7XG4gICAgfVxufVxuXG5SYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX01PRFVMRV9OQU1FID0gJ21vZHVsZU5hbWUnO1xuUmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzLktFWV9NT0RVTEVfSU5GTyA9ICdtb2R1bGVJbmZvJztcblJhZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfUkFESU9fRU5BQkxFX0FWQUlMQUJMRSA9ICdyYWRpb0VuYWJsZUF2YWlsYWJsZSc7XG5SYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX1JBRElPX0JBTkRfQVZBSUxBQkxFID0gJ3JhZGlvQmFuZEF2YWlsYWJsZSc7XG5SYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX1JBRElPX0ZSRVFVRU5DWV9BVkFJTEFCTEUgPSAncmFkaW9GcmVxdWVuY3lBdmFpbGFibGUnO1xuUmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzLktFWV9IRF9DSEFOTkVMX0FWQUlMQUJMRSA9ICdoZENoYW5uZWxBdmFpbGFibGUnO1xuUmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzLktFWV9SRFNfREFUQV9BVkFJTEFCTEUgPSAncmRzRGF0YUF2YWlsYWJsZSc7XG5SYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0FWQUlMQUJMRV9IRFNfQVZBSUxBQkxFID0gJ2F2YWlsYWJsZUhEc0F2YWlsYWJsZSc7XG5SYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0FWQUlMQUJMRV9IRF9DSEFOTkVMU19BVkFJTEFCTEUgPSAnYXZhaWxhYmxlSGRDaGFubmVsc0F2YWlsYWJsZSc7XG5SYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX1NUQVRFX0FWQUlMQUJMRSA9ICdzdGF0ZUF2YWlsYWJsZSc7XG5SYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX1NJR05BTF9TVFJFTkdUSF9BVkFJTEFCTEUgPSAnc2lnbmFsU3RyZW5ndGhBdmFpbGFibGUnO1xuUmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzLktFWV9TSUdOQUxfQ0hBTkdFX1RIUkVTSE9MRF9BVkFJTEFCTEUgPSAnc2lnbmFsQ2hhbmdlVGhyZXNob2xkQXZhaWxhYmxlJztcblJhZGlvQ29udHJvbENhcGFiaWxpdGllcy5LRVlfU0lTX0RBVEFfQVZBSUxBQkxFID0gJ3Npc0RhdGFBdmFpbGFibGUnO1xuUmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzLktFWV9IRF9SQURJT19FTkFCTEVfQVZBSUxBQkxFID0gJ2hkUmFkaW9FbmFibGVBdmFpbGFibGUnO1xuUmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzLktFWV9TSVJJVVNYTV9SQURJT19BVkFJTEFCTEUgPSAnc2lyaXVzeG1SYWRpb0F2YWlsYWJsZSc7XG5cbmV4cG9ydCB7IFJhZGlvQ29udHJvbENhcGFiaWxpdGllcyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBNb2R1bGVJbmZvIH0gZnJvbSAnLi9Nb2R1bGVJbmZvLmpzJztcblxuY2xhc3MgSE1JU2V0dGluZ3NDb250cm9sQ2FwYWJpbGl0aWVzIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSAtIFRoZSBzaG9ydCBmcmllbmRseSBuYW1lIG9mIHRoZSBobWkgc2V0dGluZyBtb2R1bGUuIEl0IHNob3VsZCBub3QgYmUgdXNlZCB0byBpZGVudGlmeSBhXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICBtb2R1bGUgYnkgbW9iaWxlIGFwcGxpY2F0aW9uLlxuICAgICAqIEByZXR1cm4ge0hNSVNldHRpbmdzQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRNb2R1bGVOYW1lIChuYW1lKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEhNSVNldHRpbmdzQ29udHJvbENhcGFiaWxpdGllcy5LRVlfTU9EVUxFX05BTUUsIG5hbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0TW9kdWxlTmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihITUlTZXR0aW5nc0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX01PRFVMRV9OQU1FKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge01vZHVsZUluZm99IGluZm8gLSBJbmZvcm1hdGlvbiBhYm91dCBhIFJDIG1vZHVsZSwgaW5jbHVkaW5nIGl0cyBpZC5cbiAgICAgKiBAcmV0dXJuIHtITUlTZXR0aW5nc0NvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0TW9kdWxlSW5mbyAoaW5mbykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShNb2R1bGVJbmZvLCBpbmZvKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoSE1JU2V0dGluZ3NDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9NT0RVTEVfSU5GTywgaW5mbyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge01vZHVsZUluZm99XG4gICAgICovXG4gICAgZ2V0TW9kdWxlSW5mbyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChNb2R1bGVJbmZvLCBITUlTZXR0aW5nc0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX01PRFVMRV9JTkZPKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGF2YWlsYWJsZSAtIEF2YWlsYWJpbGl0eSBvZiB0aGUgY29udHJvbCBvZiBkaXN0YW5jZSB1bml0LlxuICAgICAqIEByZXR1cm4ge0hNSVNldHRpbmdzQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXREaXN0YW5jZVVuaXRBdmFpbGFibGUgKGF2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihITUlTZXR0aW5nc0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0RJU1RBTkNFX1VOSVRfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldERpc3RhbmNlVW5pdEF2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihITUlTZXR0aW5nc0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0RJU1RBTkNFX1VOSVRfQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGF2YWlsYWJsZSAtIEF2YWlsYWJpbGl0eSBvZiB0aGUgY29udHJvbCBvZiB0ZW1wZXJhdHVyZSB1bml0LlxuICAgICAqIEByZXR1cm4ge0hNSVNldHRpbmdzQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRUZW1wZXJhdHVyZVVuaXRBdmFpbGFibGUgKGF2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihITUlTZXR0aW5nc0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX1RFTVBFUkFUVVJFX1VOSVRfQVZBSUxBQkxFLCBhdmFpbGFibGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFRlbXBlcmF0dXJlVW5pdEF2YWlsYWJsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihITUlTZXR0aW5nc0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX1RFTVBFUkFUVVJFX1VOSVRfQVZBSUxBQkxFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGF2YWlsYWJsZSAtIEF2YWlsYWJpbGl0eSBvZiB0aGUgY29udHJvbCBvZiBITUkgZGlzcGxheSBtb2RlLlxuICAgICAqIEByZXR1cm4ge0hNSVNldHRpbmdzQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXREaXNwbGF5TW9kZVVuaXRBdmFpbGFibGUgKGF2YWlsYWJsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihITUlTZXR0aW5nc0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0RJU1BMQVlfTU9ERV9VTklUX0FWQUlMQUJMRSwgYXZhaWxhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXREaXNwbGF5TW9kZVVuaXRBdmFpbGFibGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoSE1JU2V0dGluZ3NDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9ESVNQTEFZX01PREVfVU5JVF9BVkFJTEFCTEUpO1xuICAgIH1cbn1cblxuSE1JU2V0dGluZ3NDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9NT0RVTEVfTkFNRSA9ICdtb2R1bGVOYW1lJztcbkhNSVNldHRpbmdzQ29udHJvbENhcGFiaWxpdGllcy5LRVlfTU9EVUxFX0lORk8gPSAnbW9kdWxlSW5mbyc7XG5ITUlTZXR0aW5nc0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0RJU1RBTkNFX1VOSVRfQVZBSUxBQkxFID0gJ2Rpc3RhbmNlVW5pdEF2YWlsYWJsZSc7XG5ITUlTZXR0aW5nc0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX1RFTVBFUkFUVVJFX1VOSVRfQVZBSUxBQkxFID0gJ3RlbXBlcmF0dXJlVW5pdEF2YWlsYWJsZSc7XG5ITUlTZXR0aW5nc0NvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0RJU1BMQVlfTU9ERV9VTklUX0FWQUlMQUJMRSA9ICdkaXNwbGF5TW9kZVVuaXRBdmFpbGFibGUnO1xuXG5leHBvcnQgeyBITUlTZXR0aW5nc0NvbnRyb2xDYXBhYmlsaXRpZXMgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBBdWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMgfSBmcm9tICcuL0F1ZGlvQ29udHJvbENhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBMaWdodENvbnRyb2xDYXBhYmlsaXRpZXMgfSBmcm9tICcuL0xpZ2h0Q29udHJvbENhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBDbGltYXRlQ29udHJvbENhcGFiaWxpdGllcyB9IGZyb20gJy4vQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMuanMnO1xuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IEJ1dHRvbkNhcGFiaWxpdGllcyB9IGZyb20gJy4vQnV0dG9uQ2FwYWJpbGl0aWVzLmpzJztcbmltcG9ydCB7IFNlYXRDb250cm9sQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi9TZWF0Q29udHJvbENhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBSYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMgfSBmcm9tICcuL1JhZGlvQ29udHJvbENhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBITUlTZXR0aW5nc0NvbnRyb2xDYXBhYmlsaXRpZXMgfSBmcm9tICcuL0hNSVNldHRpbmdzQ29udHJvbENhcGFiaWxpdGllcy5qcyc7XG5cbmNsYXNzIFJlbW90ZUNvbnRyb2xDYXBhYmlsaXRpZXMgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Q2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXNbXX0gY2FwYWJpbGl0aWVzIC0gSWYgaW5jbHVkZWQsIHRoZSBwbGF0Zm9ybSBzdXBwb3J0cyBSQyBjbGltYXRlIGNvbnRyb2xzLiBGb3JcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMgYmFzZWxpbmUgdmVyc2lvbiwgbWF4c2l6ZT0xLiBpLmUuIG9ubHkgb25lIGNsaW1hdGVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgbW9kdWxlIGlzIHN1cHBvcnRlZC5cbiAgICAgKiBAcmV0dXJuIHtSZW1vdGVDb250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldENsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzIChjYXBhYmlsaXRpZXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMsIGNhcGFiaWxpdGllcywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlbW90ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0NMSU1BVEVfQ09OVFJPTF9DQVBBQklMSVRJRVMsIGNhcGFiaWxpdGllcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0NsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzW119XG4gICAgICovXG4gICAgZ2V0Q2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMsIFJlbW90ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0NMSU1BVEVfQ09OVFJPTF9DQVBBQklMSVRJRVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7UmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzW119IGNhcGFiaWxpdGllcyAtIElmIGluY2x1ZGVkLCB0aGUgcGxhdGZvcm0gc3VwcG9ydHMgUkMgcmFkaW8gY29udHJvbHMuRm9yIHRoaXNcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlbGluZSB2ZXJzaW9uLCBtYXhzaXplPTEuIGkuZS4gb25seSBvbmUgcmFkaW8gY29udHJvbFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZHVsZSBpcyBzdXBwb3J0ZWQuXG4gICAgICogQHJldHVybiB7UmVtb3RlQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRSYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMgKGNhcGFiaWxpdGllcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShSYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMsIGNhcGFiaWxpdGllcywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlbW90ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX1JBRElPX0NPTlRST0xfQ0FQQUJJTElUSUVTLCBjYXBhYmlsaXRpZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtSYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXNbXX1cbiAgICAgKi9cbiAgICBnZXRSYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoUmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzLCBSZW1vdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9SQURJT19DT05UUk9MX0NBUEFCSUxJVElFUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCdXR0b25DYXBhYmlsaXRpZXNbXX0gY2FwYWJpbGl0aWVzIC0gSWYgaW5jbHVkZWQsIHRoZSBwbGF0Zm9ybSBzdXBwb3J0cyBSQyBidXR0b24gY29udHJvbHMgd2l0aCB0aGVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmNsdWRlZCBidXR0b24gbmFtZXMuXG4gICAgICogQHJldHVybiB7UmVtb3RlQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRCdXR0b25DYXBhYmlsaXRpZXMgKGNhcGFiaWxpdGllcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShCdXR0b25DYXBhYmlsaXRpZXMsIGNhcGFiaWxpdGllcywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlbW90ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0JVVFRPTl9DQVBBQklMSVRJRVMsIGNhcGFiaWxpdGllcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0J1dHRvbkNhcGFiaWxpdGllc1tdfVxuICAgICAqL1xuICAgIGdldEJ1dHRvbkNhcGFiaWxpdGllcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChCdXR0b25DYXBhYmlsaXRpZXMsIFJlbW90ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0JVVFRPTl9DQVBBQklMSVRJRVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7QXVkaW9Db250cm9sQ2FwYWJpbGl0aWVzW119IGNhcGFiaWxpdGllcyAtIElmIGluY2x1ZGVkLCB0aGUgcGxhdGZvcm0gc3VwcG9ydHMgYXVkaW8gY29udHJvbHMuXG4gICAgICogQHJldHVybiB7UmVtb3RlQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRBdWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMgKGNhcGFiaWxpdGllcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShBdWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMsIGNhcGFiaWxpdGllcywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlbW90ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0FVRElPX0NPTlRST0xfQ0FQQUJJTElUSUVTLCBjYXBhYmlsaXRpZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtBdWRpb0NvbnRyb2xDYXBhYmlsaXRpZXNbXX1cbiAgICAgKi9cbiAgICBnZXRBdWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQXVkaW9Db250cm9sQ2FwYWJpbGl0aWVzLCBSZW1vdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9BVURJT19DT05UUk9MX0NBUEFCSUxJVElFUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtITUlTZXR0aW5nc0NvbnRyb2xDYXBhYmlsaXRpZXN9IGNhcGFiaWxpdGllcyAtIElmIGluY2x1ZGVkLCB0aGUgcGxhdGZvcm0gc3VwcG9ydHMgaG1pIHNldHRpbmcgY29udHJvbHMuXG4gICAgICogQHJldHVybiB7UmVtb3RlQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRIbWlTZXR0aW5nc0NvbnRyb2xDYXBhYmlsaXRpZXMgKGNhcGFiaWxpdGllcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShITUlTZXR0aW5nc0NvbnRyb2xDYXBhYmlsaXRpZXMsIGNhcGFiaWxpdGllcyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlbW90ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0hNSV9TRVRUSU5HU19DT05UUk9MX0NBUEFCSUxJVElFUywgY2FwYWJpbGl0aWVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7SE1JU2V0dGluZ3NDb250cm9sQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIGdldEhtaVNldHRpbmdzQ29udHJvbENhcGFiaWxpdGllcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChITUlTZXR0aW5nc0NvbnRyb2xDYXBhYmlsaXRpZXMsIFJlbW90ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0hNSV9TRVRUSU5HU19DT05UUk9MX0NBUEFCSUxJVElFUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtMaWdodENvbnRyb2xDYXBhYmlsaXRpZXN9IGNhcGFiaWxpdGllcyAtIElmIGluY2x1ZGVkLCB0aGUgcGxhdGZvcm0gc3VwcG9ydHMgbGlnaHQgY29udHJvbHMuXG4gICAgICogQHJldHVybiB7UmVtb3RlQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBzZXRMaWdodENvbnRyb2xDYXBhYmlsaXRpZXMgKGNhcGFiaWxpdGllcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShMaWdodENvbnRyb2xDYXBhYmlsaXRpZXMsIGNhcGFiaWxpdGllcyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFJlbW90ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX0xJR0hUX0NPTlRST0xfQ0FQQUJJTElUSUVTLCBjYXBhYmlsaXRpZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtMaWdodENvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgZ2V0TGlnaHRDb250cm9sQ2FwYWJpbGl0aWVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KExpZ2h0Q29udHJvbENhcGFiaWxpdGllcywgUmVtb3RlQ29udHJvbENhcGFiaWxpdGllcy5LRVlfTElHSFRfQ09OVFJPTF9DQVBBQklMSVRJRVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2VhdENvbnRyb2xDYXBhYmlsaXRpZXNbXX0gY2FwYWJpbGl0aWVzIC0gSWYgaW5jbHVkZWQsIHRoZSBwbGF0Zm9ybSBzdXBwb3J0cyBzZWF0IGNvbnRyb2xzLlxuICAgICAqIEByZXR1cm4ge1JlbW90ZUNvbnRyb2xDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgc2V0U2VhdENvbnRyb2xDYXBhYmlsaXRpZXMgKGNhcGFiaWxpdGllcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShTZWF0Q29udHJvbENhcGFiaWxpdGllcywgY2FwYWJpbGl0aWVzLCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVtb3RlQ29udHJvbENhcGFiaWxpdGllcy5LRVlfU0VBVF9DT05UUk9MX0NBUEFCSUxJVElFUywgY2FwYWJpbGl0aWVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U2VhdENvbnRyb2xDYXBhYmlsaXRpZXNbXX1cbiAgICAgKi9cbiAgICBnZXRTZWF0Q29udHJvbENhcGFiaWxpdGllcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChTZWF0Q29udHJvbENhcGFiaWxpdGllcywgUmVtb3RlQ29udHJvbENhcGFiaWxpdGllcy5LRVlfU0VBVF9DT05UUk9MX0NBUEFCSUxJVElFUyk7XG4gICAgfVxufVxuXG5SZW1vdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9DTElNQVRFX0NPTlRST0xfQ0FQQUJJTElUSUVTID0gJ2NsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzJztcblJlbW90ZUNvbnRyb2xDYXBhYmlsaXRpZXMuS0VZX1JBRElPX0NPTlRST0xfQ0FQQUJJTElUSUVTID0gJ3JhZGlvQ29udHJvbENhcGFiaWxpdGllcyc7XG5SZW1vdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9CVVRUT05fQ0FQQUJJTElUSUVTID0gJ2J1dHRvbkNhcGFiaWxpdGllcyc7XG5SZW1vdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9BVURJT19DT05UUk9MX0NBUEFCSUxJVElFUyA9ICdhdWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMnO1xuUmVtb3RlQ29udHJvbENhcGFiaWxpdGllcy5LRVlfSE1JX1NFVFRJTkdTX0NPTlRST0xfQ0FQQUJJTElUSUVTID0gJ2htaVNldHRpbmdzQ29udHJvbENhcGFiaWxpdGllcyc7XG5SZW1vdGVDb250cm9sQ2FwYWJpbGl0aWVzLktFWV9MSUdIVF9DT05UUk9MX0NBUEFCSUxJVElFUyA9ICdsaWdodENvbnRyb2xDYXBhYmlsaXRpZXMnO1xuUmVtb3RlQ29udHJvbENhcGFiaWxpdGllcy5LRVlfU0VBVF9DT05UUk9MX0NBUEFCSUxJVElFUyA9ICdzZWF0Q29udHJvbENhcGFiaWxpdGllcyc7XG5cbmV4cG9ydCB7IFJlbW90ZUNvbnRyb2xDYXBhYmlsaXRpZXMgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgU2VhdExvY2F0aW9uIH0gZnJvbSAnLi9TZWF0TG9jYXRpb24uanMnO1xuXG4vKipcbiAqIENvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IHRoZSBsb2NhdGlvbnMgb2YgZWFjaCBzZWF0XG4gKi9cbmNsYXNzIFNlYXRMb2NhdGlvbkNhcGFiaWxpdHkgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSByb3dzXG4gICAgICogQHJldHVybiB7U2VhdExvY2F0aW9uQ2FwYWJpbGl0eX1cbiAgICAgKi9cbiAgICBzZXRSb3dzIChyb3dzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNlYXRMb2NhdGlvbkNhcGFiaWxpdHkuS0VZX1JPV1MsIHJvd3MpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0Um93cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihTZWF0TG9jYXRpb25DYXBhYmlsaXR5LktFWV9ST1dTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gY29sdW1uc1xuICAgICAqIEByZXR1cm4ge1NlYXRMb2NhdGlvbkNhcGFiaWxpdHl9XG4gICAgICovXG4gICAgc2V0Q29sdW1ucyAoY29sdW1ucykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZWF0TG9jYXRpb25DYXBhYmlsaXR5LktFWV9DT0xVTU5TLCBjb2x1bW5zKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldENvbHVtbnMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoU2VhdExvY2F0aW9uQ2FwYWJpbGl0eS5LRVlfQ09MVU1OUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGxldmVsc1xuICAgICAqIEByZXR1cm4ge1NlYXRMb2NhdGlvbkNhcGFiaWxpdHl9XG4gICAgICovXG4gICAgc2V0TGV2ZWxzIChsZXZlbHMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU2VhdExvY2F0aW9uQ2FwYWJpbGl0eS5LRVlfTEVWRUxTLCBsZXZlbHMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0TGV2ZWxzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFNlYXRMb2NhdGlvbkNhcGFiaWxpdHkuS0VZX0xFVkVMUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTZWF0TG9jYXRpb25bXX0gc2VhdHMgLSBDb250YWlucyBhIGxpc3Qgb2YgU2VhdExvY2F0aW9uIGluIHRoZSB2ZWhpY2xlXG4gICAgICogQHJldHVybiB7U2VhdExvY2F0aW9uQ2FwYWJpbGl0eX1cbiAgICAgKi9cbiAgICBzZXRTZWF0cyAoc2VhdHMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoU2VhdExvY2F0aW9uLCBzZWF0cywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFNlYXRMb2NhdGlvbkNhcGFiaWxpdHkuS0VZX1NFQVRTLCBzZWF0cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1NlYXRMb2NhdGlvbltdfVxuICAgICAqL1xuICAgIGdldFNlYXRzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFNlYXRMb2NhdGlvbiwgU2VhdExvY2F0aW9uQ2FwYWJpbGl0eS5LRVlfU0VBVFMpO1xuICAgIH1cbn1cblxuU2VhdExvY2F0aW9uQ2FwYWJpbGl0eS5LRVlfUk9XUyA9ICdyb3dzJztcblNlYXRMb2NhdGlvbkNhcGFiaWxpdHkuS0VZX0NPTFVNTlMgPSAnY29sdW1ucyc7XG5TZWF0TG9jYXRpb25DYXBhYmlsaXR5LktFWV9MRVZFTFMgPSAnbGV2ZWxzJztcblNlYXRMb2NhdGlvbkNhcGFiaWxpdHkuS0VZX1NFQVRTID0gJ3NlYXRzJztcblxuZXhwb3J0IHsgU2VhdExvY2F0aW9uQ2FwYWJpbGl0eSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBTZXJ2aWNlVXBkYXRlUmVhc29uXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBTZXJ2aWNlVXBkYXRlUmVhc29uIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBzZXJ2aWNlIGhhcyBqdXN0IGJlZW4gcHVibGlzaGVkIHdpdGggdGhlIG1vZHVsZSBhbmQgb25jZSBhY3RpdmF0ZWQgdG8gdGhlIHByaW1hcnkgc2VydmljZSBvZiBpdHMgdHlwZSwgaXRcbiAgICAgKiB3aWxsIGJlIHJlYWR5IGZvciBwb3NzaWJsZSBjb25zdW1wdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBQVUJMSVNIRUQgKCkge1xuICAgICAgICByZXR1cm4gU2VydmljZVVwZGF0ZVJlYXNvbi5fTUFQLlBVQkxJU0hFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgc2VydmljZSBoYXMganVzdCBiZWVuIHVucHVibGlzaGVkIHdpdGggdGhlIG1vZHVsZSBhbmQgaXMgbm8gbG9uZ2VyIGFjY2Vzc2libGVcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSRU1PVkVEICgpIHtcbiAgICAgICAgcmV0dXJuIFNlcnZpY2VVcGRhdGVSZWFzb24uX01BUC5SRU1PVkVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBzZXJ2aWNlIGlzIGFjdGl2YXRlZCBhcyB0aGUgcHJpbWFyeSBzZXJ2aWNlIG9mIHRoaXMgdHlwZS4gQWxsIHJlcXVlc3RzIGRlYWxpbmcgd2l0aCB0aGlzIHNlcnZpY2UgdHlwZSB3aWxsXG4gICAgICogYmUgaGFuZGxlZCBieSB0aGlzIHNlcnZpY2UuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQUNUSVZBVEVEICgpIHtcbiAgICAgICAgcmV0dXJuIFNlcnZpY2VVcGRhdGVSZWFzb24uX01BUC5BQ1RJVkFURUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIHNlcnZpY2UgaGFzIGJlZW4gZGVhY3RpdmF0ZWQgYXMgdGhlIHByaW1hcnkgc2VydmljZSBvZiBpdHMgdHlwZVxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IERFQUNUSVZBVEVEICgpIHtcbiAgICAgICAgcmV0dXJuIFNlcnZpY2VVcGRhdGVSZWFzb24uX01BUC5ERUFDVElWQVRFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgc2VydmljZSBoYXMgdXBkYXRlZCBpdHMgbWFuaWZlc3QuIFRoaXMgY291bGQgaW1wbHkgdXBkYXRlZCBjYXBhYmlsaXRpZXNcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBNQU5JRkVTVF9VUERBVEUgKCkge1xuICAgICAgICByZXR1cm4gU2VydmljZVVwZGF0ZVJlYXNvbi5fTUFQLk1BTklGRVNUX1VQREFURTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBTZXJ2aWNlVXBkYXRlUmVhc29uLl92YWx1ZUZvcktleShrZXksIFNlcnZpY2VVcGRhdGVSZWFzb24uX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBTZXJ2aWNlVXBkYXRlUmVhc29uLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgU2VydmljZVVwZGF0ZVJlYXNvbi5fTUFQKTtcbiAgICB9XG59XG5cblNlcnZpY2VVcGRhdGVSZWFzb24uX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdQVUJMSVNIRUQnOiAnUFVCTElTSEVEJyxcbiAgICAnUkVNT1ZFRCc6ICdSRU1PVkVEJyxcbiAgICAnQUNUSVZBVEVEJzogJ0FDVElWQVRFRCcsXG4gICAgJ0RFQUNUSVZBVEVEJzogJ0RFQUNUSVZBVEVEJyxcbiAgICAnTUFOSUZFU1RfVVBEQVRFJzogJ01BTklGRVNUX1VQREFURScsXG59KTtcblxuZXhwb3J0IHsgU2VydmljZVVwZGF0ZVJlYXNvbiB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5cbmNsYXNzIE5hdmlnYXRpb25TZXJ2aWNlTWFuaWZlc3QgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gcG9pbnRzIC0gSW5mb3JtcyB0aGUgc3Vic2NyaWJlciBpZiB0aGlzIHNlcnZpY2UgY2FuIGFjdHVhbGx5IGFjY2VwdCB3YXkgcG9pbnRzLlxuICAgICAqIEByZXR1cm4ge05hdmlnYXRpb25TZXJ2aWNlTWFuaWZlc3R9XG4gICAgICovXG4gICAgc2V0QWNjZXB0c1dheVBvaW50cyAocG9pbnRzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE5hdmlnYXRpb25TZXJ2aWNlTWFuaWZlc3QuS0VZX0FDQ0VQVFNfV0FZX1BPSU5UUywgcG9pbnRzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRBY2NlcHRzV2F5UG9pbnRzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE5hdmlnYXRpb25TZXJ2aWNlTWFuaWZlc3QuS0VZX0FDQ0VQVFNfV0FZX1BPSU5UUyk7XG4gICAgfVxufVxuXG5OYXZpZ2F0aW9uU2VydmljZU1hbmlmZXN0LktFWV9BQ0NFUFRTX1dBWV9QT0lOVFMgPSAnYWNjZXB0c1dheVBvaW50cyc7XG5cbmV4cG9ydCB7IE5hdmlnYXRpb25TZXJ2aWNlTWFuaWZlc3QgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuXG5jbGFzcyBXZWF0aGVyU2VydmljZU1hbmlmZXN0IGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHN1cHBvcnRlZFxuICAgICAqIEByZXR1cm4ge1dlYXRoZXJTZXJ2aWNlTWFuaWZlc3R9XG4gICAgICovXG4gICAgc2V0Q3VycmVudEZvcmVjYXN0U3VwcG9ydGVkIChzdXBwb3J0ZWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoV2VhdGhlclNlcnZpY2VNYW5pZmVzdC5LRVlfQ1VSUkVOVF9GT1JFQ0FTVF9TVVBQT1JURUQsIHN1cHBvcnRlZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0Q3VycmVudEZvcmVjYXN0U3VwcG9ydGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFdlYXRoZXJTZXJ2aWNlTWFuaWZlc3QuS0VZX0NVUlJFTlRfRk9SRUNBU1RfU1VQUE9SVEVEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYW1vdW50XG4gICAgICogQHJldHVybiB7V2VhdGhlclNlcnZpY2VNYW5pZmVzdH1cbiAgICAgKi9cbiAgICBzZXRNYXhNdWx0aWRheUZvcmVjYXN0QW1vdW50IChhbW91bnQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoV2VhdGhlclNlcnZpY2VNYW5pZmVzdC5LRVlfTUFYX01VTFRJREFZX0ZPUkVDQVNUX0FNT1VOVCwgYW1vdW50KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldE1heE11bHRpZGF5Rm9yZWNhc3RBbW91bnQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoV2VhdGhlclNlcnZpY2VNYW5pZmVzdC5LRVlfTUFYX01VTFRJREFZX0ZPUkVDQVNUX0FNT1VOVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGFtb3VudFxuICAgICAqIEByZXR1cm4ge1dlYXRoZXJTZXJ2aWNlTWFuaWZlc3R9XG4gICAgICovXG4gICAgc2V0TWF4SG91cmx5Rm9yZWNhc3RBbW91bnQgKGFtb3VudCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihXZWF0aGVyU2VydmljZU1hbmlmZXN0LktFWV9NQVhfSE9VUkxZX0ZPUkVDQVNUX0FNT1VOVCwgYW1vdW50KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldE1heEhvdXJseUZvcmVjYXN0QW1vdW50ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFdlYXRoZXJTZXJ2aWNlTWFuaWZlc3QuS0VZX01BWF9IT1VSTFlfRk9SRUNBU1RfQU1PVU5UKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYW1vdW50XG4gICAgICogQHJldHVybiB7V2VhdGhlclNlcnZpY2VNYW5pZmVzdH1cbiAgICAgKi9cbiAgICBzZXRNYXhNaW51dGVseUZvcmVjYXN0QW1vdW50IChhbW91bnQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoV2VhdGhlclNlcnZpY2VNYW5pZmVzdC5LRVlfTUFYX01JTlVURUxZX0ZPUkVDQVNUX0FNT1VOVCwgYW1vdW50KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldE1heE1pbnV0ZWx5Rm9yZWNhc3RBbW91bnQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoV2VhdGhlclNlcnZpY2VNYW5pZmVzdC5LRVlfTUFYX01JTlVURUxZX0ZPUkVDQVNUX0FNT1VOVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBzdXBwb3J0ZWRcbiAgICAgKiBAcmV0dXJuIHtXZWF0aGVyU2VydmljZU1hbmlmZXN0fVxuICAgICAqL1xuICAgIHNldFdlYXRoZXJGb3JMb2NhdGlvblN1cHBvcnRlZCAoc3VwcG9ydGVkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdlYXRoZXJTZXJ2aWNlTWFuaWZlc3QuS0VZX1dFQVRIRVJfRk9SX0xPQ0FUSU9OX1NVUFBPUlRFRCwgc3VwcG9ydGVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRXZWF0aGVyRm9yTG9jYXRpb25TdXBwb3J0ZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoV2VhdGhlclNlcnZpY2VNYW5pZmVzdC5LRVlfV0VBVEhFUl9GT1JfTE9DQVRJT05fU1VQUE9SVEVEKTtcbiAgICB9XG59XG5cbldlYXRoZXJTZXJ2aWNlTWFuaWZlc3QuS0VZX0NVUlJFTlRfRk9SRUNBU1RfU1VQUE9SVEVEID0gJ2N1cnJlbnRGb3JlY2FzdFN1cHBvcnRlZCc7XG5XZWF0aGVyU2VydmljZU1hbmlmZXN0LktFWV9NQVhfTVVMVElEQVlfRk9SRUNBU1RfQU1PVU5UID0gJ21heE11bHRpZGF5Rm9yZWNhc3RBbW91bnQnO1xuV2VhdGhlclNlcnZpY2VNYW5pZmVzdC5LRVlfTUFYX0hPVVJMWV9GT1JFQ0FTVF9BTU9VTlQgPSAnbWF4SG91cmx5Rm9yZWNhc3RBbW91bnQnO1xuV2VhdGhlclNlcnZpY2VNYW5pZmVzdC5LRVlfTUFYX01JTlVURUxZX0ZPUkVDQVNUX0FNT1VOVCA9ICdtYXhNaW51dGVseUZvcmVjYXN0QW1vdW50JztcbldlYXRoZXJTZXJ2aWNlTWFuaWZlc3QuS0VZX1dFQVRIRVJfRk9SX0xPQ0FUSU9OX1NVUFBPUlRFRCA9ICd3ZWF0aGVyRm9yTG9jYXRpb25TdXBwb3J0ZWQnO1xuXG5leHBvcnQgeyBXZWF0aGVyU2VydmljZU1hbmlmZXN0IH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcblxuY2xhc3MgTWVkaWFTZXJ2aWNlTWFuaWZlc3QgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cbn1cblxuXG5leHBvcnQgeyBNZWRpYVNlcnZpY2VNYW5pZmVzdCB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IE5hdmlnYXRpb25TZXJ2aWNlTWFuaWZlc3QgfSBmcm9tICcuL05hdmlnYXRpb25TZXJ2aWNlTWFuaWZlc3QuanMnO1xuaW1wb3J0IHsgSW1hZ2UgfSBmcm9tICcuL0ltYWdlLmpzJztcbmltcG9ydCB7IFNkbE1zZ1ZlcnNpb24gfSBmcm9tICcuL1NkbE1zZ1ZlcnNpb24uanMnO1xuaW1wb3J0IHsgV2VhdGhlclNlcnZpY2VNYW5pZmVzdCB9IGZyb20gJy4vV2VhdGhlclNlcnZpY2VNYW5pZmVzdC5qcyc7XG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgTWVkaWFTZXJ2aWNlTWFuaWZlc3QgfSBmcm9tICcuL01lZGlhU2VydmljZU1hbmlmZXN0LmpzJztcblxuLyoqXG4gKiBUaGlzIG1hbmlmZXN0IGNvbnRhaW5zIGFsbCB0aGUgaW5mb3JtYXRpb24gbmVjZXNzYXJ5IGZvciB0aGUgc2VydmljZSB0byBiZSBwdWJsaXNoZWQsIGFjdGl2YXRlZCwgYW5kIGNvbnN1bWVycyBhYmxlXG4gKiB0byBpbnRlcmFjdCB3aXRoIGl0XG4gKi9cbmNsYXNzIEFwcFNlcnZpY2VNYW5pZmVzdCBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBVbmlxdWUgbmFtZSBvZiB0aGlzIHNlcnZpY2VcbiAgICAgKiBAcmV0dXJuIHtBcHBTZXJ2aWNlTWFuaWZlc3R9XG4gICAgICovXG4gICAgc2V0U2VydmljZU5hbWUgKG5hbWUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQXBwU2VydmljZU1hbmlmZXN0LktFWV9TRVJWSUNFX05BTUUsIG5hbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0U2VydmljZU5hbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQXBwU2VydmljZU1hbmlmZXN0LktFWV9TRVJWSUNFX05BTUUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIC0gVGhlIHR5cGUgb2Ygc2VydmljZSB0aGF0IGlzIHRvIGJlIG9mZmVyZWQgYnkgdGhpcyBhcHAuIFNlZSBBcHBTZXJ2aWNlVHlwZSBmb3Iga25vd24gZW51bVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgZXF1aXZhbGVudCB0eXBlcy4gUGFyYW1ldGVyIGlzIGEgc3RyaW5nIHRvIGFsbG93IGZvciBuZXcgc2VydmljZSB0eXBlcyB0byBiZSB1c2VkIGJ5IGFwcHNcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIG9uIG9sZGVyIHZlcnNpb25zIG9mIFNETCBDb3JlLlxuICAgICAqIEByZXR1cm4ge0FwcFNlcnZpY2VNYW5pZmVzdH1cbiAgICAgKi9cbiAgICBzZXRTZXJ2aWNlVHlwZSAodHlwZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBcHBTZXJ2aWNlTWFuaWZlc3QuS0VZX1NFUlZJQ0VfVFlQRSwgdHlwZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRTZXJ2aWNlVHlwZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihBcHBTZXJ2aWNlTWFuaWZlc3QuS0VZX1NFUlZJQ0VfVFlQRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtJbWFnZX0gaWNvbiAtIFRoZSBpY29uIHRvIGJlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHNlcnZpY2UuIE1vc3QgbGlrZWx5IHRoZSBzYW1lIGFzIHRoZSBhcHBJY29uLlxuICAgICAqIEByZXR1cm4ge0FwcFNlcnZpY2VNYW5pZmVzdH1cbiAgICAgKi9cbiAgICBzZXRTZXJ2aWNlSWNvbiAoaWNvbikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShJbWFnZSwgaWNvbik7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEFwcFNlcnZpY2VNYW5pZmVzdC5LRVlfU0VSVklDRV9JQ09OLCBpY29uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7SW1hZ2V9XG4gICAgICovXG4gICAgZ2V0U2VydmljZUljb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoSW1hZ2UsIEFwcFNlcnZpY2VNYW5pZmVzdC5LRVlfU0VSVklDRV9JQ09OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGNvbnN1bWVycyAtIElmIHRydWUsIGFwcCBzZXJ2aWNlIGNvbnN1bWVycyBiZXlvbmQgdGhlIElWSSBzeXN0ZW0gd2lsbCBiZSBhYmxlIHRvIGFjY2VzcyB0aGlzXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXJ2aWNlLiBJZiBmYWxzZSwgb25seSB0aGUgSVZJIHN5c3RlbSB3aWxsIGJlIGFibGUgY29uc3VtZSB0aGUgc2VydmljZS4gSWYgbm90XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm92aWRlZCwgaXQgaXMgYXNzdW1lZCB0byBiZSBmYWxzZS5cbiAgICAgKiBAcmV0dXJuIHtBcHBTZXJ2aWNlTWFuaWZlc3R9XG4gICAgICovXG4gICAgc2V0QWxsb3dBcHBDb25zdW1lcnMgKGNvbnN1bWVycykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBcHBTZXJ2aWNlTWFuaWZlc3QuS0VZX0FMTE9XX0FQUF9DT05TVU1FUlMsIGNvbnN1bWVycyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0QWxsb3dBcHBDb25zdW1lcnMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQXBwU2VydmljZU1hbmlmZXN0LktFWV9BTExPV19BUFBfQ09OU1VNRVJTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NkbE1zZ1ZlcnNpb259IHZlcnNpb24gLSBUaGlzIGlzIHRoZSBtYXggUlBDIFNwZWMgdmVyc2lvbiB0aGUgYXBwIHNlcnZpY2UgdW5kZXJzdGFuZHMuIFRoaXMgaXMgaW1wb3J0YW50XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHVyaW5nIHRoZSBSUEMgcGFzc3Rocm91Z2ggZnVuY3Rpb25hbGl0eS4gSWYgbm90IGluY2x1ZGVkLCBpdCBpcyBhc3N1bWVkIHRoZSBtYXhcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uIG9mIHRoZSBtb2R1bGUgaXMgYWNjZXB0YWJsZS5cbiAgICAgKiBAcmV0dXJuIHtBcHBTZXJ2aWNlTWFuaWZlc3R9XG4gICAgICovXG4gICAgc2V0UnBjU3BlY1ZlcnNpb24gKHZlcnNpb24pIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoU2RsTXNnVmVyc2lvbiwgdmVyc2lvbik7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEFwcFNlcnZpY2VNYW5pZmVzdC5LRVlfUlBDX1NQRUNfVkVSU0lPTiwgdmVyc2lvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1NkbE1zZ1ZlcnNpb259XG4gICAgICovXG4gICAgZ2V0UnBjU3BlY1ZlcnNpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoU2RsTXNnVmVyc2lvbiwgQXBwU2VydmljZU1hbmlmZXN0LktFWV9SUENfU1BFQ19WRVJTSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcltdfSBjcyAtIFRoaXMgZmllbGQgY29udGFpbnMgdGhlIEZ1bmN0aW9uIElEcyBmb3IgdGhlIFJQQ3MgdGhhdCB0aGlzIHNlcnZpY2UgaW50ZW5kcyB0byBoYW5kbGVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIGNvcnJlY3RseS4gVGhpcyBtZWFucyB0aGUgc2VydmljZSB3aWxsIHByb3ZpZGUgbWVhbmluZ2Z1bCByZXNwb25zZXMuXG4gICAgICogQHJldHVybiB7QXBwU2VydmljZU1hbmlmZXN0fVxuICAgICAqL1xuICAgIHNldEhhbmRsZWRSUENzIChjcykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBcHBTZXJ2aWNlTWFuaWZlc3QuS0VZX0hBTkRMRURfUlBDUywgY3MpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJbXX1cbiAgICAgKi9cbiAgICBnZXRIYW5kbGVkUlBDcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihBcHBTZXJ2aWNlTWFuaWZlc3QuS0VZX0hBTkRMRURfUlBDUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtNZWRpYVNlcnZpY2VNYW5pZmVzdH0gbWFuaWZlc3RcbiAgICAgKiBAcmV0dXJuIHtBcHBTZXJ2aWNlTWFuaWZlc3R9XG4gICAgICovXG4gICAgc2V0TWVkaWFTZXJ2aWNlTWFuaWZlc3QgKG1hbmlmZXN0KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKE1lZGlhU2VydmljZU1hbmlmZXN0LCBtYW5pZmVzdCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEFwcFNlcnZpY2VNYW5pZmVzdC5LRVlfTUVESUFfU0VSVklDRV9NQU5JRkVTVCwgbWFuaWZlc3QpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtNZWRpYVNlcnZpY2VNYW5pZmVzdH1cbiAgICAgKi9cbiAgICBnZXRNZWRpYVNlcnZpY2VNYW5pZmVzdCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChNZWRpYVNlcnZpY2VNYW5pZmVzdCwgQXBwU2VydmljZU1hbmlmZXN0LktFWV9NRURJQV9TRVJWSUNFX01BTklGRVNUKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1dlYXRoZXJTZXJ2aWNlTWFuaWZlc3R9IG1hbmlmZXN0XG4gICAgICogQHJldHVybiB7QXBwU2VydmljZU1hbmlmZXN0fVxuICAgICAqL1xuICAgIHNldFdlYXRoZXJTZXJ2aWNlTWFuaWZlc3QgKG1hbmlmZXN0KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFdlYXRoZXJTZXJ2aWNlTWFuaWZlc3QsIG1hbmlmZXN0KTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQXBwU2VydmljZU1hbmlmZXN0LktFWV9XRUFUSEVSX1NFUlZJQ0VfTUFOSUZFU1QsIG1hbmlmZXN0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7V2VhdGhlclNlcnZpY2VNYW5pZmVzdH1cbiAgICAgKi9cbiAgICBnZXRXZWF0aGVyU2VydmljZU1hbmlmZXN0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFdlYXRoZXJTZXJ2aWNlTWFuaWZlc3QsIEFwcFNlcnZpY2VNYW5pZmVzdC5LRVlfV0VBVEhFUl9TRVJWSUNFX01BTklGRVNUKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge05hdmlnYXRpb25TZXJ2aWNlTWFuaWZlc3R9IG1hbmlmZXN0XG4gICAgICogQHJldHVybiB7QXBwU2VydmljZU1hbmlmZXN0fVxuICAgICAqL1xuICAgIHNldE5hdmlnYXRpb25TZXJ2aWNlTWFuaWZlc3QgKG1hbmlmZXN0KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKE5hdmlnYXRpb25TZXJ2aWNlTWFuaWZlc3QsIG1hbmlmZXN0KTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQXBwU2VydmljZU1hbmlmZXN0LktFWV9OQVZJR0FUSU9OX1NFUlZJQ0VfTUFOSUZFU1QsIG1hbmlmZXN0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TmF2aWdhdGlvblNlcnZpY2VNYW5pZmVzdH1cbiAgICAgKi9cbiAgICBnZXROYXZpZ2F0aW9uU2VydmljZU1hbmlmZXN0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KE5hdmlnYXRpb25TZXJ2aWNlTWFuaWZlc3QsIEFwcFNlcnZpY2VNYW5pZmVzdC5LRVlfTkFWSUdBVElPTl9TRVJWSUNFX01BTklGRVNUKTtcbiAgICB9XG59XG5cbkFwcFNlcnZpY2VNYW5pZmVzdC5LRVlfU0VSVklDRV9OQU1FID0gJ3NlcnZpY2VOYW1lJztcbkFwcFNlcnZpY2VNYW5pZmVzdC5LRVlfU0VSVklDRV9UWVBFID0gJ3NlcnZpY2VUeXBlJztcbkFwcFNlcnZpY2VNYW5pZmVzdC5LRVlfU0VSVklDRV9JQ09OID0gJ3NlcnZpY2VJY29uJztcbkFwcFNlcnZpY2VNYW5pZmVzdC5LRVlfQUxMT1dfQVBQX0NPTlNVTUVSUyA9ICdhbGxvd0FwcENvbnN1bWVycyc7XG5BcHBTZXJ2aWNlTWFuaWZlc3QuS0VZX1JQQ19TUEVDX1ZFUlNJT04gPSAncnBjU3BlY1ZlcnNpb24nO1xuQXBwU2VydmljZU1hbmlmZXN0LktFWV9IQU5ETEVEX1JQQ1MgPSAnaGFuZGxlZFJQQ3MnO1xuQXBwU2VydmljZU1hbmlmZXN0LktFWV9NRURJQV9TRVJWSUNFX01BTklGRVNUID0gJ21lZGlhU2VydmljZU1hbmlmZXN0JztcbkFwcFNlcnZpY2VNYW5pZmVzdC5LRVlfV0VBVEhFUl9TRVJWSUNFX01BTklGRVNUID0gJ3dlYXRoZXJTZXJ2aWNlTWFuaWZlc3QnO1xuQXBwU2VydmljZU1hbmlmZXN0LktFWV9OQVZJR0FUSU9OX1NFUlZJQ0VfTUFOSUZFU1QgPSAnbmF2aWdhdGlvblNlcnZpY2VNYW5pZmVzdCc7XG5cbmV4cG9ydCB7IEFwcFNlcnZpY2VNYW5pZmVzdCB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBBcHBTZXJ2aWNlTWFuaWZlc3QgfSBmcm9tICcuL0FwcFNlcnZpY2VNYW5pZmVzdC5qcyc7XG5cbi8qKlxuICogVGhpcyBpcyB0aGUgcmVjb3JkIG9mIGFuIGFwcCBzZXJ2aWNlIHB1Ymxpc2hlciB0aGF0IHRoZSBtb2R1bGUgaGFzLiBJdCBzaG91bGQgY29udGFpbiB0aGUgbW9zdCB1cCB0byBkYXRlXG4gKiBpbmZvcm1hdGlvbiBpbmNsdWRpbmcgdGhlIHNlcnZpY2UncyBhY3RpdmUgc3RhdGVcbiAqL1xuY2xhc3MgQXBwU2VydmljZVJlY29yZCBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGlkIC0gQSB1bmlxdWUgSUQgdGllZCB0byB0aGlzIHNwZWNpZmljIHNlcnZpY2UgcmVjb3JkLiBUaGUgSUQgaXMgc3VwcGxpZWQgYnkgdGhlIG1vZHVsZSB0aGF0XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgc2VydmljZXMgcHVibGlzaCB0aGVtc2VsdmVzLlxuICAgICAqIEByZXR1cm4ge0FwcFNlcnZpY2VSZWNvcmR9XG4gICAgICovXG4gICAgc2V0U2VydmljZUlEIChpZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBcHBTZXJ2aWNlUmVjb3JkLktFWV9TRVJWSUNFX0lELCBpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRTZXJ2aWNlSUQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQXBwU2VydmljZVJlY29yZC5LRVlfU0VSVklDRV9JRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtBcHBTZXJ2aWNlTWFuaWZlc3R9IG1hbmlmZXN0IC0gTWFuaWZlc3QgZm9yIHRoZSBzZXJ2aWNlIHRoYXQgdGhpcyByZWNvcmQgaXMgZm9yLlxuICAgICAqIEByZXR1cm4ge0FwcFNlcnZpY2VSZWNvcmR9XG4gICAgICovXG4gICAgc2V0U2VydmljZU1hbmlmZXN0IChtYW5pZmVzdCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShBcHBTZXJ2aWNlTWFuaWZlc3QsIG1hbmlmZXN0KTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQXBwU2VydmljZVJlY29yZC5LRVlfU0VSVklDRV9NQU5JRkVTVCwgbWFuaWZlc3QpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtBcHBTZXJ2aWNlTWFuaWZlc3R9XG4gICAgICovXG4gICAgZ2V0U2VydmljZU1hbmlmZXN0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEFwcFNlcnZpY2VNYW5pZmVzdCwgQXBwU2VydmljZVJlY29yZC5LRVlfU0VSVklDRV9NQU5JRkVTVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBwdWJsaXNoZWQgLSBJZiB0cnVlLCB0aGUgc2VydmljZSBpcyBwdWJsaXNoZWQgYW5kIGF2YWlsYWJsZS4gSWYgZmFsc2UsIHRoZSBzZXJ2aWNlIGhhcyBsaWtlbHlcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGp1c3QgYmVlbiB1bnB1Ymxpc2hlZCwgYW5kIHNob3VsZCBiZSBjb25zaWRlcmVkIHVuYXZhaWxhYmxlLlxuICAgICAqIEByZXR1cm4ge0FwcFNlcnZpY2VSZWNvcmR9XG4gICAgICovXG4gICAgc2V0U2VydmljZVB1Ymxpc2hlZCAocHVibGlzaGVkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEFwcFNlcnZpY2VSZWNvcmQuS0VZX1NFUlZJQ0VfUFVCTElTSEVELCBwdWJsaXNoZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFNlcnZpY2VQdWJsaXNoZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQXBwU2VydmljZVJlY29yZC5LRVlfU0VSVklDRV9QVUJMSVNIRUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYWN0aXZlIC0gSWYgdHJ1ZSwgdGhlIHNlcnZpY2UgaXMgdGhlIGFjdGl2ZSBwcmltYXJ5IHNlcnZpY2Ugb2YgdGhlIHN1cHBsaWVkIHNlcnZpY2UgdHlwZS4gSXRcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbGwgcmVjZWl2ZSBhbGwgcG90ZW50aWFsIFJQQ3MgdGhhdCBhcmUgcGFzc2VkIHRocm91Z2ggdG8gdGhhdCBzZXJ2aWNlIHR5cGUuIElmIGZhbHNlLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQgaXMgbm90IHRoZSBwcmltYXJ5IHNlcnZpY2Ugb2YgdGhlIHN1cHBsaWVkIHR5cGUuIFNlZSBzZXJ2aWNlUHVibGlzaGVkIGZvciBpdHNcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGF2YWlsYWJpbGl0eS5cbiAgICAgKiBAcmV0dXJuIHtBcHBTZXJ2aWNlUmVjb3JkfVxuICAgICAqL1xuICAgIHNldFNlcnZpY2VBY3RpdmUgKGFjdGl2ZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBcHBTZXJ2aWNlUmVjb3JkLktFWV9TRVJWSUNFX0FDVElWRSwgYWN0aXZlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRTZXJ2aWNlQWN0aXZlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEFwcFNlcnZpY2VSZWNvcmQuS0VZX1NFUlZJQ0VfQUNUSVZFKTtcbiAgICB9XG59XG5cbkFwcFNlcnZpY2VSZWNvcmQuS0VZX1NFUlZJQ0VfSUQgPSAnc2VydmljZUlEJztcbkFwcFNlcnZpY2VSZWNvcmQuS0VZX1NFUlZJQ0VfTUFOSUZFU1QgPSAnc2VydmljZU1hbmlmZXN0JztcbkFwcFNlcnZpY2VSZWNvcmQuS0VZX1NFUlZJQ0VfUFVCTElTSEVEID0gJ3NlcnZpY2VQdWJsaXNoZWQnO1xuQXBwU2VydmljZVJlY29yZC5LRVlfU0VSVklDRV9BQ1RJVkUgPSAnc2VydmljZUFjdGl2ZSc7XG5cbmV4cG9ydCB7IEFwcFNlcnZpY2VSZWNvcmQgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgU2VydmljZVVwZGF0ZVJlYXNvbiB9IGZyb20gJy4uL2VudW1zL1NlcnZpY2VVcGRhdGVSZWFzb24uanMnO1xuaW1wb3J0IHsgQXBwU2VydmljZVJlY29yZCB9IGZyb20gJy4vQXBwU2VydmljZVJlY29yZC5qcyc7XG5cbmNsYXNzIEFwcFNlcnZpY2VDYXBhYmlsaXR5IGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VVcGRhdGVSZWFzb259IHJlYXNvbiAtIE9ubHkgaW5jbHVkZWQgaW4gT25TeXN0ZW1DYXBhYmlsaXR5VXBkYXRlZC4gVXBkYXRlIHJlYXNvbiBmb3Igc2VydmljZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjb3JkLlxuICAgICAqIEByZXR1cm4ge0FwcFNlcnZpY2VDYXBhYmlsaXR5fVxuICAgICAqL1xuICAgIHNldFVwZGF0ZVJlYXNvbiAocmVhc29uKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFNlcnZpY2VVcGRhdGVSZWFzb24sIHJlYXNvbik7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEFwcFNlcnZpY2VDYXBhYmlsaXR5LktFWV9VUERBVEVfUkVBU09OLCByZWFzb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTZXJ2aWNlVXBkYXRlUmVhc29ufVxuICAgICAqL1xuICAgIGdldFVwZGF0ZVJlYXNvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChTZXJ2aWNlVXBkYXRlUmVhc29uLCBBcHBTZXJ2aWNlQ2FwYWJpbGl0eS5LRVlfVVBEQVRFX1JFQVNPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtBcHBTZXJ2aWNlUmVjb3JkfSByZWNvcmQgLSBTZXJ2aWNlIHJlY29yZCBmb3IgYSBzcGVjaWZpYyBhcHAgc2VydmljZSBwcm92aWRlclxuICAgICAqIEByZXR1cm4ge0FwcFNlcnZpY2VDYXBhYmlsaXR5fVxuICAgICAqL1xuICAgIHNldFVwZGF0ZWRBcHBTZXJ2aWNlUmVjb3JkIChyZWNvcmQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQXBwU2VydmljZVJlY29yZCwgcmVjb3JkKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQXBwU2VydmljZUNhcGFiaWxpdHkuS0VZX1VQREFURURfQVBQX1NFUlZJQ0VfUkVDT1JELCByZWNvcmQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtBcHBTZXJ2aWNlUmVjb3JkfVxuICAgICAqL1xuICAgIGdldFVwZGF0ZWRBcHBTZXJ2aWNlUmVjb3JkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEFwcFNlcnZpY2VSZWNvcmQsIEFwcFNlcnZpY2VDYXBhYmlsaXR5LktFWV9VUERBVEVEX0FQUF9TRVJWSUNFX1JFQ09SRCk7XG4gICAgfVxufVxuXG5BcHBTZXJ2aWNlQ2FwYWJpbGl0eS5LRVlfVVBEQVRFX1JFQVNPTiA9ICd1cGRhdGVSZWFzb24nO1xuQXBwU2VydmljZUNhcGFiaWxpdHkuS0VZX1VQREFURURfQVBQX1NFUlZJQ0VfUkVDT1JEID0gJ3VwZGF0ZWRBcHBTZXJ2aWNlUmVjb3JkJztcblxuZXhwb3J0IHsgQXBwU2VydmljZUNhcGFiaWxpdHkgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgQXBwU2VydmljZUNhcGFiaWxpdHkgfSBmcm9tICcuL0FwcFNlcnZpY2VDYXBhYmlsaXR5LmpzJztcblxuLyoqXG4gKiBDYXBhYmlsaXRpZXMgb2YgYXBwIHNlcnZpY2VzIGluY2x1ZGluZyB3aGF0IHNlcnZpY2UgdHlwZXMgYXJlIHN1cHBvcnRlZCBhbmQgdGhlIGN1cnJlbnQgc3RhdGUgb2Ygc2VydmljZXMuXG4gKi9cbmNsYXNzIEFwcFNlcnZpY2VzQ2FwYWJpbGl0aWVzIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0FwcFNlcnZpY2VDYXBhYmlsaXR5W119IHNlcnZpY2VzIC0gQW4gYXJyYXkgb2YgY3VycmVudGx5IGF2YWlsYWJsZSBzZXJ2aWNlcy4gSWYgdGhpcyBpcyBhbiB1cGRhdGUgdG8gdGhlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcGFiaWxpdHkgdGhlIGFmZmVjdGVkIHNlcnZpY2VzIHdpbGwgaW5jbHVkZSBhbiB1cGRhdGUgcmVhc29uIGluIHRoYXRcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbVxuICAgICAqIEByZXR1cm4ge0FwcFNlcnZpY2VzQ2FwYWJpbGl0aWVzfVxuICAgICAqL1xuICAgIHNldEFwcFNlcnZpY2VzIChzZXJ2aWNlcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShBcHBTZXJ2aWNlQ2FwYWJpbGl0eSwgc2VydmljZXMsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBcHBTZXJ2aWNlc0NhcGFiaWxpdGllcy5LRVlfQVBQX1NFUlZJQ0VTLCBzZXJ2aWNlcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0FwcFNlcnZpY2VDYXBhYmlsaXR5W119XG4gICAgICovXG4gICAgZ2V0QXBwU2VydmljZXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQXBwU2VydmljZUNhcGFiaWxpdHksIEFwcFNlcnZpY2VzQ2FwYWJpbGl0aWVzLktFWV9BUFBfU0VSVklDRVMpO1xuICAgIH1cbn1cblxuQXBwU2VydmljZXNDYXBhYmlsaXRpZXMuS0VZX0FQUF9TRVJWSUNFUyA9ICdhcHBTZXJ2aWNlcyc7XG5cbmV4cG9ydCB7IEFwcFNlcnZpY2VzQ2FwYWJpbGl0aWVzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcblxuLyoqXG4gKiBFeHRlbmRlZCBjYXBhYmlsaXRpZXMgZm9yIGFuIG9uYm9hcmQgbmF2aWdhdGlvbiBzeXN0ZW1cbiAqL1xuY2xhc3MgTmF2aWdhdGlvbkNhcGFiaWxpdHkgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gZW5hYmxlZCAtIElmIHRoZSBtb2R1bGUgaGFzIHRoZSBhYmlsaXR5IHRvIGFkZCBsb2NhdGlvbnMgdG8gdGhlIG9uYm9hcmQgbmF2XG4gICAgICogQHJldHVybiB7TmF2aWdhdGlvbkNhcGFiaWxpdHl9XG4gICAgICovXG4gICAgc2V0U2VuZExvY2F0aW9uRW5hYmxlZCAoZW5hYmxlZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihOYXZpZ2F0aW9uQ2FwYWJpbGl0eS5LRVlfU0VORF9MT0NBVElPTl9FTkFCTEVELCBlbmFibGVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRTZW5kTG9jYXRpb25FbmFibGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE5hdmlnYXRpb25DYXBhYmlsaXR5LktFWV9TRU5EX0xPQ0FUSU9OX0VOQUJMRUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gZW5hYmxlZCAtIElmIHRoZSBtb2R1bGUgaGFzIHRoZSBhYmlsaXR5IHRvIHJldHVybiB3YXkgcG9pbnRzIGZyb20gb25ib2FyZCBuYXZcbiAgICAgKiBAcmV0dXJuIHtOYXZpZ2F0aW9uQ2FwYWJpbGl0eX1cbiAgICAgKi9cbiAgICBzZXRHZXRXYXlQb2ludHNFbmFibGVkIChlbmFibGVkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE5hdmlnYXRpb25DYXBhYmlsaXR5LktFWV9HRVRfV0FZX1BPSU5UU19FTkFCTEVELCBlbmFibGVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRHZXRXYXlQb2ludHNFbmFibGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE5hdmlnYXRpb25DYXBhYmlsaXR5LktFWV9HRVRfV0FZX1BPSU5UU19FTkFCTEVEKTtcbiAgICB9XG59XG5cbk5hdmlnYXRpb25DYXBhYmlsaXR5LktFWV9TRU5EX0xPQ0FUSU9OX0VOQUJMRUQgPSAnc2VuZExvY2F0aW9uRW5hYmxlZCc7XG5OYXZpZ2F0aW9uQ2FwYWJpbGl0eS5LRVlfR0VUX1dBWV9QT0lOVFNfRU5BQkxFRCA9ICdnZXRXYXlQb2ludHNFbmFibGVkJztcblxuZXhwb3J0IHsgTmF2aWdhdGlvbkNhcGFiaWxpdHkgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHkgfSBmcm9tICcuL1ZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eS5qcyc7XG5pbXBvcnQgeyBQaG9uZUNhcGFiaWxpdHkgfSBmcm9tICcuL1Bob25lQ2FwYWJpbGl0eS5qcyc7XG5pbXBvcnQgeyBEaXNwbGF5Q2FwYWJpbGl0eSB9IGZyb20gJy4vRGlzcGxheUNhcGFiaWxpdHkuanMnO1xuaW1wb3J0IHsgUmVtb3RlQ29udHJvbENhcGFiaWxpdGllcyB9IGZyb20gJy4vUmVtb3RlQ29udHJvbENhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBTZWF0TG9jYXRpb25DYXBhYmlsaXR5IH0gZnJvbSAnLi9TZWF0TG9jYXRpb25DYXBhYmlsaXR5LmpzJztcbmltcG9ydCB7IFN5c3RlbUNhcGFiaWxpdHlUeXBlIH0gZnJvbSAnLi4vZW51bXMvU3lzdGVtQ2FwYWJpbGl0eVR5cGUuanMnO1xuaW1wb3J0IHsgQXBwU2VydmljZXNDYXBhYmlsaXRpZXMgfSBmcm9tICcuL0FwcFNlcnZpY2VzQ2FwYWJpbGl0aWVzLmpzJztcbmltcG9ydCB7IE5hdmlnYXRpb25DYXBhYmlsaXR5IH0gZnJvbSAnLi9OYXZpZ2F0aW9uQ2FwYWJpbGl0eS5qcyc7XG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuXG4vKipcbiAqIFRoZSBzeXN0ZW1DYXBhYmlsaXR5VHlwZSBpZGVudGlmaWVzIHdoaWNoIGRhdGEgb2JqZWN0IGV4aXN0cyBpbiB0aGlzIHN0cnVjdC4gRm9yIGV4YW1wbGUsIGlmIHRoZSBTeXN0ZW1DYXBhYmlsaXR5XG4gKiBUeXBlIGlzIE5BVklHQVRJT04gdGhlbiBhIFwibmF2aWdhdGlvbkNhcGFiaWxpdHlcIiBzaG91bGQgZXhpc3RcbiAqL1xuY2xhc3MgU3lzdGVtQ2FwYWJpbGl0eSBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTeXN0ZW1DYXBhYmlsaXR5VHlwZX0gdHlwZSAtIFVzZWQgYXMgYSBkZXNjcmlwdG9yIG9mIHdoYXQgZGF0YSB0byBleHBlY3QgaW4gdGhpcyBzdHJ1Y3QuIFRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JyZXNwb25kaW5nIHBhcmFtIHRvIHRoaXMgZW51bSBzaG91bGQgYmUgaW5jbHVkZWQgYW5kIHRoZSBvbmx5IG90aGVyIHBhcmFtXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluY2x1ZGVkLlxuICAgICAqIEByZXR1cm4ge1N5c3RlbUNhcGFiaWxpdHl9XG4gICAgICovXG4gICAgc2V0U3lzdGVtQ2FwYWJpbGl0eVR5cGUgKHR5cGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoU3lzdGVtQ2FwYWJpbGl0eVR5cGUsIHR5cGUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTeXN0ZW1DYXBhYmlsaXR5LktFWV9TWVNURU1fQ0FQQUJJTElUWV9UWVBFLCB0eXBlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3lzdGVtQ2FwYWJpbGl0eVR5cGV9XG4gICAgICovXG4gICAgZ2V0U3lzdGVtQ2FwYWJpbGl0eVR5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoU3lzdGVtQ2FwYWJpbGl0eVR5cGUsIFN5c3RlbUNhcGFiaWxpdHkuS0VZX1NZU1RFTV9DQVBBQklMSVRZX1RZUEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TmF2aWdhdGlvbkNhcGFiaWxpdHl9IGNhcGFiaWxpdHkgLSBEZXNjcmliZXMgZXh0ZW5kZWQgY2FwYWJpbGl0aWVzIGZvciBvbmJvYXJkIG5hdmlnYXRpb24gc3lzdGVtXG4gICAgICogQHJldHVybiB7U3lzdGVtQ2FwYWJpbGl0eX1cbiAgICAgKi9cbiAgICBzZXROYXZpZ2F0aW9uQ2FwYWJpbGl0eSAoY2FwYWJpbGl0eSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShOYXZpZ2F0aW9uQ2FwYWJpbGl0eSwgY2FwYWJpbGl0eSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFN5c3RlbUNhcGFiaWxpdHkuS0VZX05BVklHQVRJT05fQ0FQQUJJTElUWSwgY2FwYWJpbGl0eSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge05hdmlnYXRpb25DYXBhYmlsaXR5fVxuICAgICAqL1xuICAgIGdldE5hdmlnYXRpb25DYXBhYmlsaXR5ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KE5hdmlnYXRpb25DYXBhYmlsaXR5LCBTeXN0ZW1DYXBhYmlsaXR5LktFWV9OQVZJR0FUSU9OX0NBUEFCSUxJVFkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7UGhvbmVDYXBhYmlsaXR5fSBjYXBhYmlsaXR5IC0gRGVzY3JpYmVzIGV4dGVuZGVkIGNhcGFiaWxpdGllcyBvZiB0aGUgbW9kdWxlJ3MgcGhvbmUgZmVhdHVyZVxuICAgICAqIEByZXR1cm4ge1N5c3RlbUNhcGFiaWxpdHl9XG4gICAgICovXG4gICAgc2V0UGhvbmVDYXBhYmlsaXR5IChjYXBhYmlsaXR5KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFBob25lQ2FwYWJpbGl0eSwgY2FwYWJpbGl0eSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFN5c3RlbUNhcGFiaWxpdHkuS0VZX1BIT05FX0NBUEFCSUxJVFksIGNhcGFiaWxpdHkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtQaG9uZUNhcGFiaWxpdHl9XG4gICAgICovXG4gICAgZ2V0UGhvbmVDYXBhYmlsaXR5ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFBob25lQ2FwYWJpbGl0eSwgU3lzdGVtQ2FwYWJpbGl0eS5LRVlfUEhPTkVfQ0FQQUJJTElUWSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHl9IGNhcGFiaWxpdHkgLSBEZXNjcmliZXMgZXh0ZW5kZWQgY2FwYWJpbGl0aWVzIG9mIHRoZSBtb2R1bGUncyBwaG9uZSBmZWF0dXJlXG4gICAgICogQHJldHVybiB7U3lzdGVtQ2FwYWJpbGl0eX1cbiAgICAgKi9cbiAgICBzZXRWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHkgKGNhcGFiaWxpdHkpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmlkZW9TdHJlYW1pbmdDYXBhYmlsaXR5LCBjYXBhYmlsaXR5KTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3lzdGVtQ2FwYWJpbGl0eS5LRVlfVklERU9fU1RSRUFNSU5HX0NBUEFCSUxJVFksIGNhcGFiaWxpdHkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHl9XG4gICAgICovXG4gICAgZ2V0VmlkZW9TdHJlYW1pbmdDYXBhYmlsaXR5ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eSwgU3lzdGVtQ2FwYWJpbGl0eS5LRVlfVklERU9fU1RSRUFNSU5HX0NBUEFCSUxJVFkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7UmVtb3RlQ29udHJvbENhcGFiaWxpdGllc30gY2FwYWJpbGl0eSAtIERlc2NyaWJlcyBleHRlbmRlZCBjYXBhYmlsaXRpZXMgb2YgdGhlIG1vZHVsZSdzIHBob25lIGZlYXR1cmVcbiAgICAgKiBAcmV0dXJuIHtTeXN0ZW1DYXBhYmlsaXR5fVxuICAgICAqL1xuICAgIHNldFJlbW90ZUNvbnRyb2xDYXBhYmlsaXR5IChjYXBhYmlsaXR5KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFJlbW90ZUNvbnRyb2xDYXBhYmlsaXRpZXMsIGNhcGFiaWxpdHkpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTeXN0ZW1DYXBhYmlsaXR5LktFWV9SRU1PVEVfQ09OVFJPTF9DQVBBQklMSVRZLCBjYXBhYmlsaXR5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7UmVtb3RlQ29udHJvbENhcGFiaWxpdGllc31cbiAgICAgKi9cbiAgICBnZXRSZW1vdGVDb250cm9sQ2FwYWJpbGl0eSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChSZW1vdGVDb250cm9sQ2FwYWJpbGl0aWVzLCBTeXN0ZW1DYXBhYmlsaXR5LktFWV9SRU1PVEVfQ09OVFJPTF9DQVBBQklMSVRZKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0FwcFNlcnZpY2VzQ2FwYWJpbGl0aWVzfSBjYXBhYmlsaXRpZXMgLSBBbiBhcnJheSBvZiBjdXJyZW50bHkgYXZhaWxhYmxlIHNlcnZpY2VzLiBJZiB0aGlzIGlzIGFuIHVwZGF0ZSB0b1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBjYXBhYmlsaXR5IHRoZSBhZmZlY3RlZCBzZXJ2aWNlcyB3aWxsIGluY2x1ZGUgYW4gdXBkYXRlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uIGluIHRoYXQgaXRlbVxuICAgICAqIEByZXR1cm4ge1N5c3RlbUNhcGFiaWxpdHl9XG4gICAgICovXG4gICAgc2V0QXBwU2VydmljZXNDYXBhYmlsaXRpZXMgKGNhcGFiaWxpdGllcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShBcHBTZXJ2aWNlc0NhcGFiaWxpdGllcywgY2FwYWJpbGl0aWVzKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoU3lzdGVtQ2FwYWJpbGl0eS5LRVlfQVBQX1NFUlZJQ0VTX0NBUEFCSUxJVElFUywgY2FwYWJpbGl0aWVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7QXBwU2VydmljZXNDYXBhYmlsaXRpZXN9XG4gICAgICovXG4gICAgZ2V0QXBwU2VydmljZXNDYXBhYmlsaXRpZXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQXBwU2VydmljZXNDYXBhYmlsaXRpZXMsIFN5c3RlbUNhcGFiaWxpdHkuS0VZX0FQUF9TRVJWSUNFU19DQVBBQklMSVRJRVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2VhdExvY2F0aW9uQ2FwYWJpbGl0eX0gY2FwYWJpbGl0eSAtIENvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IHRoZSBsb2NhdGlvbnMgb2YgZWFjaCBzZWF0XG4gICAgICogQHJldHVybiB7U3lzdGVtQ2FwYWJpbGl0eX1cbiAgICAgKi9cbiAgICBzZXRTZWF0TG9jYXRpb25DYXBhYmlsaXR5IChjYXBhYmlsaXR5KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFNlYXRMb2NhdGlvbkNhcGFiaWxpdHksIGNhcGFiaWxpdHkpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTeXN0ZW1DYXBhYmlsaXR5LktFWV9TRUFUX0xPQ0FUSU9OX0NBUEFCSUxJVFksIGNhcGFiaWxpdHkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTZWF0TG9jYXRpb25DYXBhYmlsaXR5fVxuICAgICAqL1xuICAgIGdldFNlYXRMb2NhdGlvbkNhcGFiaWxpdHkgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoU2VhdExvY2F0aW9uQ2FwYWJpbGl0eSwgU3lzdGVtQ2FwYWJpbGl0eS5LRVlfU0VBVF9MT0NBVElPTl9DQVBBQklMSVRZKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Rpc3BsYXlDYXBhYmlsaXR5W119IGNhcGFiaWxpdGllc1xuICAgICAqIEByZXR1cm4ge1N5c3RlbUNhcGFiaWxpdHl9XG4gICAgICovXG4gICAgc2V0RGlzcGxheUNhcGFiaWxpdGllcyAoY2FwYWJpbGl0aWVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKERpc3BsYXlDYXBhYmlsaXR5LCBjYXBhYmlsaXRpZXMsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTeXN0ZW1DYXBhYmlsaXR5LktFWV9ESVNQTEFZX0NBUEFCSUxJVElFUywgY2FwYWJpbGl0aWVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7RGlzcGxheUNhcGFiaWxpdHlbXX1cbiAgICAgKi9cbiAgICBnZXREaXNwbGF5Q2FwYWJpbGl0aWVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KERpc3BsYXlDYXBhYmlsaXR5LCBTeXN0ZW1DYXBhYmlsaXR5LktFWV9ESVNQTEFZX0NBUEFCSUxJVElFUyk7XG4gICAgfVxufVxuXG5TeXN0ZW1DYXBhYmlsaXR5LktFWV9TWVNURU1fQ0FQQUJJTElUWV9UWVBFID0gJ3N5c3RlbUNhcGFiaWxpdHlUeXBlJztcblN5c3RlbUNhcGFiaWxpdHkuS0VZX05BVklHQVRJT05fQ0FQQUJJTElUWSA9ICduYXZpZ2F0aW9uQ2FwYWJpbGl0eSc7XG5TeXN0ZW1DYXBhYmlsaXR5LktFWV9QSE9ORV9DQVBBQklMSVRZID0gJ3Bob25lQ2FwYWJpbGl0eSc7XG5TeXN0ZW1DYXBhYmlsaXR5LktFWV9WSURFT19TVFJFQU1JTkdfQ0FQQUJJTElUWSA9ICd2aWRlb1N0cmVhbWluZ0NhcGFiaWxpdHknO1xuU3lzdGVtQ2FwYWJpbGl0eS5LRVlfUkVNT1RFX0NPTlRST0xfQ0FQQUJJTElUWSA9ICdyZW1vdGVDb250cm9sQ2FwYWJpbGl0eSc7XG5TeXN0ZW1DYXBhYmlsaXR5LktFWV9BUFBfU0VSVklDRVNfQ0FQQUJJTElUSUVTID0gJ2FwcFNlcnZpY2VzQ2FwYWJpbGl0aWVzJztcblN5c3RlbUNhcGFiaWxpdHkuS0VZX1NFQVRfTE9DQVRJT05fQ0FQQUJJTElUWSA9ICdzZWF0TG9jYXRpb25DYXBhYmlsaXR5JztcblN5c3RlbUNhcGFiaWxpdHkuS0VZX0RJU1BMQVlfQ0FQQUJJTElUSUVTID0gJ2Rpc3BsYXlDYXBhYmlsaXRpZXMnO1xuXG5leHBvcnQgeyBTeXN0ZW1DYXBhYmlsaXR5IH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBTeXN0ZW1DYXBhYmlsaXR5IH0gZnJvbSAnLi4vc3RydWN0cy9TeXN0ZW1DYXBhYmlsaXR5LmpzJztcblxuY2xhc3MgR2V0U3lzdGVtQ2FwYWJpbGl0eVJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuR2V0U3lzdGVtQ2FwYWJpbGl0eSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTeXN0ZW1DYXBhYmlsaXR5fSBjYXBhYmlsaXR5IC0gVGhlIHN5c3RlbUNhcGFiaWxpdHlUeXBlIGlkZW50aWZpZXMgd2hpY2ggZGF0YSBvYmplY3QgZXhpc3RzIGluIHRoaXNcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QuIEZvciBleGFtcGxlLCBpZiB0aGUgU3lzdGVtQ2FwYWJpbGl0eSBUeXBlIGlzIE5BVklHQVRJT04gdGhlbiBhXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJuYXZpZ2F0aW9uQ2FwYWJpbGl0eVwiIHNob3VsZCBleGlzdFxuICAgICAqIEByZXR1cm4ge0dldFN5c3RlbUNhcGFiaWxpdHlSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRTeXN0ZW1DYXBhYmlsaXR5IChjYXBhYmlsaXR5KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFN5c3RlbUNhcGFiaWxpdHksIGNhcGFiaWxpdHkpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRTeXN0ZW1DYXBhYmlsaXR5UmVzcG9uc2UuS0VZX1NZU1RFTV9DQVBBQklMSVRZLCBjYXBhYmlsaXR5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3lzdGVtQ2FwYWJpbGl0eX1cbiAgICAgKi9cbiAgICBnZXRTeXN0ZW1DYXBhYmlsaXR5ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFN5c3RlbUNhcGFiaWxpdHksIEdldFN5c3RlbUNhcGFiaWxpdHlSZXNwb25zZS5LRVlfU1lTVEVNX0NBUEFCSUxJVFkpO1xuICAgIH1cbn1cblxuR2V0U3lzdGVtQ2FwYWJpbGl0eVJlc3BvbnNlLktFWV9TWVNURU1fQ0FQQUJJTElUWSA9ICdzeXN0ZW1DYXBhYmlsaXR5JztcblxuZXhwb3J0IHsgR2V0U3lzdGVtQ2FwYWJpbGl0eVJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcblxuY2xhc3MgUmVjdGFuZ2xlIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCAtIFRoZSB1cHBlciBsZWZ0IFgtY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlXG4gICAgICogQHJldHVybiB7UmVjdGFuZ2xlfVxuICAgICAqL1xuICAgIHNldFggKHgpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVjdGFuZ2xlLktFWV9YLCB4KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFggKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmVjdGFuZ2xlLktFWV9YKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geSAtIFRoZSB1cHBlciBsZWZ0IFktY29vcmRpbmF0ZSBvZiB0aGUgcmVjdGFuZ2xlXG4gICAgICogQHJldHVybiB7UmVjdGFuZ2xlfVxuICAgICAqL1xuICAgIHNldFkgKHkpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVjdGFuZ2xlLktFWV9ZLCB5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFkgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmVjdGFuZ2xlLktFWV9ZKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gd2lkdGggLSBUaGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZVxuICAgICAqIEByZXR1cm4ge1JlY3RhbmdsZX1cbiAgICAgKi9cbiAgICBzZXRXaWR0aCAod2lkdGgpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUmVjdGFuZ2xlLktFWV9XSURUSCwgd2lkdGgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0V2lkdGggKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUmVjdGFuZ2xlLktFWV9XSURUSCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGhlaWdodCAtIFRoZSBoZWlnaHQgb2YgdGhlIHJlY3RhbmdsZVxuICAgICAqIEByZXR1cm4ge1JlY3RhbmdsZX1cbiAgICAgKi9cbiAgICBzZXRIZWlnaHQgKGhlaWdodCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihSZWN0YW5nbGUuS0VZX0hFSUdIVCwgaGVpZ2h0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldEhlaWdodCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihSZWN0YW5nbGUuS0VZX0hFSUdIVCk7XG4gICAgfVxufVxuXG5SZWN0YW5nbGUuS0VZX1ggPSAneCc7XG5SZWN0YW5nbGUuS0VZX1kgPSAneSc7XG5SZWN0YW5nbGUuS0VZX1dJRFRIID0gJ3dpZHRoJztcblJlY3RhbmdsZS5LRVlfSEVJR0hUID0gJ2hlaWdodCc7XG5cbmV4cG9ydCB7IFJlY3RhbmdsZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJlY3RhbmdsZSB9IGZyb20gJy4vUmVjdGFuZ2xlLmpzJztcbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5cbi8qKlxuICogRGVmaW5lcyBoYXB0aWMgZGF0YSBmb3IgZWFjaCB1c2VyIGNvbnRyb2wgb2JqZWN0IGZvciB2aWRlbyBzdHJlYW1pbmcgYXBwbGljYXRpb25cbiAqL1xuY2xhc3MgSGFwdGljUmVjdCBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGlkIC0gQSB1c2VyIGNvbnRyb2wgc3BhdGlhbCBpZGVudGlmaWVyXG4gICAgICogQHJldHVybiB7SGFwdGljUmVjdH1cbiAgICAgKi9cbiAgICBzZXRJZCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoSGFwdGljUmVjdC5LRVlfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldElkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEhhcHRpY1JlY3QuS0VZX0lEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1JlY3RhbmdsZX0gcmVjdCAtIFRoZSBwb3NpdGlvbiBvZiB0aGUgaGFwdGljIHJlY3RhbmdsZSB0byBiZSBoaWdobGlnaHRlZC4gVGhlIGNlbnRlciBvZiB0aGlzIHJlY3RhbmdsZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lsbCBiZSBcInRvdWNoZWRcIiB3aGVuIGEgcHJlc3Mgb2NjdXJzLlxuICAgICAqIEByZXR1cm4ge0hhcHRpY1JlY3R9XG4gICAgICovXG4gICAgc2V0UmVjdCAocmVjdCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShSZWN0YW5nbGUsIHJlY3QpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihIYXB0aWNSZWN0LktFWV9SRUNULCByZWN0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7UmVjdGFuZ2xlfVxuICAgICAqL1xuICAgIGdldFJlY3QgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoUmVjdGFuZ2xlLCBIYXB0aWNSZWN0LktFWV9SRUNUKTtcbiAgICB9XG59XG5cbkhhcHRpY1JlY3QuS0VZX0lEID0gJ2lkJztcbkhhcHRpY1JlY3QuS0VZX1JFQ1QgPSAncmVjdCc7XG5cbmV4cG9ydCB7IEhhcHRpY1JlY3QgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBIYXB0aWNSZWN0IH0gZnJvbSAnLi4vc3RydWN0cy9IYXB0aWNSZWN0LmpzJztcblxuLyoqXG4gKiBTZW5kIHRoZSBzcGF0aWFsIGRhdGEgZ2F0aGVyZWQgZnJvbSBTRExDYXJXaW5kb3cgb3IgVmlydHVhbERpc3BsYXlFbmNvZGVyIHRvIHRoZSBITUkuIFRoaXMgZGF0YSB3aWxsIGJlIHV0aWxpemVkIGJ5XG4gKiB0aGUgSE1JIHRvIGRldGVybWluZSBob3cgYW5kIHdoZW4gaGFwdGljIGV2ZW50cyBzaG91bGQgb2NjdXJcbiAqL1xuY2xhc3MgU2VuZEhhcHRpY0RhdGEgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlNlbmRIYXB0aWNEYXRhKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0hhcHRpY1JlY3RbXX0gZGF0YSAtIEFycmF5IG9mIHNwYXRpYWwgZGF0YSBzdHJ1Y3R1cmVzIHRoYXQgcmVwcmVzZW50IHRoZSBsb2NhdGlvbnMgb2YgYWxsIHVzZXIgY29udHJvbHNcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXNlbnQgb24gdGhlIEhNSS4gVGhpcyBkYXRhIHNob3VsZCBiZSB1cGRhdGVkIGlmL3doZW4gdGhlIGFwcGxpY2F0aW9uIHByZXNlbnRzIGFcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBzY3JlZW4uIFdoZW4gYSByZXF1ZXN0IGlzIHNlbnQsIGlmIHN1Y2Nlc3NmdWwsIGl0IHdpbGwgcmVwbGFjZSBhbGwgc3BhdGlhbCBkYXRhXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91c2x5IHNlbnQgdGhyb3VnaCBSUEMuIElmIGFuIGVtcHR5IGFycmF5IGlzIHNlbnQsIHRoZSBleGlzdGluZyBzcGF0aWFsIGRhdGFcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbGwgYmUgY2xlYXJlZFxuICAgICAqIEByZXR1cm4ge1NlbmRIYXB0aWNEYXRhfVxuICAgICAqL1xuICAgIHNldEhhcHRpY1JlY3REYXRhIChkYXRhKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEhhcHRpY1JlY3QsIGRhdGEsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZW5kSGFwdGljRGF0YS5LRVlfSEFQVElDX1JFQ1RfREFUQSwgZGF0YSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0hhcHRpY1JlY3RbXX1cbiAgICAgKi9cbiAgICBnZXRIYXB0aWNSZWN0RGF0YSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChIYXB0aWNSZWN0LCBTZW5kSGFwdGljRGF0YS5LRVlfSEFQVElDX1JFQ1RfREFUQSk7XG4gICAgfVxufVxuXG5TZW5kSGFwdGljRGF0YS5LRVlfSEFQVElDX1JFQ1RfREFUQSA9ICdoYXB0aWNSZWN0RGF0YSc7XG5cbmV4cG9ydCB7IFNlbmRIYXB0aWNEYXRhIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbmNsYXNzIFNlbmRIYXB0aWNEYXRhUmVzcG9uc2UgZXh0ZW5kcyBScGNSZXNwb25zZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5TZW5kSGFwdGljRGF0YSk7XG4gICAgfVxufVxuXG5cbmV4cG9ydCB7IFNlbmRIYXB0aWNEYXRhUmVzcG9uc2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBFbnVtZXJhdGlvbiBmb3IgdGhlIHVzZXIncyBwcmVmZXJlbmNlIG9mIHdoaWNoIGFwcCB0eXBlIHRvIHVzZSB3aGVuIGJvdGggYXJlIGF2YWlsYWJsZVxuICogQHR5cGVkZWYge0VudW19IEh5YnJpZEFwcFByZWZlcmVuY2VcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIEh5YnJpZEFwcFByZWZlcmVuY2UgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTU9CSUxFICgpIHtcbiAgICAgICAgcmV0dXJuIEh5YnJpZEFwcFByZWZlcmVuY2UuX01BUC5NT0JJTEU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ0xPVUQgKCkge1xuICAgICAgICByZXR1cm4gSHlicmlkQXBwUHJlZmVyZW5jZS5fTUFQLkNMT1VEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEJPVEggKCkge1xuICAgICAgICByZXR1cm4gSHlicmlkQXBwUHJlZmVyZW5jZS5fTUFQLkJPVEg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gSHlicmlkQXBwUHJlZmVyZW5jZS5fdmFsdWVGb3JLZXkoa2V5LCBIeWJyaWRBcHBQcmVmZXJlbmNlLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gSHlicmlkQXBwUHJlZmVyZW5jZS5fa2V5Rm9yVmFsdWUodmFsdWUsIEh5YnJpZEFwcFByZWZlcmVuY2UuX01BUCk7XG4gICAgfVxufVxuXG5IeWJyaWRBcHBQcmVmZXJlbmNlLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnTU9CSUxFJzogJ01PQklMRScsXG4gICAgJ0NMT1VEJzogJ0NMT1VEJyxcbiAgICAnQk9USCc6ICdCT1RIJyxcbn0pO1xuXG5leHBvcnQgeyBIeWJyaWRBcHBQcmVmZXJlbmNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IEh5YnJpZEFwcFByZWZlcmVuY2UgfSBmcm9tICcuLi9lbnVtcy9IeWJyaWRBcHBQcmVmZXJlbmNlLmpzJztcblxuY2xhc3MgQ2xvdWRBcHBQcm9wZXJ0aWVzIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ1tdfSBuaWNrbmFtZXMgLSBBbiBhcnJheSBvZiBhcHAgbmFtZXMgYSBjbG91ZCBhcHAgaXMgYWxsb3dlZCB0byByZWdpc3RlciB3aXRoLiBJZiBpbmNsdWRlZCBpbiBhXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2V0Q2xvdWRBcHBQcm9wZXJ0aWVzIHJlcXVlc3QsIHRoaXMgdmFsdWUgd2lsbCBvdmVyd3JpdGUgdGhlIGV4aXN0aW5nIFwibmlja25hbWVzXCJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZCBpbiB0aGUgYXBwIHBvbGljaWVzIHNlY3Rpb24gb2YgdGhlIHBvbGljeSB0YWJsZS5cbiAgICAgKiBAcmV0dXJuIHtDbG91ZEFwcFByb3BlcnRpZXN9XG4gICAgICovXG4gICAgc2V0Tmlja25hbWVzIChuaWNrbmFtZXMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2xvdWRBcHBQcm9wZXJ0aWVzLktFWV9OSUNLTkFNRVMsIG5pY2tuYW1lcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ1tdfVxuICAgICAqL1xuICAgIGdldE5pY2tuYW1lcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihDbG91ZEFwcFByb3BlcnRpZXMuS0VZX05JQ0tOQU1FUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGlkXG4gICAgICogQHJldHVybiB7Q2xvdWRBcHBQcm9wZXJ0aWVzfVxuICAgICAqL1xuICAgIHNldEFwcElEIChpZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihDbG91ZEFwcFByb3BlcnRpZXMuS0VZX0FQUF9JRCwgaWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0QXBwSUQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQ2xvdWRBcHBQcm9wZXJ0aWVzLktFWV9BUFBfSUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gZW5hYmxlZCAtIElmIHRydWUsIGNsb3VkIGFwcCB3aWxsIGJlIGluY2x1ZGVkIGluIEhNSSBSUEMgVXBkYXRlQXBwTGlzdFxuICAgICAqIEByZXR1cm4ge0Nsb3VkQXBwUHJvcGVydGllc31cbiAgICAgKi9cbiAgICBzZXRFbmFibGVkIChlbmFibGVkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENsb3VkQXBwUHJvcGVydGllcy5LRVlfRU5BQkxFRCwgZW5hYmxlZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0RW5hYmxlZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihDbG91ZEFwcFByb3BlcnRpZXMuS0VZX0VOQUJMRUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0b2tlbiAtIFVzZWQgdG8gYXV0aGVudGljYXRlIHdlYnNvY2tldCBjb25uZWN0aW9uIG9uIGFwcCBhY3RpdmF0aW9uXG4gICAgICogQHJldHVybiB7Q2xvdWRBcHBQcm9wZXJ0aWVzfVxuICAgICAqL1xuICAgIHNldEF1dGhUb2tlbiAodG9rZW4pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2xvdWRBcHBQcm9wZXJ0aWVzLktFWV9BVVRIX1RPS0VOLCB0b2tlbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRBdXRoVG9rZW4gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQ2xvdWRBcHBQcm9wZXJ0aWVzLktFWV9BVVRIX1RPS0VOKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSAtIFNwZWNpZmllcyB0aGUgY29ubmVjdGlvbiB0eXBlIENvcmUgc2hvdWxkIHVzZVxuICAgICAqIEByZXR1cm4ge0Nsb3VkQXBwUHJvcGVydGllc31cbiAgICAgKi9cbiAgICBzZXRDbG91ZFRyYW5zcG9ydFR5cGUgKHR5cGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQ2xvdWRBcHBQcm9wZXJ0aWVzLktFWV9DTE9VRF9UUkFOU1BPUlRfVFlQRSwgdHlwZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRDbG91ZFRyYW5zcG9ydFR5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQ2xvdWRBcHBQcm9wZXJ0aWVzLktFWV9DTE9VRF9UUkFOU1BPUlRfVFlQRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtIeWJyaWRBcHBQcmVmZXJlbmNlfSBwcmVmZXJlbmNlIC0gU3BlY2lmaWVzIHRoZSB1c2VyIHByZWZlcmVuY2UgdG8gdXNlIHRoZSBjbG91ZCBhcHAgdmVyc2lvbiBvciBtb2JpbGVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHAgdmVyc2lvbiB3aGVuIGJvdGggYXJlIGF2YWlsYWJsZVxuICAgICAqIEByZXR1cm4ge0Nsb3VkQXBwUHJvcGVydGllc31cbiAgICAgKi9cbiAgICBzZXRIeWJyaWRBcHBQcmVmZXJlbmNlIChwcmVmZXJlbmNlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEh5YnJpZEFwcFByZWZlcmVuY2UsIHByZWZlcmVuY2UpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihDbG91ZEFwcFByb3BlcnRpZXMuS0VZX0hZQlJJRF9BUFBfUFJFRkVSRU5DRSwgcHJlZmVyZW5jZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0h5YnJpZEFwcFByZWZlcmVuY2V9XG4gICAgICovXG4gICAgZ2V0SHlicmlkQXBwUHJlZmVyZW5jZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChIeWJyaWRBcHBQcmVmZXJlbmNlLCBDbG91ZEFwcFByb3BlcnRpZXMuS0VZX0hZQlJJRF9BUFBfUFJFRkVSRU5DRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGVuZHBvaW50IC0gU3BlY2lmaWVzIHRoZSBlbmRwb2ludCB3aGljaCBDb3JlIHdpbGwgYXR0ZW1wdCB0byBjb25uZWN0IHRvIHdoZW4gdGhpcyBhcHAgaXMgc2VsZWN0ZWRcbiAgICAgKiBAcmV0dXJuIHtDbG91ZEFwcFByb3BlcnRpZXN9XG4gICAgICovXG4gICAgc2V0RW5kcG9pbnQgKGVuZHBvaW50KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENsb3VkQXBwUHJvcGVydGllcy5LRVlfRU5EUE9JTlQsIGVuZHBvaW50KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldEVuZHBvaW50ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKENsb3VkQXBwUHJvcGVydGllcy5LRVlfRU5EUE9JTlQpO1xuICAgIH1cbn1cblxuQ2xvdWRBcHBQcm9wZXJ0aWVzLktFWV9OSUNLTkFNRVMgPSAnbmlja25hbWVzJztcbkNsb3VkQXBwUHJvcGVydGllcy5LRVlfQVBQX0lEID0gJ2FwcElEJztcbkNsb3VkQXBwUHJvcGVydGllcy5LRVlfRU5BQkxFRCA9ICdlbmFibGVkJztcbkNsb3VkQXBwUHJvcGVydGllcy5LRVlfQVVUSF9UT0tFTiA9ICdhdXRoVG9rZW4nO1xuQ2xvdWRBcHBQcm9wZXJ0aWVzLktFWV9DTE9VRF9UUkFOU1BPUlRfVFlQRSA9ICdjbG91ZFRyYW5zcG9ydFR5cGUnO1xuQ2xvdWRBcHBQcm9wZXJ0aWVzLktFWV9IWUJSSURfQVBQX1BSRUZFUkVOQ0UgPSAnaHlicmlkQXBwUHJlZmVyZW5jZSc7XG5DbG91ZEFwcFByb3BlcnRpZXMuS0VZX0VORFBPSU5UID0gJ2VuZHBvaW50JztcblxuZXhwb3J0IHsgQ2xvdWRBcHBQcm9wZXJ0aWVzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgQ2xvdWRBcHBQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vc3RydWN0cy9DbG91ZEFwcFByb3BlcnRpZXMuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG4vKipcbiAqIFJQQyB1c2VkIHRvIGVuYWJsZS9kaXNhYmxlIGEgY2xvdWQgYXBwbGljYXRpb24gYW5kIHNldCBpdHMgY2xvdWQtcmVsYXRlZCBwb2xpY3kgcHJvcGVydGllc1xuICovXG5jbGFzcyBTZXRDbG91ZEFwcFByb3BlcnRpZXMgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlNldENsb3VkQXBwUHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtDbG91ZEFwcFByb3BlcnRpZXN9IHByb3BlcnRpZXMgLSBUaGUgbmV3IGNsb3VkIGFwcGxpY2F0aW9uIHByb3BlcnRpZXNcbiAgICAgKiBAcmV0dXJuIHtTZXRDbG91ZEFwcFByb3BlcnRpZXN9XG4gICAgICovXG4gICAgc2V0UHJvcGVydGllcyAocHJvcGVydGllcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShDbG91ZEFwcFByb3BlcnRpZXMsIHByb3BlcnRpZXMpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihTZXRDbG91ZEFwcFByb3BlcnRpZXMuS0VZX1BST1BFUlRJRVMsIHByb3BlcnRpZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtDbG91ZEFwcFByb3BlcnRpZXN9XG4gICAgICovXG4gICAgZ2V0UHJvcGVydGllcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChDbG91ZEFwcFByb3BlcnRpZXMsIFNldENsb3VkQXBwUHJvcGVydGllcy5LRVlfUFJPUEVSVElFUyk7XG4gICAgfVxufVxuXG5TZXRDbG91ZEFwcFByb3BlcnRpZXMuS0VZX1BST1BFUlRJRVMgPSAncHJvcGVydGllcyc7XG5cbmV4cG9ydCB7IFNldENsb3VkQXBwUHJvcGVydGllcyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG4vKipcbiAqIFRoZSByZXNwb25zZSB0byBTZXRDbG91ZEFwcFByb3BlcnRpZXNcbiAqL1xuY2xhc3MgU2V0Q2xvdWRBcHBQcm9wZXJ0aWVzUmVzcG9uc2UgZXh0ZW5kcyBScGNSZXNwb25zZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5TZXRDbG91ZEFwcFByb3BlcnRpZXMpO1xuICAgIH1cbn1cblxuXG5leHBvcnQgeyBTZXRDbG91ZEFwcFByb3BlcnRpZXNSZXNwb25zZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1JlcXVlc3QgfSBmcm9tICcuLi9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcblxuLyoqXG4gKiBSUEMgdXNlZCB0byBnZXQgdGhlIGN1cnJlbnQgcHJvcGVydGllcyBvZiBhIGNsb3VkIGFwcGxpY2F0aW9uXG4gKi9cbmNsYXNzIEdldENsb3VkQXBwUHJvcGVydGllcyBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuR2V0Q2xvdWRBcHBQcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gaWRcbiAgICAgKiBAcmV0dXJuIHtHZXRDbG91ZEFwcFByb3BlcnRpZXN9XG4gICAgICovXG4gICAgc2V0QXBwSUQgKGlkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEdldENsb3VkQXBwUHJvcGVydGllcy5LRVlfQVBQX0lELCBpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRBcHBJRCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXRDbG91ZEFwcFByb3BlcnRpZXMuS0VZX0FQUF9JRCk7XG4gICAgfVxufVxuXG5HZXRDbG91ZEFwcFByb3BlcnRpZXMuS0VZX0FQUF9JRCA9ICdhcHBJRCc7XG5cbmV4cG9ydCB7IEdldENsb3VkQXBwUHJvcGVydGllcyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IENsb3VkQXBwUHJvcGVydGllcyB9IGZyb20gJy4uL3N0cnVjdHMvQ2xvdWRBcHBQcm9wZXJ0aWVzLmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG4vKipcbiAqIFRoZSByZXNwb25zZSB0byBHZXRDbG91ZEFwcFByb3BlcnRpZXNcbiAqL1xuY2xhc3MgR2V0Q2xvdWRBcHBQcm9wZXJ0aWVzUmVzcG9uc2UgZXh0ZW5kcyBScGNSZXNwb25zZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5HZXRDbG91ZEFwcFByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Q2xvdWRBcHBQcm9wZXJ0aWVzfSBwcm9wZXJ0aWVzIC0gVGhlIHJlcXVlc3RlZCBjbG91ZCBhcHBsaWNhdGlvbiBwcm9wZXJ0aWVzXG4gICAgICogQHJldHVybiB7R2V0Q2xvdWRBcHBQcm9wZXJ0aWVzUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0UHJvcGVydGllcyAocHJvcGVydGllcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShDbG91ZEFwcFByb3BlcnRpZXMsIHByb3BlcnRpZXMpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRDbG91ZEFwcFByb3BlcnRpZXNSZXNwb25zZS5LRVlfUFJPUEVSVElFUywgcHJvcGVydGllcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Nsb3VkQXBwUHJvcGVydGllc31cbiAgICAgKi9cbiAgICBnZXRQcm9wZXJ0aWVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KENsb3VkQXBwUHJvcGVydGllcywgR2V0Q2xvdWRBcHBQcm9wZXJ0aWVzUmVzcG9uc2UuS0VZX1BST1BFUlRJRVMpO1xuICAgIH1cbn1cblxuR2V0Q2xvdWRBcHBQcm9wZXJ0aWVzUmVzcG9uc2UuS0VZX1BST1BFUlRJRVMgPSAncHJvcGVydGllcyc7XG5cbmV4cG9ydCB7IEdldENsb3VkQXBwUHJvcGVydGllc1Jlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgQXBwU2VydmljZU1hbmlmZXN0IH0gZnJvbSAnLi4vc3RydWN0cy9BcHBTZXJ2aWNlTWFuaWZlc3QuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhIHNlcnZpY2Ugb2ZmZXJlZCBieSB0aGlzIGFwcCBvbiB0aGUgbW9kdWxlLiBTdWJzZXF1ZW50IGNhbGxzIHdpdGggdGhlIHNhbWUgc2VydmljZSB0eXBlIHdpbGwgdXBkYXRlIHRoZVxuICogbWFuaWZlc3QgZm9yIHRoYXQgc2VydmljZS5cbiAqL1xuY2xhc3MgUHVibGlzaEFwcFNlcnZpY2UgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlB1Ymxpc2hBcHBTZXJ2aWNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0FwcFNlcnZpY2VNYW5pZmVzdH0gbWFuaWZlc3QgLSBUaGUgbWFuaWZlc3Qgb2YgdGhlIHNlcnZpY2UgdGhhdCB3aXNoZXMgdG8gYmUgcHVibGlzaGVkLiBJZiBhbHJlYWR5XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGlzaGVkLCB0aGUgdXBkYXRlZCBtYW5pZmVzdCBmb3IgdGhpcyBzZXJ2aWNlLlxuICAgICAqIEByZXR1cm4ge1B1Ymxpc2hBcHBTZXJ2aWNlfVxuICAgICAqL1xuICAgIHNldEFwcFNlcnZpY2VNYW5pZmVzdCAobWFuaWZlc3QpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQXBwU2VydmljZU1hbmlmZXN0LCBtYW5pZmVzdCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFB1Ymxpc2hBcHBTZXJ2aWNlLktFWV9BUFBfU0VSVklDRV9NQU5JRkVTVCwgbWFuaWZlc3QpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtBcHBTZXJ2aWNlTWFuaWZlc3R9XG4gICAgICovXG4gICAgZ2V0QXBwU2VydmljZU1hbmlmZXN0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEFwcFNlcnZpY2VNYW5pZmVzdCwgUHVibGlzaEFwcFNlcnZpY2UuS0VZX0FQUF9TRVJWSUNFX01BTklGRVNUKTtcbiAgICB9XG59XG5cblB1Ymxpc2hBcHBTZXJ2aWNlLktFWV9BUFBfU0VSVklDRV9NQU5JRkVTVCA9ICdhcHBTZXJ2aWNlTWFuaWZlc3QnO1xuXG5leHBvcnQgeyBQdWJsaXNoQXBwU2VydmljZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgQXBwU2VydmljZVJlY29yZCB9IGZyb20gJy4uL3N0cnVjdHMvQXBwU2VydmljZVJlY29yZC5qcyc7XG5cbi8qKlxuICogUmVzcG9uc2UgdG8gdGhlIHJlcXVlc3QgdG8gcmVnaXN0ZXIgYSBzZXJ2aWNlIG9mZmVyZWQgYnkgdGhpcyBhcHAgb24gdGhlIG1vZHVsZVxuICovXG5jbGFzcyBQdWJsaXNoQXBwU2VydmljZVJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuUHVibGlzaEFwcFNlcnZpY2UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7QXBwU2VydmljZVJlY29yZH0gcmVjb3JkIC0gSWYgdGhlIHJlcXVlc3Qgd2FzIHN1Y2Nlc3NmdWwsIHRoaXMgb2JqZWN0IHdpbGwgYmUgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIHRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VydmljZSByZWNvcmQgZm9yIHRoZSBwdWJsaXNoZWQgc2VydmljZS4gVGhpcyB3aWxsIGluY2x1ZGUgdGhlIENvcmUgc3VwcGxpZWRcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcnZpY2UgSUQuXG4gICAgICogQHJldHVybiB7UHVibGlzaEFwcFNlcnZpY2VSZXNwb25zZX1cbiAgICAgKi9cbiAgICBzZXRBcHBTZXJ2aWNlUmVjb3JkIChyZWNvcmQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQXBwU2VydmljZVJlY29yZCwgcmVjb3JkKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUHVibGlzaEFwcFNlcnZpY2VSZXNwb25zZS5LRVlfQVBQX1NFUlZJQ0VfUkVDT1JELCByZWNvcmQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtBcHBTZXJ2aWNlUmVjb3JkfVxuICAgICAqL1xuICAgIGdldEFwcFNlcnZpY2VSZWNvcmQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQXBwU2VydmljZVJlY29yZCwgUHVibGlzaEFwcFNlcnZpY2VSZXNwb25zZS5LRVlfQVBQX1NFUlZJQ0VfUkVDT1JEKTtcbiAgICB9XG59XG5cblB1Ymxpc2hBcHBTZXJ2aWNlUmVzcG9uc2UuS0VZX0FQUF9TRVJWSUNFX1JFQ09SRCA9ICdhcHBTZXJ2aWNlUmVjb3JkJztcblxuZXhwb3J0IHsgUHVibGlzaEFwcFNlcnZpY2VSZXNwb25zZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1JlcXVlc3QgfSBmcm9tICcuLi9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcblxuLyoqXG4gKiBVbnB1Ymxpc2ggYW4gZXhpc3Rpbmcgc2VydmljZSBwdWJsaXNoZWQgYnkgdGhpcyBhcHBsaWNhdGlvbi5cbiAqL1xuY2xhc3MgVW5wdWJsaXNoQXBwU2VydmljZSBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuVW5wdWJsaXNoQXBwU2VydmljZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGlkIC0gVGhlIElEIG9mIHRoZSBzZXJ2aWNlIHRvIGJlIHVucHVibGlzaGVkLlxuICAgICAqIEByZXR1cm4ge1VucHVibGlzaEFwcFNlcnZpY2V9XG4gICAgICovXG4gICAgc2V0U2VydmljZUlEIChpZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihVbnB1Ymxpc2hBcHBTZXJ2aWNlLktFWV9TRVJWSUNFX0lELCBpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRTZXJ2aWNlSUQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoVW5wdWJsaXNoQXBwU2VydmljZS5LRVlfU0VSVklDRV9JRCk7XG4gICAgfVxufVxuXG5VbnB1Ymxpc2hBcHBTZXJ2aWNlLktFWV9TRVJWSUNFX0lEID0gJ3NlcnZpY2VJRCc7XG5cbmV4cG9ydCB7IFVucHVibGlzaEFwcFNlcnZpY2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBScGNSZXNwb25zZSB9IGZyb20gJy4uL1JwY1Jlc3BvbnNlLmpzJztcblxuLyoqXG4gKiBUaGUgcmVzcG9uc2UgdG8gVW5wdWJsaXNoQXBwU2VydmljZVxuICovXG5jbGFzcyBVbnB1Ymxpc2hBcHBTZXJ2aWNlUmVzcG9uc2UgZXh0ZW5kcyBScGNSZXNwb25zZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5VbnB1Ymxpc2hBcHBTZXJ2aWNlKTtcbiAgICB9XG59XG5cblxuZXhwb3J0IHsgVW5wdWJsaXNoQXBwU2VydmljZVJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG4vKipcbiAqIFRoaXMgcmVxdWVzdCBhc2tzIHRoZSBtb2R1bGUgZm9yIGN1cnJlbnQgZGF0YSByZWxhdGVkIHRvIHRoZSBzcGVjaWZpYyBzZXJ2aWNlLiBJdCBhbHNvIGluY2x1ZGVzIGFuIG9wdGlvbiB0b1xuICogc3Vic2NyaWJlIHRvIHRoYXQgc2VydmljZSBmb3IgZnV0dXJlIHVwZGF0ZXNcbiAqL1xuY2xhc3MgR2V0QXBwU2VydmljZURhdGEgZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkdldEFwcFNlcnZpY2VEYXRhKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSAtIFRoZSB0eXBlIG9mIHNlcnZpY2UgdGhhdCBpcyB0byBiZSBvZmZlcmVkIGJ5IHRoaXMgYXBwLiBTZWUgQXBwU2VydmljZVR5cGUgZm9yIGtub3duIGVudW1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIGVxdWl2YWxlbnQgdHlwZXMuIFBhcmFtZXRlciBpcyBhIHN0cmluZyB0byBhbGxvdyBmb3IgbmV3IHNlcnZpY2UgdHlwZXMgdG8gYmUgdXNlZCBieSBhcHBzXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICBvbiBvbGRlciB2ZXJzaW9ucyBvZiBTREwgQ29yZS5cbiAgICAgKiBAcmV0dXJuIHtHZXRBcHBTZXJ2aWNlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRTZXJ2aWNlVHlwZSAodHlwZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRBcHBTZXJ2aWNlRGF0YS5LRVlfU0VSVklDRV9UWVBFLCB0eXBlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldFNlcnZpY2VUeXBlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEdldEFwcFNlcnZpY2VEYXRhLktFWV9TRVJWSUNFX1RZUEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gc3Vic2NyaWJlIC0gSWYgdHJ1ZSwgdGhlIGNvbnN1bWVyIGlzIHJlcXVlc3RpbmcgdG8gc3Vic2NyaWJlIHRvIGFsbCBmdXR1cmUgdXBkYXRlcyBmcm9tIHRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VydmljZSBwdWJsaXNoZXIuIElmIGZhbHNlLCB0aGUgY29uc3VtZXIgZG9lc24ndCB3aXNoIHRvIHN1YnNjcmliZSBhbmQgc2hvdWxkIGJlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnN1YnNjcmliZWQgaWYgaXQgd2FzIHByZXZpb3VzbHkgc3Vic2NyaWJlZC5cbiAgICAgKiBAcmV0dXJuIHtHZXRBcHBTZXJ2aWNlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRTdWJzY3JpYmUgKHN1YnNjcmliZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRBcHBTZXJ2aWNlRGF0YS5LRVlfU1VCU0NSSUJFLCBzdWJzY3JpYmUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFN1YnNjcmliZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihHZXRBcHBTZXJ2aWNlRGF0YS5LRVlfU1VCU0NSSUJFKTtcbiAgICB9XG59XG5cbkdldEFwcFNlcnZpY2VEYXRhLktFWV9TRVJWSUNFX1RZUEUgPSAnc2VydmljZVR5cGUnO1xuR2V0QXBwU2VydmljZURhdGEuS0VZX1NVQlNDUklCRSA9ICdzdWJzY3JpYmUnO1xuXG5leHBvcnQgeyBHZXRBcHBTZXJ2aWNlRGF0YSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBOYXZpZ2F0aW9uSnVuY3Rpb25cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIE5hdmlnYXRpb25KdW5jdGlvbiBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIGp1bmN0aW9uIHRoYXQgcmVwcmVzZW50cyBhIHN0YW5kYXJkIGludGVyc2VjdGlvbiB3aXRoIGEgc2luZ2xlIHJvYWQgY3Jvc3NpbmcgYW5vdGhlci5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSRUdVTEFSICgpIHtcbiAgICAgICAgcmV0dXJuIE5hdmlnYXRpb25KdW5jdGlvbi5fTUFQLlJFR1VMQVI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBqdW5jdGlvbiB3aGVyZSB0aGUgcm9hZCBzcGxpdHMgb2ZmIGludG8gdHdvIHBhdGhzOyBhIGZvcmsgaW4gdGhlIHJvYWQuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQklGVVJDQVRJT04gKCkge1xuICAgICAgICByZXR1cm4gTmF2aWdhdGlvbkp1bmN0aW9uLl9NQVAuQklGVVJDQVRJT047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBqdW5jdGlvbiB0aGF0IGhhcyBtdWx0aXBsZSBpbnRlcnNlY3Rpb25zIGFuZCBwYXRocy5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBNVUxUSV9DQVJSSUFHRVdBWSAoKSB7XG4gICAgICAgIHJldHVybiBOYXZpZ2F0aW9uSnVuY3Rpb24uX01BUC5NVUxUSV9DQVJSSUFHRVdBWTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIGp1bmN0aW9uIHdoZXJlIHRyYWZmaWMgbW92ZXMgaW4gYSBzaW5nbGUgZGlyZWN0aW9uIGFyb3VuZCBhIGNlbnRyYWwsIG5vbi10cmF2ZXJzYWJsZSBwb2ludCB0byByZWFjaCBvbmUgb2ZcbiAgICAgKiB0aGUgY29ubmVjdGluZyByb2Fkcy5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBST1VOREFCT1VUICgpIHtcbiAgICAgICAgcmV0dXJuIE5hdmlnYXRpb25KdW5jdGlvbi5fTUFQLlJPVU5EQUJPVVQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2ltaWxhciB0byBhIHJvdW5kYWJvdXQsIGhvd2V2ZXIgdGhlIGNlbnRlciBvZiB0aGUgcm91bmRhYm91dCBpcyBmdWxseSB0cmF2ZXJzYWJsZS4gQWxzbyBrbm93biBhcyBhIG1pbmktXG4gICAgICogcm91bmRhYm91dC5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBUUkFWRVJTQUJMRV9ST1VOREFCT1VUICgpIHtcbiAgICAgICAgcmV0dXJuIE5hdmlnYXRpb25KdW5jdGlvbi5fTUFQLlRSQVZFUlNBQkxFX1JPVU5EQUJPVVQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBqdW5jdGlvbiB3aGVyZSBsZWZ0cyBkaXZlcmdlIHRvIHRoZSByaWdodCwgdGhlbiBjdXJ2ZSB0byB0aGUgbGVmdCwgY29udmVydGluZyBhIGxlZnQgdHVybiB0byBhIGNyb3NzaW5nXG4gICAgICogbWFuZXV2ZXIuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSlVHSEFORExFICgpIHtcbiAgICAgICAgcmV0dXJuIE5hdmlnYXRpb25KdW5jdGlvbi5fTUFQLkpVR0hBTkRMRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNdWx0aXBsZSB3YXkgaW50ZXJzZWN0aW9uIHRoYXQgYWxsb3dzIHRyYWZmaWMgdG8gZmxvdyBiYXNlZCBvbiBwcmlvcml0eTsgbW9zdCBjb21tb25seSByaWdodCBvZiB3YXkgYW5kIGZpcnN0XG4gICAgICogaW4sIGZpcnN0IG91dC5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBBTExfV0FZX1lJRUxEICgpIHtcbiAgICAgICAgcmV0dXJuIE5hdmlnYXRpb25KdW5jdGlvbi5fTUFQLkFMTF9XQVlfWUlFTEQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBqdW5jdGlvbiBkZXNpZ25hdGVkIGZvciB0cmFmZmljIHR1cm4gYXJvdW5kcy5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBUVVJOX0FST1VORCAoKSB7XG4gICAgICAgIHJldHVybiBOYXZpZ2F0aW9uSnVuY3Rpb24uX01BUC5UVVJOX0FST1VORDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBOYXZpZ2F0aW9uSnVuY3Rpb24uX3ZhbHVlRm9yS2V5KGtleSwgTmF2aWdhdGlvbkp1bmN0aW9uLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gTmF2aWdhdGlvbkp1bmN0aW9uLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgTmF2aWdhdGlvbkp1bmN0aW9uLl9NQVApO1xuICAgIH1cbn1cblxuTmF2aWdhdGlvbkp1bmN0aW9uLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnUkVHVUxBUic6ICdSRUdVTEFSJyxcbiAgICAnQklGVVJDQVRJT04nOiAnQklGVVJDQVRJT04nLFxuICAgICdNVUxUSV9DQVJSSUFHRVdBWSc6ICdNVUxUSV9DQVJSSUFHRVdBWScsXG4gICAgJ1JPVU5EQUJPVVQnOiAnUk9VTkRBQk9VVCcsXG4gICAgJ1RSQVZFUlNBQkxFX1JPVU5EQUJPVVQnOiAnVFJBVkVSU0FCTEVfUk9VTkRBQk9VVCcsXG4gICAgJ0pVR0hBTkRMRSc6ICdKVUdIQU5ETEUnLFxuICAgICdBTExfV0FZX1lJRUxEJzogJ0FMTF9XQVlfWUlFTEQnLFxuICAgICdUVVJOX0FST1VORCc6ICdUVVJOX0FST1VORCcsXG59KTtcblxuZXhwb3J0IHsgTmF2aWdhdGlvbkp1bmN0aW9uIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYge0VudW19IERpcmVjdGlvblxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgRGlyZWN0aW9uIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IExFRlQgKCkge1xuICAgICAgICByZXR1cm4gRGlyZWN0aW9uLl9NQVAuTEVGVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBSSUdIVCAoKSB7XG4gICAgICAgIHJldHVybiBEaXJlY3Rpb24uX01BUC5SSUdIVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBEaXJlY3Rpb24uX3ZhbHVlRm9yS2V5KGtleSwgRGlyZWN0aW9uLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gRGlyZWN0aW9uLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgRGlyZWN0aW9uLl9NQVApO1xuICAgIH1cbn1cblxuRGlyZWN0aW9uLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnTEVGVCc6ICdMRUZUJyxcbiAgICAnUklHSFQnOiAnUklHSFQnLFxufSk7XG5cbmV4cG9ydCB7IERpcmVjdGlvbiB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBOYXZpZ2F0aW9uQWN0aW9uXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBOYXZpZ2F0aW9uQWN0aW9uIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVzaW5nIHRoaXMgYWN0aW9uIHBsdXMgYSBzdXBwbGllZCBkaXJlY3Rpb24gY2FuIGdpdmUgdGhlIHR5cGUgb2YgdHVybi5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBUVVJOICgpIHtcbiAgICAgICAgcmV0dXJuIE5hdmlnYXRpb25BY3Rpb24uX01BUC5UVVJOO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEVYSVQgKCkge1xuICAgICAgICByZXR1cm4gTmF2aWdhdGlvbkFjdGlvbi5fTUFQLkVYSVQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU1RBWSAoKSB7XG4gICAgICAgIHJldHVybiBOYXZpZ2F0aW9uQWN0aW9uLl9NQVAuU1RBWTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBNRVJHRSAoKSB7XG4gICAgICAgIHJldHVybiBOYXZpZ2F0aW9uQWN0aW9uLl9NQVAuTUVSR0U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRkVSUlkgKCkge1xuICAgICAgICByZXR1cm4gTmF2aWdhdGlvbkFjdGlvbi5fTUFQLkZFUlJZO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENBUl9TSFVUVExFX1RSQUlOICgpIHtcbiAgICAgICAgcmV0dXJuIE5hdmlnYXRpb25BY3Rpb24uX01BUC5DQVJfU0hVVFRMRV9UUkFJTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBXQVlQT0lOVCAoKSB7XG4gICAgICAgIHJldHVybiBOYXZpZ2F0aW9uQWN0aW9uLl9NQVAuV0FZUE9JTlQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gTmF2aWdhdGlvbkFjdGlvbi5fdmFsdWVGb3JLZXkoa2V5LCBOYXZpZ2F0aW9uQWN0aW9uLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gTmF2aWdhdGlvbkFjdGlvbi5fa2V5Rm9yVmFsdWUodmFsdWUsIE5hdmlnYXRpb25BY3Rpb24uX01BUCk7XG4gICAgfVxufVxuXG5OYXZpZ2F0aW9uQWN0aW9uLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnVFVSTic6ICdUVVJOJyxcbiAgICAnRVhJVCc6ICdFWElUJyxcbiAgICAnU1RBWSc6ICdTVEFZJyxcbiAgICAnTUVSR0UnOiAnTUVSR0UnLFxuICAgICdGRVJSWSc6ICdGRVJSWScsXG4gICAgJ0NBUl9TSFVUVExFX1RSQUlOJzogJ0NBUl9TSFVUVExFX1RSQUlOJyxcbiAgICAnV0FZUE9JTlQnOiAnV0FZUE9JTlQnLFxufSk7XG5cbmV4cG9ydCB7IE5hdmlnYXRpb25BY3Rpb24gfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBJbWFnZSB9IGZyb20gJy4vSW1hZ2UuanMnO1xuaW1wb3J0IHsgRGF0ZVRpbWUgfSBmcm9tICcuL0RhdGVUaW1lLmpzJztcbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBOYXZpZ2F0aW9uSnVuY3Rpb24gfSBmcm9tICcuLi9lbnVtcy9OYXZpZ2F0aW9uSnVuY3Rpb24uanMnO1xuaW1wb3J0IHsgRGlyZWN0aW9uIH0gZnJvbSAnLi4vZW51bXMvRGlyZWN0aW9uLmpzJztcbmltcG9ydCB7IExvY2F0aW9uRGV0YWlscyB9IGZyb20gJy4vTG9jYXRpb25EZXRhaWxzLmpzJztcbmltcG9ydCB7IE5hdmlnYXRpb25BY3Rpb24gfSBmcm9tICcuLi9lbnVtcy9OYXZpZ2F0aW9uQWN0aW9uLmpzJztcblxuY2xhc3MgTmF2aWdhdGlvbkluc3RydWN0aW9uIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0xvY2F0aW9uRGV0YWlsc30gZGV0YWlsc1xuICAgICAqIEByZXR1cm4ge05hdmlnYXRpb25JbnN0cnVjdGlvbn1cbiAgICAgKi9cbiAgICBzZXRMb2NhdGlvbkRldGFpbHMgKGRldGFpbHMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTG9jYXRpb25EZXRhaWxzLCBkZXRhaWxzKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTmF2aWdhdGlvbkluc3RydWN0aW9uLktFWV9MT0NBVElPTl9ERVRBSUxTLCBkZXRhaWxzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TG9jYXRpb25EZXRhaWxzfVxuICAgICAqL1xuICAgIGdldExvY2F0aW9uRGV0YWlscyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChMb2NhdGlvbkRldGFpbHMsIE5hdmlnYXRpb25JbnN0cnVjdGlvbi5LRVlfTE9DQVRJT05fREVUQUlMUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOYXZpZ2F0aW9uQWN0aW9ufSBhY3Rpb25cbiAgICAgKiBAcmV0dXJuIHtOYXZpZ2F0aW9uSW5zdHJ1Y3Rpb259XG4gICAgICovXG4gICAgc2V0QWN0aW9uIChhY3Rpb24pIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTmF2aWdhdGlvbkFjdGlvbiwgYWN0aW9uKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTmF2aWdhdGlvbkluc3RydWN0aW9uLktFWV9BQ1RJT04sIGFjdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge05hdmlnYXRpb25BY3Rpb259XG4gICAgICovXG4gICAgZ2V0QWN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KE5hdmlnYXRpb25BY3Rpb24sIE5hdmlnYXRpb25JbnN0cnVjdGlvbi5LRVlfQUNUSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0RhdGVUaW1lfSBldGFcbiAgICAgKiBAcmV0dXJuIHtOYXZpZ2F0aW9uSW5zdHJ1Y3Rpb259XG4gICAgICovXG4gICAgc2V0RXRhIChldGEpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoRGF0ZVRpbWUsIGV0YSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE5hdmlnYXRpb25JbnN0cnVjdGlvbi5LRVlfRVRBLCBldGEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtEYXRlVGltZX1cbiAgICAgKi9cbiAgICBnZXRFdGEgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoRGF0ZVRpbWUsIE5hdmlnYXRpb25JbnN0cnVjdGlvbi5LRVlfRVRBKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYmVhcmluZyAtIFRoZSBhbmdsZSBhdCB3aGljaCB0aGlzIGluc3RydWN0aW9uIHRha2VzIHBsYWNlLiBGb3IgZXhhbXBsZSwgMCB3b3VsZCBtZWFuIHN0cmFpZ2h0LFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVzcyB0aGFuIDQ1IGlzIGJlYXJpbmcgcmlnaHQsIGdyZWF0ZXIgdGhhbiAxMzUgaXMgc2hhcnAgcmlnaHQsIGJldHdlZW4gNDUgYW5kIDEzNSBpcyBhXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICByZWd1bGFyIHJpZ2h0LCBhbmQgMTgwIGlzIGEgVS1UdXJuLCBldGMuXG4gICAgICogQHJldHVybiB7TmF2aWdhdGlvbkluc3RydWN0aW9ufVxuICAgICAqL1xuICAgIHNldEJlYXJpbmcgKGJlYXJpbmcpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTmF2aWdhdGlvbkluc3RydWN0aW9uLktFWV9CRUFSSU5HLCBiZWFyaW5nKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldEJlYXJpbmcgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoTmF2aWdhdGlvbkluc3RydWN0aW9uLktFWV9CRUFSSU5HKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge05hdmlnYXRpb25KdW5jdGlvbn0gdHlwZVxuICAgICAqIEByZXR1cm4ge05hdmlnYXRpb25JbnN0cnVjdGlvbn1cbiAgICAgKi9cbiAgICBzZXRKdW5jdGlvblR5cGUgKHR5cGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTmF2aWdhdGlvbkp1bmN0aW9uLCB0eXBlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTmF2aWdhdGlvbkluc3RydWN0aW9uLktFWV9KVU5DVElPTl9UWVBFLCB0eXBlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TmF2aWdhdGlvbkp1bmN0aW9ufVxuICAgICAqL1xuICAgIGdldEp1bmN0aW9uVHlwZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChOYXZpZ2F0aW9uSnVuY3Rpb24sIE5hdmlnYXRpb25JbnN0cnVjdGlvbi5LRVlfSlVOQ1RJT05fVFlQRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtEaXJlY3Rpb259IHNpZGUgLSBVc2VkIHRvIGluZmVyIHdoaWNoIHNpZGUgb2YgdGhlIHJvYWQgdGhpcyBpbnN0cnVjdGlvbiB0YWtlcyBwbGFjZS4gRm9yIGEgVS1UdXJuXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAoYWN0aW9uPVRVUk4sIGJlYXJpbmc9MTgwKSB0aGlzIHdpbGwgZGV0ZXJtaW5lIHdoaWNoIGRpcmVjdGlvbiB0aGUgdHVybiBzaG91bGQgdGFrZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2UuXG4gICAgICogQHJldHVybiB7TmF2aWdhdGlvbkluc3RydWN0aW9ufVxuICAgICAqL1xuICAgIHNldERyaXZpbmdTaWRlIChzaWRlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKERpcmVjdGlvbiwgc2lkZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE5hdmlnYXRpb25JbnN0cnVjdGlvbi5LRVlfRFJJVklOR19TSURFLCBzaWRlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7RGlyZWN0aW9ufVxuICAgICAqL1xuICAgIGdldERyaXZpbmdTaWRlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KERpcmVjdGlvbiwgTmF2aWdhdGlvbkluc3RydWN0aW9uLktFWV9EUklWSU5HX1NJREUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBkZXRhaWxzIC0gVGhpcyBpcyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGluc3RydWN0aW9uLCB1c2VkIHRvIGRpc3BsYXkgaW5zdHJ1Y3Rpb25zIHRvXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgdXNlcnMuIFRoaXMgaXMgbm90IGludGVuZGVkIHRvIGJlIHJlYWQgYWxvdWQgdG8gdGhlIHVzZXJzLCBzZWUgdGhlIHBhcmFtIHByb21wdCBpblxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgTmF2aWdhdGlvblNlcnZpY2VEYXRhIGZvciB0aGF0LlxuICAgICAqIEByZXR1cm4ge05hdmlnYXRpb25JbnN0cnVjdGlvbn1cbiAgICAgKi9cbiAgICBzZXREZXRhaWxzIChkZXRhaWxzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE5hdmlnYXRpb25JbnN0cnVjdGlvbi5LRVlfREVUQUlMUywgZGV0YWlscyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXREZXRhaWxzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE5hdmlnYXRpb25JbnN0cnVjdGlvbi5LRVlfREVUQUlMUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtJbWFnZX0gaW1hZ2UgLSBBbiBpbWFnZSByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGluc3RydWN0aW9uLlxuICAgICAqIEByZXR1cm4ge05hdmlnYXRpb25JbnN0cnVjdGlvbn1cbiAgICAgKi9cbiAgICBzZXRJbWFnZSAoaW1hZ2UpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoSW1hZ2UsIGltYWdlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTmF2aWdhdGlvbkluc3RydWN0aW9uLktFWV9JTUFHRSwgaW1hZ2UpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtJbWFnZX1cbiAgICAgKi9cbiAgICBnZXRJbWFnZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChJbWFnZSwgTmF2aWdhdGlvbkluc3RydWN0aW9uLktFWV9JTUFHRSk7XG4gICAgfVxufVxuXG5OYXZpZ2F0aW9uSW5zdHJ1Y3Rpb24uS0VZX0xPQ0FUSU9OX0RFVEFJTFMgPSAnbG9jYXRpb25EZXRhaWxzJztcbk5hdmlnYXRpb25JbnN0cnVjdGlvbi5LRVlfQUNUSU9OID0gJ2FjdGlvbic7XG5OYXZpZ2F0aW9uSW5zdHJ1Y3Rpb24uS0VZX0VUQSA9ICdldGEnO1xuTmF2aWdhdGlvbkluc3RydWN0aW9uLktFWV9CRUFSSU5HID0gJ2JlYXJpbmcnO1xuTmF2aWdhdGlvbkluc3RydWN0aW9uLktFWV9KVU5DVElPTl9UWVBFID0gJ2p1bmN0aW9uVHlwZSc7XG5OYXZpZ2F0aW9uSW5zdHJ1Y3Rpb24uS0VZX0RSSVZJTkdfU0lERSA9ICdkcml2aW5nU2lkZSc7XG5OYXZpZ2F0aW9uSW5zdHJ1Y3Rpb24uS0VZX0RFVEFJTFMgPSAnZGV0YWlscyc7XG5OYXZpZ2F0aW9uSW5zdHJ1Y3Rpb24uS0VZX0lNQUdFID0gJ2ltYWdlJztcblxuZXhwb3J0IHsgTmF2aWdhdGlvbkluc3RydWN0aW9uIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRGF0ZVRpbWUgfSBmcm9tICcuL0RhdGVUaW1lLmpzJztcbmltcG9ydCB7IExvY2F0aW9uRGV0YWlscyB9IGZyb20gJy4vTG9jYXRpb25EZXRhaWxzLmpzJztcbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBOYXZpZ2F0aW9uSW5zdHJ1Y3Rpb24gfSBmcm9tICcuL05hdmlnYXRpb25JbnN0cnVjdGlvbi5qcyc7XG5cbi8qKlxuICogVGhpcyBkYXRhIGlzIHJlbGF0ZWQgdG8gd2hhdCBhIG5hdmlnYXRpb24gc2VydmljZSB3b3VsZCBwcm92aWRlLlxuICovXG5jbGFzcyBOYXZpZ2F0aW9uU2VydmljZURhdGEgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RGF0ZVRpbWV9IHN0YW1wIC0gVGhpcyBpcyB0aGUgdGltZXN0YW1wIG9mIHdoZW4gdGhlIGRhdGEgd2FzIGdlbmVyYXRlZC4gVGhpcyBpcyB0byBlbnN1cmUgYW55IHRpbWUgb3JcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3RhbmNlIGdpdmVuIGluIHRoZSBkYXRhIGNhbiBhY2N1cmF0ZWx5IGJlIGFkanVzdGVkIGlmIG5lY2Vzc2FyeS5cbiAgICAgKiBAcmV0dXJuIHtOYXZpZ2F0aW9uU2VydmljZURhdGF9XG4gICAgICovXG4gICAgc2V0VGltZVN0YW1wIChzdGFtcCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShEYXRlVGltZSwgc3RhbXApO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihOYXZpZ2F0aW9uU2VydmljZURhdGEuS0VZX1RJTUVfU1RBTVAsIHN0YW1wKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7RGF0ZVRpbWV9XG4gICAgICovXG4gICAgZ2V0VGltZVN0YW1wICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KERhdGVUaW1lLCBOYXZpZ2F0aW9uU2VydmljZURhdGEuS0VZX1RJTUVfU1RBTVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TG9jYXRpb25EZXRhaWxzfSBvcmlnaW5cbiAgICAgKiBAcmV0dXJuIHtOYXZpZ2F0aW9uU2VydmljZURhdGF9XG4gICAgICovXG4gICAgc2V0T3JpZ2luIChvcmlnaW4pIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTG9jYXRpb25EZXRhaWxzLCBvcmlnaW4pO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihOYXZpZ2F0aW9uU2VydmljZURhdGEuS0VZX09SSUdJTiwgb3JpZ2luKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TG9jYXRpb25EZXRhaWxzfVxuICAgICAqL1xuICAgIGdldE9yaWdpbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChMb2NhdGlvbkRldGFpbHMsIE5hdmlnYXRpb25TZXJ2aWNlRGF0YS5LRVlfT1JJR0lOKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0xvY2F0aW9uRGV0YWlsc30gZGVzdGluYXRpb25cbiAgICAgKiBAcmV0dXJuIHtOYXZpZ2F0aW9uU2VydmljZURhdGF9XG4gICAgICovXG4gICAgc2V0RGVzdGluYXRpb24gKGRlc3RpbmF0aW9uKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKExvY2F0aW9uRGV0YWlscywgZGVzdGluYXRpb24pO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihOYXZpZ2F0aW9uU2VydmljZURhdGEuS0VZX0RFU1RJTkFUSU9OLCBkZXN0aW5hdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0xvY2F0aW9uRGV0YWlsc31cbiAgICAgKi9cbiAgICBnZXREZXN0aW5hdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChMb2NhdGlvbkRldGFpbHMsIE5hdmlnYXRpb25TZXJ2aWNlRGF0YS5LRVlfREVTVElOQVRJT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RGF0ZVRpbWV9IGV0YVxuICAgICAqIEByZXR1cm4ge05hdmlnYXRpb25TZXJ2aWNlRGF0YX1cbiAgICAgKi9cbiAgICBzZXREZXN0aW5hdGlvbkVUQSAoZXRhKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKERhdGVUaW1lLCBldGEpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihOYXZpZ2F0aW9uU2VydmljZURhdGEuS0VZX0RFU1RJTkFUSU9OX0VUQSwgZXRhKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7RGF0ZVRpbWV9XG4gICAgICovXG4gICAgZ2V0RGVzdGluYXRpb25FVEEgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoRGF0ZVRpbWUsIE5hdmlnYXRpb25TZXJ2aWNlRGF0YS5LRVlfREVTVElOQVRJT05fRVRBKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge05hdmlnYXRpb25JbnN0cnVjdGlvbltdfSBpbnN0cnVjdGlvbnMgLSBUaGlzIGFycmF5IHNob3VsZCBiZSBvcmRlcmVkIHdpdGggYWxsIHJlbWFpbmluZyBpbnN0cnVjdGlvbnMuIFRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0IG9mIHRoaXMgYXJyYXkgc2hvdWxkIGFsd2F5cyBjb250YWluIHRoZSBuZXh0IGluc3RydWN0aW9uLlxuICAgICAqIEByZXR1cm4ge05hdmlnYXRpb25TZXJ2aWNlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRJbnN0cnVjdGlvbnMgKGluc3RydWN0aW9ucykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShOYXZpZ2F0aW9uSW5zdHJ1Y3Rpb24sIGluc3RydWN0aW9ucywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE5hdmlnYXRpb25TZXJ2aWNlRGF0YS5LRVlfSU5TVFJVQ1RJT05TLCBpbnN0cnVjdGlvbnMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOYXZpZ2F0aW9uSW5zdHJ1Y3Rpb25bXX1cbiAgICAgKi9cbiAgICBnZXRJbnN0cnVjdGlvbnMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTmF2aWdhdGlvbkluc3RydWN0aW9uLCBOYXZpZ2F0aW9uU2VydmljZURhdGEuS0VZX0lOU1RSVUNUSU9OUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtEYXRlVGltZX0gZXRhXG4gICAgICogQHJldHVybiB7TmF2aWdhdGlvblNlcnZpY2VEYXRhfVxuICAgICAqL1xuICAgIHNldE5leHRJbnN0cnVjdGlvbkVUQSAoZXRhKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKERhdGVUaW1lLCBldGEpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihOYXZpZ2F0aW9uU2VydmljZURhdGEuS0VZX05FWFRfSU5TVFJVQ1RJT05fRVRBLCBldGEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtEYXRlVGltZX1cbiAgICAgKi9cbiAgICBnZXROZXh0SW5zdHJ1Y3Rpb25FVEEgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoRGF0ZVRpbWUsIE5hdmlnYXRpb25TZXJ2aWNlRGF0YS5LRVlfTkVYVF9JTlNUUlVDVElPTl9FVEEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBkaXN0YW5jZSAtIFRoZSBkaXN0YW5jZSB0byB0aGlzIGluc3RydWN0aW9uIGZyb20gY3VycmVudCBsb2NhdGlvbi4gVGhpcyBzaG91bGQgb25seSBiZSB1cGRhdGVkXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlciAuMSB1bml0IG9mIGRpc3RhbmNlLiBGb3IgbW9yZSBhY2N1cmFjeSB0aGUgY29uc3VtZXIgY2FuIHVzZSB0aGUgR1BTIGxvY2F0aW9uIG9mXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRzZWxmIGFuZCB0aGUgbmV4dCBpbnN0cnVjdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtOYXZpZ2F0aW9uU2VydmljZURhdGF9XG4gICAgICovXG4gICAgc2V0TmV4dEluc3RydWN0aW9uRGlzdGFuY2UgKGRpc3RhbmNlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE5hdmlnYXRpb25TZXJ2aWNlRGF0YS5LRVlfTkVYVF9JTlNUUlVDVElPTl9ESVNUQU5DRSwgZGlzdGFuY2UpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0TmV4dEluc3RydWN0aW9uRGlzdGFuY2UgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoTmF2aWdhdGlvblNlcnZpY2VEYXRhLktFWV9ORVhUX0lOU1RSVUNUSU9OX0RJU1RBTkNFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc2NhbGUgLSBEaXN0YW5jZSB0aWxsIG5leHQgbWFuZXV2ZXIgKHN0YXJ0aW5nIGZyb20pIGZyb20gcHJldmlvdXMgbWFuZXV2ZXIuXG4gICAgICogQHJldHVybiB7TmF2aWdhdGlvblNlcnZpY2VEYXRhfVxuICAgICAqL1xuICAgIHNldE5leHRJbnN0cnVjdGlvbkRpc3RhbmNlU2NhbGUgKHNjYWxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE5hdmlnYXRpb25TZXJ2aWNlRGF0YS5LRVlfTkVYVF9JTlNUUlVDVElPTl9ESVNUQU5DRV9TQ0FMRSwgc2NhbGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0TmV4dEluc3RydWN0aW9uRGlzdGFuY2VTY2FsZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihOYXZpZ2F0aW9uU2VydmljZURhdGEuS0VZX05FWFRfSU5TVFJVQ1RJT05fRElTVEFOQ0VfU0NBTEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9tcHQgLSBUaGlzIGlzIGEgcHJvbXB0IG1lc3NhZ2UgdGhhdCBzaG91bGQgYmUgY29udmV5ZWQgdG8gdGhlIHVzZXIgdGhyb3VnaCBlaXRoZXIgZGlzcGxheSBvclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICB2b2ljZSAoVFRTKS4gVGhpcyBwYXJhbSB3aWxsIGNoYW5nZSBvZnRlbiBhcyBpdCBzaG91bGQgcmVwcmVzZW50IHRoZSBmb2xsb3dpbmc6XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGFwcHJvYWNoaW5nIGluc3RydWN0aW9uLCBwb3N0IGluc3RydWN0aW9uLCBhbGVydHMgdGhhdCBhZmZlY3QgdGhlIGN1cnJlbnQgbmF2aWdhdGlvblxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLCBldGMuXG4gICAgICogQHJldHVybiB7TmF2aWdhdGlvblNlcnZpY2VEYXRhfVxuICAgICAqL1xuICAgIHNldFByb21wdCAocHJvbXB0KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE5hdmlnYXRpb25TZXJ2aWNlRGF0YS5LRVlfUFJPTVBULCBwcm9tcHQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0UHJvbXB0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE5hdmlnYXRpb25TZXJ2aWNlRGF0YS5LRVlfUFJPTVBUKTtcbiAgICB9XG59XG5cbk5hdmlnYXRpb25TZXJ2aWNlRGF0YS5LRVlfVElNRV9TVEFNUCA9ICd0aW1lU3RhbXAnO1xuTmF2aWdhdGlvblNlcnZpY2VEYXRhLktFWV9PUklHSU4gPSAnb3JpZ2luJztcbk5hdmlnYXRpb25TZXJ2aWNlRGF0YS5LRVlfREVTVElOQVRJT04gPSAnZGVzdGluYXRpb24nO1xuTmF2aWdhdGlvblNlcnZpY2VEYXRhLktFWV9ERVNUSU5BVElPTl9FVEEgPSAnZGVzdGluYXRpb25FVEEnO1xuTmF2aWdhdGlvblNlcnZpY2VEYXRhLktFWV9JTlNUUlVDVElPTlMgPSAnaW5zdHJ1Y3Rpb25zJztcbk5hdmlnYXRpb25TZXJ2aWNlRGF0YS5LRVlfTkVYVF9JTlNUUlVDVElPTl9FVEEgPSAnbmV4dEluc3RydWN0aW9uRVRBJztcbk5hdmlnYXRpb25TZXJ2aWNlRGF0YS5LRVlfTkVYVF9JTlNUUlVDVElPTl9ESVNUQU5DRSA9ICduZXh0SW5zdHJ1Y3Rpb25EaXN0YW5jZSc7XG5OYXZpZ2F0aW9uU2VydmljZURhdGEuS0VZX05FWFRfSU5TVFJVQ1RJT05fRElTVEFOQ0VfU0NBTEUgPSAnbmV4dEluc3RydWN0aW9uRGlzdGFuY2VTY2FsZSc7XG5OYXZpZ2F0aW9uU2VydmljZURhdGEuS0VZX1BST01QVCA9ICdwcm9tcHQnO1xuXG5leHBvcnQgeyBOYXZpZ2F0aW9uU2VydmljZURhdGEgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gTWVkaWFUeXBlXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBNZWRpYVR5cGUgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTVVTSUMgKCkge1xuICAgICAgICByZXR1cm4gTWVkaWFUeXBlLl9NQVAuTVVTSUM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUE9EQ0FTVCAoKSB7XG4gICAgICAgIHJldHVybiBNZWRpYVR5cGUuX01BUC5QT0RDQVNUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFVRElPQk9PSyAoKSB7XG4gICAgICAgIHJldHVybiBNZWRpYVR5cGUuX01BUC5BVURJT0JPT0s7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgT1RIRVIgKCkge1xuICAgICAgICByZXR1cm4gTWVkaWFUeXBlLl9NQVAuT1RIRVI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gTWVkaWFUeXBlLl92YWx1ZUZvcktleShrZXksIE1lZGlhVHlwZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIE1lZGlhVHlwZS5fa2V5Rm9yVmFsdWUodmFsdWUsIE1lZGlhVHlwZS5fTUFQKTtcbiAgICB9XG59XG5cbk1lZGlhVHlwZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ01VU0lDJzogJ01VU0lDJyxcbiAgICAnUE9EQ0FTVCc6ICdQT0RDQVNUJyxcbiAgICAnQVVESU9CT09LJzogJ0FVRElPQk9PSycsXG4gICAgJ09USEVSJzogJ09USEVSJyxcbn0pO1xuXG5leHBvcnQgeyBNZWRpYVR5cGUgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgSW1hZ2UgfSBmcm9tICcuL0ltYWdlLmpzJztcbmltcG9ydCB7IE1lZGlhVHlwZSB9IGZyb20gJy4uL2VudW1zL01lZGlhVHlwZS5qcyc7XG5cbi8qKlxuICogVGhpcyBkYXRhIGlzIHJlbGF0ZWQgdG8gd2hhdCBhIG1lZGlhIHNlcnZpY2Ugc2hvdWxkIHByb3ZpZGVcbiAqL1xuY2xhc3MgTWVkaWFTZXJ2aWNlRGF0YSBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtNZWRpYVR5cGV9IHR5cGUgLSBUaGUgdHlwZSBvZiB0aGUgY3VycmVudGx5IHBsYXlpbmcgb3IgcGF1c2VkIHRyYWNrLlxuICAgICAqIEByZXR1cm4ge01lZGlhU2VydmljZURhdGF9XG4gICAgICovXG4gICAgc2V0TWVkaWFUeXBlICh0eXBlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKE1lZGlhVHlwZSwgdHlwZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE1lZGlhU2VydmljZURhdGEuS0VZX01FRElBX1RZUEUsIHR5cGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtNZWRpYVR5cGV9XG4gICAgICovXG4gICAgZ2V0TWVkaWFUeXBlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KE1lZGlhVHlwZSwgTWVkaWFTZXJ2aWNlRGF0YS5LRVlfTUVESUFfVFlQRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHRpdGxlIC0gTXVzaWM6IFRoZSBuYW1lIG9mIHRoZSBjdXJyZW50IHRyYWNrIFBvZGNhc3Q6IFRoZSBuYW1lIG9mIHRoZSBjdXJyZW50IGVwaXNvZGUgQXVkaW9ib29rOlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIFRoZSBuYW1lIG9mIHRoZSBjdXJyZW50IGNoYXB0ZXJcbiAgICAgKiBAcmV0dXJuIHtNZWRpYVNlcnZpY2VEYXRhfVxuICAgICAqL1xuICAgIHNldE1lZGlhVGl0bGUgKHRpdGxlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE1lZGlhU2VydmljZURhdGEuS0VZX01FRElBX1RJVExFLCB0aXRsZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRNZWRpYVRpdGxlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE1lZGlhU2VydmljZURhdGEuS0VZX01FRElBX1RJVExFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gYXJ0aXN0IC0gTXVzaWM6IFRoZSBuYW1lIG9mIHRoZSBjdXJyZW50IGFsYnVtIGFydGlzdCBQb2RjYXN0OiBUaGUgcHJvdmlkZXIgb2YgdGhlIHBvZGNhc3QgKGhvc3RzLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBuZXR3b3JrLCBjb21wYW55KSBBdWRpb2Jvb2s6IFRoZSBib29rIGF1dGhvcidzIG5hbWVcbiAgICAgKiBAcmV0dXJuIHtNZWRpYVNlcnZpY2VEYXRhfVxuICAgICAqL1xuICAgIHNldE1lZGlhQXJ0aXN0IChhcnRpc3QpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTWVkaWFTZXJ2aWNlRGF0YS5LRVlfTUVESUFfQVJUSVNULCBhcnRpc3QpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0TWVkaWFBcnRpc3QgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoTWVkaWFTZXJ2aWNlRGF0YS5LRVlfTUVESUFfQVJUSVNUKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gYWxidW0gLSBNdXNpYzogVGhlIG5hbWUgb2YgdGhlIGN1cnJlbnQgYWxidW0gUG9kY2FzdDogVGhlIG5hbWUgb2YgdGhlIGN1cnJlbnQgcG9kY2FzdCBzaG93XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgQXVkaW9ib29rOiBUaGUgbmFtZSBvZiB0aGUgY3VycmVudCBib29rXG4gICAgICogQHJldHVybiB7TWVkaWFTZXJ2aWNlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRNZWRpYUFsYnVtIChhbGJ1bSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihNZWRpYVNlcnZpY2VEYXRhLktFWV9NRURJQV9BTEJVTSwgYWxidW0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0TWVkaWFBbGJ1bSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihNZWRpYVNlcnZpY2VEYXRhLktFWV9NRURJQV9BTEJVTSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBNdXNpYzogVGhlIG5hbWUgb2YgdGhlIHBsYXlsaXN0IG9yIHJhZGlvIHN0YXRpb24sIGlmIHRoZSB1c2VyIGlzIHBsYXlpbmcgZnJvbSBhIHBsYXlsaXN0LFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgb3RoZXJ3aXNlLCBOdWxsIFBvZGNhc3Q6IFRoZSBuYW1lIG9mIHRoZSBwbGF5bGlzdCwgaWYgdGhlIHVzZXIgaXMgcGxheWluZyBmcm9tIGEgcGxheWxpc3QsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICBvdGhlcndpc2UsIE51bGwgQXVkaW9ib29rOiBMaWtlbHkgbm90IGFwcGxpY2FibGUsIHBvc3NpYmx5IGEgY29sbGVjdGlvbiBvciBcInBsYXlsaXN0XCIgb2ZcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIGJvb2tzXG4gICAgICogQHJldHVybiB7TWVkaWFTZXJ2aWNlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRQbGF5bGlzdE5hbWUgKG5hbWUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTWVkaWFTZXJ2aWNlRGF0YS5LRVlfUExBWUxJU1RfTkFNRSwgbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRQbGF5bGlzdE5hbWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoTWVkaWFTZXJ2aWNlRGF0YS5LRVlfUExBWUxJU1RfTkFNRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBleHBsaWNpdCAtIFdoZXRoZXIgb3Igbm90IHRoZSBjb250ZW50IGN1cnJlbnRseSBwbGF5aW5nIChlLmcuIHRoZSB0cmFjaywgZXBpc29kZSwgb3IgYm9vaylcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbnMgZXhwbGljaXQgY29udGVudFxuICAgICAqIEByZXR1cm4ge01lZGlhU2VydmljZURhdGF9XG4gICAgICovXG4gICAgc2V0SXNFeHBsaWNpdCAoZXhwbGljaXQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTWVkaWFTZXJ2aWNlRGF0YS5LRVlfSVNfRVhQTElDSVQsIGV4cGxpY2l0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRJc0V4cGxpY2l0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE1lZGlhU2VydmljZURhdGEuS0VZX0lTX0VYUExJQ0lUKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gcHJvZ3Jlc3MgLSBNdXNpYzogVGhlIGN1cnJlbnQgcHJvZ3Jlc3Mgb2YgdGhlIHRyYWNrIGluIHNlY29uZHMgUG9kY2FzdDogVGhlIGN1cnJlbnQgcHJvZ3Jlc3Mgb2ZcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgZXBpc29kZSBpbiBzZWNvbmRzIEF1ZGlvYm9vazogVGhlIGN1cnJlbnQgcHJvZ3Jlc3Mgb2YgdGhlIGN1cnJlbnQgc2VnbWVudCAoZS5nLlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBjaGFwdGVyKSBpbiBzZWNvbmRzXG4gICAgICogQHJldHVybiB7TWVkaWFTZXJ2aWNlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRUcmFja1BsYXliYWNrUHJvZ3Jlc3MgKHByb2dyZXNzKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE1lZGlhU2VydmljZURhdGEuS0VZX1RSQUNLX1BMQVlCQUNLX1BST0dSRVNTLCBwcm9ncmVzcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRUcmFja1BsYXliYWNrUHJvZ3Jlc3MgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoTWVkaWFTZXJ2aWNlRGF0YS5LRVlfVFJBQ0tfUExBWUJBQ0tfUFJPR1JFU1MpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBkdXJhdGlvbiAtIE11c2ljOiBUaGUgdG90YWwgZHVyYXRpb24gb2YgdGhlIHRyYWNrIGluIHNlY29uZHMgUG9kY2FzdDogVGhlIHRvdGFsIGR1cmF0aW9uIG9mIHRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVwaXNvZGUgaW4gc2Vjb25kcyBBdWRpb2Jvb2s6IFRoZSB0b3RhbCBkdXJhdGlvbiBvZiB0aGUgY3VycmVudCBzZWdtZW50IChlLmcuIHRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXB0ZXIpIGluIHNlY29uZHNcbiAgICAgKiBAcmV0dXJuIHtNZWRpYVNlcnZpY2VEYXRhfVxuICAgICAqL1xuICAgIHNldFRyYWNrUGxheWJhY2tEdXJhdGlvbiAoZHVyYXRpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTWVkaWFTZXJ2aWNlRGF0YS5LRVlfVFJBQ0tfUExBWUJBQ0tfRFVSQVRJT04sIGR1cmF0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFRyYWNrUGxheWJhY2tEdXJhdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihNZWRpYVNlcnZpY2VEYXRhLktFWV9UUkFDS19QTEFZQkFDS19EVVJBVElPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHByb2dyZXNzIC0gTXVzaWM6IFRoZSBjdXJyZW50IHByb2dyZXNzIG9mIHRoZSBwbGF5YmFjayBxdWV1ZSBpbiBzZWNvbmRzIFBvZGNhc3Q6IFRoZSBjdXJyZW50XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvZ3Jlc3Mgb2YgdGhlIHBsYXliYWNrIHF1ZXVlIGluIHNlY29uZHMgQXVkaW9ib29rOiBUaGUgY3VycmVudCBwcm9ncmVzcyBvZiB0aGVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGF5YmFjayBxdWV1ZSAoZS5nLiB0aGUgYm9vaykgaW4gc2Vjb25kc1xuICAgICAqIEByZXR1cm4ge01lZGlhU2VydmljZURhdGF9XG4gICAgICovXG4gICAgc2V0UXVldWVQbGF5YmFja1Byb2dyZXNzIChwcm9ncmVzcykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihNZWRpYVNlcnZpY2VEYXRhLktFWV9RVUVVRV9QTEFZQkFDS19QUk9HUkVTUywgcHJvZ3Jlc3MpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0UXVldWVQbGF5YmFja1Byb2dyZXNzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE1lZGlhU2VydmljZURhdGEuS0VZX1FVRVVFX1BMQVlCQUNLX1BST0dSRVNTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZHVyYXRpb24gLSBNdXNpYzogVGhlIHRvdGFsIGR1cmF0aW9uIG9mIHRoZSBwbGF5YmFjayBxdWV1ZSBpbiBzZWNvbmRzIFBvZGNhc3Q6IFRoZSB0b3RhbCBkdXJhdGlvblxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mIHRoZSBwbGF5YmFjayBxdWV1ZSBpbiBzZWNvbmRzIEF1ZGlvYm9vazogVGhlIHRvdGFsIGR1cmF0aW9uIG9mIHRoZSBwbGF5YmFjayBxdWV1ZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlLmcuIHRoZSBib29rKSBpbiBzZWNvbmRzXG4gICAgICogQHJldHVybiB7TWVkaWFTZXJ2aWNlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRRdWV1ZVBsYXliYWNrRHVyYXRpb24gKGR1cmF0aW9uKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE1lZGlhU2VydmljZURhdGEuS0VZX1FVRVVFX1BMQVlCQUNLX0RVUkFUSU9OLCBkdXJhdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRRdWV1ZVBsYXliYWNrRHVyYXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoTWVkaWFTZXJ2aWNlRGF0YS5LRVlfUVVFVUVfUExBWUJBQ0tfRFVSQVRJT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBudW1iZXIgLSBNdXNpYzogVGhlIGN1cnJlbnQgbnVtYmVyICgxIGJhc2VkKSBvZiB0aGUgdHJhY2sgaW4gdGhlIHBsYXliYWNrIHF1ZXVlIFBvZGNhc3Q6IFRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50IG51bWJlciAoMSBiYXNlZCkgb2YgdGhlIGVwaXNvZGUgaW4gdGhlIHBsYXliYWNrIHF1ZXVlIEF1ZGlvYm9vazogVGhlIGN1cnJlbnRcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyICgxIGJhc2VkKSBvZiB0aGUgZXBpc29kZSBpbiB0aGUgcGxheWJhY2sgcXVldWUgKGUuZy4gdGhlIGNoYXB0ZXIgbnVtYmVyIGluIHRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBib29rKVxuICAgICAqIEByZXR1cm4ge01lZGlhU2VydmljZURhdGF9XG4gICAgICovXG4gICAgc2V0UXVldWVDdXJyZW50VHJhY2tOdW1iZXIgKG51bWJlcikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihNZWRpYVNlcnZpY2VEYXRhLktFWV9RVUVVRV9DVVJSRU5UX1RSQUNLX05VTUJFUiwgbnVtYmVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFF1ZXVlQ3VycmVudFRyYWNrTnVtYmVyICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE1lZGlhU2VydmljZURhdGEuS0VZX1FVRVVFX0NVUlJFTlRfVFJBQ0tfTlVNQkVSKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gY291bnQgLSBNdXNpYzogVGhlIHRvdGFsIG51bWJlciBvZiB0cmFja3MgaW4gdGhlIHBsYXliYWNrIHF1ZXVlIFBvZGNhc3Q6IFRoZSB0b3RhbCBudW1iZXIgb2ZcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBlcGlzb2RlcyBpbiB0aGUgcGxheWJhY2sgcXVldWUgQXVkaW9ib29rOiBUaGUgdG90YWwgbnVtYmVyIG9mIHNlY3Rpb25zIGluIHRoZSBwbGF5YmFja1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHF1ZXVlIChlLmcuIHRoZSBudW1iZXIgb2YgY2hhcHRlcnMgaW4gdGhlIGJvb2spXG4gICAgICogQHJldHVybiB7TWVkaWFTZXJ2aWNlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRRdWV1ZVRvdGFsVHJhY2tDb3VudCAoY291bnQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTWVkaWFTZXJ2aWNlRGF0YS5LRVlfUVVFVUVfVE9UQUxfVFJBQ0tfQ09VTlQsIGNvdW50KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFF1ZXVlVG90YWxUcmFja0NvdW50ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE1lZGlhU2VydmljZURhdGEuS0VZX1FVRVVFX1RPVEFMX1RSQUNLX0NPVU5UKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0ltYWdlfSBpbWFnZSAtIE11c2ljOiBUaGUgYWxidW0gYXJ0IG9mIHRoZSBjdXJyZW50IHRyYWNrIFBvZGNhc3Q6IFRoZSBwb2RjYXN0IG9yIGNoYXB0ZXIgYXJ0d29yayBvZiB0aGVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnQgcG9kY2FzdCBlcGlzb2RlIEF1ZGlvYm9vazogVGhlIGJvb2sgb3IgY2hhcHRlciBhcnR3b3JrIG9mIHRoZSBjdXJyZW50IGF1ZGlvYm9va1xuICAgICAqIEByZXR1cm4ge01lZGlhU2VydmljZURhdGF9XG4gICAgICovXG4gICAgc2V0TWVkaWFJbWFnZSAoaW1hZ2UpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoSW1hZ2UsIGltYWdlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoTWVkaWFTZXJ2aWNlRGF0YS5LRVlfTUVESUFfSU1BR0UsIGltYWdlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7SW1hZ2V9XG4gICAgICovXG4gICAgZ2V0TWVkaWFJbWFnZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChJbWFnZSwgTWVkaWFTZXJ2aWNlRGF0YS5LRVlfTUVESUFfSU1BR0UpO1xuICAgIH1cbn1cblxuTWVkaWFTZXJ2aWNlRGF0YS5LRVlfTUVESUFfVFlQRSA9ICdtZWRpYVR5cGUnO1xuTWVkaWFTZXJ2aWNlRGF0YS5LRVlfTUVESUFfVElUTEUgPSAnbWVkaWFUaXRsZSc7XG5NZWRpYVNlcnZpY2VEYXRhLktFWV9NRURJQV9BUlRJU1QgPSAnbWVkaWFBcnRpc3QnO1xuTWVkaWFTZXJ2aWNlRGF0YS5LRVlfTUVESUFfQUxCVU0gPSAnbWVkaWFBbGJ1bSc7XG5NZWRpYVNlcnZpY2VEYXRhLktFWV9QTEFZTElTVF9OQU1FID0gJ3BsYXlsaXN0TmFtZSc7XG5NZWRpYVNlcnZpY2VEYXRhLktFWV9JU19FWFBMSUNJVCA9ICdpc0V4cGxpY2l0Jztcbk1lZGlhU2VydmljZURhdGEuS0VZX1RSQUNLX1BMQVlCQUNLX1BST0dSRVNTID0gJ3RyYWNrUGxheWJhY2tQcm9ncmVzcyc7XG5NZWRpYVNlcnZpY2VEYXRhLktFWV9UUkFDS19QTEFZQkFDS19EVVJBVElPTiA9ICd0cmFja1BsYXliYWNrRHVyYXRpb24nO1xuTWVkaWFTZXJ2aWNlRGF0YS5LRVlfUVVFVUVfUExBWUJBQ0tfUFJPR1JFU1MgPSAncXVldWVQbGF5YmFja1Byb2dyZXNzJztcbk1lZGlhU2VydmljZURhdGEuS0VZX1FVRVVFX1BMQVlCQUNLX0RVUkFUSU9OID0gJ3F1ZXVlUGxheWJhY2tEdXJhdGlvbic7XG5NZWRpYVNlcnZpY2VEYXRhLktFWV9RVUVVRV9DVVJSRU5UX1RSQUNLX05VTUJFUiA9ICdxdWV1ZUN1cnJlbnRUcmFja051bWJlcic7XG5NZWRpYVNlcnZpY2VEYXRhLktFWV9RVUVVRV9UT1RBTF9UUkFDS19DT1VOVCA9ICdxdWV1ZVRvdGFsVHJhY2tDb3VudCc7XG5NZWRpYVNlcnZpY2VEYXRhLktFWV9NRURJQV9JTUFHRSA9ICdtZWRpYUltYWdlJztcblxuZXhwb3J0IHsgTWVkaWFTZXJ2aWNlRGF0YSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFRlbXBlcmF0dXJlIH0gZnJvbSAnLi9UZW1wZXJhdHVyZS5qcyc7XG5pbXBvcnQgeyBJbWFnZSB9IGZyb20gJy4vSW1hZ2UuanMnO1xuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IERhdGVUaW1lIH0gZnJvbSAnLi9EYXRlVGltZS5qcyc7XG5cbmNsYXNzIFdlYXRoZXJEYXRhIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1RlbXBlcmF0dXJlfSB0ZW1wZXJhdHVyZVxuICAgICAqIEByZXR1cm4ge1dlYXRoZXJEYXRhfVxuICAgICAqL1xuICAgIHNldEN1cnJlbnRUZW1wZXJhdHVyZSAodGVtcGVyYXR1cmUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVGVtcGVyYXR1cmUsIHRlbXBlcmF0dXJlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoV2VhdGhlckRhdGEuS0VZX0NVUlJFTlRfVEVNUEVSQVRVUkUsIHRlbXBlcmF0dXJlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VGVtcGVyYXR1cmV9XG4gICAgICovXG4gICAgZ2V0Q3VycmVudFRlbXBlcmF0dXJlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFRlbXBlcmF0dXJlLCBXZWF0aGVyRGF0YS5LRVlfQ1VSUkVOVF9URU1QRVJBVFVSRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtUZW1wZXJhdHVyZX0gaGlnaFxuICAgICAqIEByZXR1cm4ge1dlYXRoZXJEYXRhfVxuICAgICAqL1xuICAgIHNldFRlbXBlcmF0dXJlSGlnaCAoaGlnaCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShUZW1wZXJhdHVyZSwgaGlnaCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdlYXRoZXJEYXRhLktFWV9URU1QRVJBVFVSRV9ISUdILCBoaWdoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VGVtcGVyYXR1cmV9XG4gICAgICovXG4gICAgZ2V0VGVtcGVyYXR1cmVIaWdoICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFRlbXBlcmF0dXJlLCBXZWF0aGVyRGF0YS5LRVlfVEVNUEVSQVRVUkVfSElHSCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtUZW1wZXJhdHVyZX0gbG93XG4gICAgICogQHJldHVybiB7V2VhdGhlckRhdGF9XG4gICAgICovXG4gICAgc2V0VGVtcGVyYXR1cmVMb3cgKGxvdykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShUZW1wZXJhdHVyZSwgbG93KTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoV2VhdGhlckRhdGEuS0VZX1RFTVBFUkFUVVJFX0xPVywgbG93KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VGVtcGVyYXR1cmV9XG4gICAgICovXG4gICAgZ2V0VGVtcGVyYXR1cmVMb3cgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVGVtcGVyYXR1cmUsIFdlYXRoZXJEYXRhLktFWV9URU1QRVJBVFVSRV9MT1cpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VGVtcGVyYXR1cmV9IHRlbXBlcmF0dXJlXG4gICAgICogQHJldHVybiB7V2VhdGhlckRhdGF9XG4gICAgICovXG4gICAgc2V0QXBwYXJlbnRUZW1wZXJhdHVyZSAodGVtcGVyYXR1cmUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVGVtcGVyYXR1cmUsIHRlbXBlcmF0dXJlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoV2VhdGhlckRhdGEuS0VZX0FQUEFSRU5UX1RFTVBFUkFUVVJFLCB0ZW1wZXJhdHVyZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1RlbXBlcmF0dXJlfVxuICAgICAqL1xuICAgIGdldEFwcGFyZW50VGVtcGVyYXR1cmUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVGVtcGVyYXR1cmUsIFdlYXRoZXJEYXRhLktFWV9BUFBBUkVOVF9URU1QRVJBVFVSRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtUZW1wZXJhdHVyZX0gaGlnaFxuICAgICAqIEByZXR1cm4ge1dlYXRoZXJEYXRhfVxuICAgICAqL1xuICAgIHNldEFwcGFyZW50VGVtcGVyYXR1cmVIaWdoIChoaWdoKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFRlbXBlcmF0dXJlLCBoaWdoKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoV2VhdGhlckRhdGEuS0VZX0FQUEFSRU5UX1RFTVBFUkFUVVJFX0hJR0gsIGhpZ2gpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtUZW1wZXJhdHVyZX1cbiAgICAgKi9cbiAgICBnZXRBcHBhcmVudFRlbXBlcmF0dXJlSGlnaCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChUZW1wZXJhdHVyZSwgV2VhdGhlckRhdGEuS0VZX0FQUEFSRU5UX1RFTVBFUkFUVVJFX0hJR0gpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VGVtcGVyYXR1cmV9IGxvd1xuICAgICAqIEByZXR1cm4ge1dlYXRoZXJEYXRhfVxuICAgICAqL1xuICAgIHNldEFwcGFyZW50VGVtcGVyYXR1cmVMb3cgKGxvdykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShUZW1wZXJhdHVyZSwgbG93KTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoV2VhdGhlckRhdGEuS0VZX0FQUEFSRU5UX1RFTVBFUkFUVVJFX0xPVywgbG93KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VGVtcGVyYXR1cmV9XG4gICAgICovXG4gICAgZ2V0QXBwYXJlbnRUZW1wZXJhdHVyZUxvdyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChUZW1wZXJhdHVyZSwgV2VhdGhlckRhdGEuS0VZX0FQUEFSRU5UX1RFTVBFUkFUVVJFX0xPVyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHN1bW1hcnlcbiAgICAgKiBAcmV0dXJuIHtXZWF0aGVyRGF0YX1cbiAgICAgKi9cbiAgICBzZXRXZWF0aGVyU3VtbWFyeSAoc3VtbWFyeSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihXZWF0aGVyRGF0YS5LRVlfV0VBVEhFUl9TVU1NQVJZLCBzdW1tYXJ5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldFdlYXRoZXJTdW1tYXJ5ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFdlYXRoZXJEYXRhLktFWV9XRUFUSEVSX1NVTU1BUlkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RGF0ZVRpbWV9IHRpbWVcbiAgICAgKiBAcmV0dXJuIHtXZWF0aGVyRGF0YX1cbiAgICAgKi9cbiAgICBzZXRUaW1lICh0aW1lKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKERhdGVUaW1lLCB0aW1lKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoV2VhdGhlckRhdGEuS0VZX1RJTUUsIHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtEYXRlVGltZX1cbiAgICAgKi9cbiAgICBnZXRUaW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KERhdGVUaW1lLCBXZWF0aGVyRGF0YS5LRVlfVElNRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGh1bWlkaXR5IC0gMCB0byAxLCBwZXJjZW50YWdlIGh1bWlkaXR5XG4gICAgICogQHJldHVybiB7V2VhdGhlckRhdGF9XG4gICAgICovXG4gICAgc2V0SHVtaWRpdHkgKGh1bWlkaXR5KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdlYXRoZXJEYXRhLktFWV9IVU1JRElUWSwgaHVtaWRpdHkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0SHVtaWRpdHkgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoV2VhdGhlckRhdGEuS0VZX0hVTUlESVRZKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gY292ZXIgLSAwIHRvIDEsIHBlcmNlbnRhZ2UgY2xvdWQgY292ZXJcbiAgICAgKiBAcmV0dXJuIHtXZWF0aGVyRGF0YX1cbiAgICAgKi9cbiAgICBzZXRDbG91ZENvdmVyIChjb3Zlcikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihXZWF0aGVyRGF0YS5LRVlfQ0xPVURfQ09WRVIsIGNvdmVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldENsb3VkQ292ZXIgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoV2VhdGhlckRhdGEuS0VZX0NMT1VEX0NPVkVSKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gcGhhc2UgLSAwIHRvIDEsIHBlcmNlbnRhZ2Ugb2YgdGhlIG1vb24gc2VlbiwgZS5nLiAwID0gbm8gbW9vbiwgMC4yNSA9IHF1YXJ0ZXIgbW9vblxuICAgICAqIEByZXR1cm4ge1dlYXRoZXJEYXRhfVxuICAgICAqL1xuICAgIHNldE1vb25QaGFzZSAocGhhc2UpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoV2VhdGhlckRhdGEuS0VZX01PT05fUEhBU0UsIHBoYXNlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldE1vb25QaGFzZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihXZWF0aGVyRGF0YS5LRVlfTU9PTl9QSEFTRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGJlYXJpbmcgLSBJbiBkZWdyZWVzLCB0cnVlIG5vcnRoIGF0IDAgZGVncmVlc1xuICAgICAqIEByZXR1cm4ge1dlYXRoZXJEYXRhfVxuICAgICAqL1xuICAgIHNldFdpbmRCZWFyaW5nIChiZWFyaW5nKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdlYXRoZXJEYXRhLktFWV9XSU5EX0JFQVJJTkcsIGJlYXJpbmcpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0V2luZEJlYXJpbmcgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoV2VhdGhlckRhdGEuS0VZX1dJTkRfQkVBUklORyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGd1c3QgLSBrbS9oclxuICAgICAqIEByZXR1cm4ge1dlYXRoZXJEYXRhfVxuICAgICAqL1xuICAgIHNldFdpbmRHdXN0IChndXN0KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdlYXRoZXJEYXRhLktFWV9XSU5EX0dVU1QsIGd1c3QpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0V2luZEd1c3QgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoV2VhdGhlckRhdGEuS0VZX1dJTkRfR1VTVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNwZWVkIC0ga20vaHJcbiAgICAgKiBAcmV0dXJuIHtXZWF0aGVyRGF0YX1cbiAgICAgKi9cbiAgICBzZXRXaW5kU3BlZWQgKHNwZWVkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdlYXRoZXJEYXRhLktFWV9XSU5EX1NQRUVELCBzcGVlZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRXaW5kU3BlZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoV2VhdGhlckRhdGEuS0VZX1dJTkRfU1BFRUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBiZWFyaW5nIC0gSW4gZGVncmVlcywgdHJ1ZSBub3J0aCBhdCAwIGRlZ3JlZXNcbiAgICAgKiBAcmV0dXJuIHtXZWF0aGVyRGF0YX1cbiAgICAgKi9cbiAgICBzZXROZWFyZXN0U3Rvcm1CZWFyaW5nIChiZWFyaW5nKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdlYXRoZXJEYXRhLktFWV9ORUFSRVNUX1NUT1JNX0JFQVJJTkcsIGJlYXJpbmcpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0TmVhcmVzdFN0b3JtQmVhcmluZyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihXZWF0aGVyRGF0YS5LRVlfTkVBUkVTVF9TVE9STV9CRUFSSU5HKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZGlzdGFuY2UgLSBJbiBrbVxuICAgICAqIEByZXR1cm4ge1dlYXRoZXJEYXRhfVxuICAgICAqL1xuICAgIHNldE5lYXJlc3RTdG9ybURpc3RhbmNlIChkaXN0YW5jZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihXZWF0aGVyRGF0YS5LRVlfTkVBUkVTVF9TVE9STV9ESVNUQU5DRSwgZGlzdGFuY2UpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0TmVhcmVzdFN0b3JtRGlzdGFuY2UgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoV2VhdGhlckRhdGEuS0VZX05FQVJFU1RfU1RPUk1fRElTVEFOQ0UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBhY2N1bXVsYXRpb24gLSBjbVxuICAgICAqIEByZXR1cm4ge1dlYXRoZXJEYXRhfVxuICAgICAqL1xuICAgIHNldFByZWNpcEFjY3VtdWxhdGlvbiAoYWNjdW11bGF0aW9uKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdlYXRoZXJEYXRhLktFWV9QUkVDSVBfQUNDVU1VTEFUSU9OLCBhY2N1bXVsYXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0UHJlY2lwQWNjdW11bGF0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFdlYXRoZXJEYXRhLktFWV9QUkVDSVBfQUNDVU1VTEFUSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaW50ZW5zaXR5IC0gY20gb2Ygd2F0ZXIgcGVyIGhvdXJcbiAgICAgKiBAcmV0dXJuIHtXZWF0aGVyRGF0YX1cbiAgICAgKi9cbiAgICBzZXRQcmVjaXBJbnRlbnNpdHkgKGludGVuc2l0eSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihXZWF0aGVyRGF0YS5LRVlfUFJFQ0lQX0lOVEVOU0lUWSwgaW50ZW5zaXR5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFByZWNpcEludGVuc2l0eSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihXZWF0aGVyRGF0YS5LRVlfUFJFQ0lQX0lOVEVOU0lUWSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHByb2JhYmlsaXR5IC0gMCB0byAxLCBwZXJjZW50YWdlIGNoYW5jZVxuICAgICAqIEByZXR1cm4ge1dlYXRoZXJEYXRhfVxuICAgICAqL1xuICAgIHNldFByZWNpcFByb2JhYmlsaXR5IChwcm9iYWJpbGl0eSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihXZWF0aGVyRGF0YS5LRVlfUFJFQ0lQX1BST0JBQklMSVRZLCBwcm9iYWJpbGl0eSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRQcmVjaXBQcm9iYWJpbGl0eSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihXZWF0aGVyRGF0YS5LRVlfUFJFQ0lQX1BST0JBQklMSVRZKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSAtIGUuZy4gXCJyYWluXCIsIFwic25vd1wiLCBcInNsZWV0XCIsIFwiaGFpbFwiXG4gICAgICogQHJldHVybiB7V2VhdGhlckRhdGF9XG4gICAgICovXG4gICAgc2V0UHJlY2lwVHlwZSAodHlwZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihXZWF0aGVyRGF0YS5LRVlfUFJFQ0lQX1RZUEUsIHR5cGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0UHJlY2lwVHlwZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihXZWF0aGVyRGF0YS5LRVlfUFJFQ0lQX1RZUEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB2aXNpYmlsaXR5IC0gSW4ga21cbiAgICAgKiBAcmV0dXJuIHtXZWF0aGVyRGF0YX1cbiAgICAgKi9cbiAgICBzZXRWaXNpYmlsaXR5ICh2aXNpYmlsaXR5KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdlYXRoZXJEYXRhLktFWV9WSVNJQklMSVRZLCB2aXNpYmlsaXR5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFZpc2liaWxpdHkgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoV2VhdGhlckRhdGEuS0VZX1ZJU0lCSUxJVFkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7SW1hZ2V9IGljb25cbiAgICAgKiBAcmV0dXJuIHtXZWF0aGVyRGF0YX1cbiAgICAgKi9cbiAgICBzZXRXZWF0aGVySWNvbiAoaWNvbikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShJbWFnZSwgaWNvbik7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdlYXRoZXJEYXRhLktFWV9XRUFUSEVSX0lDT04sIGljb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtJbWFnZX1cbiAgICAgKi9cbiAgICBnZXRXZWF0aGVySWNvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChJbWFnZSwgV2VhdGhlckRhdGEuS0VZX1dFQVRIRVJfSUNPTik7XG4gICAgfVxufVxuXG5XZWF0aGVyRGF0YS5LRVlfQ1VSUkVOVF9URU1QRVJBVFVSRSA9ICdjdXJyZW50VGVtcGVyYXR1cmUnO1xuV2VhdGhlckRhdGEuS0VZX1RFTVBFUkFUVVJFX0hJR0ggPSAndGVtcGVyYXR1cmVIaWdoJztcbldlYXRoZXJEYXRhLktFWV9URU1QRVJBVFVSRV9MT1cgPSAndGVtcGVyYXR1cmVMb3cnO1xuV2VhdGhlckRhdGEuS0VZX0FQUEFSRU5UX1RFTVBFUkFUVVJFID0gJ2FwcGFyZW50VGVtcGVyYXR1cmUnO1xuV2VhdGhlckRhdGEuS0VZX0FQUEFSRU5UX1RFTVBFUkFUVVJFX0hJR0ggPSAnYXBwYXJlbnRUZW1wZXJhdHVyZUhpZ2gnO1xuV2VhdGhlckRhdGEuS0VZX0FQUEFSRU5UX1RFTVBFUkFUVVJFX0xPVyA9ICdhcHBhcmVudFRlbXBlcmF0dXJlTG93JztcbldlYXRoZXJEYXRhLktFWV9XRUFUSEVSX1NVTU1BUlkgPSAnd2VhdGhlclN1bW1hcnknO1xuV2VhdGhlckRhdGEuS0VZX1RJTUUgPSAndGltZSc7XG5XZWF0aGVyRGF0YS5LRVlfSFVNSURJVFkgPSAnaHVtaWRpdHknO1xuV2VhdGhlckRhdGEuS0VZX0NMT1VEX0NPVkVSID0gJ2Nsb3VkQ292ZXInO1xuV2VhdGhlckRhdGEuS0VZX01PT05fUEhBU0UgPSAnbW9vblBoYXNlJztcbldlYXRoZXJEYXRhLktFWV9XSU5EX0JFQVJJTkcgPSAnd2luZEJlYXJpbmcnO1xuV2VhdGhlckRhdGEuS0VZX1dJTkRfR1VTVCA9ICd3aW5kR3VzdCc7XG5XZWF0aGVyRGF0YS5LRVlfV0lORF9TUEVFRCA9ICd3aW5kU3BlZWQnO1xuV2VhdGhlckRhdGEuS0VZX05FQVJFU1RfU1RPUk1fQkVBUklORyA9ICduZWFyZXN0U3Rvcm1CZWFyaW5nJztcbldlYXRoZXJEYXRhLktFWV9ORUFSRVNUX1NUT1JNX0RJU1RBTkNFID0gJ25lYXJlc3RTdG9ybURpc3RhbmNlJztcbldlYXRoZXJEYXRhLktFWV9QUkVDSVBfQUNDVU1VTEFUSU9OID0gJ3ByZWNpcEFjY3VtdWxhdGlvbic7XG5XZWF0aGVyRGF0YS5LRVlfUFJFQ0lQX0lOVEVOU0lUWSA9ICdwcmVjaXBJbnRlbnNpdHknO1xuV2VhdGhlckRhdGEuS0VZX1BSRUNJUF9QUk9CQUJJTElUWSA9ICdwcmVjaXBQcm9iYWJpbGl0eSc7XG5XZWF0aGVyRGF0YS5LRVlfUFJFQ0lQX1RZUEUgPSAncHJlY2lwVHlwZSc7XG5XZWF0aGVyRGF0YS5LRVlfVklTSUJJTElUWSA9ICd2aXNpYmlsaXR5JztcbldlYXRoZXJEYXRhLktFWV9XRUFUSEVSX0lDT04gPSAnd2VhdGhlckljb24nO1xuXG5leHBvcnQgeyBXZWF0aGVyRGF0YSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IERhdGVUaW1lIH0gZnJvbSAnLi9EYXRlVGltZS5qcyc7XG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuXG5jbGFzcyBXZWF0aGVyQWxlcnQgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0aXRsZVxuICAgICAqIEByZXR1cm4ge1dlYXRoZXJBbGVydH1cbiAgICAgKi9cbiAgICBzZXRUaXRsZSAodGl0bGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoV2VhdGhlckFsZXJ0LktFWV9USVRMRSwgdGl0bGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0VGl0bGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoV2VhdGhlckFsZXJ0LktFWV9USVRMRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHN1bW1hcnlcbiAgICAgKiBAcmV0dXJuIHtXZWF0aGVyQWxlcnR9XG4gICAgICovXG4gICAgc2V0U3VtbWFyeSAoc3VtbWFyeSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihXZWF0aGVyQWxlcnQuS0VZX1NVTU1BUlksIHN1bW1hcnkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0U3VtbWFyeSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihXZWF0aGVyQWxlcnQuS0VZX1NVTU1BUlkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RGF0ZVRpbWV9IGV4cGlyZXNcbiAgICAgKiBAcmV0dXJuIHtXZWF0aGVyQWxlcnR9XG4gICAgICovXG4gICAgc2V0RXhwaXJlcyAoZXhwaXJlcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShEYXRlVGltZSwgZXhwaXJlcyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdlYXRoZXJBbGVydC5LRVlfRVhQSVJFUywgZXhwaXJlcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0RhdGVUaW1lfVxuICAgICAqL1xuICAgIGdldEV4cGlyZXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoRGF0ZVRpbWUsIFdlYXRoZXJBbGVydC5LRVlfRVhQSVJFUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmdbXX0gcmVnaW9uc1xuICAgICAqIEByZXR1cm4ge1dlYXRoZXJBbGVydH1cbiAgICAgKi9cbiAgICBzZXRSZWdpb25zIChyZWdpb25zKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdlYXRoZXJBbGVydC5LRVlfUkVHSU9OUywgcmVnaW9ucyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ1tdfVxuICAgICAqL1xuICAgIGdldFJlZ2lvbnMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoV2VhdGhlckFsZXJ0LktFWV9SRUdJT05TKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gc2V2ZXJpdHlcbiAgICAgKiBAcmV0dXJuIHtXZWF0aGVyQWxlcnR9XG4gICAgICovXG4gICAgc2V0U2V2ZXJpdHkgKHNldmVyaXR5KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdlYXRoZXJBbGVydC5LRVlfU0VWRVJJVFksIHNldmVyaXR5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldFNldmVyaXR5ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFdlYXRoZXJBbGVydC5LRVlfU0VWRVJJVFkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RGF0ZVRpbWV9IGlzc3VlZFxuICAgICAqIEByZXR1cm4ge1dlYXRoZXJBbGVydH1cbiAgICAgKi9cbiAgICBzZXRUaW1lSXNzdWVkIChpc3N1ZWQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoRGF0ZVRpbWUsIGlzc3VlZCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdlYXRoZXJBbGVydC5LRVlfVElNRV9JU1NVRUQsIGlzc3VlZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0RhdGVUaW1lfVxuICAgICAqL1xuICAgIGdldFRpbWVJc3N1ZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoRGF0ZVRpbWUsIFdlYXRoZXJBbGVydC5LRVlfVElNRV9JU1NVRUQpO1xuICAgIH1cbn1cblxuV2VhdGhlckFsZXJ0LktFWV9USVRMRSA9ICd0aXRsZSc7XG5XZWF0aGVyQWxlcnQuS0VZX1NVTU1BUlkgPSAnc3VtbWFyeSc7XG5XZWF0aGVyQWxlcnQuS0VZX0VYUElSRVMgPSAnZXhwaXJlcyc7XG5XZWF0aGVyQWxlcnQuS0VZX1JFR0lPTlMgPSAncmVnaW9ucyc7XG5XZWF0aGVyQWxlcnQuS0VZX1NFVkVSSVRZID0gJ3NldmVyaXR5JztcbldlYXRoZXJBbGVydC5LRVlfVElNRV9JU1NVRUQgPSAndGltZUlzc3VlZCc7XG5cbmV4cG9ydCB7IFdlYXRoZXJBbGVydCB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFdlYXRoZXJEYXRhIH0gZnJvbSAnLi9XZWF0aGVyRGF0YS5qcyc7XG5pbXBvcnQgeyBMb2NhdGlvbkRldGFpbHMgfSBmcm9tICcuL0xvY2F0aW9uRGV0YWlscy5qcyc7XG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuaW1wb3J0IHsgV2VhdGhlckFsZXJ0IH0gZnJvbSAnLi9XZWF0aGVyQWxlcnQuanMnO1xuXG4vKipcbiAqIFRoaXMgZGF0YSBpcyByZWxhdGVkIHRvIHdoYXQgYSB3ZWF0aGVyIHNlcnZpY2Ugd291bGQgcHJvdmlkZVxuICovXG5jbGFzcyBXZWF0aGVyU2VydmljZURhdGEgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TG9jYXRpb25EZXRhaWxzfSBsb2NhdGlvblxuICAgICAqIEByZXR1cm4ge1dlYXRoZXJTZXJ2aWNlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRMb2NhdGlvbiAobG9jYXRpb24pIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTG9jYXRpb25EZXRhaWxzLCBsb2NhdGlvbik7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdlYXRoZXJTZXJ2aWNlRGF0YS5LRVlfTE9DQVRJT04sIGxvY2F0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TG9jYXRpb25EZXRhaWxzfVxuICAgICAqL1xuICAgIGdldExvY2F0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KExvY2F0aW9uRGV0YWlscywgV2VhdGhlclNlcnZpY2VEYXRhLktFWV9MT0NBVElPTik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtXZWF0aGVyRGF0YX0gZm9yZWNhc3RcbiAgICAgKiBAcmV0dXJuIHtXZWF0aGVyU2VydmljZURhdGF9XG4gICAgICovXG4gICAgc2V0Q3VycmVudEZvcmVjYXN0IChmb3JlY2FzdCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShXZWF0aGVyRGF0YSwgZm9yZWNhc3QpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihXZWF0aGVyU2VydmljZURhdGEuS0VZX0NVUlJFTlRfRk9SRUNBU1QsIGZvcmVjYXN0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7V2VhdGhlckRhdGF9XG4gICAgICovXG4gICAgZ2V0Q3VycmVudEZvcmVjYXN0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFdlYXRoZXJEYXRhLCBXZWF0aGVyU2VydmljZURhdGEuS0VZX0NVUlJFTlRfRk9SRUNBU1QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7V2VhdGhlckRhdGFbXX0gZm9yZWNhc3RcbiAgICAgKiBAcmV0dXJuIHtXZWF0aGVyU2VydmljZURhdGF9XG4gICAgICovXG4gICAgc2V0TWludXRlRm9yZWNhc3QgKGZvcmVjYXN0KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFdlYXRoZXJEYXRhLCBmb3JlY2FzdCwgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFdlYXRoZXJTZXJ2aWNlRGF0YS5LRVlfTUlOVVRFX0ZPUkVDQVNULCBmb3JlY2FzdCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1dlYXRoZXJEYXRhW119XG4gICAgICovXG4gICAgZ2V0TWludXRlRm9yZWNhc3QgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoV2VhdGhlckRhdGEsIFdlYXRoZXJTZXJ2aWNlRGF0YS5LRVlfTUlOVVRFX0ZPUkVDQVNUKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1dlYXRoZXJEYXRhW119IGZvcmVjYXN0XG4gICAgICogQHJldHVybiB7V2VhdGhlclNlcnZpY2VEYXRhfVxuICAgICAqL1xuICAgIHNldEhvdXJseUZvcmVjYXN0IChmb3JlY2FzdCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShXZWF0aGVyRGF0YSwgZm9yZWNhc3QsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihXZWF0aGVyU2VydmljZURhdGEuS0VZX0hPVVJMWV9GT1JFQ0FTVCwgZm9yZWNhc3QpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtXZWF0aGVyRGF0YVtdfVxuICAgICAqL1xuICAgIGdldEhvdXJseUZvcmVjYXN0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFdlYXRoZXJEYXRhLCBXZWF0aGVyU2VydmljZURhdGEuS0VZX0hPVVJMWV9GT1JFQ0FTVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtXZWF0aGVyRGF0YVtdfSBmb3JlY2FzdFxuICAgICAqIEByZXR1cm4ge1dlYXRoZXJTZXJ2aWNlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRNdWx0aWRheUZvcmVjYXN0IChmb3JlY2FzdCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShXZWF0aGVyRGF0YSwgZm9yZWNhc3QsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihXZWF0aGVyU2VydmljZURhdGEuS0VZX01VTFRJREFZX0ZPUkVDQVNULCBmb3JlY2FzdCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1dlYXRoZXJEYXRhW119XG4gICAgICovXG4gICAgZ2V0TXVsdGlkYXlGb3JlY2FzdCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChXZWF0aGVyRGF0YSwgV2VhdGhlclNlcnZpY2VEYXRhLktFWV9NVUxUSURBWV9GT1JFQ0FTVCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtXZWF0aGVyQWxlcnRbXX0gYWxlcnRzIC0gVGhpcyBhcnJheSBzaG91bGQgYmUgb3JkZXJlZCB3aXRoIHRoZSBmaXJzdCBvYmplY3QgYmVpbmcgdGhlIGN1cnJlbnQgZGF5XG4gICAgICogQHJldHVybiB7V2VhdGhlclNlcnZpY2VEYXRhfVxuICAgICAqL1xuICAgIHNldEFsZXJ0cyAoYWxlcnRzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFdlYXRoZXJBbGVydCwgYWxlcnRzLCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoV2VhdGhlclNlcnZpY2VEYXRhLktFWV9BTEVSVFMsIGFsZXJ0cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1dlYXRoZXJBbGVydFtdfVxuICAgICAqL1xuICAgIGdldEFsZXJ0cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChXZWF0aGVyQWxlcnQsIFdlYXRoZXJTZXJ2aWNlRGF0YS5LRVlfQUxFUlRTKTtcbiAgICB9XG59XG5cbldlYXRoZXJTZXJ2aWNlRGF0YS5LRVlfTE9DQVRJT04gPSAnbG9jYXRpb24nO1xuV2VhdGhlclNlcnZpY2VEYXRhLktFWV9DVVJSRU5UX0ZPUkVDQVNUID0gJ2N1cnJlbnRGb3JlY2FzdCc7XG5XZWF0aGVyU2VydmljZURhdGEuS0VZX01JTlVURV9GT1JFQ0FTVCA9ICdtaW51dGVGb3JlY2FzdCc7XG5XZWF0aGVyU2VydmljZURhdGEuS0VZX0hPVVJMWV9GT1JFQ0FTVCA9ICdob3VybHlGb3JlY2FzdCc7XG5XZWF0aGVyU2VydmljZURhdGEuS0VZX01VTFRJREFZX0ZPUkVDQVNUID0gJ211bHRpZGF5Rm9yZWNhc3QnO1xuV2VhdGhlclNlcnZpY2VEYXRhLktFWV9BTEVSVFMgPSAnYWxlcnRzJztcblxuZXhwb3J0IHsgV2VhdGhlclNlcnZpY2VEYXRhIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi4vUnBjU3RydWN0LmpzJztcbmltcG9ydCB7IE5hdmlnYXRpb25TZXJ2aWNlRGF0YSB9IGZyb20gJy4vTmF2aWdhdGlvblNlcnZpY2VEYXRhLmpzJztcbmltcG9ydCB7IE1lZGlhU2VydmljZURhdGEgfSBmcm9tICcuL01lZGlhU2VydmljZURhdGEuanMnO1xuaW1wb3J0IHsgV2VhdGhlclNlcnZpY2VEYXRhIH0gZnJvbSAnLi9XZWF0aGVyU2VydmljZURhdGEuanMnO1xuXG4vKipcbiAqIENvbnRhaW5zIGFsbCB0aGUgY3VycmVudCBkYXRhIG9mIHRoZSBhcHAgc2VydmljZS4gVGhlIHNlcnZpY2VUeXBlIHdpbGwgbGluayB0byB3aGljaCBvZiB0aGUgc2VydmljZSBkYXRhIG9iamVjdHMgYXJlXG4gKiBpbmNsdWRlZCBpbiB0aGlzIG9iamVjdCAoZS5nLiBpZiB0aGUgc2VydmljZSB0eXBlIGlzIE1FRElBLCB0aGUgbWVkaWFTZXJ2aWNlRGF0YSBwYXJhbSBzaG91bGQgYmUgaW5jbHVkZWQpLlxuICovXG5jbGFzcyBBcHBTZXJ2aWNlRGF0YSBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgLSBUaGUgdHlwZSBvZiBzZXJ2aWNlIHRoYXQgaXMgdG8gYmUgb2ZmZXJlZCBieSB0aGlzIGFwcC4gU2VlIEFwcFNlcnZpY2VUeXBlIGZvciBrbm93biBlbnVtXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICBlcXVpdmFsZW50IHR5cGVzLiBQYXJhbWV0ZXIgaXMgYSBzdHJpbmcgdG8gYWxsb3cgZm9yIG5ldyBzZXJ2aWNlIHR5cGVzIHRvIGJlIHVzZWQgYnkgYXBwc1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgb24gb2xkZXIgdmVyc2lvbnMgb2YgU0RMIENvcmUuXG4gICAgICogQHJldHVybiB7QXBwU2VydmljZURhdGF9XG4gICAgICovXG4gICAgc2V0U2VydmljZVR5cGUgKHR5cGUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQXBwU2VydmljZURhdGEuS0VZX1NFUlZJQ0VfVFlQRSwgdHlwZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRTZXJ2aWNlVHlwZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihBcHBTZXJ2aWNlRGF0YS5LRVlfU0VSVklDRV9UWVBFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gaWRcbiAgICAgKiBAcmV0dXJuIHtBcHBTZXJ2aWNlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRTZXJ2aWNlSUQgKGlkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEFwcFNlcnZpY2VEYXRhLktFWV9TRVJWSUNFX0lELCBpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRTZXJ2aWNlSUQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoQXBwU2VydmljZURhdGEuS0VZX1NFUlZJQ0VfSUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TWVkaWFTZXJ2aWNlRGF0YX0gZGF0YSAtIFRoaXMgZGF0YSBpcyByZWxhdGVkIHRvIHdoYXQgYSBtZWRpYSBzZXJ2aWNlIHNob3VsZCBwcm92aWRlXG4gICAgICogQHJldHVybiB7QXBwU2VydmljZURhdGF9XG4gICAgICovXG4gICAgc2V0TWVkaWFTZXJ2aWNlRGF0YSAoZGF0YSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShNZWRpYVNlcnZpY2VEYXRhLCBkYXRhKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQXBwU2VydmljZURhdGEuS0VZX01FRElBX1NFUlZJQ0VfREFUQSwgZGF0YSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge01lZGlhU2VydmljZURhdGF9XG4gICAgICovXG4gICAgZ2V0TWVkaWFTZXJ2aWNlRGF0YSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChNZWRpYVNlcnZpY2VEYXRhLCBBcHBTZXJ2aWNlRGF0YS5LRVlfTUVESUFfU0VSVklDRV9EQVRBKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1dlYXRoZXJTZXJ2aWNlRGF0YX0gZGF0YSAtIFRoaXMgZGF0YSBpcyByZWxhdGVkIHRvIHdoYXQgYSB3ZWF0aGVyIHNlcnZpY2Ugd291bGQgcHJvdmlkZVxuICAgICAqIEByZXR1cm4ge0FwcFNlcnZpY2VEYXRhfVxuICAgICAqL1xuICAgIHNldFdlYXRoZXJTZXJ2aWNlRGF0YSAoZGF0YSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShXZWF0aGVyU2VydmljZURhdGEsIGRhdGEpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihBcHBTZXJ2aWNlRGF0YS5LRVlfV0VBVEhFUl9TRVJWSUNFX0RBVEEsIGRhdGEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtXZWF0aGVyU2VydmljZURhdGF9XG4gICAgICovXG4gICAgZ2V0V2VhdGhlclNlcnZpY2VEYXRhICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFdlYXRoZXJTZXJ2aWNlRGF0YSwgQXBwU2VydmljZURhdGEuS0VZX1dFQVRIRVJfU0VSVklDRV9EQVRBKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge05hdmlnYXRpb25TZXJ2aWNlRGF0YX0gZGF0YSAtIFRoaXMgZGF0YSBpcyByZWxhdGVkIHRvIHdoYXQgYSBuYXZpZ2F0aW9uIHNlcnZpY2Ugd291bGQgcHJvdmlkZS5cbiAgICAgKiBAcmV0dXJuIHtBcHBTZXJ2aWNlRGF0YX1cbiAgICAgKi9cbiAgICBzZXROYXZpZ2F0aW9uU2VydmljZURhdGEgKGRhdGEpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTmF2aWdhdGlvblNlcnZpY2VEYXRhLCBkYXRhKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoQXBwU2VydmljZURhdGEuS0VZX05BVklHQVRJT05fU0VSVklDRV9EQVRBLCBkYXRhKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TmF2aWdhdGlvblNlcnZpY2VEYXRhfVxuICAgICAqL1xuICAgIGdldE5hdmlnYXRpb25TZXJ2aWNlRGF0YSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChOYXZpZ2F0aW9uU2VydmljZURhdGEsIEFwcFNlcnZpY2VEYXRhLktFWV9OQVZJR0FUSU9OX1NFUlZJQ0VfREFUQSk7XG4gICAgfVxufVxuXG5BcHBTZXJ2aWNlRGF0YS5LRVlfU0VSVklDRV9UWVBFID0gJ3NlcnZpY2VUeXBlJztcbkFwcFNlcnZpY2VEYXRhLktFWV9TRVJWSUNFX0lEID0gJ3NlcnZpY2VJRCc7XG5BcHBTZXJ2aWNlRGF0YS5LRVlfTUVESUFfU0VSVklDRV9EQVRBID0gJ21lZGlhU2VydmljZURhdGEnO1xuQXBwU2VydmljZURhdGEuS0VZX1dFQVRIRVJfU0VSVklDRV9EQVRBID0gJ3dlYXRoZXJTZXJ2aWNlRGF0YSc7XG5BcHBTZXJ2aWNlRGF0YS5LRVlfTkFWSUdBVElPTl9TRVJWSUNFX0RBVEEgPSAnbmF2aWdhdGlvblNlcnZpY2VEYXRhJztcblxuZXhwb3J0IHsgQXBwU2VydmljZURhdGEgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBBcHBTZXJ2aWNlRGF0YSB9IGZyb20gJy4uL3N0cnVjdHMvQXBwU2VydmljZURhdGEuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbi8qKlxuICogVGhpcyByZXNwb25zZSBpbmNsdWRlcyB0aGUgZGF0YSB0aGF0IHdhcyByZXF1ZXN0ZWQgZnJvbSB0aGUgc3BlY2lmaWMgc2VydmljZVxuICovXG5jbGFzcyBHZXRBcHBTZXJ2aWNlRGF0YVJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuR2V0QXBwU2VydmljZURhdGEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7QXBwU2VydmljZURhdGF9IGRhdGEgLSBDb250YWlucyBhbGwgdGhlIGN1cnJlbnQgZGF0YSBvZiB0aGUgYXBwIHNlcnZpY2UuIFRoZSBzZXJ2aWNlVHlwZSB3aWxsIGxpbmsgdG9cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpY2ggb2YgdGhlIHNlcnZpY2UgZGF0YSBvYmplY3RzIGFyZSBpbmNsdWRlZCBpbiB0aGlzIG9iamVjdCAoZS5nLiBpZiB0aGUgc2VydmljZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlIGlzIE1FRElBLCB0aGUgbWVkaWFTZXJ2aWNlRGF0YSBwYXJhbSBzaG91bGQgYmUgaW5jbHVkZWQpLlxuICAgICAqIEByZXR1cm4ge0dldEFwcFNlcnZpY2VEYXRhUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0U2VydmljZURhdGEgKGRhdGEpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQXBwU2VydmljZURhdGEsIGRhdGEpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihHZXRBcHBTZXJ2aWNlRGF0YVJlc3BvbnNlLktFWV9TRVJWSUNFX0RBVEEsIGRhdGEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtBcHBTZXJ2aWNlRGF0YX1cbiAgICAgKi9cbiAgICBnZXRTZXJ2aWNlRGF0YSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChBcHBTZXJ2aWNlRGF0YSwgR2V0QXBwU2VydmljZURhdGFSZXNwb25zZS5LRVlfU0VSVklDRV9EQVRBKTtcbiAgICB9XG59XG5cbkdldEFwcFNlcnZpY2VEYXRhUmVzcG9uc2UuS0VZX1NFUlZJQ0VfREFUQSA9ICdzZXJ2aWNlRGF0YSc7XG5cbmV4cG9ydCB7IEdldEFwcFNlcnZpY2VEYXRhUmVzcG9uc2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi4vUnBjUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5cbmNsYXNzIFBlcmZvcm1BcHBTZXJ2aWNlSW50ZXJhY3Rpb24gZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELlBlcmZvcm1BcHBTZXJ2aWNlSW50ZXJhY3Rpb24pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB1cmkgLSBGdWxseSBxdWFsaWZpZWQgVVJJIGJhc2VkIG9uIGEgcHJlZGV0ZXJtaW5lZCBzY2hlbWUgcHJvdmlkZWQgYnkgdGhlIGFwcCBzZXJ2aWNlLiBTREwgbWFrZXNcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgbm8gZ3VhcmFudGVlIHRoYXQgdGhpcyBVUkkgaXMgY29ycmVjdC5cbiAgICAgKiBAcmV0dXJuIHtQZXJmb3JtQXBwU2VydmljZUludGVyYWN0aW9ufVxuICAgICAqL1xuICAgIHNldFNlcnZpY2VVcmkgKHVyaSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihQZXJmb3JtQXBwU2VydmljZUludGVyYWN0aW9uLktFWV9TRVJWSUNFX1VSSSwgdXJpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldFNlcnZpY2VVcmkgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUGVyZm9ybUFwcFNlcnZpY2VJbnRlcmFjdGlvbi5LRVlfU0VSVklDRV9VUkkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBpZCAtIFRoZSBzZXJ2aWNlIElEIHRoYXQgdGhlIGFwcCBjb25zdW1lciB3aXNoZXMgdG8gc2VuZCB0aGlzIFVSSS5cbiAgICAgKiBAcmV0dXJuIHtQZXJmb3JtQXBwU2VydmljZUludGVyYWN0aW9ufVxuICAgICAqL1xuICAgIHNldFNlcnZpY2VJRCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUGVyZm9ybUFwcFNlcnZpY2VJbnRlcmFjdGlvbi5LRVlfU0VSVklDRV9JRCwgaWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0U2VydmljZUlEICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFBlcmZvcm1BcHBTZXJ2aWNlSW50ZXJhY3Rpb24uS0VZX1NFUlZJQ0VfSUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBhcHAgLSBUaGlzIHN0cmluZyBpcyB0aGUgYXBwSUQgb2YgdGhlIGFwcCByZXF1ZXN0aW5nIHRoZSBhcHAgc2VydmljZSBwcm92aWRlciB0YWtlIHRoZSBzcGVjaWZpY1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb24uXG4gICAgICogQHJldHVybiB7UGVyZm9ybUFwcFNlcnZpY2VJbnRlcmFjdGlvbn1cbiAgICAgKi9cbiAgICBzZXRPcmlnaW5BcHAgKGFwcCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihQZXJmb3JtQXBwU2VydmljZUludGVyYWN0aW9uLktFWV9PUklHSU5fQVBQLCBhcHApO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0T3JpZ2luQXBwICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFBlcmZvcm1BcHBTZXJ2aWNlSW50ZXJhY3Rpb24uS0VZX09SSUdJTl9BUFApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gYWN0aXZlIC0gVGhpcyBmbGFnIHNpZ25hbHMgdGhlIHJlcXVlc3RpbmcgY29uc3VtZXIgd291bGQgbGlrZSB0aGlzIHNlcnZpY2UgdG8gYmVjb21lIHRoZSBhY3RpdmVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW1hcnkgc2VydmljZSBvZiB0aGUgZGVzdGluYXRpb24ncyB0eXBlLlxuICAgICAqIEByZXR1cm4ge1BlcmZvcm1BcHBTZXJ2aWNlSW50ZXJhY3Rpb259XG4gICAgICovXG4gICAgc2V0UmVxdWVzdFNlcnZpY2VBY3RpdmUgKGFjdGl2ZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihQZXJmb3JtQXBwU2VydmljZUludGVyYWN0aW9uLktFWV9SRVFVRVNUX1NFUlZJQ0VfQUNUSVZFLCBhY3RpdmUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldFJlcXVlc3RTZXJ2aWNlQWN0aXZlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFBlcmZvcm1BcHBTZXJ2aWNlSW50ZXJhY3Rpb24uS0VZX1JFUVVFU1RfU0VSVklDRV9BQ1RJVkUpO1xuICAgIH1cbn1cblxuUGVyZm9ybUFwcFNlcnZpY2VJbnRlcmFjdGlvbi5LRVlfU0VSVklDRV9VUkkgPSAnc2VydmljZVVyaSc7XG5QZXJmb3JtQXBwU2VydmljZUludGVyYWN0aW9uLktFWV9TRVJWSUNFX0lEID0gJ3NlcnZpY2VJRCc7XG5QZXJmb3JtQXBwU2VydmljZUludGVyYWN0aW9uLktFWV9PUklHSU5fQVBQID0gJ29yaWdpbkFwcCc7XG5QZXJmb3JtQXBwU2VydmljZUludGVyYWN0aW9uLktFWV9SRVFVRVNUX1NFUlZJQ0VfQUNUSVZFID0gJ3JlcXVlc3RTZXJ2aWNlQWN0aXZlJztcblxuZXhwb3J0IHsgUGVyZm9ybUFwcFNlcnZpY2VJbnRlcmFjdGlvbiB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG5jbGFzcyBQZXJmb3JtQXBwU2VydmljZUludGVyYWN0aW9uUmVzcG9uc2UgZXh0ZW5kcyBScGNSZXNwb25zZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5QZXJmb3JtQXBwU2VydmljZUludGVyYWN0aW9uKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gcmVzdWx0IC0gVGhlIHNlcnZpY2UgY2FuIHByb3ZpZGUgc3BlY2lmaWMgcmVzdWx0IHN0cmluZ3MgdG8gdGhlIGNvbnN1bWVyIHRocm91Z2ggdGhpcyBwYXJhbS5cbiAgICAgKiBAcmV0dXJuIHtQZXJmb3JtQXBwU2VydmljZUludGVyYWN0aW9uUmVzcG9uc2V9XG4gICAgICovXG4gICAgc2V0U2VydmljZVNwZWNpZmljUmVzdWx0IChyZXN1bHQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUGVyZm9ybUFwcFNlcnZpY2VJbnRlcmFjdGlvblJlc3BvbnNlLktFWV9TRVJWSUNFX1NQRUNJRklDX1JFU1VMVCwgcmVzdWx0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldFNlcnZpY2VTcGVjaWZpY1Jlc3VsdCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihQZXJmb3JtQXBwU2VydmljZUludGVyYWN0aW9uUmVzcG9uc2UuS0VZX1NFUlZJQ0VfU1BFQ0lGSUNfUkVTVUxUKTtcbiAgICB9XG59XG5cblBlcmZvcm1BcHBTZXJ2aWNlSW50ZXJhY3Rpb25SZXNwb25zZS5LRVlfU0VSVklDRV9TUEVDSUZJQ19SRVNVTFQgPSAnc2VydmljZVNwZWNpZmljUmVzdWx0JztcblxuZXhwb3J0IHsgUGVyZm9ybUFwcFNlcnZpY2VJbnRlcmFjdGlvblJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG4vKipcbiAqIENsb3NlIGFuIGFjdGl2ZSBpbnRlcmFjdGlvbiBvbiB0aGUgSE1JLlxuICovXG5jbGFzcyBDYW5jZWxJbnRlcmFjdGlvbiBleHRlbmRzIFJwY1JlcXVlc3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuQ2FuY2VsSW50ZXJhY3Rpb24pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBpZCAtIFRoZSBJRCBvZiB0aGUgc3BlY2lmaWMgaW50ZXJhY3Rpb24geW91IHdhbnQgdG8gZGlzbWlzcy4gSWYgbm90IHNldCwgdGhlIG1vc3QgcmVjZW50IG9mIHRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIFJQQyB0eXBlIHNldCBpbiBmdW5jdGlvbklEIHdpbGwgYmUgZGlzbWlzc2VkLlxuICAgICAqIEByZXR1cm4ge0NhbmNlbEludGVyYWN0aW9ufVxuICAgICAqL1xuICAgIHNldENhbmNlbElEIChpZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihDYW5jZWxJbnRlcmFjdGlvbi5LRVlfQ0FOQ0VMX0lELCBpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRDYW5jZWxJRCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihDYW5jZWxJbnRlcmFjdGlvbi5LRVlfQ0FOQ0VMX0lEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaWQgLSBUaGUgSUQgb2YgdGhlIHR5cGUgb2YgaW50ZXJhY3Rpb24gdGhlIGRldmVsb3BlciB3YW50cyB0byBkaXNtaXNzLiBPbmx5IHZhbHVlcyAxMCxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAoUGVyZm9ybUludGVyYWN0aW9uSUQpLCAxMiAoQWxlcnRJRCksIDI1IChTY3JvbGxhYmxlTWVzc2FnZUlEKSwgYW5kIDI2IChTbGlkZXJJRCkgYXJlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgcGVybWl0dGVkLlxuICAgICAqIEByZXR1cm4ge0NhbmNlbEludGVyYWN0aW9ufVxuICAgICAqL1xuICAgIHNldEZ1bmN0aW9uSUQgKGlkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKENhbmNlbEludGVyYWN0aW9uLktFWV9GVU5DVElPTl9JRCwgaWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0RnVuY3Rpb25JRCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihDYW5jZWxJbnRlcmFjdGlvbi5LRVlfRlVOQ1RJT05fSUQpO1xuICAgIH1cbn1cblxuQ2FuY2VsSW50ZXJhY3Rpb24uS0VZX0NBTkNFTF9JRCA9ICdjYW5jZWxJRCc7XG5DYW5jZWxJbnRlcmFjdGlvbi5LRVlfRlVOQ1RJT05fSUQgPSAnZnVuY3Rpb25JRCc7XG5cbmV4cG9ydCB7IENhbmNlbEludGVyYWN0aW9uIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbi8qKlxuICogSWYgbm8gYXBwbGljYWJsZSByZXF1ZXN0IGNhbiBiZSBkaXNtaXNzZWQsIHRoZSByZXN1bHQgd2lsbCBiZSBJR05PUkVELlxuICovXG5jbGFzcyBDYW5jZWxJbnRlcmFjdGlvblJlc3BvbnNlIGV4dGVuZHMgUnBjUmVzcG9uc2Uge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuQ2FuY2VsSW50ZXJhY3Rpb24pO1xuICAgIH1cbn1cblxuXG5leHBvcnQgeyBDYW5jZWxJbnRlcmFjdGlvblJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG4vKipcbiAqIFJlcXVlc3QgZnJvbSB0aGUgYXBwbGljYXRpb24gdG8gZXhpdCB0aGUgZm9yZWdyb3VuZCBhbmQgZW50ZXIgSE1JX05PTkUuXG4gKi9cbmNsYXNzIENsb3NlQXBwbGljYXRpb24gZXh0ZW5kcyBScGNSZXF1ZXN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkNsb3NlQXBwbGljYXRpb24pO1xuICAgIH1cbn1cblxuXG5leHBvcnQgeyBDbG9zZUFwcGxpY2F0aW9uIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuLi9ScGNSZXNwb25zZS5qcyc7XG5cbmNsYXNzIENsb3NlQXBwbGljYXRpb25SZXNwb25zZSBleHRlbmRzIFJwY1Jlc3BvbnNlIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELkNsb3NlQXBwbGljYXRpb24pO1xuICAgIH1cbn1cblxuXG5leHBvcnQgeyBDbG9zZUFwcGxpY2F0aW9uUmVzcG9uc2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBFbnVtZXJhdGlvbiB0aGF0IGRlc2NyaWJlcyBwb3NzaWJsZSBjb250ZXh0cyBhbiBhcHAncyBITUkgbWlnaHQgYmUgaW4uIENvbW11bmljYXRlZCB0byB3aGljaGV2ZXIgYXBwIGlzIGluIEhNSSBGVUxMLFxuICogZXhjZXB0IEFsZXJ0LlxuICogQHR5cGVkZWYge0VudW19IFN5c3RlbUNvbnRleHRcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIFN5c3RlbUNvbnRleHQgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGFwcCdzIHBlcnNpc3RlbnQgZGlzcGxheSAod2hldGhlciBtZWRpYS9ub24tbWVkaWEvbmF2aWdhdGlvbikgaXMgZnVsbHkgdmlzaWJsZSBvbnNjcmVlbi5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTWVNDVFhUX01BSU4gKCkge1xuICAgICAgICByZXR1cm4gU3lzdGVtQ29udGV4dC5fTUFQLlNZU0NUWFRfTUFJTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgc3lzdGVtIGlzIGN1cnJlbnRseSBpbiBhIFZSIHNlc3Npb24gKHdpdGggd2hhdGV2ZXIgZGVkaWNhdGVkIFZSIHNjcmVlbiBiZWluZyBvdmVybGFpZCBvbnNjcmVlbikuXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU1lTQ1RYVF9WUlNFU1NJT04gKCkge1xuICAgICAgICByZXR1cm4gU3lzdGVtQ29udGV4dC5fTUFQLlNZU0NUWFRfVlJTRVNTSU9OO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBzeXN0ZW0gaXMgY3VycmVudGx5IGRpc3BsYXlpbmcgYW4gaW4tQXBwIG1lbnUgb25zY3JlZW4uXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgU1lTQ1RYVF9NRU5VICgpIHtcbiAgICAgICAgcmV0dXJuIFN5c3RlbUNvbnRleHQuX01BUC5TWVNDVFhUX01FTlU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGFwcCdzIGRpc3BsYXkgSE1JIGlzIGN1cnJlbnRseSBiZWluZyBvYnNjdXJlZCBieSBlaXRoZXIgYSBzeXN0ZW0gb3Igb3RoZXIgYXBwJ3Mgb3ZlcmxheS5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTWVNDVFhUX0hNSV9PQlNDVVJFRCAoKSB7XG4gICAgICAgIHJldHVybiBTeXN0ZW1Db250ZXh0Ll9NQVAuU1lTQ1RYVF9ITUlfT0JTQ1VSRUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQnJvYWRjYXN0IG9ubHkgdG8gd2hpY2hldmVyIGFwcCBoYXMgYW4gYWxlcnQgY3VycmVudGx5IGJlaW5nIGRpc3BsYXllZC5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTWVNDVFhUX0FMRVJUICgpIHtcbiAgICAgICAgcmV0dXJuIFN5c3RlbUNvbnRleHQuX01BUC5TWVNDVFhUX0FMRVJUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFN5c3RlbUNvbnRleHQuX3ZhbHVlRm9yS2V5KGtleSwgU3lzdGVtQ29udGV4dC5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFN5c3RlbUNvbnRleHQuX2tleUZvclZhbHVlKHZhbHVlLCBTeXN0ZW1Db250ZXh0Ll9NQVApO1xuICAgIH1cbn1cblxuU3lzdGVtQ29udGV4dC5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1NZU0NUWFRfTUFJTic6ICdNQUlOJyxcbiAgICAnU1lTQ1RYVF9WUlNFU1NJT04nOiAnVlJTRVNTSU9OJyxcbiAgICAnU1lTQ1RYVF9NRU5VJzogJ01FTlUnLFxuICAgICdTWVNDVFhUX0hNSV9PQlNDVVJFRCc6ICdITUlfT0JTQ1VSRUQnLFxuICAgICdTWVNDVFhUX0FMRVJUJzogJ0FMRVJUJyxcbn0pO1xuXG5leHBvcnQgeyBTeXN0ZW1Db250ZXh0IH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY01lc3NhZ2UgfSBmcm9tICcuL1JwY01lc3NhZ2UuanMnO1xuaW1wb3J0IHsgUnBjVHlwZSB9IGZyb20gJy4vZW51bXMvUnBjVHlwZS5qcyc7XG5cbmNsYXNzIFJwY05vdGlmaWNhdGlvbiBleHRlbmRzIFJwY01lc3NhZ2Uge1xuICAgIC8qKlxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldFJQQ1R5cGUoUnBjVHlwZS5OT1RJRklDQVRJT04pO1xuICAgIH1cbn1cblxuZXhwb3J0IHsgUnBjTm90aWZpY2F0aW9uIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogRW51bWVyYXRpb24gdGhhdCBkZXNjcmliZXMgcG9zc2libGUgc3RhdGVzIG9mIGF1ZGlvIHN0cmVhbWluZy5cbiAqIEB0eXBlZGVmIHtFbnVtfSBBdWRpb1N0cmVhbWluZ1N0YXRlXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBBdWRpb1N0cmVhbWluZ1N0YXRlIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFVRElCTEUgKCkge1xuICAgICAgICByZXR1cm4gQXVkaW9TdHJlYW1pbmdTdGF0ZS5fTUFQLkFVRElCTEU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQVRURU5VQVRFRCAoKSB7XG4gICAgICAgIHJldHVybiBBdWRpb1N0cmVhbWluZ1N0YXRlLl9NQVAuQVRURU5VQVRFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOT1RfQVVESUJMRSAoKSB7XG4gICAgICAgIHJldHVybiBBdWRpb1N0cmVhbWluZ1N0YXRlLl9NQVAuTk9UX0FVRElCTEU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gQXVkaW9TdHJlYW1pbmdTdGF0ZS5fdmFsdWVGb3JLZXkoa2V5LCBBdWRpb1N0cmVhbWluZ1N0YXRlLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gQXVkaW9TdHJlYW1pbmdTdGF0ZS5fa2V5Rm9yVmFsdWUodmFsdWUsIEF1ZGlvU3RyZWFtaW5nU3RhdGUuX01BUCk7XG4gICAgfVxufVxuXG5BdWRpb1N0cmVhbWluZ1N0YXRlLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnQVVESUJMRSc6ICdBVURJQkxFJyxcbiAgICAnQVRURU5VQVRFRCc6ICdBVFRFTlVBVEVEJyxcbiAgICAnTk9UX0FVRElCTEUnOiAnTk9UX0FVRElCTEUnLFxufSk7XG5cbmV4cG9ydCB7IEF1ZGlvU3RyZWFtaW5nU3RhdGUgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBFbnVtZXJhdGlvbiB0aGF0IGRlc2NyaWJlcyBjdXJyZW50IGxldmVscyBvZiBITUkuXG4gKiBAdHlwZWRlZiB7RW51bX0gSE1JTGV2ZWxcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIEhNSUxldmVsIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEhNSV9GVUxMICgpIHtcbiAgICAgICAgcmV0dXJuIEhNSUxldmVsLl9NQVAuSE1JX0ZVTEw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgSE1JX0xJTUlURUQgKCkge1xuICAgICAgICByZXR1cm4gSE1JTGV2ZWwuX01BUC5ITUlfTElNSVRFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBITUlfQkFDS0dST1VORCAoKSB7XG4gICAgICAgIHJldHVybiBITUlMZXZlbC5fTUFQLkhNSV9CQUNLR1JPVU5EO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEhNSV9OT05FICgpIHtcbiAgICAgICAgcmV0dXJuIEhNSUxldmVsLl9NQVAuSE1JX05PTkU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gSE1JTGV2ZWwuX3ZhbHVlRm9yS2V5KGtleSwgSE1JTGV2ZWwuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBITUlMZXZlbC5fa2V5Rm9yVmFsdWUodmFsdWUsIEhNSUxldmVsLl9NQVApO1xuICAgIH1cbn1cblxuSE1JTGV2ZWwuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdITUlfRlVMTCc6ICdGVUxMJyxcbiAgICAnSE1JX0xJTUlURUQnOiAnTElNSVRFRCcsXG4gICAgJ0hNSV9CQUNLR1JPVU5EJzogJ0JBQ0tHUk9VTkQnLFxuICAgICdITUlfTk9ORSc6ICdOT05FJyxcbn0pO1xuXG5leHBvcnQgeyBITUlMZXZlbCB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEVudW1lcmF0aW9uIHRoYXQgZGVzY3JpYmVzIHBvc3NpYmxlIHN0YXRlcyBvZiB2aWRlbyBzdHJlYW1pbmcuXG4gKiBAdHlwZWRlZiB7RW51bX0gVmlkZW9TdHJlYW1pbmdTdGF0ZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgVmlkZW9TdHJlYW1pbmdTdGF0ZSBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBTVFJFQU1BQkxFICgpIHtcbiAgICAgICAgcmV0dXJuIFZpZGVvU3RyZWFtaW5nU3RhdGUuX01BUC5TVFJFQU1BQkxFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5PVF9TVFJFQU1BQkxFICgpIHtcbiAgICAgICAgcmV0dXJuIFZpZGVvU3RyZWFtaW5nU3RhdGUuX01BUC5OT1RfU1RSRUFNQUJMRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBWaWRlb1N0cmVhbWluZ1N0YXRlLl92YWx1ZUZvcktleShrZXksIFZpZGVvU3RyZWFtaW5nU3RhdGUuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBWaWRlb1N0cmVhbWluZ1N0YXRlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgVmlkZW9TdHJlYW1pbmdTdGF0ZS5fTUFQKTtcbiAgICB9XG59XG5cblZpZGVvU3RyZWFtaW5nU3RhdGUuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdTVFJFQU1BQkxFJzogJ1NUUkVBTUFCTEUnLFxuICAgICdOT1RfU1RSRUFNQUJMRSc6ICdOT1RfU1RSRUFNQUJMRScsXG59KTtcblxuZXhwb3J0IHsgVmlkZW9TdHJlYW1pbmdTdGF0ZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFN5c3RlbUNvbnRleHQgfSBmcm9tICcuLi9lbnVtcy9TeXN0ZW1Db250ZXh0LmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY05vdGlmaWNhdGlvbiB9IGZyb20gJy4uL1JwY05vdGlmaWNhdGlvbi5qcyc7XG5pbXBvcnQgeyBBdWRpb1N0cmVhbWluZ1N0YXRlIH0gZnJvbSAnLi4vZW51bXMvQXVkaW9TdHJlYW1pbmdTdGF0ZS5qcyc7XG5pbXBvcnQgeyBITUlMZXZlbCB9IGZyb20gJy4uL2VudW1zL0hNSUxldmVsLmpzJztcbmltcG9ydCB7IFZpZGVvU3RyZWFtaW5nU3RhdGUgfSBmcm9tICcuLi9lbnVtcy9WaWRlb1N0cmVhbWluZ1N0YXRlLmpzJztcblxuY2xhc3MgT25ITUlTdGF0dXMgZXh0ZW5kcyBScGNOb3RpZmljYXRpb24ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuT25ITUlTdGF0dXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7SE1JTGV2ZWx9IGxldmVsIC0gU2VlIEhNSUxldmVsXG4gICAgICogQHJldHVybiB7T25ITUlTdGF0dXN9XG4gICAgICovXG4gICAgc2V0SG1pTGV2ZWwgKGxldmVsKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEhNSUxldmVsLCBsZXZlbCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uSE1JU3RhdHVzLktFWV9ITUlfTEVWRUwsIGxldmVsKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7SE1JTGV2ZWx9XG4gICAgICovXG4gICAgZ2V0SG1pTGV2ZWwgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoSE1JTGV2ZWwsIE9uSE1JU3RhdHVzLktFWV9ITUlfTEVWRUwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7QXVkaW9TdHJlYW1pbmdTdGF0ZX0gc3RhdGUgLSBTZWUgQXVkaW9TdHJlYW1pbmdTdGF0ZVxuICAgICAqIEByZXR1cm4ge09uSE1JU3RhdHVzfVxuICAgICAqL1xuICAgIHNldEF1ZGlvU3RyZWFtaW5nU3RhdGUgKHN0YXRlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEF1ZGlvU3RyZWFtaW5nU3RhdGUsIHN0YXRlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25ITUlTdGF0dXMuS0VZX0FVRElPX1NUUkVBTUlOR19TVEFURSwgc3RhdGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtBdWRpb1N0cmVhbWluZ1N0YXRlfVxuICAgICAqL1xuICAgIGdldEF1ZGlvU3RyZWFtaW5nU3RhdGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQXVkaW9TdHJlYW1pbmdTdGF0ZSwgT25ITUlTdGF0dXMuS0VZX0FVRElPX1NUUkVBTUlOR19TVEFURSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTeXN0ZW1Db250ZXh0fSBjb250ZXh0IC0gU2VlIFN5c3RlbUNvbnRleHRcbiAgICAgKiBAcmV0dXJuIHtPbkhNSVN0YXR1c31cbiAgICAgKi9cbiAgICBzZXRTeXN0ZW1Db250ZXh0IChjb250ZXh0KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFN5c3RlbUNvbnRleHQsIGNvbnRleHQpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPbkhNSVN0YXR1cy5LRVlfU1lTVEVNX0NPTlRFWFQsIGNvbnRleHQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTeXN0ZW1Db250ZXh0fVxuICAgICAqL1xuICAgIGdldFN5c3RlbUNvbnRleHQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoU3lzdGVtQ29udGV4dCwgT25ITUlTdGF0dXMuS0VZX1NZU1RFTV9DT05URVhUKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZpZGVvU3RyZWFtaW5nU3RhdGV9IHN0YXRlIC0gU2VlIFZpZGVvU3RyZWFtaW5nU3RhdGUuIElmIGl0IGlzIE5PVF9TVFJFQU1BQkxFLCB0aGUgYXBwIG11c3Qgc3RvcFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1pbmcgdmlkZW8gdG8gU0RMIENvcmUoc3RvcCBzZXJ2aWNlKS5cbiAgICAgKiBAcmV0dXJuIHtPbkhNSVN0YXR1c31cbiAgICAgKi9cbiAgICBzZXRWaWRlb1N0cmVhbWluZ1N0YXRlIChzdGF0ZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShWaWRlb1N0cmVhbWluZ1N0YXRlLCBzdGF0ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uSE1JU3RhdHVzLktFWV9WSURFT19TVFJFQU1JTkdfU1RBVEUsIHN0YXRlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmlkZW9TdHJlYW1pbmdTdGF0ZX1cbiAgICAgKi9cbiAgICBnZXRWaWRlb1N0cmVhbWluZ1N0YXRlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZpZGVvU3RyZWFtaW5nU3RhdGUsIE9uSE1JU3RhdHVzLktFWV9WSURFT19TVFJFQU1JTkdfU1RBVEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBpZCAtIFRoaXMgaXMgdGhlIHVuaXF1ZSBJRCBhc3NpZ25lZCB0byB0aGUgd2luZG93IHRoYXQgdGhpcyBSUEMgaXMgaW50ZW5kZWQuIElmIHRoaXMgcGFyYW0gaXMgbm90XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgaW5jbHVkZWQsIGl0IHdpbGwgYmUgYXNzdW1lZCB0aGF0IHRoaXMgcmVxdWVzdCBpcyBzcGVjaWZpY2FsbHkgZm9yIHRoZSBtYWluIHdpbmRvdyBvbiB0aGVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBtYWluIGRpc3BsYXkuIFNlZSBQcmVkZWZpbmVkV2luZG93cyBlbnVtLlxuICAgICAqIEByZXR1cm4ge09uSE1JU3RhdHVzfVxuICAgICAqL1xuICAgIHNldFdpbmRvd0lEIChpZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPbkhNSVN0YXR1cy5LRVlfV0lORE9XX0lELCBpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRXaW5kb3dJRCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihPbkhNSVN0YXR1cy5LRVlfV0lORE9XX0lEKTtcbiAgICB9XG59XG5cbk9uSE1JU3RhdHVzLktFWV9ITUlfTEVWRUwgPSAnaG1pTGV2ZWwnO1xuT25ITUlTdGF0dXMuS0VZX0FVRElPX1NUUkVBTUlOR19TVEFURSA9ICdhdWRpb1N0cmVhbWluZ1N0YXRlJztcbk9uSE1JU3RhdHVzLktFWV9TWVNURU1fQ09OVEVYVCA9ICdzeXN0ZW1Db250ZXh0Jztcbk9uSE1JU3RhdHVzLktFWV9WSURFT19TVFJFQU1JTkdfU1RBVEUgPSAndmlkZW9TdHJlYW1pbmdTdGF0ZSc7XG5PbkhNSVN0YXR1cy5LRVlfV0lORE9XX0lEID0gJ3dpbmRvd0lEJztcblxuZXhwb3J0IHsgT25ITUlTdGF0dXMgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBFcnJvciBjb2RlLCB3aGljaCBjb21lcyBmcm9tIHRoZSBtb2R1bGUgc2lkZS5cbiAqIEB0eXBlZGVmIHtFbnVtfSBBcHBJbnRlcmZhY2VVbnJlZ2lzdGVyZWRSZWFzb25cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIEFwcEludGVyZmFjZVVucmVnaXN0ZXJlZFJlYXNvbiBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBJR05JVElPTl9PRkYgKCkge1xuICAgICAgICByZXR1cm4gQXBwSW50ZXJmYWNlVW5yZWdpc3RlcmVkUmVhc29uLl9NQVAuSUdOSVRJT05fT0ZGO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEJMVUVUT09USF9PRkYgKCkge1xuICAgICAgICByZXR1cm4gQXBwSW50ZXJmYWNlVW5yZWdpc3RlcmVkUmVhc29uLl9NQVAuQkxVRVRPT1RIX09GRjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBVU0JfRElTQ09OTkVDVEVEICgpIHtcbiAgICAgICAgcmV0dXJuIEFwcEludGVyZmFjZVVucmVnaXN0ZXJlZFJlYXNvbi5fTUFQLlVTQl9ESVNDT05ORUNURUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUkVRVUVTVF9XSElMRV9JTl9OT05FX0hNSV9MRVZFTCAoKSB7XG4gICAgICAgIHJldHVybiBBcHBJbnRlcmZhY2VVbnJlZ2lzdGVyZWRSZWFzb24uX01BUC5SRVFVRVNUX1dISUxFX0lOX05PTkVfSE1JX0xFVkVMO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFRPT19NQU5ZX1JFUVVFU1RTICgpIHtcbiAgICAgICAgcmV0dXJuIEFwcEludGVyZmFjZVVucmVnaXN0ZXJlZFJlYXNvbi5fTUFQLlRPT19NQU5ZX1JFUVVFU1RTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IERSSVZFUl9ESVNUUkFDVElPTl9WSU9MQVRJT04gKCkge1xuICAgICAgICByZXR1cm4gQXBwSW50ZXJmYWNlVW5yZWdpc3RlcmVkUmVhc29uLl9NQVAuRFJJVkVSX0RJU1RSQUNUSU9OX1ZJT0xBVElPTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBMQU5HVUFHRV9DSEFOR0UgKCkge1xuICAgICAgICByZXR1cm4gQXBwSW50ZXJmYWNlVW5yZWdpc3RlcmVkUmVhc29uLl9NQVAuTEFOR1VBR0VfQ0hBTkdFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE1BU1RFUl9SRVNFVCAoKSB7XG4gICAgICAgIHJldHVybiBBcHBJbnRlcmZhY2VVbnJlZ2lzdGVyZWRSZWFzb24uX01BUC5NQVNURVJfUkVTRVQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRkFDVE9SWV9ERUZBVUxUUyAoKSB7XG4gICAgICAgIHJldHVybiBBcHBJbnRlcmZhY2VVbnJlZ2lzdGVyZWRSZWFzb24uX01BUC5GQUNUT1JZX0RFRkFVTFRTO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEFQUF9VTkFVVEhPUklaRUQgKCkge1xuICAgICAgICByZXR1cm4gQXBwSW50ZXJmYWNlVW5yZWdpc3RlcmVkUmVhc29uLl9NQVAuQVBQX1VOQVVUSE9SSVpFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBQUk9UT0NPTF9WSU9MQVRJT04gKCkge1xuICAgICAgICByZXR1cm4gQXBwSW50ZXJmYWNlVW5yZWdpc3RlcmVkUmVhc29uLl9NQVAuUFJPVE9DT0xfVklPTEFUSU9OO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFVOU1VQUE9SVEVEX0hNSV9SRVNPVVJDRSAoKSB7XG4gICAgICAgIHJldHVybiBBcHBJbnRlcmZhY2VVbnJlZ2lzdGVyZWRSZWFzb24uX01BUC5VTlNVUFBPUlRFRF9ITUlfUkVTT1VSQ0U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gQXBwSW50ZXJmYWNlVW5yZWdpc3RlcmVkUmVhc29uLl92YWx1ZUZvcktleShrZXksIEFwcEludGVyZmFjZVVucmVnaXN0ZXJlZFJlYXNvbi5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIEFwcEludGVyZmFjZVVucmVnaXN0ZXJlZFJlYXNvbi5fa2V5Rm9yVmFsdWUodmFsdWUsIEFwcEludGVyZmFjZVVucmVnaXN0ZXJlZFJlYXNvbi5fTUFQKTtcbiAgICB9XG59XG5cbkFwcEludGVyZmFjZVVucmVnaXN0ZXJlZFJlYXNvbi5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0lHTklUSU9OX09GRic6ICdJR05JVElPTl9PRkYnLFxuICAgICdCTFVFVE9PVEhfT0ZGJzogJ0JMVUVUT09USF9PRkYnLFxuICAgICdVU0JfRElTQ09OTkVDVEVEJzogJ1VTQl9ESVNDT05ORUNURUQnLFxuICAgICdSRVFVRVNUX1dISUxFX0lOX05PTkVfSE1JX0xFVkVMJzogJ1JFUVVFU1RfV0hJTEVfSU5fTk9ORV9ITUlfTEVWRUwnLFxuICAgICdUT09fTUFOWV9SRVFVRVNUUyc6ICdUT09fTUFOWV9SRVFVRVNUUycsXG4gICAgJ0RSSVZFUl9ESVNUUkFDVElPTl9WSU9MQVRJT04nOiAnRFJJVkVSX0RJU1RSQUNUSU9OX1ZJT0xBVElPTicsXG4gICAgJ0xBTkdVQUdFX0NIQU5HRSc6ICdMQU5HVUFHRV9DSEFOR0UnLFxuICAgICdNQVNURVJfUkVTRVQnOiAnTUFTVEVSX1JFU0VUJyxcbiAgICAnRkFDVE9SWV9ERUZBVUxUUyc6ICdGQUNUT1JZX0RFRkFVTFRTJyxcbiAgICAnQVBQX1VOQVVUSE9SSVpFRCc6ICdBUFBfVU5BVVRIT1JJWkVEJyxcbiAgICAnUFJPVE9DT0xfVklPTEFUSU9OJzogJ1BST1RPQ09MX1ZJT0xBVElPTicsXG4gICAgJ1VOU1VQUE9SVEVEX0hNSV9SRVNPVVJDRSc6ICdVTlNVUFBPUlRFRF9ITUlfUkVTT1VSQ0UnLFxufSk7XG5cbmV4cG9ydCB7IEFwcEludGVyZmFjZVVucmVnaXN0ZXJlZFJlYXNvbiB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IEFwcEludGVyZmFjZVVucmVnaXN0ZXJlZFJlYXNvbiB9IGZyb20gJy4uL2VudW1zL0FwcEludGVyZmFjZVVucmVnaXN0ZXJlZFJlYXNvbi5qcyc7XG5pbXBvcnQgeyBScGNOb3RpZmljYXRpb24gfSBmcm9tICcuLi9ScGNOb3RpZmljYXRpb24uanMnO1xuXG5jbGFzcyBPbkFwcEludGVyZmFjZVVucmVnaXN0ZXJlZCBleHRlbmRzIFJwY05vdGlmaWNhdGlvbiB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5PbkFwcEludGVyZmFjZVVucmVnaXN0ZXJlZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtBcHBJbnRlcmZhY2VVbnJlZ2lzdGVyZWRSZWFzb259IHJlYXNvbiAtIFNlZSBBcHBJbnRlcmZhY2VVbnJlZ2lzdGVyZWRSZWFzb25cbiAgICAgKiBAcmV0dXJuIHtPbkFwcEludGVyZmFjZVVucmVnaXN0ZXJlZH1cbiAgICAgKi9cbiAgICBzZXRSZWFzb24gKHJlYXNvbikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShBcHBJbnRlcmZhY2VVbnJlZ2lzdGVyZWRSZWFzb24sIHJlYXNvbik7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uQXBwSW50ZXJmYWNlVW5yZWdpc3RlcmVkLktFWV9SRUFTT04sIHJlYXNvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0FwcEludGVyZmFjZVVucmVnaXN0ZXJlZFJlYXNvbn1cbiAgICAgKi9cbiAgICBnZXRSZWFzb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQXBwSW50ZXJmYWNlVW5yZWdpc3RlcmVkUmVhc29uLCBPbkFwcEludGVyZmFjZVVucmVnaXN0ZXJlZC5LRVlfUkVBU09OKTtcbiAgICB9XG59XG5cbk9uQXBwSW50ZXJmYWNlVW5yZWdpc3RlcmVkLktFWV9SRUFTT04gPSAncmVhc29uJztcblxuZXhwb3J0IHsgT25BcHBJbnRlcmZhY2VVbnJlZ2lzdGVyZWQgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gQnV0dG9uRXZlbnRNb2RlXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBCdXR0b25FdmVudE1vZGUgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBidXR0b24gaGFzIGJlZW4gcmVsZWFzZWQgdXBcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBCVVRUT05VUCAoKSB7XG4gICAgICAgIHJldHVybiBCdXR0b25FdmVudE1vZGUuX01BUC5CVVRUT05VUDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIGJ1dHRvbiBoYXMgYmVlbiBwcmVzc2VkIGRvd25cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBCVVRUT05ET1dOICgpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbkV2ZW50TW9kZS5fTUFQLkJVVFRPTkRPV047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gQnV0dG9uRXZlbnRNb2RlLl92YWx1ZUZvcktleShrZXksIEJ1dHRvbkV2ZW50TW9kZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIEJ1dHRvbkV2ZW50TW9kZS5fa2V5Rm9yVmFsdWUodmFsdWUsIEJ1dHRvbkV2ZW50TW9kZS5fTUFQKTtcbiAgICB9XG59XG5cbkJ1dHRvbkV2ZW50TW9kZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0JVVFRPTlVQJzogJ0JVVFRPTlVQJyxcbiAgICAnQlVUVE9ORE9XTic6ICdCVVRUT05ET1dOJyxcbn0pO1xuXG5leHBvcnQgeyBCdXR0b25FdmVudE1vZGUgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBCdXR0b25OYW1lIH0gZnJvbSAnLi4vZW51bXMvQnV0dG9uTmFtZS5qcyc7XG5pbXBvcnQgeyBCdXR0b25FdmVudE1vZGUgfSBmcm9tICcuLi9lbnVtcy9CdXR0b25FdmVudE1vZGUuanMnO1xuaW1wb3J0IHsgUnBjTm90aWZpY2F0aW9uIH0gZnJvbSAnLi4vUnBjTm90aWZpY2F0aW9uLmpzJztcblxuLyoqXG4gKiBOb3RpZmllcyBhcHBsaWNhdGlvbiBvZiBVUC9ET1dOIGV2ZW50cyBmb3IgYnV0dG9ucyB0byB3aGljaCB0aGUgYXBwbGljYXRpb24gaXMgc3Vic2NyaWJlZC5cbiAqL1xuY2xhc3MgT25CdXR0b25FdmVudCBleHRlbmRzIFJwY05vdGlmaWNhdGlvbiB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5PbkJ1dHRvbkV2ZW50KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0J1dHRvbk5hbWV9IG5hbWUgLSBEZWZpbmVzIHRoZSBoYXJkIChwaHlzaWNhbCkgYW5kIHNvZnQgKHRvdWNoc2NyZWVuKSBidXR0b25zIGF2YWlsYWJsZSBmcm9tIHRoZSBtb2R1bGVcbiAgICAgKiBAcmV0dXJuIHtPbkJ1dHRvbkV2ZW50fVxuICAgICAqL1xuICAgIHNldEJ1dHRvbk5hbWUgKG5hbWUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQnV0dG9uTmFtZSwgbmFtZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uQnV0dG9uRXZlbnQuS0VZX0JVVFRPTl9OQU1FLCBuYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7QnV0dG9uTmFtZX1cbiAgICAgKi9cbiAgICBnZXRCdXR0b25OYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEJ1dHRvbk5hbWUsIE9uQnV0dG9uRXZlbnQuS0VZX0JVVFRPTl9OQU1FKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0J1dHRvbkV2ZW50TW9kZX0gbW9kZSAtIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgaXMgYW4gVVAgb3IgRE9XTiBldmVudC5cbiAgICAgKiBAcmV0dXJuIHtPbkJ1dHRvbkV2ZW50fVxuICAgICAqL1xuICAgIHNldEJ1dHRvbkV2ZW50TW9kZSAobW9kZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShCdXR0b25FdmVudE1vZGUsIG1vZGUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPbkJ1dHRvbkV2ZW50LktFWV9CVVRUT05fRVZFTlRfTU9ERSwgbW9kZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0J1dHRvbkV2ZW50TW9kZX1cbiAgICAgKi9cbiAgICBnZXRCdXR0b25FdmVudE1vZGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQnV0dG9uRXZlbnRNb2RlLCBPbkJ1dHRvbkV2ZW50LktFWV9CVVRUT05fRVZFTlRfTU9ERSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGlkIC0gSWYgQnV0dG9uTmFtZSBpcyBcIkNVU1RPTV9CVVRUT05cIiwgdGhpcyByZWZlcmVuY2VzIHRoZSBpbnRlZ2VyIElEIHBhc3NlZCBieSBhIGN1c3RvbSBidXR0b24uXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgKGUuZy4gc29mdEJ1dHRvbiBJRClcbiAgICAgKiBAcmV0dXJuIHtPbkJ1dHRvbkV2ZW50fVxuICAgICAqL1xuICAgIHNldEN1c3RvbUJ1dHRvbklEIChpZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPbkJ1dHRvbkV2ZW50LktFWV9DVVNUT01fQlVUVE9OX0lELCBpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRDdXN0b21CdXR0b25JRCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihPbkJ1dHRvbkV2ZW50LktFWV9DVVNUT01fQlVUVE9OX0lEKTtcbiAgICB9XG59XG5cbk9uQnV0dG9uRXZlbnQuS0VZX0JVVFRPTl9OQU1FID0gJ2J1dHRvbk5hbWUnO1xuT25CdXR0b25FdmVudC5LRVlfQlVUVE9OX0VWRU5UX01PREUgPSAnYnV0dG9uRXZlbnRNb2RlJztcbk9uQnV0dG9uRXZlbnQuS0VZX0NVU1RPTV9CVVRUT05fSUQgPSAnY3VzdG9tQnV0dG9uSUQnO1xuXG5leHBvcnQgeyBPbkJ1dHRvbkV2ZW50IH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgQnV0dG9uUHJlc3NNb2RlIH0gZnJvbSAnLi4vZW51bXMvQnV0dG9uUHJlc3NNb2RlLmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IEJ1dHRvbk5hbWUgfSBmcm9tICcuLi9lbnVtcy9CdXR0b25OYW1lLmpzJztcbmltcG9ydCB7IFJwY05vdGlmaWNhdGlvbiB9IGZyb20gJy4uL1JwY05vdGlmaWNhdGlvbi5qcyc7XG5cbi8qKlxuICogTm90aWZpZXMgYXBwbGljYXRpb24gb2YgTE9ORy9TSE9SVCBwcmVzcyBldmVudHMgZm9yIGJ1dHRvbnMgdG8gd2hpY2ggdGhlIGFwcGxpY2F0aW9uIGlzIHN1YnNjcmliZWQuXG4gKi9cbmNsYXNzIE9uQnV0dG9uUHJlc3MgZXh0ZW5kcyBScGNOb3RpZmljYXRpb24ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuT25CdXR0b25QcmVzcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCdXR0b25OYW1lfSBuYW1lIC0gRGVmaW5lcyB0aGUgaGFyZCAocGh5c2ljYWwpIGFuZCBzb2Z0ICh0b3VjaHNjcmVlbikgYnV0dG9ucyBhdmFpbGFibGUgZnJvbSB0aGUgbW9kdWxlXG4gICAgICogQHJldHVybiB7T25CdXR0b25QcmVzc31cbiAgICAgKi9cbiAgICBzZXRCdXR0b25OYW1lIChuYW1lKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEJ1dHRvbk5hbWUsIG5hbWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPbkJ1dHRvblByZXNzLktFWV9CVVRUT05fTkFNRSwgbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0J1dHRvbk5hbWV9XG4gICAgICovXG4gICAgZ2V0QnV0dG9uTmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChCdXR0b25OYW1lLCBPbkJ1dHRvblByZXNzLktFWV9CVVRUT05fTkFNRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCdXR0b25QcmVzc01vZGV9IG1vZGUgLSBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIGlzIGEgTE9ORyBvciBTSE9SVCBidXR0b24gcHJlc3MgZXZlbnQuXG4gICAgICogQHJldHVybiB7T25CdXR0b25QcmVzc31cbiAgICAgKi9cbiAgICBzZXRCdXR0b25QcmVzc01vZGUgKG1vZGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQnV0dG9uUHJlc3NNb2RlLCBtb2RlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25CdXR0b25QcmVzcy5LRVlfQlVUVE9OX1BSRVNTX01PREUsIG1vZGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCdXR0b25QcmVzc01vZGV9XG4gICAgICovXG4gICAgZ2V0QnV0dG9uUHJlc3NNb2RlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEJ1dHRvblByZXNzTW9kZSwgT25CdXR0b25QcmVzcy5LRVlfQlVUVE9OX1BSRVNTX01PREUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBpZCAtIElmIEJ1dHRvbk5hbWUgaXMgXCJDVVNUT01fQlVUVE9OXCIsIHRoaXMgcmVmZXJlbmNlcyB0aGUgaW50ZWdlciBJRCBwYXNzZWQgYnkgYSBjdXN0b20gYnV0dG9uLlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIChlLmcuIHNvZnRCdXR0b24gSUQpXG4gICAgICogQHJldHVybiB7T25CdXR0b25QcmVzc31cbiAgICAgKi9cbiAgICBzZXRDdXN0b21CdXR0b25JRCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25CdXR0b25QcmVzcy5LRVlfQ1VTVE9NX0JVVFRPTl9JRCwgaWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0Q3VzdG9tQnV0dG9uSUQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoT25CdXR0b25QcmVzcy5LRVlfQ1VTVE9NX0JVVFRPTl9JRCk7XG4gICAgfVxufVxuXG5PbkJ1dHRvblByZXNzLktFWV9CVVRUT05fTkFNRSA9ICdidXR0b25OYW1lJztcbk9uQnV0dG9uUHJlc3MuS0VZX0JVVFRPTl9QUkVTU19NT0RFID0gJ2J1dHRvblByZXNzTW9kZSc7XG5PbkJ1dHRvblByZXNzLktFWV9DVVNUT01fQlVUVE9OX0lEID0gJ2N1c3RvbUJ1dHRvbklEJztcblxuZXhwb3J0IHsgT25CdXR0b25QcmVzcyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEFpcmJhZ1N0YXR1cyB9IGZyb20gJy4uL3N0cnVjdHMvQWlyYmFnU3RhdHVzLmpzJztcbmltcG9ydCB7IENsdXN0ZXJNb2RlU3RhdHVzIH0gZnJvbSAnLi4vc3RydWN0cy9DbHVzdGVyTW9kZVN0YXR1cy5qcyc7XG5pbXBvcnQgeyBWZWhpY2xlRGF0YUV2ZW50U3RhdHVzIH0gZnJvbSAnLi4vZW51bXMvVmVoaWNsZURhdGFFdmVudFN0YXR1cy5qcyc7XG5pbXBvcnQgeyBFbWVyZ2VuY3lFdmVudCB9IGZyb20gJy4uL3N0cnVjdHMvRW1lcmdlbmN5RXZlbnQuanMnO1xuaW1wb3J0IHsgVHVyblNpZ25hbCB9IGZyb20gJy4uL2VudW1zL1R1cm5TaWduYWwuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgSGVhZExhbXBTdGF0dXMgfSBmcm9tICcuLi9zdHJ1Y3RzL0hlYWRMYW1wU3RhdHVzLmpzJztcbmltcG9ydCB7IERldmljZVN0YXR1cyB9IGZyb20gJy4uL3N0cnVjdHMvRGV2aWNlU3RhdHVzLmpzJztcbmltcG9ydCB7IFdpcGVyU3RhdHVzIH0gZnJvbSAnLi4vZW51bXMvV2lwZXJTdGF0dXMuanMnO1xuaW1wb3J0IHsgUnBjTm90aWZpY2F0aW9uIH0gZnJvbSAnLi4vUnBjTm90aWZpY2F0aW9uLmpzJztcbmltcG9ydCB7IEVsZWN0cm9uaWNQYXJrQnJha2VTdGF0dXMgfSBmcm9tICcuLi9lbnVtcy9FbGVjdHJvbmljUGFya0JyYWtlU3RhdHVzLmpzJztcbmltcG9ydCB7IE15S2V5IH0gZnJvbSAnLi4vc3RydWN0cy9NeUtleS5qcyc7XG5pbXBvcnQgeyBHUFNEYXRhIH0gZnJvbSAnLi4vc3RydWN0cy9HUFNEYXRhLmpzJztcbmltcG9ydCB7IFBSTkRMIH0gZnJvbSAnLi4vZW51bXMvUFJOREwuanMnO1xuaW1wb3J0IHsgRnVlbFJhbmdlIH0gZnJvbSAnLi4vc3RydWN0cy9GdWVsUmFuZ2UuanMnO1xuaW1wb3J0IHsgRUNhbGxJbmZvIH0gZnJvbSAnLi4vc3RydWN0cy9FQ2FsbEluZm8uanMnO1xuaW1wb3J0IHsgQmVsdFN0YXR1cyB9IGZyb20gJy4uL3N0cnVjdHMvQmVsdFN0YXR1cy5qcyc7XG5pbXBvcnQgeyBDb21wb25lbnRWb2x1bWVTdGF0dXMgfSBmcm9tICcuLi9lbnVtcy9Db21wb25lbnRWb2x1bWVTdGF0dXMuanMnO1xuaW1wb3J0IHsgQm9keUluZm9ybWF0aW9uIH0gZnJvbSAnLi4vc3RydWN0cy9Cb2R5SW5mb3JtYXRpb24uanMnO1xuaW1wb3J0IHsgVGlyZVN0YXR1cyB9IGZyb20gJy4uL3N0cnVjdHMvVGlyZVN0YXR1cy5qcyc7XG5cbi8qKlxuICogQ2FsbGJhY2sgZm9yIHRoZSBwZXJpb2RpYyBhbmQgbm9uIHBlcmlvZGljIHZlaGljbGUgZGF0YSByZWFkIGZ1bmN0aW9uLlxuICovXG5jbGFzcyBPblZlaGljbGVEYXRhIGV4dGVuZHMgUnBjTm90aWZpY2F0aW9uIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELk9uVmVoaWNsZURhdGEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7R1BTRGF0YX0gZ3BzIC0gU2VlIEdQU0RhdGFcbiAgICAgKiBAcmV0dXJuIHtPblZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldEdwcyAoZ3BzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEdQU0RhdGEsIGdwcyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uVmVoaWNsZURhdGEuS0VZX0dQUywgZ3BzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7R1BTRGF0YX1cbiAgICAgKi9cbiAgICBnZXRHcHMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoR1BTRGF0YSwgT25WZWhpY2xlRGF0YS5LRVlfR1BTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc3BlZWQgLSBUaGUgdmVoaWNsZSBzcGVlZCBpbiBraWxvbWV0ZXJzIHBlciBob3VyXG4gICAgICogQHJldHVybiB7T25WZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRTcGVlZCAoc3BlZWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25WZWhpY2xlRGF0YS5LRVlfU1BFRUQsIHNwZWVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFNwZWVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE9uVmVoaWNsZURhdGEuS0VZX1NQRUVEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gcnBtIC0gVGhlIG51bWJlciBvZiByZXZvbHV0aW9ucyBwZXIgbWludXRlIG9mIHRoZSBlbmdpbmVcbiAgICAgKiBAcmV0dXJuIHtPblZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldFJwbSAocnBtKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uVmVoaWNsZURhdGEuS0VZX1JQTSwgcnBtKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFJwbSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihPblZlaGljbGVEYXRhLktFWV9SUE0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBsZXZlbCAtIFRoZSBmdWVsIGxldmVsIGluIHRoZSB0YW5rIChwZXJjZW50YWdlKVxuICAgICAqIEByZXR1cm4ge09uVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0RnVlbExldmVsIChsZXZlbCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPblZlaGljbGVEYXRhLktFWV9GVUVMX0xFVkVMLCBsZXZlbCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRGdWVsTGV2ZWwgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoT25WZWhpY2xlRGF0YS5LRVlfRlVFTF9MRVZFTCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtDb21wb25lbnRWb2x1bWVTdGF0dXN9IGxldmVsX3N0YXRlIC0gVGhlIGZ1ZWwgbGV2ZWwgc3RhdGVcbiAgICAgKiBAcmV0dXJuIHtPblZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldEZ1ZWxMZXZlbF9TdGF0ZSAobGV2ZWxfc3RhdGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQ29tcG9uZW50Vm9sdW1lU3RhdHVzLCBsZXZlbF9zdGF0ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uVmVoaWNsZURhdGEuS0VZX0ZVRUxfTEVWRUxfU1RBVEUsIGxldmVsX3N0YXRlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Q29tcG9uZW50Vm9sdW1lU3RhdHVzfVxuICAgICAqL1xuICAgIGdldEZ1ZWxMZXZlbF9TdGF0ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChDb21wb25lbnRWb2x1bWVTdGF0dXMsIE9uVmVoaWNsZURhdGEuS0VZX0ZVRUxfTEVWRUxfU1RBVEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBjb25zdW1wdGlvbiAtIFRoZSBpbnN0YW50YW5lb3VzIGZ1ZWwgY29uc3VtcHRpb24gaW4gbWljcm9saXRyZXNcbiAgICAgKiBAcmV0dXJuIHtPblZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldEluc3RhbnRGdWVsQ29uc3VtcHRpb24gKGNvbnN1bXB0aW9uKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uVmVoaWNsZURhdGEuS0VZX0lOU1RBTlRfRlVFTF9DT05TVU1QVElPTiwgY29uc3VtcHRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0SW5zdGFudEZ1ZWxDb25zdW1wdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihPblZlaGljbGVEYXRhLktFWV9JTlNUQU5UX0ZVRUxfQ09OU1VNUFRJT04pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RnVlbFJhbmdlW119IHJhbmdlIC0gVGhlIGVzdGltYXRlIHJhbmdlIGluIEtNIHRoZSB2ZWhpY2xlIGNhbiB0cmF2ZWwgYmFzZWQgb24gZnVlbCBsZXZlbCBhbmQgY29uc3VtcHRpb25cbiAgICAgKiBAcmV0dXJuIHtPblZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldEZ1ZWxSYW5nZSAocmFuZ2UpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoRnVlbFJhbmdlLCByYW5nZSwgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uVmVoaWNsZURhdGEuS0VZX0ZVRUxfUkFOR0UsIHJhbmdlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7RnVlbFJhbmdlW119XG4gICAgICovXG4gICAgZ2V0RnVlbFJhbmdlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEZ1ZWxSYW5nZSwgT25WZWhpY2xlRGF0YS5LRVlfRlVFTF9SQU5HRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHRlbXBlcmF0dXJlIC0gVGhlIGV4dGVybmFsIHRlbXBlcmF0dXJlIGluIGRlZ3JlZXMgY2Vsc2l1c1xuICAgICAqIEByZXR1cm4ge09uVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0RXh0ZXJuYWxUZW1wZXJhdHVyZSAodGVtcGVyYXR1cmUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25WZWhpY2xlRGF0YS5LRVlfRVhURVJOQUxfVEVNUEVSQVRVUkUsIHRlbXBlcmF0dXJlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldEV4dGVybmFsVGVtcGVyYXR1cmUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoT25WZWhpY2xlRGF0YS5LRVlfRVhURVJOQUxfVEVNUEVSQVRVUkUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VHVyblNpZ25hbH0gc2lnbmFsIC0gU2VlIFR1cm5TaWduYWxcbiAgICAgKiBAcmV0dXJuIHtPblZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldFR1cm5TaWduYWwgKHNpZ25hbCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShUdXJuU2lnbmFsLCBzaWduYWwpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPblZlaGljbGVEYXRhLktFWV9UVVJOX1NJR05BTCwgc2lnbmFsKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VHVyblNpZ25hbH1cbiAgICAgKi9cbiAgICBnZXRUdXJuU2lnbmFsICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFR1cm5TaWduYWwsIE9uVmVoaWNsZURhdGEuS0VZX1RVUk5fU0lHTkFMKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdmluIC0gVmVoaWNsZSBpZGVudGlmaWNhdGlvbiBudW1iZXIuXG4gICAgICogQHJldHVybiB7T25WZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRWaW4gKHZpbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPblZlaGljbGVEYXRhLktFWV9WSU4sIHZpbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRWaW4gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoT25WZWhpY2xlRGF0YS5LRVlfVklOKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1BSTkRMfSBwcm5kbCAtIFNlZSBQUk5ETFxuICAgICAqIEByZXR1cm4ge09uVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0UHJuZGwgKHBybmRsKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFBSTkRMLCBwcm5kbCk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uVmVoaWNsZURhdGEuS0VZX1BSTkRMLCBwcm5kbCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1BSTkRMfVxuICAgICAqL1xuICAgIGdldFBybmRsICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFBSTkRMLCBPblZlaGljbGVEYXRhLktFWV9QUk5ETCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtUaXJlU3RhdHVzfSBwcmVzc3VyZSAtIFNlZSBUaXJlU3RhdHVzXG4gICAgICogQHJldHVybiB7T25WZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRUaXJlUHJlc3N1cmUgKHByZXNzdXJlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFRpcmVTdGF0dXMsIHByZXNzdXJlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25WZWhpY2xlRGF0YS5LRVlfVElSRV9QUkVTU1VSRSwgcHJlc3N1cmUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtUaXJlU3RhdHVzfVxuICAgICAqL1xuICAgIGdldFRpcmVQcmVzc3VyZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChUaXJlU3RhdHVzLCBPblZlaGljbGVEYXRhLktFWV9USVJFX1BSRVNTVVJFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gb2RvbWV0ZXIgLSBPZG9tZXRlciBpbiBrbVxuICAgICAqIEByZXR1cm4ge09uVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0T2RvbWV0ZXIgKG9kb21ldGVyKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uVmVoaWNsZURhdGEuS0VZX09ET01FVEVSLCBvZG9tZXRlcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRPZG9tZXRlciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihPblZlaGljbGVEYXRhLktFWV9PRE9NRVRFUik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCZWx0U3RhdHVzfSBzdGF0dXMgLSBUaGUgc3RhdHVzIG9mIHRoZSBzZWF0IGJlbHRzXG4gICAgICogQHJldHVybiB7T25WZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRCZWx0U3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQmVsdFN0YXR1cywgc3RhdHVzKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25WZWhpY2xlRGF0YS5LRVlfQkVMVF9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0JlbHRTdGF0dXN9XG4gICAgICovXG4gICAgZ2V0QmVsdFN0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChCZWx0U3RhdHVzLCBPblZlaGljbGVEYXRhLktFWV9CRUxUX1NUQVRVUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb2R5SW5mb3JtYXRpb259IGluZm9ybWF0aW9uIC0gVGhlIGJvZHkgaW5mb3JtYXRpb24gaW5jbHVkaW5nIHBvd2VyIG1vZGVzXG4gICAgICogQHJldHVybiB7T25WZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRCb2R5SW5mb3JtYXRpb24gKGluZm9ybWF0aW9uKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEJvZHlJbmZvcm1hdGlvbiwgaW5mb3JtYXRpb24pO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPblZlaGljbGVEYXRhLktFWV9CT0RZX0lORk9STUFUSU9OLCBpbmZvcm1hdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0JvZHlJbmZvcm1hdGlvbn1cbiAgICAgKi9cbiAgICBnZXRCb2R5SW5mb3JtYXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQm9keUluZm9ybWF0aW9uLCBPblZlaGljbGVEYXRhLktFWV9CT0RZX0lORk9STUFUSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0RldmljZVN0YXR1c30gc3RhdHVzIC0gVGhlIGRldmljZSBzdGF0dXMgaW5jbHVkaW5nIHNpZ25hbCBhbmQgYmF0dGVyeSBzdHJlbmd0aFxuICAgICAqIEByZXR1cm4ge09uVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0RGV2aWNlU3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoRGV2aWNlU3RhdHVzLCBzdGF0dXMpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPblZlaGljbGVEYXRhLktFWV9ERVZJQ0VfU1RBVFVTLCBzdGF0dXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtEZXZpY2VTdGF0dXN9XG4gICAgICovXG4gICAgZ2V0RGV2aWNlU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KERldmljZVN0YXR1cywgT25WZWhpY2xlRGF0YS5LRVlfREVWSUNFX1NUQVRVUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWhpY2xlRGF0YUV2ZW50U3RhdHVzfSBicmFraW5nIC0gVGhlIHN0YXR1cyBvZiB0aGUgYnJha2UgcGVkYWxcbiAgICAgKiBAcmV0dXJuIHtPblZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldERyaXZlckJyYWtpbmcgKGJyYWtpbmcpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVmVoaWNsZURhdGFFdmVudFN0YXR1cywgYnJha2luZyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uVmVoaWNsZURhdGEuS0VZX0RSSVZFUl9CUkFLSU5HLCBicmFraW5nKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VmVoaWNsZURhdGFFdmVudFN0YXR1c31cbiAgICAgKi9cbiAgICBnZXREcml2ZXJCcmFraW5nICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFZlaGljbGVEYXRhRXZlbnRTdGF0dXMsIE9uVmVoaWNsZURhdGEuS0VZX0RSSVZFUl9CUkFLSU5HKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1dpcGVyU3RhdHVzfSBzdGF0dXMgLSBUaGUgc3RhdHVzIG9mIHRoZSB3aXBlcnNcbiAgICAgKiBAcmV0dXJuIHtPblZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldFdpcGVyU3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoV2lwZXJTdGF0dXMsIHN0YXR1cyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uVmVoaWNsZURhdGEuS0VZX1dJUEVSX1NUQVRVUywgc3RhdHVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7V2lwZXJTdGF0dXN9XG4gICAgICovXG4gICAgZ2V0V2lwZXJTdGF0dXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoV2lwZXJTdGF0dXMsIE9uVmVoaWNsZURhdGEuS0VZX1dJUEVSX1NUQVRVUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtIZWFkTGFtcFN0YXR1c30gc3RhdHVzIC0gU3RhdHVzIG9mIHRoZSBoZWFkIGxhbXBzXG4gICAgICogQHJldHVybiB7T25WZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRIZWFkTGFtcFN0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEhlYWRMYW1wU3RhdHVzLCBzdGF0dXMpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPblZlaGljbGVEYXRhLktFWV9IRUFEX0xBTVBfU1RBVFVTLCBzdGF0dXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtIZWFkTGFtcFN0YXR1c31cbiAgICAgKi9cbiAgICBnZXRIZWFkTGFtcFN0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChIZWFkTGFtcFN0YXR1cywgT25WZWhpY2xlRGF0YS5LRVlfSEVBRF9MQU1QX1NUQVRVUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHRvcnF1ZSAtIFRvcnF1ZSB2YWx1ZSBmb3IgZW5naW5lIChpbiBObSkgb24gbm9uLWRpZXNlbCB2YXJpYW50c1xuICAgICAqIEByZXR1cm4ge09uVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0RW5naW5lVG9ycXVlICh0b3JxdWUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25WZWhpY2xlRGF0YS5LRVlfRU5HSU5FX1RPUlFVRSwgdG9ycXVlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldEVuZ2luZVRvcnF1ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihPblZlaGljbGVEYXRhLktFWV9FTkdJTkVfVE9SUVVFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gcG9zaXRpb24gLSBBY2NlbGVyYXRvciBwZWRhbCBwb3NpdGlvbiAocGVyY2VudGFnZSBkZXByZXNzZWQpXG4gICAgICogQHJldHVybiB7T25WZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRBY2NQZWRhbFBvc2l0aW9uIChwb3NpdGlvbikge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPblZlaGljbGVEYXRhLktFWV9BQ0NfUEVEQUxfUE9TSVRJT04sIHBvc2l0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldEFjY1BlZGFsUG9zaXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoT25WZWhpY2xlRGF0YS5LRVlfQUNDX1BFREFMX1BPU0lUSU9OKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYW5nbGUgLSBDdXJyZW50IGFuZ2xlIG9mIHRoZSBzdGVlcmluZyB3aGVlbCAoaW4gZGVnKVxuICAgICAqIEByZXR1cm4ge09uVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0U3RlZXJpbmdXaGVlbEFuZ2xlIChhbmdsZSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPblZlaGljbGVEYXRhLktFWV9TVEVFUklOR19XSEVFTF9BTkdMRSwgYW5nbGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0U3RlZXJpbmdXaGVlbEFuZ2xlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE9uVmVoaWNsZURhdGEuS0VZX1NURUVSSU5HX1dIRUVMX0FOR0xFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbGlmZSAtIFRoZSBlc3RpbWF0ZWQgcGVyY2VudGFnZSBvZiByZW1haW5pbmcgb2lsIGxpZmUgb2YgdGhlIGVuZ2luZS5cbiAgICAgKiBAcmV0dXJuIHtPblZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldEVuZ2luZU9pbExpZmUgKGxpZmUpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25WZWhpY2xlRGF0YS5LRVlfRU5HSU5FX09JTF9MSUZFLCBsaWZlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldEVuZ2luZU9pbExpZmUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoT25WZWhpY2xlRGF0YS5LRVlfRU5HSU5FX09JTF9MSUZFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0VsZWN0cm9uaWNQYXJrQnJha2VTdGF0dXN9IHN0YXR1cyAtIFRoZSBzdGF0dXMgb2YgdGhlIHBhcmsgYnJha2UgYXMgcHJvdmlkZWQgYnkgRWxlY3RyaWMgUGFyayBCcmFrZSAoRVBCKVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtLlxuICAgICAqIEByZXR1cm4ge09uVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0RWxlY3Ryb25pY1BhcmtCcmFrZVN0YXR1cyAoc3RhdHVzKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEVsZWN0cm9uaWNQYXJrQnJha2VTdGF0dXMsIHN0YXR1cyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uVmVoaWNsZURhdGEuS0VZX0VMRUNUUk9OSUNfUEFSS19CUkFLRV9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0VsZWN0cm9uaWNQYXJrQnJha2VTdGF0dXN9XG4gICAgICovXG4gICAgZ2V0RWxlY3Ryb25pY1BhcmtCcmFrZVN0YXR1cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChFbGVjdHJvbmljUGFya0JyYWtlU3RhdHVzLCBPblZlaGljbGVEYXRhLktFWV9FTEVDVFJPTklDX1BBUktfQlJBS0VfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gaWQgLSBQYXJhbWV0ZXIgdXNlZCBieSBjbG91ZCBhcHBzIHRvIGlkZW50aWZ5IGEgaGVhZCB1bml0XG4gICAgICogQHJldHVybiB7T25WZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRDbG91ZEFwcFZlaGljbGVJRCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25WZWhpY2xlRGF0YS5LRVlfQ0xPVURfQVBQX1ZFSElDTEVfSUQsIGlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIGdldENsb3VkQXBwVmVoaWNsZUlEICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE9uVmVoaWNsZURhdGEuS0VZX0NMT1VEX0FQUF9WRUhJQ0xFX0lEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0VDYWxsSW5mb30gaW5mbyAtIEVtZXJnZW5jeSBDYWxsIG5vdGlmaWNhdGlvbiBhbmQgY29uZmlybWF0aW9uIGRhdGFcbiAgICAgKiBAcmV0dXJuIHtPblZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldEVDYWxsSW5mbyAoaW5mbykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShFQ2FsbEluZm8sIGluZm8pO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPblZlaGljbGVEYXRhLktFWV9FX0NBTExfSU5GTywgaW5mbyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0VDYWxsSW5mb31cbiAgICAgKi9cbiAgICBnZXRFQ2FsbEluZm8gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoRUNhbGxJbmZvLCBPblZlaGljbGVEYXRhLktFWV9FX0NBTExfSU5GTyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtBaXJiYWdTdGF0dXN9IHN0YXR1cyAtIFRoZSBzdGF0dXMgb2YgdGhlIGFpciBiYWdzXG4gICAgICogQHJldHVybiB7T25WZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRBaXJiYWdTdGF0dXMgKHN0YXR1cykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShBaXJiYWdTdGF0dXMsIHN0YXR1cyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uVmVoaWNsZURhdGEuS0VZX0FJUkJBR19TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0FpcmJhZ1N0YXR1c31cbiAgICAgKi9cbiAgICBnZXRBaXJiYWdTdGF0dXMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoQWlyYmFnU3RhdHVzLCBPblZlaGljbGVEYXRhLktFWV9BSVJCQUdfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0VtZXJnZW5jeUV2ZW50fSBldmVudCAtIEluZm9ybWF0aW9uIHJlbGF0ZWQgdG8gYW4gZW1lcmdlbmN5IGV2ZW50IChhbmQgaWYgaXQgb2NjdXJyZWQpXG4gICAgICogQHJldHVybiB7T25WZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRFbWVyZ2VuY3lFdmVudCAoZXZlbnQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoRW1lcmdlbmN5RXZlbnQsIGV2ZW50KTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25WZWhpY2xlRGF0YS5LRVlfRU1FUkdFTkNZX0VWRU5ULCBldmVudCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0VtZXJnZW5jeUV2ZW50fVxuICAgICAqL1xuICAgIGdldEVtZXJnZW5jeUV2ZW50ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEVtZXJnZW5jeUV2ZW50LCBPblZlaGljbGVEYXRhLktFWV9FTUVSR0VOQ1lfRVZFTlQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Q2x1c3Rlck1vZGVTdGF0dXN9IHN0YXR1cyAtIFRoZSBzdGF0dXMgbW9kZXMgb2YgdGhlIGNsdXN0ZXJcbiAgICAgKiBAcmV0dXJuIHtPblZlaGljbGVEYXRhfVxuICAgICAqL1xuICAgIHNldENsdXN0ZXJNb2RlU3RhdHVzIChzdGF0dXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoQ2x1c3Rlck1vZGVTdGF0dXMsIHN0YXR1cyk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uVmVoaWNsZURhdGEuS0VZX0NMVVNURVJfTU9ERV9TVEFUVVMsIHN0YXR1cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0NsdXN0ZXJNb2RlU3RhdHVzfVxuICAgICAqL1xuICAgIGdldENsdXN0ZXJNb2RlU3RhdHVzICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KENsdXN0ZXJNb2RlU3RhdHVzLCBPblZlaGljbGVEYXRhLktFWV9DTFVTVEVSX01PREVfU1RBVFVTKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge015S2V5fSBrZXkgLSBJbmZvcm1hdGlvbiByZWxhdGVkIHRvIHRoZSBNeUtleSBmZWF0dXJlXG4gICAgICogQHJldHVybiB7T25WZWhpY2xlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRNeUtleSAoa2V5KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKE15S2V5LCBrZXkpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPblZlaGljbGVEYXRhLktFWV9NWV9LRVksIGtleSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge015S2V5fVxuICAgICAqL1xuICAgIGdldE15S2V5ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KE15S2V5LCBPblZlaGljbGVEYXRhLktFWV9NWV9LRVkpO1xuICAgIH1cbn1cblxuT25WZWhpY2xlRGF0YS5LRVlfR1BTID0gJ2dwcyc7XG5PblZlaGljbGVEYXRhLktFWV9TUEVFRCA9ICdzcGVlZCc7XG5PblZlaGljbGVEYXRhLktFWV9SUE0gPSAncnBtJztcbk9uVmVoaWNsZURhdGEuS0VZX0ZVRUxfTEVWRUwgPSAnZnVlbExldmVsJztcbk9uVmVoaWNsZURhdGEuS0VZX0ZVRUxfTEVWRUxfU1RBVEUgPSAnZnVlbExldmVsX1N0YXRlJztcbk9uVmVoaWNsZURhdGEuS0VZX0lOU1RBTlRfRlVFTF9DT05TVU1QVElPTiA9ICdpbnN0YW50RnVlbENvbnN1bXB0aW9uJztcbk9uVmVoaWNsZURhdGEuS0VZX0ZVRUxfUkFOR0UgPSAnZnVlbFJhbmdlJztcbk9uVmVoaWNsZURhdGEuS0VZX0VYVEVSTkFMX1RFTVBFUkFUVVJFID0gJ2V4dGVybmFsVGVtcGVyYXR1cmUnO1xuT25WZWhpY2xlRGF0YS5LRVlfVFVSTl9TSUdOQUwgPSAndHVyblNpZ25hbCc7XG5PblZlaGljbGVEYXRhLktFWV9WSU4gPSAndmluJztcbk9uVmVoaWNsZURhdGEuS0VZX1BSTkRMID0gJ3BybmRsJztcbk9uVmVoaWNsZURhdGEuS0VZX1RJUkVfUFJFU1NVUkUgPSAndGlyZVByZXNzdXJlJztcbk9uVmVoaWNsZURhdGEuS0VZX09ET01FVEVSID0gJ29kb21ldGVyJztcbk9uVmVoaWNsZURhdGEuS0VZX0JFTFRfU1RBVFVTID0gJ2JlbHRTdGF0dXMnO1xuT25WZWhpY2xlRGF0YS5LRVlfQk9EWV9JTkZPUk1BVElPTiA9ICdib2R5SW5mb3JtYXRpb24nO1xuT25WZWhpY2xlRGF0YS5LRVlfREVWSUNFX1NUQVRVUyA9ICdkZXZpY2VTdGF0dXMnO1xuT25WZWhpY2xlRGF0YS5LRVlfRFJJVkVSX0JSQUtJTkcgPSAnZHJpdmVyQnJha2luZyc7XG5PblZlaGljbGVEYXRhLktFWV9XSVBFUl9TVEFUVVMgPSAnd2lwZXJTdGF0dXMnO1xuT25WZWhpY2xlRGF0YS5LRVlfSEVBRF9MQU1QX1NUQVRVUyA9ICdoZWFkTGFtcFN0YXR1cyc7XG5PblZlaGljbGVEYXRhLktFWV9FTkdJTkVfVE9SUVVFID0gJ2VuZ2luZVRvcnF1ZSc7XG5PblZlaGljbGVEYXRhLktFWV9BQ0NfUEVEQUxfUE9TSVRJT04gPSAnYWNjUGVkYWxQb3NpdGlvbic7XG5PblZlaGljbGVEYXRhLktFWV9TVEVFUklOR19XSEVFTF9BTkdMRSA9ICdzdGVlcmluZ1doZWVsQW5nbGUnO1xuT25WZWhpY2xlRGF0YS5LRVlfRU5HSU5FX09JTF9MSUZFID0gJ2VuZ2luZU9pbExpZmUnO1xuT25WZWhpY2xlRGF0YS5LRVlfRUxFQ1RST05JQ19QQVJLX0JSQUtFX1NUQVRVUyA9ICdlbGVjdHJvbmljUGFya0JyYWtlU3RhdHVzJztcbk9uVmVoaWNsZURhdGEuS0VZX0NMT1VEX0FQUF9WRUhJQ0xFX0lEID0gJ2Nsb3VkQXBwVmVoaWNsZUlEJztcbk9uVmVoaWNsZURhdGEuS0VZX0VfQ0FMTF9JTkZPID0gJ2VDYWxsSW5mbyc7XG5PblZlaGljbGVEYXRhLktFWV9BSVJCQUdfU1RBVFVTID0gJ2FpcmJhZ1N0YXR1cyc7XG5PblZlaGljbGVEYXRhLktFWV9FTUVSR0VOQ1lfRVZFTlQgPSAnZW1lcmdlbmN5RXZlbnQnO1xuT25WZWhpY2xlRGF0YS5LRVlfQ0xVU1RFUl9NT0RFX1NUQVRVUyA9ICdjbHVzdGVyTW9kZVN0YXR1cyc7XG5PblZlaGljbGVEYXRhLktFWV9NWV9LRVkgPSAnbXlLZXknO1xuXG5leHBvcnQgeyBPblZlaGljbGVEYXRhIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgVHJpZ2dlclNvdXJjZSB9IGZyb20gJy4uL2VudW1zL1RyaWdnZXJTb3VyY2UuanMnO1xuaW1wb3J0IHsgUnBjTm90aWZpY2F0aW9uIH0gZnJvbSAnLi4vUnBjTm90aWZpY2F0aW9uLmpzJztcblxuY2xhc3MgT25Db21tYW5kIGV4dGVuZHMgUnBjTm90aWZpY2F0aW9uIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELk9uQ29tbWFuZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGlkIC0gQ29tbWFuZCBJRCwgd2hpY2ggaXMgcmVsYXRlZCB0byBhIHNwZWNpZmljIG1lbnUgZW50cnlcbiAgICAgKiBAcmV0dXJuIHtPbkNvbW1hbmR9XG4gICAgICovXG4gICAgc2V0Q21kSUQgKGlkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uQ29tbWFuZC5LRVlfQ01EX0lELCBpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRDbWRJRCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihPbkNvbW1hbmQuS0VZX0NNRF9JRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtUcmlnZ2VyU291cmNlfSBzb3VyY2UgLSBTZWUgVHJpZ2dlclNvdXJjZVxuICAgICAqIEByZXR1cm4ge09uQ29tbWFuZH1cbiAgICAgKi9cbiAgICBzZXRUcmlnZ2VyU291cmNlIChzb3VyY2UpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVHJpZ2dlclNvdXJjZSwgc291cmNlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25Db21tYW5kLktFWV9UUklHR0VSX1NPVVJDRSwgc291cmNlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VHJpZ2dlclNvdXJjZX1cbiAgICAgKi9cbiAgICBnZXRUcmlnZ2VyU291cmNlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFRyaWdnZXJTb3VyY2UsIE9uQ29tbWFuZC5LRVlfVFJJR0dFUl9TT1VSQ0UpO1xuICAgIH1cbn1cblxuT25Db21tYW5kLktFWV9DTURfSUQgPSAnY21kSUQnO1xuT25Db21tYW5kLktFWV9UUklHR0VSX1NPVVJDRSA9ICd0cmlnZ2VyU291cmNlJztcblxuZXhwb3J0IHsgT25Db21tYW5kIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogRW51bWVyYXRpb24gdGhhdCBkZXNjcmliZXMgcG9zc2libGUgc3RhdGVzIG9mIHR1cm4tYnktdHVybiBjbGllbnQgb3IgU21hcnREZXZpY2VMaW5rIGFwcC5cbiAqIEB0eXBlZGVmIHtFbnVtfSBUQlRTdGF0ZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgVEJUU3RhdGUgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUk9VVEVfVVBEQVRFX1JFUVVFU1QgKCkge1xuICAgICAgICByZXR1cm4gVEJUU3RhdGUuX01BUC5ST1VURV9VUERBVEVfUkVRVUVTVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBST1VURV9BQ0NFUFRFRCAoKSB7XG4gICAgICAgIHJldHVybiBUQlRTdGF0ZS5fTUFQLlJPVVRFX0FDQ0VQVEVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJPVVRFX1JFRlVTRUQgKCkge1xuICAgICAgICByZXR1cm4gVEJUU3RhdGUuX01BUC5ST1VURV9SRUZVU0VEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFJPVVRFX0NBTkNFTExFRCAoKSB7XG4gICAgICAgIHJldHVybiBUQlRTdGF0ZS5fTUFQLlJPVVRFX0NBTkNFTExFRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFVEFfUkVRVUVTVCAoKSB7XG4gICAgICAgIHJldHVybiBUQlRTdGF0ZS5fTUFQLkVUQV9SRVFVRVNUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5FWFRfVFVSTl9SRVFVRVNUICgpIHtcbiAgICAgICAgcmV0dXJuIFRCVFN0YXRlLl9NQVAuTkVYVF9UVVJOX1JFUVVFU1Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUk9VVEVfU1RBVFVTX1JFUVVFU1QgKCkge1xuICAgICAgICByZXR1cm4gVEJUU3RhdGUuX01BUC5ST1VURV9TVEFUVVNfUkVRVUVTVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBST1VURV9TVU1NQVJZX1JFUVVFU1QgKCkge1xuICAgICAgICByZXR1cm4gVEJUU3RhdGUuX01BUC5ST1VURV9TVU1NQVJZX1JFUVVFU1Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVFJJUF9TVEFUVVNfUkVRVUVTVCAoKSB7XG4gICAgICAgIHJldHVybiBUQlRTdGF0ZS5fTUFQLlRSSVBfU1RBVFVTX1JFUVVFU1Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUk9VVEVfVVBEQVRFX1JFUVVFU1RfVElNRU9VVCAoKSB7XG4gICAgICAgIHJldHVybiBUQlRTdGF0ZS5fTUFQLlJPVVRFX1VQREFURV9SRVFVRVNUX1RJTUVPVVQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gVEJUU3RhdGUuX3ZhbHVlRm9yS2V5KGtleSwgVEJUU3RhdGUuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBUQlRTdGF0ZS5fa2V5Rm9yVmFsdWUodmFsdWUsIFRCVFN0YXRlLl9NQVApO1xuICAgIH1cbn1cblxuVEJUU3RhdGUuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdST1VURV9VUERBVEVfUkVRVUVTVCc6ICdST1VURV9VUERBVEVfUkVRVUVTVCcsXG4gICAgJ1JPVVRFX0FDQ0VQVEVEJzogJ1JPVVRFX0FDQ0VQVEVEJyxcbiAgICAnUk9VVEVfUkVGVVNFRCc6ICdST1VURV9SRUZVU0VEJyxcbiAgICAnUk9VVEVfQ0FOQ0VMTEVEJzogJ1JPVVRFX0NBTkNFTExFRCcsXG4gICAgJ0VUQV9SRVFVRVNUJzogJ0VUQV9SRVFVRVNUJyxcbiAgICAnTkVYVF9UVVJOX1JFUVVFU1QnOiAnTkVYVF9UVVJOX1JFUVVFU1QnLFxuICAgICdST1VURV9TVEFUVVNfUkVRVUVTVCc6ICdST1VURV9TVEFUVVNfUkVRVUVTVCcsXG4gICAgJ1JPVVRFX1NVTU1BUllfUkVRVUVTVCc6ICdST1VURV9TVU1NQVJZX1JFUVVFU1QnLFxuICAgICdUUklQX1NUQVRVU19SRVFVRVNUJzogJ1RSSVBfU1RBVFVTX1JFUVVFU1QnLFxuICAgICdST1VURV9VUERBVEVfUkVRVUVTVF9USU1FT1VUJzogJ1JPVVRFX1VQREFURV9SRVFVRVNUX1RJTUVPVVQnLFxufSk7XG5cbmV4cG9ydCB7IFRCVFN0YXRlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgVEJUU3RhdGUgfSBmcm9tICcuLi9lbnVtcy9UQlRTdGF0ZS5qcyc7XG5pbXBvcnQgeyBScGNOb3RpZmljYXRpb24gfSBmcm9tICcuLi9ScGNOb3RpZmljYXRpb24uanMnO1xuXG4vKipcbiAqIFByb3ZpZGVzIGFwcGxpY2F0aW9ucyB3aXRoIG5vdGlmaWNhdGlvbnMgc3BlY2lmaWMgdG8gdGhlIGN1cnJlbnQgVEJUIGNsaWVudCBzdGF0dXMgb24gdGhlIG1vZHVsZVxuICovXG5jbGFzcyBPblRCVENsaWVudFN0YXRlIGV4dGVuZHMgUnBjTm90aWZpY2F0aW9uIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELk9uVEJUQ2xpZW50U3RhdGUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VEJUU3RhdGV9IHN0YXRlIC0gQ3VycmVudCBTdGF0ZSBvZiBUQlQgY2xpZW50XG4gICAgICogQHJldHVybiB7T25UQlRDbGllbnRTdGF0ZX1cbiAgICAgKi9cbiAgICBzZXRTdGF0ZSAoc3RhdGUpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoVEJUU3RhdGUsIHN0YXRlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25UQlRDbGllbnRTdGF0ZS5LRVlfU1RBVEUsIHN0YXRlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VEJUU3RhdGV9XG4gICAgICovXG4gICAgZ2V0U3RhdGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVEJUU3RhdGUsIE9uVEJUQ2xpZW50U3RhdGUuS0VZX1NUQVRFKTtcbiAgICB9XG59XG5cbk9uVEJUQ2xpZW50U3RhdGUuS0VZX1NUQVRFID0gJ3N0YXRlJztcblxuZXhwb3J0IHsgT25UQlRDbGllbnRTdGF0ZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEVudW1lcmF0aW9uIHRoYXQgZGVzY3JpYmVzIHBvc3NpYmxlIHN0YXRlcyBvZiBkcml2ZXIgZGlzdHJhY3Rpb24uXG4gKiBAdHlwZWRlZiB7RW51bX0gRHJpdmVyRGlzdHJhY3Rpb25TdGF0ZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgRHJpdmVyRGlzdHJhY3Rpb25TdGF0ZSBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBERF9PTiAoKSB7XG4gICAgICAgIHJldHVybiBEcml2ZXJEaXN0cmFjdGlvblN0YXRlLl9NQVAuRERfT047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRERfT0ZGICgpIHtcbiAgICAgICAgcmV0dXJuIERyaXZlckRpc3RyYWN0aW9uU3RhdGUuX01BUC5ERF9PRkY7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gRHJpdmVyRGlzdHJhY3Rpb25TdGF0ZS5fdmFsdWVGb3JLZXkoa2V5LCBEcml2ZXJEaXN0cmFjdGlvblN0YXRlLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gRHJpdmVyRGlzdHJhY3Rpb25TdGF0ZS5fa2V5Rm9yVmFsdWUodmFsdWUsIERyaXZlckRpc3RyYWN0aW9uU3RhdGUuX01BUCk7XG4gICAgfVxufVxuXG5Ecml2ZXJEaXN0cmFjdGlvblN0YXRlLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnRERfT04nOiAnRERfT04nLFxuICAgICdERF9PRkYnOiAnRERfT0ZGJyxcbn0pO1xuXG5leHBvcnQgeyBEcml2ZXJEaXN0cmFjdGlvblN0YXRlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRHJpdmVyRGlzdHJhY3Rpb25TdGF0ZSB9IGZyb20gJy4uL2VudW1zL0RyaXZlckRpc3RyYWN0aW9uU3RhdGUuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUnBjTm90aWZpY2F0aW9uIH0gZnJvbSAnLi4vUnBjTm90aWZpY2F0aW9uLmpzJztcblxuLyoqXG4gKiBQcm92aWRlcyBkcml2ZXIgZGlzdHJhY3Rpb24gc3RhdGUgdG8gbW9iaWxlIGFwcGxpY2F0aW9uc1xuICovXG5jbGFzcyBPbkRyaXZlckRpc3RyYWN0aW9uIGV4dGVuZHMgUnBjTm90aWZpY2F0aW9uIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELk9uRHJpdmVyRGlzdHJhY3Rpb24pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RHJpdmVyRGlzdHJhY3Rpb25TdGF0ZX0gc3RhdGUgLSBDdXJyZW50IFN0YXRlIG9mIERyaXZlciBEaXN0cmFjdGlvblxuICAgICAqIEByZXR1cm4ge09uRHJpdmVyRGlzdHJhY3Rpb259XG4gICAgICovXG4gICAgc2V0U3RhdGUgKHN0YXRlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKERyaXZlckRpc3RyYWN0aW9uU3RhdGUsIHN0YXRlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25Ecml2ZXJEaXN0cmFjdGlvbi5LRVlfU1RBVEUsIHN0YXRlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7RHJpdmVyRGlzdHJhY3Rpb25TdGF0ZX1cbiAgICAgKi9cbiAgICBnZXRTdGF0ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChEcml2ZXJEaXN0cmFjdGlvblN0YXRlLCBPbkRyaXZlckRpc3RyYWN0aW9uLktFWV9TVEFURSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBlbmFibGVkIC0gSWYgZW5hYmxlZCwgdGhlIGxvY2sgc2NyZWVuIHdpbGwgYmUgYWJsZSB0byBiZSBkaXNtaXNzZWQgd2hpbGUgY29ubmVjdGVkIHRvIFNETCxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGxvd2luZyB1c2VycyB0aGUgYWJpbGl0eSB0byBpbnRlcmFjdCB3aXRoIHRoZSBhcHAuIERpc21pc3NhbHMgc2hvdWxkIGluY2x1ZGUgYVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgdG8gdGhlIHVzZXIgYW5kIGVuc3VyZSB0aGF0IHRoZXkgYXJlIG5vdCB0aGUgZHJpdmVyLlxuICAgICAqIEByZXR1cm4ge09uRHJpdmVyRGlzdHJhY3Rpb259XG4gICAgICovXG4gICAgc2V0TG9ja1NjcmVlbkRpc21pc3NhbEVuYWJsZWQgKGVuYWJsZWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25Ecml2ZXJEaXN0cmFjdGlvbi5LRVlfTE9DS19TQ1JFRU5fRElTTUlTU0FMX0VOQUJMRUQsIGVuYWJsZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldExvY2tTY3JlZW5EaXNtaXNzYWxFbmFibGVkICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE9uRHJpdmVyRGlzdHJhY3Rpb24uS0VZX0xPQ0tfU0NSRUVOX0RJU01JU1NBTF9FTkFCTEVEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gd2FybmluZyAtIFdhcm5pbmcgbWVzc2FnZSB0byBiZSBkaXNwbGF5ZWQgb24gdGhlIGxvY2sgc2NyZWVuIHdoZW4gZGlzbWlzc2FsIGlzIGVuYWJsZWQuIFRoaXNcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgc2hvdWxkIGJlIHVzZWQgdG8gZW5zdXJlIHRoYXQgdGhlIHVzZXIgaXMgbm90IHRoZSBkcml2ZXIgb2YgdGhlIHZlaGljbGUsIGV4LlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgYFN3aXBlIGRvd24gdG8gZGlzbWlzcywgYWNrbm93bGVkZ2luZyB0aGF0IHlvdSBhcmUgbm90IHRoZSBkcml2ZXIuYC4gVGhpcyBwYXJhbWV0ZXJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIG11c3QgYmUgcHJlc2VudCBpZiBcImxvY2tTY3JlZW5EaXNtaXNzYWxFbmFibGVkXCIgaXMgc2V0IHRvIHRydWUuXG4gICAgICogQHJldHVybiB7T25Ecml2ZXJEaXN0cmFjdGlvbn1cbiAgICAgKi9cbiAgICBzZXRMb2NrU2NyZWVuRGlzbWlzc2FsV2FybmluZyAod2FybmluZykge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPbkRyaXZlckRpc3RyYWN0aW9uLktFWV9MT0NLX1NDUkVFTl9ESVNNSVNTQUxfV0FSTklORywgd2FybmluZyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRMb2NrU2NyZWVuRGlzbWlzc2FsV2FybmluZyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihPbkRyaXZlckRpc3RyYWN0aW9uLktFWV9MT0NLX1NDUkVFTl9ESVNNSVNTQUxfV0FSTklORyk7XG4gICAgfVxufVxuXG5PbkRyaXZlckRpc3RyYWN0aW9uLktFWV9TVEFURSA9ICdzdGF0ZSc7XG5PbkRyaXZlckRpc3RyYWN0aW9uLktFWV9MT0NLX1NDUkVFTl9ESVNNSVNTQUxfRU5BQkxFRCA9ICdsb2NrU2NyZWVuRGlzbWlzc2FsRW5hYmxlZCc7XG5PbkRyaXZlckRpc3RyYWN0aW9uLktFWV9MT0NLX1NDUkVFTl9ESVNNSVNTQUxfV0FSTklORyA9ICdsb2NrU2NyZWVuRGlzbWlzc2FsV2FybmluZyc7XG5cbmV4cG9ydCB7IE9uRHJpdmVyRGlzdHJhY3Rpb24gfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBITUlMZXZlbCB9IGZyb20gJy4uL2VudW1zL0hNSUxldmVsLmpzJztcbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5cbmNsYXNzIEhNSVBlcm1pc3Npb25zIGV4dGVuZHMgUnBjU3RydWN0IHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAocGFyYW1ldGVycykge1xuICAgICAgICBzdXBlcihwYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0hNSUxldmVsW119IGFsbG93ZWQgLSBBIHNldCBvZiBhbGwgSE1JIGxldmVscyB0aGF0IGFyZSBwZXJtaXR0ZWQgZm9yIHRoaXMgZ2l2ZW4gUlBDLlxuICAgICAqIEByZXR1cm4ge0hNSVBlcm1pc3Npb25zfVxuICAgICAqL1xuICAgIHNldEFsbG93ZWQgKGFsbG93ZWQpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoSE1JTGV2ZWwsIGFsbG93ZWQsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihITUlQZXJtaXNzaW9ucy5LRVlfQUxMT1dFRCwgYWxsb3dlZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0hNSUxldmVsW119XG4gICAgICovXG4gICAgZ2V0QWxsb3dlZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChITUlMZXZlbCwgSE1JUGVybWlzc2lvbnMuS0VZX0FMTE9XRUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7SE1JTGV2ZWxbXX0gZGlzYWxsb3dlZCAtIEEgc2V0IG9mIGFsbCBITUkgbGV2ZWxzIHRoYXQgYXJlIHByb2hpYml0ZWQgZm9yIHRoaXMgZ2l2ZW4gUlBDLlxuICAgICAqIEByZXR1cm4ge0hNSVBlcm1pc3Npb25zfVxuICAgICAqL1xuICAgIHNldFVzZXJEaXNhbGxvd2VkIChkaXNhbGxvd2VkKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEhNSUxldmVsLCBkaXNhbGxvd2VkLCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoSE1JUGVybWlzc2lvbnMuS0VZX1VTRVJfRElTQUxMT1dFRCwgZGlzYWxsb3dlZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0hNSUxldmVsW119XG4gICAgICovXG4gICAgZ2V0VXNlckRpc2FsbG93ZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoSE1JTGV2ZWwsIEhNSVBlcm1pc3Npb25zLktFWV9VU0VSX0RJU0FMTE9XRUQpO1xuICAgIH1cbn1cblxuSE1JUGVybWlzc2lvbnMuS0VZX0FMTE9XRUQgPSAnYWxsb3dlZCc7XG5ITUlQZXJtaXNzaW9ucy5LRVlfVVNFUl9ESVNBTExPV0VEID0gJ3VzZXJEaXNhbGxvd2VkJztcblxuZXhwb3J0IHsgSE1JUGVybWlzc2lvbnMgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBScGNTdHJ1Y3QgfSBmcm9tICcuLi9ScGNTdHJ1Y3QuanMnO1xuXG5jbGFzcyBQYXJhbWV0ZXJQZXJtaXNzaW9ucyBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmdbXX0gYWxsb3dlZCAtIEEgc2V0IG9mIGFsbCBwYXJhbWV0ZXJzIHRoYXQgYXJlIHBlcm1pdHRlZCBmb3IgdGhpcyBnaXZlbiBSUEMuXG4gICAgICogQHJldHVybiB7UGFyYW1ldGVyUGVybWlzc2lvbnN9XG4gICAgICovXG4gICAgc2V0QWxsb3dlZCAoYWxsb3dlZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihQYXJhbWV0ZXJQZXJtaXNzaW9ucy5LRVlfQUxMT1dFRCwgYWxsb3dlZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ1tdfVxuICAgICAqL1xuICAgIGdldEFsbG93ZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUGFyYW1ldGVyUGVybWlzc2lvbnMuS0VZX0FMTE9XRUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nW119IGRpc2FsbG93ZWQgLSBBIHNldCBvZiBhbGwgcGFyYW1ldGVycyB0aGF0IGFyZSBwcm9oaWJpdGVkIGZvciB0aGlzIGdpdmVuIFJQQy5cbiAgICAgKiBAcmV0dXJuIHtQYXJhbWV0ZXJQZXJtaXNzaW9uc31cbiAgICAgKi9cbiAgICBzZXRVc2VyRGlzYWxsb3dlZCAoZGlzYWxsb3dlZCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihQYXJhbWV0ZXJQZXJtaXNzaW9ucy5LRVlfVVNFUl9ESVNBTExPV0VELCBkaXNhbGxvd2VkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nW119XG4gICAgICovXG4gICAgZ2V0VXNlckRpc2FsbG93ZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUGFyYW1ldGVyUGVybWlzc2lvbnMuS0VZX1VTRVJfRElTQUxMT1dFRCk7XG4gICAgfVxufVxuXG5QYXJhbWV0ZXJQZXJtaXNzaW9ucy5LRVlfQUxMT1dFRCA9ICdhbGxvd2VkJztcblBhcmFtZXRlclBlcm1pc3Npb25zLktFWV9VU0VSX0RJU0FMTE9XRUQgPSAndXNlckRpc2FsbG93ZWQnO1xuXG5leHBvcnQgeyBQYXJhbWV0ZXJQZXJtaXNzaW9ucyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBITUlQZXJtaXNzaW9ucyB9IGZyb20gJy4vSE1JUGVybWlzc2lvbnMuanMnO1xuaW1wb3J0IHsgUGFyYW1ldGVyUGVybWlzc2lvbnMgfSBmcm9tICcuL1BhcmFtZXRlclBlcm1pc3Npb25zLmpzJztcblxuY2xhc3MgUGVybWlzc2lvbkl0ZW0gZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIC0gTmFtZSBvZiB0aGUgaW5kaXZpZHVhbCBSUEMgaW4gdGhlIHBvbGljeSB0YWJsZS5cbiAgICAgKiBAcmV0dXJuIHtQZXJtaXNzaW9uSXRlbX1cbiAgICAgKi9cbiAgICBzZXRScGNOYW1lIChuYW1lKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFBlcm1pc3Npb25JdGVtLktFWV9SUENfTkFNRSwgbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRScGNOYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKFBlcm1pc3Npb25JdGVtLktFWV9SUENfTkFNRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtITUlQZXJtaXNzaW9uc30gcGVybWlzc2lvbnNcbiAgICAgKiBAcmV0dXJuIHtQZXJtaXNzaW9uSXRlbX1cbiAgICAgKi9cbiAgICBzZXRIbWlQZXJtaXNzaW9ucyAocGVybWlzc2lvbnMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoSE1JUGVybWlzc2lvbnMsIHBlcm1pc3Npb25zKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUGVybWlzc2lvbkl0ZW0uS0VZX0hNSV9QRVJNSVNTSU9OUywgcGVybWlzc2lvbnMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtITUlQZXJtaXNzaW9uc31cbiAgICAgKi9cbiAgICBnZXRIbWlQZXJtaXNzaW9ucyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChITUlQZXJtaXNzaW9ucywgUGVybWlzc2lvbkl0ZW0uS0VZX0hNSV9QRVJNSVNTSU9OUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtQYXJhbWV0ZXJQZXJtaXNzaW9uc30gcGVybWlzc2lvbnNcbiAgICAgKiBAcmV0dXJuIHtQZXJtaXNzaW9uSXRlbX1cbiAgICAgKi9cbiAgICBzZXRQYXJhbWV0ZXJQZXJtaXNzaW9ucyAocGVybWlzc2lvbnMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoUGFyYW1ldGVyUGVybWlzc2lvbnMsIHBlcm1pc3Npb25zKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUGVybWlzc2lvbkl0ZW0uS0VZX1BBUkFNRVRFUl9QRVJNSVNTSU9OUywgcGVybWlzc2lvbnMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtQYXJhbWV0ZXJQZXJtaXNzaW9uc31cbiAgICAgKi9cbiAgICBnZXRQYXJhbWV0ZXJQZXJtaXNzaW9ucyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChQYXJhbWV0ZXJQZXJtaXNzaW9ucywgUGVybWlzc2lvbkl0ZW0uS0VZX1BBUkFNRVRFUl9QRVJNSVNTSU9OUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBlbmNyeXB0aW9uXG4gICAgICogQHJldHVybiB7UGVybWlzc2lvbkl0ZW19XG4gICAgICovXG4gICAgc2V0UmVxdWlyZUVuY3J5cHRpb24gKGVuY3J5cHRpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoUGVybWlzc2lvbkl0ZW0uS0VZX1JFUVVJUkVfRU5DUllQVElPTiwgZW5jcnlwdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0UmVxdWlyZUVuY3J5cHRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoUGVybWlzc2lvbkl0ZW0uS0VZX1JFUVVJUkVfRU5DUllQVElPTik7XG4gICAgfVxufVxuXG5QZXJtaXNzaW9uSXRlbS5LRVlfUlBDX05BTUUgPSAncnBjTmFtZSc7XG5QZXJtaXNzaW9uSXRlbS5LRVlfSE1JX1BFUk1JU1NJT05TID0gJ2htaVBlcm1pc3Npb25zJztcblBlcm1pc3Npb25JdGVtLktFWV9QQVJBTUVURVJfUEVSTUlTU0lPTlMgPSAncGFyYW1ldGVyUGVybWlzc2lvbnMnO1xuUGVybWlzc2lvbkl0ZW0uS0VZX1JFUVVJUkVfRU5DUllQVElPTiA9ICdyZXF1aXJlRW5jcnlwdGlvbic7XG5cbmV4cG9ydCB7IFBlcm1pc3Npb25JdGVtIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUGVybWlzc2lvbkl0ZW0gfSBmcm9tICcuLi9zdHJ1Y3RzL1Blcm1pc3Npb25JdGVtLmpzJztcbmltcG9ydCB7IFJwY05vdGlmaWNhdGlvbiB9IGZyb20gJy4uL1JwY05vdGlmaWNhdGlvbi5qcyc7XG5cbi8qKlxuICogUHJvdmlkZXMgdXBkYXRlIHRvIGFwcCBvZiB3aGljaCBwb2xpY3ktdGFibGUtZW5hYmxlZCBmdW5jdGlvbnMgYXJlIGF2YWlsYWJsZVxuICovXG5jbGFzcyBPblBlcm1pc3Npb25zQ2hhbmdlIGV4dGVuZHMgUnBjTm90aWZpY2F0aW9uIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELk9uUGVybWlzc2lvbnNDaGFuZ2UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7UGVybWlzc2lvbkl0ZW1bXX0gaXRlbSAtIENoYW5nZSBpbiBwZXJtaXNzaW9ucyBmb3IgYSBnaXZlbiBzZXQgb2YgUlBDc1xuICAgICAqIEByZXR1cm4ge09uUGVybWlzc2lvbnNDaGFuZ2V9XG4gICAgICovXG4gICAgc2V0UGVybWlzc2lvbkl0ZW0gKGl0ZW0pIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoUGVybWlzc2lvbkl0ZW0sIGl0ZW0sIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPblBlcm1pc3Npb25zQ2hhbmdlLktFWV9QRVJNSVNTSU9OX0lURU0sIGl0ZW0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtQZXJtaXNzaW9uSXRlbVtdfVxuICAgICAqL1xuICAgIGdldFBlcm1pc3Npb25JdGVtICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFBlcm1pc3Npb25JdGVtLCBPblBlcm1pc3Npb25zQ2hhbmdlLktFWV9QRVJNSVNTSU9OX0lURU0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gZW5jcnlwdGlvblxuICAgICAqIEByZXR1cm4ge09uUGVybWlzc2lvbnNDaGFuZ2V9XG4gICAgICovXG4gICAgc2V0UmVxdWlyZUVuY3J5cHRpb24gKGVuY3J5cHRpb24pIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25QZXJtaXNzaW9uc0NoYW5nZS5LRVlfUkVRVUlSRV9FTkNSWVBUSU9OLCBlbmNyeXB0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXRSZXF1aXJlRW5jcnlwdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihPblBlcm1pc3Npb25zQ2hhbmdlLktFWV9SRVFVSVJFX0VOQ1JZUFRJT04pO1xuICAgIH1cbn1cblxuT25QZXJtaXNzaW9uc0NoYW5nZS5LRVlfUEVSTUlTU0lPTl9JVEVNID0gJ3Blcm1pc3Npb25JdGVtJztcbk9uUGVybWlzc2lvbnNDaGFuZ2UuS0VZX1JFUVVJUkVfRU5DUllQVElPTiA9ICdyZXF1aXJlRW5jcnlwdGlvbic7XG5cbmV4cG9ydCB7IE9uUGVybWlzc2lvbnNDaGFuZ2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBScGNOb3RpZmljYXRpb24gfSBmcm9tICcuLi9ScGNOb3RpZmljYXRpb24uanMnO1xuXG4vKipcbiAqIEJpbmFyeSBkYXRhIGlzIGluIGJpbmFyeSBwYXJ0IG9mIGh5YnJpZCBtc2dcbiAqL1xuY2xhc3MgT25BdWRpb1Bhc3NUaHJ1IGV4dGVuZHMgUnBjTm90aWZpY2F0aW9uIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELk9uQXVkaW9QYXNzVGhydSk7XG4gICAgfVxufVxuXG5cbmV4cG9ydCB7IE9uQXVkaW9QYXNzVGhydSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IExhbmd1YWdlIH0gZnJvbSAnLi4vZW51bXMvTGFuZ3VhZ2UuanMnO1xuaW1wb3J0IHsgUnBjTm90aWZpY2F0aW9uIH0gZnJvbSAnLi4vUnBjTm90aWZpY2F0aW9uLmpzJztcblxuY2xhc3MgT25MYW5ndWFnZUNoYW5nZSBleHRlbmRzIFJwY05vdGlmaWNhdGlvbiB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5Pbkxhbmd1YWdlQ2hhbmdlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0xhbmd1YWdlfSBsYW5ndWFnZSAtIEN1cnJlbnQgU0RMIHZvaWNlIGVuZ2luZSAoVlIrVFRTKSBsYW5ndWFnZVxuICAgICAqIEByZXR1cm4ge09uTGFuZ3VhZ2VDaGFuZ2V9XG4gICAgICovXG4gICAgc2V0TGFuZ3VhZ2UgKGxhbmd1YWdlKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKExhbmd1YWdlLCBsYW5ndWFnZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uTGFuZ3VhZ2VDaGFuZ2UuS0VZX0xBTkdVQUdFLCBsYW5ndWFnZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0xhbmd1YWdlfVxuICAgICAqL1xuICAgIGdldExhbmd1YWdlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KExhbmd1YWdlLCBPbkxhbmd1YWdlQ2hhbmdlLktFWV9MQU5HVUFHRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBDdXJyZW50IGRpc3BsYXkgbGFuZ3VhZ2VcbiAgICAgKiBAcmV0dXJuIHtPbkxhbmd1YWdlQ2hhbmdlfVxuICAgICAqL1xuICAgIHNldEhtaURpc3BsYXlMYW5ndWFnZSAobGFuZ3VhZ2UpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTGFuZ3VhZ2UsIGxhbmd1YWdlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25MYW5ndWFnZUNoYW5nZS5LRVlfSE1JX0RJU1BMQVlfTEFOR1VBR0UsIGxhbmd1YWdlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TGFuZ3VhZ2V9XG4gICAgICovXG4gICAgZ2V0SG1pRGlzcGxheUxhbmd1YWdlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KExhbmd1YWdlLCBPbkxhbmd1YWdlQ2hhbmdlLktFWV9ITUlfRElTUExBWV9MQU5HVUFHRSk7XG4gICAgfVxufVxuXG5Pbkxhbmd1YWdlQ2hhbmdlLktFWV9MQU5HVUFHRSA9ICdsYW5ndWFnZSc7XG5Pbkxhbmd1YWdlQ2hhbmdlLktFWV9ITUlfRElTUExBWV9MQU5HVUFHRSA9ICdobWlEaXNwbGF5TGFuZ3VhZ2UnO1xuXG5leHBvcnQgeyBPbkxhbmd1YWdlQ2hhbmdlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogRW51bWVyYXRpb24gbGlzdGluZyBwb3NzaWJsZSBrZXlib2FyZCBldmVudHMuXG4gKiBAdHlwZWRlZiB7RW51bX0gS2V5Ym9hcmRFdmVudFxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgS2V5Ym9hcmRFdmVudCBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBLRVlQUkVTUyAoKSB7XG4gICAgICAgIHJldHVybiBLZXlib2FyZEV2ZW50Ll9NQVAuS0VZUFJFU1M7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRU5UUllfU1VCTUlUVEVEICgpIHtcbiAgICAgICAgcmV0dXJuIEtleWJvYXJkRXZlbnQuX01BUC5FTlRSWV9TVUJNSVRURUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRU5UUllfVk9JQ0UgKCkge1xuICAgICAgICByZXR1cm4gS2V5Ym9hcmRFdmVudC5fTUFQLkVOVFJZX1ZPSUNFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEVOVFJZX0NBTkNFTExFRCAoKSB7XG4gICAgICAgIHJldHVybiBLZXlib2FyZEV2ZW50Ll9NQVAuRU5UUllfQ0FOQ0VMTEVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEVOVFJZX0FCT1JURUQgKCkge1xuICAgICAgICByZXR1cm4gS2V5Ym9hcmRFdmVudC5fTUFQLkVOVFJZX0FCT1JURUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gS2V5Ym9hcmRFdmVudC5fdmFsdWVGb3JLZXkoa2V5LCBLZXlib2FyZEV2ZW50Ll9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gS2V5Ym9hcmRFdmVudC5fa2V5Rm9yVmFsdWUodmFsdWUsIEtleWJvYXJkRXZlbnQuX01BUCk7XG4gICAgfVxufVxuXG5LZXlib2FyZEV2ZW50Ll9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnS0VZUFJFU1MnOiAnS0VZUFJFU1MnLFxuICAgICdFTlRSWV9TVUJNSVRURUQnOiAnRU5UUllfU1VCTUlUVEVEJyxcbiAgICAnRU5UUllfVk9JQ0UnOiAnRU5UUllfVk9JQ0UnLFxuICAgICdFTlRSWV9DQU5DRUxMRUQnOiAnRU5UUllfQ0FOQ0VMTEVEJyxcbiAgICAnRU5UUllfQUJPUlRFRCc6ICdFTlRSWV9BQk9SVEVEJyxcbn0pO1xuXG5leHBvcnQgeyBLZXlib2FyZEV2ZW50IH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgS2V5Ym9hcmRFdmVudCB9IGZyb20gJy4uL2VudW1zL0tleWJvYXJkRXZlbnQuanMnO1xuaW1wb3J0IHsgUnBjTm90aWZpY2F0aW9uIH0gZnJvbSAnLi4vUnBjTm90aWZpY2F0aW9uLmpzJztcblxuLyoqXG4gKiBPbi1zY3JlZW4ga2V5Ym9hcmQgZXZlbnQuIENhbiBiZSBmdWxsIHN0cmluZyBvciBpbmRpdmlkdWFsIGtleXByZXNzZXMgZGVwZW5kaW5nIG9uIGtleWJvYXJkIG1vZGUuXG4gKi9cbmNsYXNzIE9uS2V5Ym9hcmRJbnB1dCBleHRlbmRzIFJwY05vdGlmaWNhdGlvbiB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5PbktleWJvYXJkSW5wdXQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7S2V5Ym9hcmRFdmVudH0gZXZlbnQgLSBPbi1zY3JlZW4ga2V5Ym9hcmQgaW5wdXQgZGF0YS5cbiAgICAgKiBAcmV0dXJuIHtPbktleWJvYXJkSW5wdXR9XG4gICAgICovXG4gICAgc2V0RXZlbnQgKGV2ZW50KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKEtleWJvYXJkRXZlbnQsIGV2ZW50KTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25LZXlib2FyZElucHV0LktFWV9FVkVOVCwgZXZlbnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtLZXlib2FyZEV2ZW50fVxuICAgICAqL1xuICAgIGdldEV2ZW50ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEtleWJvYXJkRXZlbnQsIE9uS2V5Ym9hcmRJbnB1dC5LRVlfRVZFTlQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIC0gT24tc2NyZWVuIGtleWJvYXJkIGlucHV0IGRhdGEuIEZvciBkeW5hbWljIGtleXByZXNzIGV2ZW50cywgdGhpcyB3aWxsIGJlIHRoZSBjdXJyZW50XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICBjb21wb3VuZGVkIHN0cmluZyBvZiBlbnRyeSB0ZXh0LiBGb3IgZW50cnkgc3VibWlzc2lvbiBldmVudHMsIHRoaXMgd2lsbCBiZSB0aGUgZnVsbCB0ZXh0XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICBlbnRyeSAodGhpcyB3aWxsIGFsd2F5cyByZXR1cm4gcmVnYXJkbGVzcyBvZiB0aGUgbW9kZSkuIEZvciBlbnRyeSBjYW5jZWxsZWQgYW5kIGVudHJ5XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICBhYm9ydGVkIGV2ZW50cywgdGhpcyBkYXRhIHBhcmFtIHdpbGwgYmUgb21pdHRlZC5cbiAgICAgKiBAcmV0dXJuIHtPbktleWJvYXJkSW5wdXR9XG4gICAgICovXG4gICAgc2V0RGF0YSAoZGF0YSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPbktleWJvYXJkSW5wdXQuS0VZX0RBVEEsIGRhdGEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0RGF0YSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihPbktleWJvYXJkSW5wdXQuS0VZX0RBVEEpO1xuICAgIH1cbn1cblxuT25LZXlib2FyZElucHV0LktFWV9FVkVOVCA9ICdldmVudCc7XG5PbktleWJvYXJkSW5wdXQuS0VZX0RBVEEgPSAnZGF0YSc7XG5cbmV4cG9ydCB7IE9uS2V5Ym9hcmRJbnB1dCB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5cbmNsYXNzIFRvdWNoQ29vcmQgZXh0ZW5kcyBScGNTdHJ1Y3Qge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHN1cGVyKHBhcmFtZXRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IC0gVGhlIHggY29vcmRpbmF0ZSBvZiB0aGUgdG91Y2guXG4gICAgICogQHJldHVybiB7VG91Y2hDb29yZH1cbiAgICAgKi9cbiAgICBzZXRYICh4KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFRvdWNoQ29vcmQuS0VZX1gsIHgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0WCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihUb3VjaENvb3JkLktFWV9YKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geSAtIFRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHRvdWNoLlxuICAgICAqIEByZXR1cm4ge1RvdWNoQ29vcmR9XG4gICAgICovXG4gICAgc2V0WSAoeSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihUb3VjaENvb3JkLktFWV9ZLCB5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFkgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoVG91Y2hDb29yZC5LRVlfWSk7XG4gICAgfVxufVxuXG5Ub3VjaENvb3JkLktFWV9YID0gJ3gnO1xuVG91Y2hDb29yZC5LRVlfWSA9ICd5JztcblxuZXhwb3J0IHsgVG91Y2hDb29yZCB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFJwY1N0cnVjdCB9IGZyb20gJy4uL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBUb3VjaENvb3JkIH0gZnJvbSAnLi9Ub3VjaENvb3JkLmpzJztcblxuY2xhc3MgVG91Y2hFdmVudCBleHRlbmRzIFJwY1N0cnVjdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgc3VwZXIocGFyYW1ldGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGlkIC0gQSB0b3VjaCdzIHVuaXF1ZSBpZGVudGlmaWVyLiBUaGUgYXBwbGljYXRpb24gY2FuIHRyYWNrIHRoZSBjdXJyZW50IHRvdWNoIGV2ZW50cyBieSBpZC4gSWYgYVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIHRvdWNoIGV2ZW50IGhhcyB0eXBlIGJlZ2luLCB0aGUgaWQgc2hvdWxkIGJlIGFkZGVkIHRvIHRoZSBzZXQgb2YgdG91Y2hlcy4gSWYgYSB0b3VjaCBldmVudFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIGhhcyB0eXBlIGVuZCwgdGhlIGlkIHNob3VsZCBiZSByZW1vdmVkIGZyb20gdGhlIHNldCBvZiB0b3VjaGVzLlxuICAgICAqIEByZXR1cm4ge1RvdWNoRXZlbnR9XG4gICAgICovXG4gICAgc2V0SWQgKGlkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKFRvdWNoRXZlbnQuS0VZX0lELCBpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRJZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihUb3VjaEV2ZW50LktFWV9JRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtOdW1iZXJbXX0gdHMgLSBUaGUgdGltZSB0aGF0IHRoZSB0b3VjaCB3YXMgcmVjb3JkZWQuIFRoaXMgbnVtYmVyIGNhbiB0aGUgdGltZSBzaW5jZSB0aGUgYmVnaW5uaW5nIG9mIHRoZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbiBvciBzb21ldGhpbmcgZWxzZSBhcyBsb25nIGFzIHRoZSB1bml0cyBhcmUgaW4gbWlsbGlzZWNvbmRzLiBUaGUgdGltZXN0YW1wIGlzIHVzZWRcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHRvIGRldGVybWluZWQgdGhlIHJhdGUgb2YgY2hhbmdlIG9mIHBvc2l0aW9uIG9mIGEgdG91Y2guIFRoZSBhcHBsaWNhdGlvbiBhbHNvIHVzZXMgdGhlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICB0aW1lIHRvIHZlcmlmeSB3aGV0aGVyIHR3byB0b3VjaGVzLCB3aXRoIGRpZmZlcmVudCBpZHMsIGFyZSBwYXJ0IG9mIGEgc2luZ2xlIGFjdGlvbiBieSB0aGVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHVzZXIuIElmIHRoZXJlIGlzIG9ubHkgYSBzaW5nbGUgdGltZXN0YW1wIGluIHRoaXMgYXJyYXksIGl0IGlzIHRoZSBzYW1lIGZvciBldmVyeVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgY29vcmRpbmF0ZSBpbiB0aGUgY29vcmRpbmF0ZXMgYXJyYXkuXG4gICAgICogQHJldHVybiB7VG91Y2hFdmVudH1cbiAgICAgKi9cbiAgICBzZXRUcyAodHMpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoVG91Y2hFdmVudC5LRVlfVFMsIHRzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyW119XG4gICAgICovXG4gICAgZ2V0VHMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoVG91Y2hFdmVudC5LRVlfVFMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VG91Y2hDb29yZFtdfSBjXG4gICAgICogQHJldHVybiB7VG91Y2hFdmVudH1cbiAgICAgKi9cbiAgICBzZXRDIChjKSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVUeXBlKFRvdWNoQ29vcmQsIGMsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihUb3VjaEV2ZW50LktFWV9DLCBjKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VG91Y2hDb29yZFtdfVxuICAgICAqL1xuICAgIGdldEMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoVG91Y2hDb29yZCwgVG91Y2hFdmVudC5LRVlfQyk7XG4gICAgfVxufVxuXG5Ub3VjaEV2ZW50LktFWV9JRCA9ICdpZCc7XG5Ub3VjaEV2ZW50LktFWV9UUyA9ICd0cyc7XG5Ub3VjaEV2ZW50LktFWV9DID0gJ2MnO1xuXG5leHBvcnQgeyBUb3VjaEV2ZW50IH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYge0VudW19IFRvdWNoVHlwZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgVG91Y2hUeXBlIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEJFR0lOICgpIHtcbiAgICAgICAgcmV0dXJuIFRvdWNoVHlwZS5fTUFQLkJFR0lOO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE1PVkUgKCkge1xuICAgICAgICByZXR1cm4gVG91Y2hUeXBlLl9NQVAuTU9WRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBFTkQgKCkge1xuICAgICAgICByZXR1cm4gVG91Y2hUeXBlLl9NQVAuRU5EO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IENBTkNFTCAoKSB7XG4gICAgICAgIHJldHVybiBUb3VjaFR5cGUuX01BUC5DQU5DRUw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gVG91Y2hUeXBlLl92YWx1ZUZvcktleShrZXksIFRvdWNoVHlwZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFRvdWNoVHlwZS5fa2V5Rm9yVmFsdWUodmFsdWUsIFRvdWNoVHlwZS5fTUFQKTtcbiAgICB9XG59XG5cblRvdWNoVHlwZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0JFR0lOJzogJ0JFR0lOJyxcbiAgICAnTU9WRSc6ICdNT1ZFJyxcbiAgICAnRU5EJzogJ0VORCcsXG4gICAgJ0NBTkNFTCc6ICdDQU5DRUwnLFxufSk7XG5cbmV4cG9ydCB7IFRvdWNoVHlwZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFRvdWNoRXZlbnQgfSBmcm9tICcuLi9zdHJ1Y3RzL1RvdWNoRXZlbnQuanMnO1xuaW1wb3J0IHsgVG91Y2hUeXBlIH0gZnJvbSAnLi4vZW51bXMvVG91Y2hUeXBlLmpzJztcbmltcG9ydCB7IFJwY05vdGlmaWNhdGlvbiB9IGZyb20gJy4uL1JwY05vdGlmaWNhdGlvbi5qcyc7XG5cbi8qKlxuICogTm90aWZpZXMgYWJvdXQgdG91Y2ggZXZlbnRzIG9uIHRoZSBzY3JlZW4ncyBwcmVzY3JpYmVkIGFyZWFcbiAqL1xuY2xhc3MgT25Ub3VjaEV2ZW50IGV4dGVuZHMgUnBjTm90aWZpY2F0aW9uIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELk9uVG91Y2hFdmVudCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtUb3VjaFR5cGV9IHR5cGUgLSBUaGUgdHlwZSBvZiB0b3VjaCBldmVudC5cbiAgICAgKiBAcmV0dXJuIHtPblRvdWNoRXZlbnR9XG4gICAgICovXG4gICAgc2V0VHlwZSAodHlwZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShUb3VjaFR5cGUsIHR5cGUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPblRvdWNoRXZlbnQuS0VZX1RZUEUsIHR5cGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtUb3VjaFR5cGV9XG4gICAgICovXG4gICAgZ2V0VHlwZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChUb3VjaFR5cGUsIE9uVG91Y2hFdmVudC5LRVlfVFlQRSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtUb3VjaEV2ZW50W119IGV2ZW50IC0gTGlzdCBvZiBhbGwgaW5kaXZpZHVhbCB0b3VjaGVzIGludm9sdmVkIGluIHRoaXMgZXZlbnQuXG4gICAgICogQHJldHVybiB7T25Ub3VjaEV2ZW50fVxuICAgICAqL1xuICAgIHNldEV2ZW50IChldmVudCkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShUb3VjaEV2ZW50LCBldmVudCwgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uVG91Y2hFdmVudC5LRVlfRVZFTlQsIGV2ZW50KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7VG91Y2hFdmVudFtdfVxuICAgICAqL1xuICAgIGdldEV2ZW50ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFRvdWNoRXZlbnQsIE9uVG91Y2hFdmVudC5LRVlfRVZFTlQpO1xuICAgIH1cbn1cblxuT25Ub3VjaEV2ZW50LktFWV9UWVBFID0gJ3R5cGUnO1xuT25Ub3VjaEV2ZW50LktFWV9FVkVOVCA9ICdldmVudCc7XG5cbmV4cG9ydCB7IE9uVG91Y2hFdmVudCB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJlcXVlc3RUeXBlIH0gZnJvbSAnLi4vZW51bXMvUmVxdWVzdFR5cGUuanMnO1xuaW1wb3J0IHsgRmlsZVR5cGUgfSBmcm9tICcuLi9lbnVtcy9GaWxlVHlwZS5qcyc7XG5pbXBvcnQgeyBScGNOb3RpZmljYXRpb24gfSBmcm9tICcuLi9ScGNOb3RpZmljYXRpb24uanMnO1xuXG4vKipcbiAqIEFuIGFzeW5jaHJvbm91cyByZXF1ZXN0IGZyb20gdGhlIHN5c3RlbSBmb3Igc3BlY2lmaWMgZGF0YSBmcm9tIHRoZSBkZXZpY2Ugb3IgdGhlIGNsb3VkIG9yIHJlc3BvbnNlIHRvIGEgcmVxdWVzdCBmcm9tXG4gKiB0aGUgZGV2aWNlIG9yIGNsb3VkIEJpbmFyeSBkYXRhIGNhbiBiZSBpbmNsdWRlZCBpbiBoeWJyaWQgcGFydCBvZiBtZXNzYWdlIGZvciBzb21lIHJlcXVlc3RzIChzdWNoIGFzIEF1dGhlbnRpY2F0aW9uXG4gKiByZXF1ZXN0IHJlc3BvbnNlcylcbiAqL1xuY2xhc3MgT25TeXN0ZW1SZXF1ZXN0IGV4dGVuZHMgUnBjTm90aWZpY2F0aW9uIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELk9uU3lzdGVtUmVxdWVzdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtSZXF1ZXN0VHlwZX0gdHlwZSAtIFRoZSB0eXBlIG9mIHN5c3RlbSByZXF1ZXN0LlxuICAgICAqIEByZXR1cm4ge09uU3lzdGVtUmVxdWVzdH1cbiAgICAgKi9cbiAgICBzZXRSZXF1ZXN0VHlwZSAodHlwZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShSZXF1ZXN0VHlwZSwgdHlwZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uU3lzdGVtUmVxdWVzdC5LRVlfUkVRVUVTVF9UWVBFLCB0eXBlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7UmVxdWVzdFR5cGV9XG4gICAgICovXG4gICAgZ2V0UmVxdWVzdFR5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoUmVxdWVzdFR5cGUsIE9uU3lzdGVtUmVxdWVzdC5LRVlfUkVRVUVTVF9UWVBFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSAtIFRoaXMgcGFyYW1ldGVyIGlzIGZpbGxlZCBmb3Igc3VwcG9ydGluZyBPRU0gcHJvcHJpZXRhcnkgZGF0YSBleGNoYW5nZXMuXG4gICAgICogQHJldHVybiB7T25TeXN0ZW1SZXF1ZXN0fVxuICAgICAqL1xuICAgIHNldFJlcXVlc3RTdWJUeXBlICh0eXBlKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uU3lzdGVtUmVxdWVzdC5LRVlfUkVRVUVTVF9TVUJfVFlQRSwgdHlwZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRSZXF1ZXN0U3ViVHlwZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihPblN5c3RlbVJlcXVlc3QuS0VZX1JFUVVFU1RfU1VCX1RZUEUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB1cmwgLSBPcHRpb25hbCBVUkwgZm9yIEhUVFAgcmVxdWVzdHMuIElmIGJsYW5rLCB0aGUgYmluYXJ5IGRhdGEgc2hhbGwgYmUgZm9yd2FyZGVkIHRvIHRoZSBhcHAuIElmXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgIG5vdCBibGFuaywgdGhlIGJpbmFyeSBkYXRhIHNoYWxsIGJlIGZvcndhcmRlZCB0byB0aGUgdXJsIHdpdGggYSBwcm92aWRlZCB0aW1lb3V0IGluXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgIHNlY29uZHMuXG4gICAgICogQHJldHVybiB7T25TeXN0ZW1SZXF1ZXN0fVxuICAgICAqL1xuICAgIHNldFVybCAodXJsKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uU3lzdGVtUmVxdWVzdC5LRVlfVVJMLCB1cmwpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgZ2V0VXJsICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE9uU3lzdGVtUmVxdWVzdC5LRVlfVVJMKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gdGltZW91dCAtIE9wdGlvbmFsIHRpbWVvdXQgZm9yIEhUVFAgcmVxdWVzdHMgUmVxdWlyZWQgaWYgYSBVUkwgaXMgcHJvdmlkZWRcbiAgICAgKiBAcmV0dXJuIHtPblN5c3RlbVJlcXVlc3R9XG4gICAgICovXG4gICAgc2V0VGltZW91dCAodGltZW91dCkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPblN5c3RlbVJlcXVlc3QuS0VZX1RJTUVPVVQsIHRpbWVvdXQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0VGltZW91dCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhcmFtZXRlcihPblN5c3RlbVJlcXVlc3QuS0VZX1RJTUVPVVQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7RmlsZVR5cGV9IHR5cGUgLSBPcHRpb25hbCBmaWxlIHR5cGUgKG1lYW50IGZvciBIVFRQIGZpbGUgcmVxdWVzdHMpLlxuICAgICAqIEByZXR1cm4ge09uU3lzdGVtUmVxdWVzdH1cbiAgICAgKi9cbiAgICBzZXRGaWxlVHlwZSAodHlwZSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShGaWxlVHlwZSwgdHlwZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uU3lzdGVtUmVxdWVzdC5LRVlfRklMRV9UWVBFLCB0eXBlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7RmlsZVR5cGV9XG4gICAgICovXG4gICAgZ2V0RmlsZVR5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoRmlsZVR5cGUsIE9uU3lzdGVtUmVxdWVzdC5LRVlfRklMRV9UWVBFKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gb2Zmc2V0IC0gT3B0aW9uYWwgb2Zmc2V0IGluIGJ5dGVzIGZvciByZXN1bWluZyBwYXJ0aWFsIGRhdGEgY2h1bmtzXG4gICAgICogQHJldHVybiB7T25TeXN0ZW1SZXF1ZXN0fVxuICAgICAqL1xuICAgIHNldE9mZnNldCAob2Zmc2V0KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uU3lzdGVtUmVxdWVzdC5LRVlfT0ZGU0VULCBvZmZzZXQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0T2Zmc2V0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE9uU3lzdGVtUmVxdWVzdC5LRVlfT0ZGU0VUKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoIC0gT3B0aW9uYWwgbGVuZ3RoIGluIGJ5dGVzIGZvciByZXN1bWluZyBwYXJ0aWFsIGRhdGEgY2h1bmtzXG4gICAgICogQHJldHVybiB7T25TeXN0ZW1SZXF1ZXN0fVxuICAgICAqL1xuICAgIHNldExlbmd0aCAobGVuZ3RoKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uU3lzdGVtUmVxdWVzdC5LRVlfTEVOR1RILCBsZW5ndGgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgZ2V0TGVuZ3RoICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE9uU3lzdGVtUmVxdWVzdC5LRVlfTEVOR1RIKTtcbiAgICB9XG59XG5cbk9uU3lzdGVtUmVxdWVzdC5LRVlfUkVRVUVTVF9UWVBFID0gJ3JlcXVlc3RUeXBlJztcbk9uU3lzdGVtUmVxdWVzdC5LRVlfUkVRVUVTVF9TVUJfVFlQRSA9ICdyZXF1ZXN0U3ViVHlwZSc7XG5PblN5c3RlbVJlcXVlc3QuS0VZX1VSTCA9ICd1cmwnO1xuT25TeXN0ZW1SZXF1ZXN0LktFWV9USU1FT1VUID0gJ3RpbWVvdXQnO1xuT25TeXN0ZW1SZXF1ZXN0LktFWV9GSUxFX1RZUEUgPSAnZmlsZVR5cGUnO1xuT25TeXN0ZW1SZXF1ZXN0LktFWV9PRkZTRVQgPSAnb2Zmc2V0Jztcbk9uU3lzdGVtUmVxdWVzdC5LRVlfTEVOR1RIID0gJ2xlbmd0aCc7XG5cbmV4cG9ydCB7IE9uU3lzdGVtUmVxdWVzdCB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY05vdGlmaWNhdGlvbiB9IGZyb20gJy4uL1JwY05vdGlmaWNhdGlvbi5qcyc7XG5cbi8qKlxuICogTm90aWZpY2F0aW9uIGNvbnRhaW5pbmcgYW4gdXBkYXRlZCBoYXNoSUQgd2hpY2ggY2FuIGJlIHVzZWQgb3ZlciBjb25uZWN0aW9uIGN5Y2xlcyAoaS5lLiBsb3NzIG9mIGNvbm5lY3Rpb24sXG4gKiBpZ25pdGlvbiBjeWNsZXMsIGV0Yy4pLiBTZW50IGFmdGVyIGluaXRpYWwgcmVnaXN0cmF0aW9uIGFuZCBzdWJzZXF1ZW50bHkgYWZ0ZXIgYW55IGNoYW5nZSBpbiB0aGUgY2FsY3VsYXRlZCBoYXNoIG9mXG4gKiBhbGwgcGVyc2lzdGVkIGFwcCBkYXRhLlxuICovXG5jbGFzcyBPbkhhc2hDaGFuZ2UgZXh0ZW5kcyBScGNOb3RpZmljYXRpb24ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuT25IYXNoQ2hhbmdlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gaWQgLSBDYWxjdWxhdGVkIGhhc2ggSUQgdG8gYmUgcmVmZXJlbmNlZCBkdXJpbmcgUmVnaXN0ZXJBcHBJbnRlcmZhY2UuXG4gICAgICogQHJldHVybiB7T25IYXNoQ2hhbmdlfVxuICAgICAqL1xuICAgIHNldEhhc2hJRCAoaWQpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25IYXNoQ2hhbmdlLktFWV9IQVNIX0lELCBpZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRIYXNoSUQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoT25IYXNoQ2hhbmdlLktFWV9IQVNIX0lEKTtcbiAgICB9XG59XG5cbk9uSGFzaENoYW5nZS5LRVlfSEFTSF9JRCA9ICdoYXNoSUQnO1xuXG5leHBvcnQgeyBPbkhhc2hDaGFuZ2UgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi4vZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBMb2NhdGlvbkRldGFpbHMgfSBmcm9tICcuLi9zdHJ1Y3RzL0xvY2F0aW9uRGV0YWlscy5qcyc7XG5pbXBvcnQgeyBScGNOb3RpZmljYXRpb24gfSBmcm9tICcuLi9ScGNOb3RpZmljYXRpb24uanMnO1xuXG4vKipcbiAqIE5vdGlmaWNhdGlvbiB3aGljaCBwcm92aWRlcyB0aGUgZW50aXJlIExvY2F0aW9uRGV0YWlscyB3aGVuIHRoZXJlIGlzIGEgY2hhbmdlIHRvIGFueSB3YXlwb2ludHMgb3IgZGVzdGluYXRpb24uXG4gKi9cbmNsYXNzIE9uV2F5UG9pbnRDaGFuZ2UgZXh0ZW5kcyBScGNOb3RpZmljYXRpb24ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuT25XYXlQb2ludENoYW5nZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtMb2NhdGlvbkRldGFpbHNbXX0gcG9pbnRzIC0gU2VlIExvY2F0aW9uRGV0YWlsc1xuICAgICAqIEByZXR1cm4ge09uV2F5UG9pbnRDaGFuZ2V9XG4gICAgICovXG4gICAgc2V0V2F5UG9pbnRzIChwb2ludHMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTG9jYXRpb25EZXRhaWxzLCBwb2ludHMsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPbldheVBvaW50Q2hhbmdlLktFWV9XQVlfUE9JTlRTLCBwb2ludHMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtMb2NhdGlvbkRldGFpbHNbXX1cbiAgICAgKi9cbiAgICBnZXRXYXlQb2ludHMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRPYmplY3QoTG9jYXRpb25EZXRhaWxzLCBPbldheVBvaW50Q2hhbmdlLktFWV9XQVlfUE9JTlRTKTtcbiAgICB9XG59XG5cbk9uV2F5UG9pbnRDaGFuZ2UuS0VZX1dBWV9QT0lOVFMgPSAnd2F5UG9pbnRzJztcblxuZXhwb3J0IHsgT25XYXlQb2ludENoYW5nZSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IE1vZHVsZURhdGEgfSBmcm9tICcuLi9zdHJ1Y3RzL01vZHVsZURhdGEuanMnO1xuaW1wb3J0IHsgUnBjTm90aWZpY2F0aW9uIH0gZnJvbSAnLi4vUnBjTm90aWZpY2F0aW9uLmpzJztcblxuY2xhc3MgT25JbnRlcmlvclZlaGljbGVEYXRhIGV4dGVuZHMgUnBjTm90aWZpY2F0aW9uIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELk9uSW50ZXJpb3JWZWhpY2xlRGF0YSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtNb2R1bGVEYXRhfSBkYXRhIC0gVGhlIG1vZHVsZVR5cGUgaW5kaWNhdGVzIHdoaWNoIHR5cGUgb2YgZGF0YSBzaG91bGQgYmUgY2hhbmdlZCBhbmQgaWRlbnRpZmllcyB3aGljaFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgb2JqZWN0IGV4aXN0cyBpbiB0aGlzIHN0cnVjdC4gRm9yIGV4YW1wbGUsIGlmIHRoZSBtb2R1bGVUeXBlIGlzIENMSU1BVEUgdGhlbiBhXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJjbGltYXRlQ29udHJvbERhdGFcIiBzaG91bGQgZXhpc3RcbiAgICAgKiBAcmV0dXJuIHtPbkludGVyaW9yVmVoaWNsZURhdGF9XG4gICAgICovXG4gICAgc2V0TW9kdWxlRGF0YSAoZGF0YSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShNb2R1bGVEYXRhLCBkYXRhKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25JbnRlcmlvclZlaGljbGVEYXRhLktFWV9NT0RVTEVfREFUQSwgZGF0YSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge01vZHVsZURhdGF9XG4gICAgICovXG4gICAgZ2V0TW9kdWxlRGF0YSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChNb2R1bGVEYXRhLCBPbkludGVyaW9yVmVoaWNsZURhdGEuS0VZX01PRFVMRV9EQVRBKTtcbiAgICB9XG59XG5cbk9uSW50ZXJpb3JWZWhpY2xlRGF0YS5LRVlfTU9EVUxFX0RBVEEgPSAnbW9kdWxlRGF0YSc7XG5cbmV4cG9ydCB7IE9uSW50ZXJpb3JWZWhpY2xlRGF0YSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IE1vZHVsZURhdGEgfSBmcm9tICcuLi9zdHJ1Y3RzL01vZHVsZURhdGEuanMnO1xuaW1wb3J0IHsgUnBjTm90aWZpY2F0aW9uIH0gZnJvbSAnLi4vUnBjTm90aWZpY2F0aW9uLmpzJztcblxuLyoqXG4gKiBJc3N1ZWQgYnkgU0RMIHRvIG5vdGlmeSB0aGUgYXBwbGljYXRpb24gYWJvdXQgcmVtb3RlIGNvbnRyb2wgc3RhdHVzIGNoYW5nZSBvbiBTRExcbiAqL1xuY2xhc3MgT25SQ1N0YXR1cyBleHRlbmRzIFJwY05vdGlmaWNhdGlvbiB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5PblJDU3RhdHVzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGFsbG93ZWQgLSBJZiBcInRydWVcIiAtIFJDIGlzIGFsbG93ZWQ7IGlmIFwiZmFsc2VcIiAtIFJDIGlzIGRpc2FsbG93ZWQuXG4gICAgICogQHJldHVybiB7T25SQ1N0YXR1c31cbiAgICAgKi9cbiAgICBzZXRBbGxvd2VkIChhbGxvd2VkKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uUkNTdGF0dXMuS0VZX0FMTE9XRUQsIGFsbG93ZWQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqL1xuICAgIGdldEFsbG93ZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoT25SQ1N0YXR1cy5LRVlfQUxMT1dFRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtNb2R1bGVEYXRhW119IG1vZHVsZXMgLSBDb250YWlucyBhIGxpc3QgKHplcm8gb3IgbW9yZSkgb2YgbW9kdWxlIHR5cGVzIHRoYXQgYXJlIGFsbG9jYXRlZCB0byB0aGVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGxpY2F0aW9uLlxuICAgICAqIEByZXR1cm4ge09uUkNTdGF0dXN9XG4gICAgICovXG4gICAgc2V0QWxsb2NhdGVkTW9kdWxlcyAobW9kdWxlcykge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShNb2R1bGVEYXRhLCBtb2R1bGVzLCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25SQ1N0YXR1cy5LRVlfQUxMT0NBVEVEX01PRFVMRVMsIG1vZHVsZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtNb2R1bGVEYXRhW119XG4gICAgICovXG4gICAgZ2V0QWxsb2NhdGVkTW9kdWxlcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChNb2R1bGVEYXRhLCBPblJDU3RhdHVzLktFWV9BTExPQ0FURURfTU9EVUxFUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtNb2R1bGVEYXRhW119IG1vZHVsZXMgLSBDb250YWlucyBhIGxpc3QgKHplcm8gb3IgbW9yZSkgb2YgbW9kdWxlIHR5cGVzIHRoYXQgYXJlIGZyZWUgdG8gYWNjZXNzIGZvciB0aGVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGxpY2F0aW9uLlxuICAgICAqIEByZXR1cm4ge09uUkNTdGF0dXN9XG4gICAgICovXG4gICAgc2V0RnJlZU1vZHVsZXMgKG1vZHVsZXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoTW9kdWxlRGF0YSwgbW9kdWxlcywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uUkNTdGF0dXMuS0VZX0ZSRUVfTU9EVUxFUywgbW9kdWxlcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge01vZHVsZURhdGFbXX1cbiAgICAgKi9cbiAgICBnZXRGcmVlTW9kdWxlcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE9iamVjdChNb2R1bGVEYXRhLCBPblJDU3RhdHVzLktFWV9GUkVFX01PRFVMRVMpO1xuICAgIH1cbn1cblxuT25SQ1N0YXR1cy5LRVlfQUxMT1dFRCA9ICdhbGxvd2VkJztcbk9uUkNTdGF0dXMuS0VZX0FMTE9DQVRFRF9NT0RVTEVTID0gJ2FsbG9jYXRlZE1vZHVsZXMnO1xuT25SQ1N0YXR1cy5LRVlfRlJFRV9NT0RVTEVTID0gJ2ZyZWVNb2R1bGVzJztcblxuZXhwb3J0IHsgT25SQ1N0YXR1cyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IEFwcFNlcnZpY2VEYXRhIH0gZnJvbSAnLi4vc3RydWN0cy9BcHBTZXJ2aWNlRGF0YS5qcyc7XG5pbXBvcnQgeyBScGNOb3RpZmljYXRpb24gfSBmcm9tICcuLi9ScGNOb3RpZmljYXRpb24uanMnO1xuXG4vKipcbiAqIFRoaXMgbm90aWZpY2F0aW9uIGluY2x1ZGVzIHRoZSBkYXRhIHRoYXQgaXMgdXBkYXRlZCBmcm9tIHRoZSBzcGVjaWZpYyBzZXJ2aWNlXG4gKi9cbmNsYXNzIE9uQXBwU2VydmljZURhdGEgZXh0ZW5kcyBScGNOb3RpZmljYXRpb24ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChzdG9yZSkge1xuICAgICAgICBzdXBlcihzdG9yZSk7XG4gICAgICAgIHRoaXMuc2V0RnVuY3Rpb25OYW1lKEZ1bmN0aW9uSUQuT25BcHBTZXJ2aWNlRGF0YSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtBcHBTZXJ2aWNlRGF0YX0gZGF0YSAtIENvbnRhaW5zIGFsbCB0aGUgY3VycmVudCBkYXRhIG9mIHRoZSBhcHAgc2VydmljZS4gVGhlIHNlcnZpY2VUeXBlIHdpbGwgbGluayB0b1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGljaCBvZiB0aGUgc2VydmljZSBkYXRhIG9iamVjdHMgYXJlIGluY2x1ZGVkIGluIHRoaXMgb2JqZWN0IChlLmcuIGlmIHRoZSBzZXJ2aWNlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgaXMgTUVESUEsIHRoZSBtZWRpYVNlcnZpY2VEYXRhIHBhcmFtIHNob3VsZCBiZSBpbmNsdWRlZCkuXG4gICAgICogQHJldHVybiB7T25BcHBTZXJ2aWNlRGF0YX1cbiAgICAgKi9cbiAgICBzZXRTZXJ2aWNlRGF0YSAoZGF0YSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlVHlwZShBcHBTZXJ2aWNlRGF0YSwgZGF0YSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uQXBwU2VydmljZURhdGEuS0VZX1NFUlZJQ0VfREFUQSwgZGF0YSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge0FwcFNlcnZpY2VEYXRhfVxuICAgICAqL1xuICAgIGdldFNlcnZpY2VEYXRhICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KEFwcFNlcnZpY2VEYXRhLCBPbkFwcFNlcnZpY2VEYXRhLktFWV9TRVJWSUNFX0RBVEEpO1xuICAgIH1cbn1cblxuT25BcHBTZXJ2aWNlRGF0YS5LRVlfU0VSVklDRV9EQVRBID0gJ3NlcnZpY2VEYXRhJztcblxuZXhwb3J0IHsgT25BcHBTZXJ2aWNlRGF0YSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFN5c3RlbUNhcGFiaWxpdHkgfSBmcm9tICcuLi9zdHJ1Y3RzL1N5c3RlbUNhcGFiaWxpdHkuanMnO1xuaW1wb3J0IHsgUnBjTm90aWZpY2F0aW9uIH0gZnJvbSAnLi4vUnBjTm90aWZpY2F0aW9uLmpzJztcblxuLyoqXG4gKiBBIG5vdGlmaWNhdGlvbiB0byBpbmZvcm0gdGhlIGNvbm5lY3RlZCBkZXZpY2UgdGhhdCBhIHNwZWNpZmljIHN5c3RlbSBjYXBhYmlsaXR5IGhhcyBjaGFuZ2VkLlxuICovXG5jbGFzcyBPblN5c3RlbUNhcGFiaWxpdHlVcGRhdGVkIGV4dGVuZHMgUnBjTm90aWZpY2F0aW9uIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoc3RvcmUpIHtcbiAgICAgICAgc3VwZXIoc3RvcmUpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTmFtZShGdW5jdGlvbklELk9uU3lzdGVtQ2FwYWJpbGl0eVVwZGF0ZWQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3lzdGVtQ2FwYWJpbGl0eX0gY2FwYWJpbGl0eSAtIFRoZSBzeXN0ZW0gY2FwYWJpbGl0eSB0aGF0IGhhcyBiZWVuIHVwZGF0ZWRcbiAgICAgKiBAcmV0dXJuIHtPblN5c3RlbUNhcGFiaWxpdHlVcGRhdGVkfVxuICAgICAqL1xuICAgIHNldFN5c3RlbUNhcGFiaWxpdHkgKGNhcGFiaWxpdHkpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVR5cGUoU3lzdGVtQ2FwYWJpbGl0eSwgY2FwYWJpbGl0eSk7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uU3lzdGVtQ2FwYWJpbGl0eVVwZGF0ZWQuS0VZX1NZU1RFTV9DQVBBQklMSVRZLCBjYXBhYmlsaXR5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3lzdGVtQ2FwYWJpbGl0eX1cbiAgICAgKi9cbiAgICBnZXRTeXN0ZW1DYXBhYmlsaXR5ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0KFN5c3RlbUNhcGFiaWxpdHksIE9uU3lzdGVtQ2FwYWJpbGl0eVVwZGF0ZWQuS0VZX1NZU1RFTV9DQVBBQklMSVRZKTtcbiAgICB9XG59XG5cbk9uU3lzdGVtQ2FwYWJpbGl0eVVwZGF0ZWQuS0VZX1NZU1RFTV9DQVBBQklMSVRZID0gJ3N5c3RlbUNhcGFiaWxpdHknO1xuXG5leHBvcnQgeyBPblN5c3RlbUNhcGFiaWxpdHlVcGRhdGVkIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuXG4vKipcbiAqIEFsbG93cyBlbmNvZGVkIGRhdGEgaW4gdGhlIGZvcm0gb2YgU3luY1AgcGFja2V0cyB0byBiZSBzZW50IHRvIHRoZSBTWU5DIG1vZHVsZS4gTGVnYWN5IC8gdjEgUHJvdG9jb2wgaW1wbGVtZW50YXRpb247XG4gKiB1c2UgU3luY1BEYXRhIGluc3RlYWQuICoqKiBERVBSRUNBVEVEICoqKlxuICovXG5jbGFzcyBFbmNvZGVkU3luY1BEYXRhIGV4dGVuZHMgUnBjUmVxdWVzdCB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5FbmNvZGVkU3luY1BEYXRhKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ1tdfSBkYXRhIC0gQ29udGFpbnMgYmFzZTY0IGVuY29kZWQgc3RyaW5nIG9mIFN5bmNQIHBhY2tldHMuXG4gICAgICogQHJldHVybiB7RW5jb2RlZFN5bmNQRGF0YX1cbiAgICAgKi9cbiAgICBzZXREYXRhIChkYXRhKSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKEVuY29kZWRTeW5jUERhdGEuS0VZX0RBVEEsIGRhdGEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmdbXX1cbiAgICAgKi9cbiAgICBnZXREYXRhICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKEVuY29kZWRTeW5jUERhdGEuS0VZX0RBVEEpO1xuICAgIH1cbn1cblxuRW5jb2RlZFN5bmNQRGF0YS5LRVlfREFUQSA9ICdkYXRhJztcblxuZXhwb3J0IHsgRW5jb2RlZFN5bmNQRGF0YSB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi9lbnVtcy9GdW5jdGlvbklELmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vUnBjUmVzcG9uc2UuanMnO1xuXG5jbGFzcyBFbmNvZGVkU3luY1BEYXRhUmVzcG9uc2UgZXh0ZW5kcyBScGNSZXNwb25zZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5FbmNvZGVkU3luY1BEYXRhKTtcbiAgICB9XG59XG5cblxuZXhwb3J0IHsgRW5jb2RlZFN5bmNQRGF0YVJlc3BvbnNlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRnVuY3Rpb25JRCB9IGZyb20gJy4uL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgUnBjTm90aWZpY2F0aW9uIH0gZnJvbSAnLi4vUnBjTm90aWZpY2F0aW9uLmpzJztcblxuLyoqXG4gKiBDYWxsYmFjayBpbmNsdWRpbmcgZW5jb2RlZCBkYXRhIG9mIGFueSBTeW5jUCBwYWNrZXRzIHRoYXQgU1lOQyBuZWVkcyB0byBzZW5kIGJhY2sgdG8gdGhlIG1vYmlsZSBkZXZpY2UuIExlZ2FjeSAvIHYxXG4gKiBQcm90b2NvbCBpbXBsZW1lbnRhdGlvbjsgcmVzcG9uZHMgdG8gRW5jb2RlZFN5bmNQRGF0YS4gKioqIERFUFJFQ0FURUQgKioqXG4gKi9cbmNsYXNzIE9uRW5jb2RlZFN5bmNQRGF0YSBleHRlbmRzIFJwY05vdGlmaWNhdGlvbiB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKHN0b3JlKSB7XG4gICAgICAgIHN1cGVyKHN0b3JlKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk5hbWUoRnVuY3Rpb25JRC5PbkVuY29kZWRTeW5jUERhdGEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nW119IGRhdGEgLSBDb250YWlucyBiYXNlNjQgZW5jb2RlZCBzdHJpbmcgb2YgU3luY1AgcGFja2V0cy5cbiAgICAgKiBAcmV0dXJuIHtPbkVuY29kZWRTeW5jUERhdGF9XG4gICAgICovXG4gICAgc2V0RGF0YSAoZGF0YSkge1xuICAgICAgICB0aGlzLnNldFBhcmFtZXRlcihPbkVuY29kZWRTeW5jUERhdGEuS0VZX0RBVEEsIGRhdGEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmdbXX1cbiAgICAgKi9cbiAgICBnZXREYXRhICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE9uRW5jb2RlZFN5bmNQRGF0YS5LRVlfREFUQSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHVybCAtIElmIGJsYW5rLCB0aGUgU3luY1AgZGF0YSBzaGFsbCBiZSBmb3J3YXJkZWQgdG8gdGhlIGFwcC4gSWYgbm90IGJsYW5rLCB0aGUgU3luY1AgZGF0YSBzaGFsbFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICBiZSBmb3J3YXJkZWQgdG8gdGhlIHByb3ZpZGVkIFVSTC5cbiAgICAgKiBAcmV0dXJuIHtPbkVuY29kZWRTeW5jUERhdGF9XG4gICAgICovXG4gICAgc2V0VVJMICh1cmwpIHtcbiAgICAgICAgdGhpcy5zZXRQYXJhbWV0ZXIoT25FbmNvZGVkU3luY1BEYXRhLktFWV9VUkwsIHVybCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBnZXRVUkwgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXIoT25FbmNvZGVkU3luY1BEYXRhLktFWV9VUkwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB0aW1lb3V0IC0gSWYgYmxhbmssIHRoZSBTeW5jUCBkYXRhIHNoYWxsIGJlIGZvcndhcmRlZCB0byB0aGUgYXBwLiBJZiBub3QgYmxhbmssIHRoZSBTeW5jUCBkYXRhXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFsbCBiZSBmb3J3YXJkZWQgd2l0aCB0aGUgcHJvdmlkZWQgdGltZW91dCBpbiBzZWNvbmRzLlxuICAgICAqIEByZXR1cm4ge09uRW5jb2RlZFN5bmNQRGF0YX1cbiAgICAgKi9cbiAgICBzZXRUaW1lb3V0ICh0aW1lb3V0KSB7XG4gICAgICAgIHRoaXMuc2V0UGFyYW1ldGVyKE9uRW5jb2RlZFN5bmNQRGF0YS5LRVlfVElNRU9VVCwgdGltZW91dCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBnZXRUaW1lb3V0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYW1ldGVyKE9uRW5jb2RlZFN5bmNQRGF0YS5LRVlfVElNRU9VVCk7XG4gICAgfVxufVxuXG5PbkVuY29kZWRTeW5jUERhdGEuS0VZX0RBVEEgPSAnZGF0YSc7XG5PbkVuY29kZWRTeW5jUERhdGEuS0VZX1VSTCA9ICdVUkwnO1xuT25FbmNvZGVkU3luY1BEYXRhLktFWV9USU1FT1VUID0gJ1RpbWVvdXQnO1xuXG5leHBvcnQgeyBPbkVuY29kZWRTeW5jUERhdGEgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG4vLyBtZXNzYWdlc1xuaW1wb3J0IHsgUmVnaXN0ZXJBcHBJbnRlcmZhY2UgfSBmcm9tICcuL21lc3NhZ2VzL1JlZ2lzdGVyQXBwSW50ZXJmYWNlLmpzJztcbmltcG9ydCB7IFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL1JlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgVW5yZWdpc3RlckFwcEludGVyZmFjZSB9IGZyb20gJy4vbWVzc2FnZXMvVW5yZWdpc3RlckFwcEludGVyZmFjZS5qcyc7XG5pbXBvcnQgeyBVbnJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL1VucmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBDcmVhdGVXaW5kb3cgfSBmcm9tICcuL21lc3NhZ2VzL0NyZWF0ZVdpbmRvdy5qcyc7XG5pbXBvcnQgeyBDcmVhdGVXaW5kb3dSZXNwb25zZSB9IGZyb20gJy4vbWVzc2FnZXMvQ3JlYXRlV2luZG93UmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgRGVsZXRlV2luZG93IH0gZnJvbSAnLi9tZXNzYWdlcy9EZWxldGVXaW5kb3cuanMnO1xuaW1wb3J0IHsgRGVsZXRlV2luZG93UmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL0RlbGV0ZVdpbmRvd1Jlc3BvbnNlLmpzJztcbmltcG9ydCB7IFNldEdsb2JhbFByb3BlcnRpZXMgfSBmcm9tICcuL21lc3NhZ2VzL1NldEdsb2JhbFByb3BlcnRpZXMuanMnO1xuaW1wb3J0IHsgU2V0R2xvYmFsUHJvcGVydGllc1Jlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9TZXRHbG9iYWxQcm9wZXJ0aWVzUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgUmVzZXRHbG9iYWxQcm9wZXJ0aWVzIH0gZnJvbSAnLi9tZXNzYWdlcy9SZXNldEdsb2JhbFByb3BlcnRpZXMuanMnO1xuaW1wb3J0IHsgUmVzZXRHbG9iYWxQcm9wZXJ0aWVzUmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL1Jlc2V0R2xvYmFsUHJvcGVydGllc1Jlc3BvbnNlLmpzJztcbmltcG9ydCB7IEFkZENvbW1hbmQgfSBmcm9tICcuL21lc3NhZ2VzL0FkZENvbW1hbmQuanMnO1xuaW1wb3J0IHsgQWRkQ29tbWFuZFJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9BZGRDb21tYW5kUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgRGVsZXRlQ29tbWFuZCB9IGZyb20gJy4vbWVzc2FnZXMvRGVsZXRlQ29tbWFuZC5qcyc7XG5pbXBvcnQgeyBEZWxldGVDb21tYW5kUmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL0RlbGV0ZUNvbW1hbmRSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBBZGRTdWJNZW51IH0gZnJvbSAnLi9tZXNzYWdlcy9BZGRTdWJNZW51LmpzJztcbmltcG9ydCB7IEFkZFN1Yk1lbnVSZXNwb25zZSB9IGZyb20gJy4vbWVzc2FnZXMvQWRkU3ViTWVudVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IERlbGV0ZVN1Yk1lbnUgfSBmcm9tICcuL21lc3NhZ2VzL0RlbGV0ZVN1Yk1lbnUuanMnO1xuaW1wb3J0IHsgRGVsZXRlU3ViTWVudVJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9EZWxldGVTdWJNZW51UmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgU2hvd0FwcE1lbnUgfSBmcm9tICcuL21lc3NhZ2VzL1Nob3dBcHBNZW51LmpzJztcbmltcG9ydCB7IFNob3dBcHBNZW51UmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL1Nob3dBcHBNZW51UmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgQ3JlYXRlSW50ZXJhY3Rpb25DaG9pY2VTZXQgfSBmcm9tICcuL21lc3NhZ2VzL0NyZWF0ZUludGVyYWN0aW9uQ2hvaWNlU2V0LmpzJztcbmltcG9ydCB7IENyZWF0ZUludGVyYWN0aW9uQ2hvaWNlU2V0UmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL0NyZWF0ZUludGVyYWN0aW9uQ2hvaWNlU2V0UmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgUGVyZm9ybUludGVyYWN0aW9uIH0gZnJvbSAnLi9tZXNzYWdlcy9QZXJmb3JtSW50ZXJhY3Rpb24uanMnO1xuaW1wb3J0IHsgUGVyZm9ybUludGVyYWN0aW9uUmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL1BlcmZvcm1JbnRlcmFjdGlvblJlc3BvbnNlLmpzJztcbmltcG9ydCB7IERlbGV0ZUludGVyYWN0aW9uQ2hvaWNlU2V0IH0gZnJvbSAnLi9tZXNzYWdlcy9EZWxldGVJbnRlcmFjdGlvbkNob2ljZVNldC5qcyc7XG5pbXBvcnQgeyBEZWxldGVJbnRlcmFjdGlvbkNob2ljZVNldFJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9EZWxldGVJbnRlcmFjdGlvbkNob2ljZVNldFJlc3BvbnNlLmpzJztcbmltcG9ydCB7IEFsZXJ0IH0gZnJvbSAnLi9tZXNzYWdlcy9BbGVydC5qcyc7XG5pbXBvcnQgeyBBbGVydFJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9BbGVydFJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFNob3cgfSBmcm9tICcuL21lc3NhZ2VzL1Nob3cuanMnO1xuaW1wb3J0IHsgU2hvd1Jlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9TaG93UmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgU3BlYWsgfSBmcm9tICcuL21lc3NhZ2VzL1NwZWFrLmpzJztcbmltcG9ydCB7IFNwZWFrUmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL1NwZWFrUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgU2V0TWVkaWFDbG9ja1RpbWVyIH0gZnJvbSAnLi9tZXNzYWdlcy9TZXRNZWRpYUNsb2NrVGltZXIuanMnO1xuaW1wb3J0IHsgU2V0TWVkaWFDbG9ja1RpbWVyUmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL1NldE1lZGlhQ2xvY2tUaW1lclJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFBlcmZvcm1BdWRpb1Bhc3NUaHJ1IH0gZnJvbSAnLi9tZXNzYWdlcy9QZXJmb3JtQXVkaW9QYXNzVGhydS5qcyc7XG5pbXBvcnQgeyBQZXJmb3JtQXVkaW9QYXNzVGhydVJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9QZXJmb3JtQXVkaW9QYXNzVGhydVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IEVuZEF1ZGlvUGFzc1RocnUgfSBmcm9tICcuL21lc3NhZ2VzL0VuZEF1ZGlvUGFzc1RocnUuanMnO1xuaW1wb3J0IHsgRW5kQXVkaW9QYXNzVGhydVJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9FbmRBdWRpb1Bhc3NUaHJ1UmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgU3Vic2NyaWJlQnV0dG9uIH0gZnJvbSAnLi9tZXNzYWdlcy9TdWJzY3JpYmVCdXR0b24uanMnO1xuaW1wb3J0IHsgU3Vic2NyaWJlQnV0dG9uUmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL1N1YnNjcmliZUJ1dHRvblJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFVuc3Vic2NyaWJlQnV0dG9uIH0gZnJvbSAnLi9tZXNzYWdlcy9VbnN1YnNjcmliZUJ1dHRvbi5qcyc7XG5pbXBvcnQgeyBVbnN1YnNjcmliZUJ1dHRvblJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9VbnN1YnNjcmliZUJ1dHRvblJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFN1YnNjcmliZVZlaGljbGVEYXRhIH0gZnJvbSAnLi9tZXNzYWdlcy9TdWJzY3JpYmVWZWhpY2xlRGF0YS5qcyc7XG5pbXBvcnQgeyBTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9TdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFVuc3Vic2NyaWJlVmVoaWNsZURhdGEgfSBmcm9tICcuL21lc3NhZ2VzL1Vuc3Vic2NyaWJlVmVoaWNsZURhdGEuanMnO1xuaW1wb3J0IHsgVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9VbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgR2V0VmVoaWNsZURhdGEgfSBmcm9tICcuL21lc3NhZ2VzL0dldFZlaGljbGVEYXRhLmpzJztcbmltcG9ydCB7IEdldFZlaGljbGVEYXRhUmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL0dldFZlaGljbGVEYXRhUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgUmVhZERJRCB9IGZyb20gJy4vbWVzc2FnZXMvUmVhZERJRC5qcyc7XG5pbXBvcnQgeyBSZWFkRElEUmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL1JlYWRESURSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBHZXREVENzIH0gZnJvbSAnLi9tZXNzYWdlcy9HZXREVENzLmpzJztcbmltcG9ydCB7IEdldERUQ3NSZXNwb25zZSB9IGZyb20gJy4vbWVzc2FnZXMvR2V0RFRDc1Jlc3BvbnNlLmpzJztcbmltcG9ydCB7IERpYWdub3N0aWNNZXNzYWdlIH0gZnJvbSAnLi9tZXNzYWdlcy9EaWFnbm9zdGljTWVzc2FnZS5qcyc7XG5pbXBvcnQgeyBEaWFnbm9zdGljTWVzc2FnZVJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9EaWFnbm9zdGljTWVzc2FnZVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFNjcm9sbGFibGVNZXNzYWdlIH0gZnJvbSAnLi9tZXNzYWdlcy9TY3JvbGxhYmxlTWVzc2FnZS5qcyc7XG5pbXBvcnQgeyBTY3JvbGxhYmxlTWVzc2FnZVJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9TY3JvbGxhYmxlTWVzc2FnZVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFNsaWRlciB9IGZyb20gJy4vbWVzc2FnZXMvU2xpZGVyLmpzJztcbmltcG9ydCB7IFNsaWRlclJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9TbGlkZXJSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBTaG93Q29uc3RhbnRUQlQgfSBmcm9tICcuL21lc3NhZ2VzL1Nob3dDb25zdGFudFRCVC5qcyc7XG5pbXBvcnQgeyBTaG93Q29uc3RhbnRUQlRSZXNwb25zZSB9IGZyb20gJy4vbWVzc2FnZXMvU2hvd0NvbnN0YW50VEJUUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgQWxlcnRNYW5ldXZlciB9IGZyb20gJy4vbWVzc2FnZXMvQWxlcnRNYW5ldXZlci5qcyc7XG5pbXBvcnQgeyBBbGVydE1hbmV1dmVyUmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL0FsZXJ0TWFuZXV2ZXJSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBVcGRhdGVUdXJuTGlzdCB9IGZyb20gJy4vbWVzc2FnZXMvVXBkYXRlVHVybkxpc3QuanMnO1xuaW1wb3J0IHsgVXBkYXRlVHVybkxpc3RSZXNwb25zZSB9IGZyb20gJy4vbWVzc2FnZXMvVXBkYXRlVHVybkxpc3RSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBDaGFuZ2VSZWdpc3RyYXRpb24gfSBmcm9tICcuL21lc3NhZ2VzL0NoYW5nZVJlZ2lzdHJhdGlvbi5qcyc7XG5pbXBvcnQgeyBDaGFuZ2VSZWdpc3RyYXRpb25SZXNwb25zZSB9IGZyb20gJy4vbWVzc2FnZXMvQ2hhbmdlUmVnaXN0cmF0aW9uUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgR2VuZXJpY1Jlc3BvbnNlUmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL0dlbmVyaWNSZXNwb25zZVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFB1dEZpbGUgfSBmcm9tICcuL21lc3NhZ2VzL1B1dEZpbGUuanMnO1xuaW1wb3J0IHsgUHV0RmlsZVJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9QdXRGaWxlUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgR2V0RmlsZSB9IGZyb20gJy4vbWVzc2FnZXMvR2V0RmlsZS5qcyc7XG5pbXBvcnQgeyBHZXRGaWxlUmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL0dldEZpbGVSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBEZWxldGVGaWxlIH0gZnJvbSAnLi9tZXNzYWdlcy9EZWxldGVGaWxlLmpzJztcbmltcG9ydCB7IERlbGV0ZUZpbGVSZXNwb25zZSB9IGZyb20gJy4vbWVzc2FnZXMvRGVsZXRlRmlsZVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IExpc3RGaWxlcyB9IGZyb20gJy4vbWVzc2FnZXMvTGlzdEZpbGVzLmpzJztcbmltcG9ydCB7IExpc3RGaWxlc1Jlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9MaXN0RmlsZXNSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBTZXRBcHBJY29uIH0gZnJvbSAnLi9tZXNzYWdlcy9TZXRBcHBJY29uLmpzJztcbmltcG9ydCB7IFNldEFwcEljb25SZXNwb25zZSB9IGZyb20gJy4vbWVzc2FnZXMvU2V0QXBwSWNvblJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFNldERpc3BsYXlMYXlvdXQgfSBmcm9tICcuL21lc3NhZ2VzL1NldERpc3BsYXlMYXlvdXQuanMnO1xuaW1wb3J0IHsgU2V0RGlzcGxheUxheW91dFJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9TZXREaXNwbGF5TGF5b3V0UmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgU3lzdGVtUmVxdWVzdCB9IGZyb20gJy4vbWVzc2FnZXMvU3lzdGVtUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBTeXN0ZW1SZXF1ZXN0UmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL1N5c3RlbVJlcXVlc3RSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBTZW5kTG9jYXRpb24gfSBmcm9tICcuL21lc3NhZ2VzL1NlbmRMb2NhdGlvbi5qcyc7XG5pbXBvcnQgeyBTZW5kTG9jYXRpb25SZXNwb25zZSB9IGZyb20gJy4vbWVzc2FnZXMvU2VuZExvY2F0aW9uUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgRGlhbE51bWJlciB9IGZyb20gJy4vbWVzc2FnZXMvRGlhbE51bWJlci5qcyc7XG5pbXBvcnQgeyBEaWFsTnVtYmVyUmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL0RpYWxOdW1iZXJSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBCdXR0b25QcmVzcyB9IGZyb20gJy4vbWVzc2FnZXMvQnV0dG9uUHJlc3MuanMnO1xuaW1wb3J0IHsgQnV0dG9uUHJlc3NSZXNwb25zZSB9IGZyb20gJy4vbWVzc2FnZXMvQnV0dG9uUHJlc3NSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBHZXRJbnRlcmlvclZlaGljbGVEYXRhIH0gZnJvbSAnLi9tZXNzYWdlcy9HZXRJbnRlcmlvclZlaGljbGVEYXRhLmpzJztcbmltcG9ydCB7IEdldEludGVyaW9yVmVoaWNsZURhdGFSZXNwb25zZSB9IGZyb20gJy4vbWVzc2FnZXMvR2V0SW50ZXJpb3JWZWhpY2xlRGF0YVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IEdldEludGVyaW9yVmVoaWNsZURhdGFDb25zZW50IH0gZnJvbSAnLi9tZXNzYWdlcy9HZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudC5qcyc7XG5pbXBvcnQgeyBHZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudFJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9HZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudFJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFJlbGVhc2VJbnRlcmlvclZlaGljbGVEYXRhTW9kdWxlIH0gZnJvbSAnLi9tZXNzYWdlcy9SZWxlYXNlSW50ZXJpb3JWZWhpY2xlRGF0YU1vZHVsZS5qcyc7XG5pbXBvcnQgeyBSZWxlYXNlSW50ZXJpb3JWZWhpY2xlRGF0YU1vZHVsZVJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9SZWxlYXNlSW50ZXJpb3JWZWhpY2xlRGF0YU1vZHVsZVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFNldEludGVyaW9yVmVoaWNsZURhdGEgfSBmcm9tICcuL21lc3NhZ2VzL1NldEludGVyaW9yVmVoaWNsZURhdGEuanMnO1xuaW1wb3J0IHsgU2V0SW50ZXJpb3JWZWhpY2xlRGF0YVJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9TZXRJbnRlcmlvclZlaGljbGVEYXRhUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgU3Vic2NyaWJlV2F5UG9pbnRzIH0gZnJvbSAnLi9tZXNzYWdlcy9TdWJzY3JpYmVXYXlQb2ludHMuanMnO1xuaW1wb3J0IHsgU3Vic2NyaWJlV2F5UG9pbnRzUmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL1N1YnNjcmliZVdheVBvaW50c1Jlc3BvbnNlLmpzJztcbmltcG9ydCB7IEdldFdheVBvaW50cyB9IGZyb20gJy4vbWVzc2FnZXMvR2V0V2F5UG9pbnRzLmpzJztcbmltcG9ydCB7IEdldFdheVBvaW50c1Jlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9HZXRXYXlQb2ludHNSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBVbnN1YnNjcmliZVdheVBvaW50cyB9IGZyb20gJy4vbWVzc2FnZXMvVW5zdWJzY3JpYmVXYXlQb2ludHMuanMnO1xuaW1wb3J0IHsgVW5zdWJzY3JpYmVXYXlQb2ludHNSZXNwb25zZSB9IGZyb20gJy4vbWVzc2FnZXMvVW5zdWJzY3JpYmVXYXlQb2ludHNSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBHZXRTeXN0ZW1DYXBhYmlsaXR5IH0gZnJvbSAnLi9tZXNzYWdlcy9HZXRTeXN0ZW1DYXBhYmlsaXR5LmpzJztcbmltcG9ydCB7IEdldFN5c3RlbUNhcGFiaWxpdHlSZXNwb25zZSB9IGZyb20gJy4vbWVzc2FnZXMvR2V0U3lzdGVtQ2FwYWJpbGl0eVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFNlbmRIYXB0aWNEYXRhIH0gZnJvbSAnLi9tZXNzYWdlcy9TZW5kSGFwdGljRGF0YS5qcyc7XG5pbXBvcnQgeyBTZW5kSGFwdGljRGF0YVJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9TZW5kSGFwdGljRGF0YVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFNldENsb3VkQXBwUHJvcGVydGllcyB9IGZyb20gJy4vbWVzc2FnZXMvU2V0Q2xvdWRBcHBQcm9wZXJ0aWVzLmpzJztcbmltcG9ydCB7IFNldENsb3VkQXBwUHJvcGVydGllc1Jlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9TZXRDbG91ZEFwcFByb3BlcnRpZXNSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBHZXRDbG91ZEFwcFByb3BlcnRpZXMgfSBmcm9tICcuL21lc3NhZ2VzL0dldENsb3VkQXBwUHJvcGVydGllcy5qcyc7XG5pbXBvcnQgeyBHZXRDbG91ZEFwcFByb3BlcnRpZXNSZXNwb25zZSB9IGZyb20gJy4vbWVzc2FnZXMvR2V0Q2xvdWRBcHBQcm9wZXJ0aWVzUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgUHVibGlzaEFwcFNlcnZpY2UgfSBmcm9tICcuL21lc3NhZ2VzL1B1Ymxpc2hBcHBTZXJ2aWNlLmpzJztcbmltcG9ydCB7IFB1Ymxpc2hBcHBTZXJ2aWNlUmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL1B1Ymxpc2hBcHBTZXJ2aWNlUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgVW5wdWJsaXNoQXBwU2VydmljZSB9IGZyb20gJy4vbWVzc2FnZXMvVW5wdWJsaXNoQXBwU2VydmljZS5qcyc7XG5pbXBvcnQgeyBVbnB1Ymxpc2hBcHBTZXJ2aWNlUmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL1VucHVibGlzaEFwcFNlcnZpY2VSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBHZXRBcHBTZXJ2aWNlRGF0YSB9IGZyb20gJy4vbWVzc2FnZXMvR2V0QXBwU2VydmljZURhdGEuanMnO1xuaW1wb3J0IHsgR2V0QXBwU2VydmljZURhdGFSZXNwb25zZSB9IGZyb20gJy4vbWVzc2FnZXMvR2V0QXBwU2VydmljZURhdGFSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBQZXJmb3JtQXBwU2VydmljZUludGVyYWN0aW9uIH0gZnJvbSAnLi9tZXNzYWdlcy9QZXJmb3JtQXBwU2VydmljZUludGVyYWN0aW9uLmpzJztcbmltcG9ydCB7IFBlcmZvcm1BcHBTZXJ2aWNlSW50ZXJhY3Rpb25SZXNwb25zZSB9IGZyb20gJy4vbWVzc2FnZXMvUGVyZm9ybUFwcFNlcnZpY2VJbnRlcmFjdGlvblJlc3BvbnNlLmpzJztcbmltcG9ydCB7IENhbmNlbEludGVyYWN0aW9uIH0gZnJvbSAnLi9tZXNzYWdlcy9DYW5jZWxJbnRlcmFjdGlvbi5qcyc7XG5pbXBvcnQgeyBDYW5jZWxJbnRlcmFjdGlvblJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9DYW5jZWxJbnRlcmFjdGlvblJlc3BvbnNlLmpzJztcbmltcG9ydCB7IENsb3NlQXBwbGljYXRpb24gfSBmcm9tICcuL21lc3NhZ2VzL0Nsb3NlQXBwbGljYXRpb24uanMnO1xuaW1wb3J0IHsgQ2xvc2VBcHBsaWNhdGlvblJlc3BvbnNlIH0gZnJvbSAnLi9tZXNzYWdlcy9DbG9zZUFwcGxpY2F0aW9uUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgT25ITUlTdGF0dXMgfSBmcm9tICcuL21lc3NhZ2VzL09uSE1JU3RhdHVzLmpzJztcbmltcG9ydCB7IE9uQXBwSW50ZXJmYWNlVW5yZWdpc3RlcmVkIH0gZnJvbSAnLi9tZXNzYWdlcy9PbkFwcEludGVyZmFjZVVucmVnaXN0ZXJlZC5qcyc7XG5pbXBvcnQgeyBPbkJ1dHRvbkV2ZW50IH0gZnJvbSAnLi9tZXNzYWdlcy9PbkJ1dHRvbkV2ZW50LmpzJztcbmltcG9ydCB7IE9uQnV0dG9uUHJlc3MgfSBmcm9tICcuL21lc3NhZ2VzL09uQnV0dG9uUHJlc3MuanMnO1xuaW1wb3J0IHsgT25WZWhpY2xlRGF0YSB9IGZyb20gJy4vbWVzc2FnZXMvT25WZWhpY2xlRGF0YS5qcyc7XG5pbXBvcnQgeyBPbkNvbW1hbmQgfSBmcm9tICcuL21lc3NhZ2VzL09uQ29tbWFuZC5qcyc7XG5pbXBvcnQgeyBPblRCVENsaWVudFN0YXRlIH0gZnJvbSAnLi9tZXNzYWdlcy9PblRCVENsaWVudFN0YXRlLmpzJztcbmltcG9ydCB7IE9uRHJpdmVyRGlzdHJhY3Rpb24gfSBmcm9tICcuL21lc3NhZ2VzL09uRHJpdmVyRGlzdHJhY3Rpb24uanMnO1xuaW1wb3J0IHsgT25QZXJtaXNzaW9uc0NoYW5nZSB9IGZyb20gJy4vbWVzc2FnZXMvT25QZXJtaXNzaW9uc0NoYW5nZS5qcyc7XG5pbXBvcnQgeyBPbkF1ZGlvUGFzc1RocnUgfSBmcm9tICcuL21lc3NhZ2VzL09uQXVkaW9QYXNzVGhydS5qcyc7XG5pbXBvcnQgeyBPbkxhbmd1YWdlQ2hhbmdlIH0gZnJvbSAnLi9tZXNzYWdlcy9Pbkxhbmd1YWdlQ2hhbmdlLmpzJztcbmltcG9ydCB7IE9uS2V5Ym9hcmRJbnB1dCB9IGZyb20gJy4vbWVzc2FnZXMvT25LZXlib2FyZElucHV0LmpzJztcbmltcG9ydCB7IE9uVG91Y2hFdmVudCB9IGZyb20gJy4vbWVzc2FnZXMvT25Ub3VjaEV2ZW50LmpzJztcbmltcG9ydCB7IE9uU3lzdGVtUmVxdWVzdCB9IGZyb20gJy4vbWVzc2FnZXMvT25TeXN0ZW1SZXF1ZXN0LmpzJztcbmltcG9ydCB7IE9uSGFzaENoYW5nZSB9IGZyb20gJy4vbWVzc2FnZXMvT25IYXNoQ2hhbmdlLmpzJztcbmltcG9ydCB7IE9uV2F5UG9pbnRDaGFuZ2UgfSBmcm9tICcuL21lc3NhZ2VzL09uV2F5UG9pbnRDaGFuZ2UuanMnO1xuaW1wb3J0IHsgT25JbnRlcmlvclZlaGljbGVEYXRhIH0gZnJvbSAnLi9tZXNzYWdlcy9PbkludGVyaW9yVmVoaWNsZURhdGEuanMnO1xuaW1wb3J0IHsgT25SQ1N0YXR1cyB9IGZyb20gJy4vbWVzc2FnZXMvT25SQ1N0YXR1cy5qcyc7XG5pbXBvcnQgeyBPbkFwcFNlcnZpY2VEYXRhIH0gZnJvbSAnLi9tZXNzYWdlcy9PbkFwcFNlcnZpY2VEYXRhLmpzJztcbmltcG9ydCB7IE9uU3lzdGVtQ2FwYWJpbGl0eVVwZGF0ZWQgfSBmcm9tICcuL21lc3NhZ2VzL09uU3lzdGVtQ2FwYWJpbGl0eVVwZGF0ZWQuanMnO1xuaW1wb3J0IHsgRW5jb2RlZFN5bmNQRGF0YSB9IGZyb20gJy4vbWVzc2FnZXMvRW5jb2RlZFN5bmNQRGF0YS5qcyc7XG5pbXBvcnQgeyBFbmNvZGVkU3luY1BEYXRhUmVzcG9uc2UgfSBmcm9tICcuL21lc3NhZ2VzL0VuY29kZWRTeW5jUERhdGFSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBPbkVuY29kZWRTeW5jUERhdGEgfSBmcm9tICcuL21lc3NhZ2VzL09uRW5jb2RlZFN5bmNQRGF0YS5qcyc7XG5cbi8vIG90aGVyXG5pbXBvcnQgeyBScGNUeXBlIH0gZnJvbSAnLi9lbnVtcy9ScGNUeXBlLmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgSnNvblJwY01hcnNoYWxsZXIgfSBmcm9tICcuLy4uL3V0aWwvSnNvblJwY01hcnNoYWxsZXIuanMnO1xuaW1wb3J0IHsgQmluYXJ5RnJhbWVIZWFkZXIgfSBmcm9tICcuLy4uL3Byb3RvY29sL0JpbmFyeUZyYW1lSGVhZGVyLmpzJztcblxuY2xhc3MgUnBjQ3JlYXRvciB7XG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYW4gU2RsUGFja2V0IHRvIGFuIFJwY01lc3NhZ2VcbiAgICAgKiBAcGFyYW0ge1NkbFBhY2tldH0gc2RsUGFja2V0XG4gICAgICogQHJldHVybiB7UnBjTWVzc2FnZX1cbiAgICAgKi9cbiAgICBzdGF0aWMgY29uc3RydWN0IChzZGxQYWNrZXQpIHtcbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IHNkbFBhY2tldC5nZXRQYXlsb2FkKCk7XG4gICAgICAgIGNvbnN0IGJpbmFyeUZyYW1lSGVhZGVyID0gQmluYXJ5RnJhbWVIZWFkZXIuZnJvbUJpbmFyeUhlYWRlcihwYXlsb2FkKTtcblxuICAgICAgICBsZXQgbWVzc2FnZTtcbiAgICAgICAgY29uc3QgcnBjVHlwZSA9IGJpbmFyeUZyYW1lSGVhZGVyLmdldFJwY1R5cGUoKTtcbiAgICAgICAgY29uc3QgcnBjTmFtZSA9IFJwY1R5cGUua2V5Rm9yVmFsdWUocnBjVHlwZSk7XG4gICAgICAgIGNvbnN0IGNvcnJlbGF0aW9uSWQgPSBiaW5hcnlGcmFtZUhlYWRlci5nZXRDb3JyZWxhdGlvbklkKCk7XG4gICAgICAgIGNvbnN0IGZ1bmN0aW9uSWQgPSBiaW5hcnlGcmFtZUhlYWRlci5nZXRGdW5jdGlvbklkKCk7XG4gICAgICAgIGNvbnN0IGZ1bmN0aW9uTmFtZSA9IEZ1bmN0aW9uSUQua2V5Rm9yVmFsdWUoZnVuY3Rpb25JZCk7XG4gICAgICAgIGNvbnN0IGJ1bGtEYXRhID0gYmluYXJ5RnJhbWVIZWFkZXIuZ2V0QnVsa0RhdGEoKTtcbiAgICAgICAgY29uc3QganNvbkRhdGEgPSBiaW5hcnlGcmFtZUhlYWRlci5nZXRKc29uRGF0YSgpO1xuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgICBwYXJhbWV0ZXJzOiBKc29uUnBjTWFyc2hhbGxlci51bm1hcnNoYWxsKGpzb25EYXRhKSxcbiAgICAgICAgfTtcblxuICAgICAgICBzd2l0Y2ggKGZ1bmN0aW9uSWQpIHtcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5SZWdpc3RlckFwcEludGVyZmFjZTpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgUmVnaXN0ZXJBcHBJbnRlcmZhY2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELlVucmVnaXN0ZXJBcHBJbnRlcmZhY2U6XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVRVUVTVCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFVucmVnaXN0ZXJBcHBJbnRlcmZhY2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBVbnJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuQ3JlYXRlV2luZG93OlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBDcmVhdGVXaW5kb3cocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBDcmVhdGVXaW5kb3dSZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5EZWxldGVXaW5kb3c6XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVRVUVTVCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IERlbGV0ZVdpbmRvdyhwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IERlbGV0ZVdpbmRvd1Jlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELlNldEdsb2JhbFByb3BlcnRpZXM6XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVRVUVTVCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFNldEdsb2JhbFByb3BlcnRpZXMocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBTZXRHbG9iYWxQcm9wZXJ0aWVzUmVzcG9uc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuUmVzZXRHbG9iYWxQcm9wZXJ0aWVzOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBSZXNldEdsb2JhbFByb3BlcnRpZXMocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBSZXNldEdsb2JhbFByb3BlcnRpZXNSZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5BZGRDb21tYW5kOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBBZGRDb21tYW5kKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFU1BPTlNFKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgQWRkQ29tbWFuZFJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELkRlbGV0ZUNvbW1hbmQ6XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVRVUVTVCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IERlbGV0ZUNvbW1hbmQocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBEZWxldGVDb21tYW5kUmVzcG9uc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuQWRkU3ViTWVudTpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgQWRkU3ViTWVudShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IEFkZFN1Yk1lbnVSZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5EZWxldGVTdWJNZW51OlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBEZWxldGVTdWJNZW51KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFU1BPTlNFKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgRGVsZXRlU3ViTWVudVJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELlNob3dBcHBNZW51OlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBTaG93QXBwTWVudShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFNob3dBcHBNZW51UmVzcG9uc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuQ3JlYXRlSW50ZXJhY3Rpb25DaG9pY2VTZXQ6XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVRVUVTVCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IENyZWF0ZUludGVyYWN0aW9uQ2hvaWNlU2V0KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFU1BPTlNFKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgQ3JlYXRlSW50ZXJhY3Rpb25DaG9pY2VTZXRSZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5QZXJmb3JtSW50ZXJhY3Rpb246XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVRVUVTVCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFBlcmZvcm1JbnRlcmFjdGlvbihwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFBlcmZvcm1JbnRlcmFjdGlvblJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELkRlbGV0ZUludGVyYWN0aW9uQ2hvaWNlU2V0OlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBEZWxldGVJbnRlcmFjdGlvbkNob2ljZVNldChwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IERlbGV0ZUludGVyYWN0aW9uQ2hvaWNlU2V0UmVzcG9uc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuQWxlcnQ6XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVRVUVTVCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IEFsZXJ0KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFU1BPTlNFKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgQWxlcnRSZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5TaG93OlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBTaG93KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFU1BPTlNFKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgU2hvd1Jlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELlNwZWFrOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBTcGVhayhwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFNwZWFrUmVzcG9uc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuU2V0TWVkaWFDbG9ja1RpbWVyOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBTZXRNZWRpYUNsb2NrVGltZXIocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBTZXRNZWRpYUNsb2NrVGltZXJSZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5QZXJmb3JtQXVkaW9QYXNzVGhydTpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgUGVyZm9ybUF1ZGlvUGFzc1RocnUocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBQZXJmb3JtQXVkaW9QYXNzVGhydVJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELkVuZEF1ZGlvUGFzc1RocnU6XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVRVUVTVCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IEVuZEF1ZGlvUGFzc1RocnUocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBFbmRBdWRpb1Bhc3NUaHJ1UmVzcG9uc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuU3Vic2NyaWJlQnV0dG9uOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBTdWJzY3JpYmVCdXR0b24ocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBTdWJzY3JpYmVCdXR0b25SZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5VbnN1YnNjcmliZUJ1dHRvbjpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgVW5zdWJzY3JpYmVCdXR0b24ocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBVbnN1YnNjcmliZUJ1dHRvblJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELlN1YnNjcmliZVZlaGljbGVEYXRhOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBTdWJzY3JpYmVWZWhpY2xlRGF0YShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuVW5zdWJzY3JpYmVWZWhpY2xlRGF0YTpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgVW5zdWJzY3JpYmVWZWhpY2xlRGF0YShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFVuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5HZXRWZWhpY2xlRGF0YTpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgR2V0VmVoaWNsZURhdGEocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBHZXRWZWhpY2xlRGF0YVJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELlJlYWRESUQ6XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVRVUVTVCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFJlYWRESUQocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBSZWFkRElEUmVzcG9uc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuR2V0RFRDczpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgR2V0RFRDcyhwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IEdldERUQ3NSZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5EaWFnbm9zdGljTWVzc2FnZTpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgRGlhZ25vc3RpY01lc3NhZ2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBEaWFnbm9zdGljTWVzc2FnZVJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELlNjcm9sbGFibGVNZXNzYWdlOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBTY3JvbGxhYmxlTWVzc2FnZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFNjcm9sbGFibGVNZXNzYWdlUmVzcG9uc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuU2xpZGVyOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBTbGlkZXIocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBTbGlkZXJSZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5TaG93Q29uc3RhbnRUQlQ6XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVRVUVTVCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFNob3dDb25zdGFudFRCVChwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFNob3dDb25zdGFudFRCVFJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELkFsZXJ0TWFuZXV2ZXI6XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVRVUVTVCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IEFsZXJ0TWFuZXV2ZXIocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBBbGVydE1hbmV1dmVyUmVzcG9uc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuVXBkYXRlVHVybkxpc3Q6XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVRVUVTVCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFVwZGF0ZVR1cm5MaXN0KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFU1BPTlNFKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgVXBkYXRlVHVybkxpc3RSZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5DaGFuZ2VSZWdpc3RyYXRpb246XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVRVUVTVCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IENoYW5nZVJlZ2lzdHJhdGlvbihwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IENoYW5nZVJlZ2lzdHJhdGlvblJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELkdlbmVyaWNSZXNwb25zZTpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IEdlbmVyaWNSZXNwb25zZVJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELlB1dEZpbGU6XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVRVUVTVCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFB1dEZpbGUocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBQdXRGaWxlUmVzcG9uc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuR2V0RmlsZTpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgR2V0RmlsZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IEdldEZpbGVSZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5EZWxldGVGaWxlOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBEZWxldGVGaWxlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFU1BPTlNFKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgRGVsZXRlRmlsZVJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELkxpc3RGaWxlczpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgTGlzdEZpbGVzKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFU1BPTlNFKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgTGlzdEZpbGVzUmVzcG9uc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuU2V0QXBwSWNvbjpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgU2V0QXBwSWNvbihwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFNldEFwcEljb25SZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5TZXREaXNwbGF5TGF5b3V0OlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBTZXREaXNwbGF5TGF5b3V0KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFU1BPTlNFKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgU2V0RGlzcGxheUxheW91dFJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELlN5c3RlbVJlcXVlc3Q6XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVRVUVTVCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFN5c3RlbVJlcXVlc3QocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBTeXN0ZW1SZXF1ZXN0UmVzcG9uc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuU2VuZExvY2F0aW9uOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBTZW5kTG9jYXRpb24ocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBTZW5kTG9jYXRpb25SZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5EaWFsTnVtYmVyOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBEaWFsTnVtYmVyKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFU1BPTlNFKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgRGlhbE51bWJlclJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELkJ1dHRvblByZXNzOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBCdXR0b25QcmVzcyhwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IEJ1dHRvblByZXNzUmVzcG9uc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuR2V0SW50ZXJpb3JWZWhpY2xlRGF0YTpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgR2V0SW50ZXJpb3JWZWhpY2xlRGF0YShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IEdldEludGVyaW9yVmVoaWNsZURhdGFSZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5HZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudDpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgR2V0SW50ZXJpb3JWZWhpY2xlRGF0YUNvbnNlbnQocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBHZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudFJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELlJlbGVhc2VJbnRlcmlvclZlaGljbGVEYXRhTW9kdWxlOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBSZWxlYXNlSW50ZXJpb3JWZWhpY2xlRGF0YU1vZHVsZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFJlbGVhc2VJbnRlcmlvclZlaGljbGVEYXRhTW9kdWxlUmVzcG9uc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuU2V0SW50ZXJpb3JWZWhpY2xlRGF0YTpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgU2V0SW50ZXJpb3JWZWhpY2xlRGF0YShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFNldEludGVyaW9yVmVoaWNsZURhdGFSZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5TdWJzY3JpYmVXYXlQb2ludHM6XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVRVUVTVCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFN1YnNjcmliZVdheVBvaW50cyhwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFN1YnNjcmliZVdheVBvaW50c1Jlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELkdldFdheVBvaW50czpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgR2V0V2F5UG9pbnRzKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFU1BPTlNFKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgR2V0V2F5UG9pbnRzUmVzcG9uc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuVW5zdWJzY3JpYmVXYXlQb2ludHM6XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVRVUVTVCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFVuc3Vic2NyaWJlV2F5UG9pbnRzKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFU1BPTlNFKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgVW5zdWJzY3JpYmVXYXlQb2ludHNSZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5HZXRTeXN0ZW1DYXBhYmlsaXR5OlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBHZXRTeXN0ZW1DYXBhYmlsaXR5KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFU1BPTlNFKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgR2V0U3lzdGVtQ2FwYWJpbGl0eVJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELlNlbmRIYXB0aWNEYXRhOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBTZW5kSGFwdGljRGF0YShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFNlbmRIYXB0aWNEYXRhUmVzcG9uc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuU2V0Q2xvdWRBcHBQcm9wZXJ0aWVzOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBTZXRDbG91ZEFwcFByb3BlcnRpZXMocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBTZXRDbG91ZEFwcFByb3BlcnRpZXNSZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5HZXRDbG91ZEFwcFByb3BlcnRpZXM6XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVRVUVTVCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IEdldENsb3VkQXBwUHJvcGVydGllcyhwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IEdldENsb3VkQXBwUHJvcGVydGllc1Jlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELlB1Ymxpc2hBcHBTZXJ2aWNlOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBQdWJsaXNoQXBwU2VydmljZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFB1Ymxpc2hBcHBTZXJ2aWNlUmVzcG9uc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuVW5wdWJsaXNoQXBwU2VydmljZTpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgVW5wdWJsaXNoQXBwU2VydmljZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFVucHVibGlzaEFwcFNlcnZpY2VSZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5HZXRBcHBTZXJ2aWNlRGF0YTpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5SRVFVRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgR2V0QXBwU2VydmljZURhdGEocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBHZXRBcHBTZXJ2aWNlRGF0YVJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELlBlcmZvcm1BcHBTZXJ2aWNlSW50ZXJhY3Rpb246XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVRVUVTVCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IFBlcmZvcm1BcHBTZXJ2aWNlSW50ZXJhY3Rpb24ocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVTUE9OU0UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBQZXJmb3JtQXBwU2VydmljZUludGVyYWN0aW9uUmVzcG9uc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuQ2FuY2VsSW50ZXJhY3Rpb246XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuUkVRVUVTVCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IENhbmNlbEludGVyYWN0aW9uKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFU1BPTlNFKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgQ2FuY2VsSW50ZXJhY3Rpb25SZXNwb25zZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5DbG9zZUFwcGxpY2F0aW9uOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBDbG9zZUFwcGxpY2F0aW9uKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFU1BPTlNFKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgQ2xvc2VBcHBsaWNhdGlvblJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELk9uSE1JU3RhdHVzOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLk5PVElGSUNBVElPTikge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IE9uSE1JU3RhdHVzKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELk9uQXBwSW50ZXJmYWNlVW5yZWdpc3RlcmVkOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLk5PVElGSUNBVElPTikge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IE9uQXBwSW50ZXJmYWNlVW5yZWdpc3RlcmVkKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELk9uQnV0dG9uRXZlbnQ6XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuTk9USUZJQ0FUSU9OKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgT25CdXR0b25FdmVudChwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5PbkJ1dHRvblByZXNzOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLk5PVElGSUNBVElPTikge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IE9uQnV0dG9uUHJlc3MocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuT25WZWhpY2xlRGF0YTpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5OT1RJRklDQVRJT04pIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBPblZlaGljbGVEYXRhKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELk9uQ29tbWFuZDpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5OT1RJRklDQVRJT04pIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBPbkNvbW1hbmQocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuT25UQlRDbGllbnRTdGF0ZTpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5OT1RJRklDQVRJT04pIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBPblRCVENsaWVudFN0YXRlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELk9uRHJpdmVyRGlzdHJhY3Rpb246XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuTk9USUZJQ0FUSU9OKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgT25Ecml2ZXJEaXN0cmFjdGlvbihwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5PblBlcm1pc3Npb25zQ2hhbmdlOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLk5PVElGSUNBVElPTikge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IE9uUGVybWlzc2lvbnNDaGFuZ2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuT25BdWRpb1Bhc3NUaHJ1OlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLk5PVElGSUNBVElPTikge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IE9uQXVkaW9QYXNzVGhydShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5Pbkxhbmd1YWdlQ2hhbmdlOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLk5PVElGSUNBVElPTikge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IE9uTGFuZ3VhZ2VDaGFuZ2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuT25LZXlib2FyZElucHV0OlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLk5PVElGSUNBVElPTikge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IE9uS2V5Ym9hcmRJbnB1dChwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5PblRvdWNoRXZlbnQ6XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuTk9USUZJQ0FUSU9OKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgT25Ub3VjaEV2ZW50KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELk9uU3lzdGVtUmVxdWVzdDpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5OT1RJRklDQVRJT04pIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBPblN5c3RlbVJlcXVlc3QocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuT25IYXNoQ2hhbmdlOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLk5PVElGSUNBVElPTikge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IE9uSGFzaENoYW5nZShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5PbldheVBvaW50Q2hhbmdlOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLk5PVElGSUNBVElPTikge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IE9uV2F5UG9pbnRDaGFuZ2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuT25JbnRlcmlvclZlaGljbGVEYXRhOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLk5PVElGSUNBVElPTikge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IE9uSW50ZXJpb3JWZWhpY2xlRGF0YShwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5PblJDU3RhdHVzOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLk5PVElGSUNBVElPTikge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbmV3IE9uUkNTdGF0dXMocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuT25BcHBTZXJ2aWNlRGF0YTpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5OT1RJRklDQVRJT04pIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBPbkFwcFNlcnZpY2VEYXRhKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELk9uU3lzdGVtQ2FwYWJpbGl0eVVwZGF0ZWQ6XG4gICAgICAgICAgICAgICAgaWYgKHJwY1R5cGUgPT09IFJwY1R5cGUuTk9USUZJQ0FUSU9OKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgT25TeXN0ZW1DYXBhYmlsaXR5VXBkYXRlZChwYXJhbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRnVuY3Rpb25JRC5FbmNvZGVkU3luY1BEYXRhOlxuICAgICAgICAgICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBFbmNvZGVkU3luY1BEYXRhKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFU1BPTlNFKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgRW5jb2RlZFN5bmNQRGF0YVJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELk9uRW5jb2RlZFN5bmNQRGF0YTpcbiAgICAgICAgICAgICAgICBpZiAocnBjVHlwZSA9PT0gUnBjVHlwZS5OT1RJRklDQVRJT04pIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBPbkVuY29kZWRTeW5jUERhdGEocGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1lc3NhZ2UgPT09IG51bGwgfHwgbWVzc2FnZSA9PT0gdW5kZWZpbmVkKSB7IC8vIGluZm9ybXMgb2YgbWlzc2luZyBjbGFzc2VzXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYFJwY0NyZWF0b3IgY291bGRuJ3QgY29uc3RydWN0IGFuIFJQQyBmb3IgdGhlICR7ZnVuY3Rpb25OYW1lfSAke3JwY05hbWV9YCk7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChycGNUeXBlID09PSBScGNUeXBlLlJFUVVFU1QgfHwgcnBjVHlwZSA9PT0gUnBjVHlwZS5SRVNQT05TRSkge1xuICAgICAgICAgICAgbWVzc2FnZS5zZXRDb3JyZWxhdGlvbklkKGNvcnJlbGF0aW9uSWQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChidWxrRGF0YSkge1xuICAgICAgICAgICAgbWVzc2FnZS5zZXRCdWxrRGF0YShidWxrRGF0YSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9XG59XG5cblxuZXhwb3J0IHsgUnBjQ3JlYXRvciB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBNZXNzYWdlRnJhbWVEaXNhc3NlbWJsZXIgfSBmcm9tICcuL01lc3NhZ2VGcmFtZURpc2Fzc2VtYmxlci5qcyc7XG5pbXBvcnQgeyBUcmFuc3BvcnRMaXN0ZW5lciB9IGZyb20gJy4uL3RyYW5zcG9ydC9UcmFuc3BvcnRMaXN0ZW5lci5qcyc7XG5pbXBvcnQgeyBWZXJzaW9uIH0gZnJvbSAnLi4vdXRpbC9WZXJzaW9uLmpzJztcbmltcG9ydCB7IFNlcnZpY2VUeXBlIH0gZnJvbSAnLi9lbnVtcy9TZXJ2aWNlVHlwZS5qcyc7XG5pbXBvcnQgeyBGcmFtZVR5cGUgfSBmcm9tICcuL2VudW1zL0ZyYW1lVHlwZS5qcyc7XG5pbXBvcnQgeyBNZXNzYWdlRnJhbWVBc3NlbWJsZXIgfSBmcm9tICcuL01lc3NhZ2VGcmFtZUFzc2VtYmxlci5qcyc7XG5pbXBvcnQgeyBTZGxQYWNrZXQgfSBmcm9tICcuL1NkbFBhY2tldC5qcyc7XG5pbXBvcnQgeyBDb250cm9sRnJhbWVUYWdzIH0gZnJvbSAnLi9lbnVtcy9Db250cm9sRnJhbWVUYWdzLmpzJztcbmltcG9ydCB7IEJpdENvbnZlcnRlciB9IGZyb20gJy4vLi4vdXRpbC9CaXRDb252ZXJ0ZXIuanMnO1xuXG5pbXBvcnQgeyBTZGxQYWNrZXRGYWN0b3J5IH0gZnJvbSAnLi9TZGxQYWNrZXRGYWN0b3J5LmpzJztcbmltcG9ydCB7IFJwY0NyZWF0b3IgfSBmcm9tICcuLy4uL3JwYy9ScGNDcmVhdG9yLmpzJztcbmltcG9ydCB7IEltYWdlUmVzb2x1dGlvbiB9IGZyb20gJy4uL3JwYy9zdHJ1Y3RzL0ltYWdlUmVzb2x1dGlvbi5qcyc7XG5pbXBvcnQgeyBWaWRlb1N0cmVhbWluZ0Zvcm1hdCB9IGZyb20gJy4uL3JwYy9zdHJ1Y3RzL1ZpZGVvU3RyZWFtaW5nRm9ybWF0LmpzJztcblxuLyoqXG4gKiBCYXNlIGltcGxlbWVudGF0aW9uIG9mIHNkbCBwcm90b2NvbC5cbiAqIFNob3VsZCBiZSBhYmxlIHRvIGhhbmRsZSBiYXNpYyBjb250cm9sIGZyYW1lcyBhbmQgYmUgYWJsZSB0b1xuICogc2VuZCBhbmQgcmVjZWl2ZSBwYWNrZXRzIGZyb20gdGhlIHRyYW5zcG9ydCBtYW5hZ2VyLlxuICogQWxzbyBzZW5kcyBrZXkgZXZlbnRzIHRvIHRoZSBzZGxQcm90b2NvbExpc3RlbmVyLlxuICovXG5jbGFzcyBTZGxQcm90b2NvbEJhc2Uge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHsgVHJhbnNwb3J0Q29uZmlnQmFzZSB9IGJhc2VUcmFuc3BvcnRDb25maWdcbiAgICAgKiBAcGFyYW0geyBTZGxQcm90b2NvbExpc3RlbmVyIH0gc2RsUHJvdG9jb2xMaXN0ZW5lclxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChiYXNlVHJhbnNwb3J0Q29uZmlnLCBzZGxQcm90b2NvbExpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMuX2Jhc2VUcmFuc3BvcnRDb25maWcgPSBiYXNlVHJhbnNwb3J0Q29uZmlnO1xuICAgICAgICB0aGlzLl90cmFuc3BvcnRDb25maWcgPSBiYXNlVHJhbnNwb3J0Q29uZmlnO1xuICAgICAgICB0aGlzLl9zZGxQcm90b2NvbExpc3RlbmVyID0gc2RsUHJvdG9jb2xMaXN0ZW5lcjtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0TWFuYWdlciA9IG51bGw7XG5cbiAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgICAgICB0aGlzLl9jcmVhdGVUcmFuc3BvcnRMaXN0ZW5lcigpO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogUmVzZXRzIHRoZSBzZGwgcHJvdG9jb2wgdG8gaXRzIGRlZmF1bHQgc3RhdGUuXG4gICAgICovXG4gICAgcmVzZXQgKCkge1xuICAgICAgICB0aGlzLl9wcm90b2NvbFZlcnNpb24gPSBuZXcgVmVyc2lvbigxLCAwLCAwKTtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q29uZmlnID0gdGhpcy5fYmFzZVRyYW5zcG9ydENvbmZpZztcbiAgICAgICAgdGhpcy5faGVhZGVyU2l6ZSA9IFNkbFByb3RvY29sQmFzZS5WMV9IRUFERVJfU0laRTtcbiAgICAgICAgdGhpcy5fc2VydmljZVN0YXR1cyA9IHt9O1xuICAgICAgICB0aGlzLl9zZXJ2aWNlU3RhdHVzW1NlcnZpY2VUeXBlLkNPTlRST0xdID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fbXR1cyA9IHt9O1xuICAgICAgICB0aGlzLl9tdHVzW1NlcnZpY2VUeXBlLlJQQ10gPSBTZGxQcm90b2NvbEJhc2UuVjFfVjJfTVRVX1NJWkUgLSB0aGlzLl9oZWFkZXJTaXplO1xuICAgICAgICB0aGlzLl9oYXNoSUQgPSAwO1xuICAgICAgICB0aGlzLl9tZXNzYWdlRnJhbWVBc3NlbWJsZXJzID0ge307XG4gICAgICAgIHRoaXMuX21lc3NhZ2VJRCA9IDE7XG4gICAgICAgIHRoaXMuX3Nlc3Npb25JRCA9IDA7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBTZXRzIGEgdHJhbnNwb3J0IG1hbmFnZXIuXG4gICAgICogQHBhcmFtIHsgVHJhbnNwb3J0TWFuYWdlckJhc2UgfSBtYW5hZ2VyXG4gICAgICovXG4gICAgc2V0VHJhbnNwb3J0TWFuYWdlciAobWFuYWdlcikge1xuICAgICAgICBpZiAoIXRoaXMuX3NlcnZpY2VTdGF0dXNbU2VydmljZVR5cGUuUlBDXSkge1xuICAgICAgICAgICAgLy8gUlBDIHNlcnZpY2UgaGFzbid0IGJlZW4gc3RhcnRlZCwgbGV0cyBzdGFydCBpdFxuICAgICAgICAgICAgdGhpcy5zdGFydFNlcnZpY2UoU2VydmljZVR5cGUuUlBDLCAwLCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0TWFuYWdlciA9IG1hbmFnZXI7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIHRoZSB0cmFuc3BvcnQgbGlzdGVuZXIuIFRoaXMgd2lsbCByZWNpZXZlIGluY29taW5nIHJlcXVlc3RzXG4gICAgICogZnJvbSB0aGUgdHJhbnNwb3J0IG1hbmFnZXIuXG4gICAgICovXG4gICAgX2NyZWF0ZVRyYW5zcG9ydExpc3RlbmVyICgpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICAgIHRoaXMuX3RyYW5zcG9ydExpc3RlbmVyID0gbmV3IFRyYW5zcG9ydExpc3RlbmVyKCk7XG4gICAgICAgIHRoaXMuX3RyYW5zcG9ydExpc3RlbmVyLnNldE9uVHJhbnNwb3J0Q29ubmVjdGVkKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNlbGYuX2hhbmRsZVRyYW5zcG9ydENvbm5lY3RlZCgpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0TGlzdGVuZXIuc2V0T25UcmFuc3BvcnREaXNjb25uZWN0ZWQoZnVuY3Rpb24gKCkge1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0TGlzdGVuZXIuc2V0T25QYWNrZXRSZWNlaXZlZChmdW5jdGlvbiAoc2RsUGFja2V0KSB7XG4gICAgICAgICAgICBzZWxmLl9oYW5kbGVQYWNrZXRSZWNlaXZlZChzZGxQYWNrZXQpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0TGlzdGVuZXIuc2V0T25FcnJvcihmdW5jdGlvbiAoKSB7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIF9oYW5kbGVUcmFuc3BvcnRDb25uZWN0ZWQgKCkge1xuICAgICAgICB0aGlzLl9zZGxQcm90b2NvbExpc3RlbmVyLm9uVHJhbnNwb3J0Q29ubmVjdGVkKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3RhcnRzIHVwIHRoZSBTREwgcHJvdG9jb2wgY2xhc3MuIEl0IHdpbGwga2ljayBvZmYgdGhlIHRyYW5zcG9ydCBtYW5hZ2VyIGFuZCB1bmRlcmx5aW5nIHRyYW5zcG9ydC5cbiAgICAgKi9cbiAgICBzdGFydCAoKSB7XG4gICAgICAgIGlmICghdGhpcy5fdHJhbnNwb3J0TWFuYWdlcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIHRyYW5zcG9ydCBtYW5hZ2VyIG11c3QgYmUgZGVmaW5lZCwgdW5hYmxlIHRvIHN0YXJ0IFNETCBQcm90b2NvbCcpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3RyYW5zcG9ydE1hbmFnZXIuc3RhcnQoKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBzZXJ2aWNlLiBUaGlzIGlzIHRoZSBmaXJzdCBzdGVwIGluIGNvbW11bmljYXRpbmcgd2l0aCBzZGwgY29yZS5cbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzZXNzaW9uSURcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGlzRW5jcnlwdGVkXG4gICAgICovXG4gICAgc3RhcnRTZXJ2aWNlIChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklELCBpc0VuY3J5cHRlZCkge1xuICAgICAgICBjb25zdCBwcm90b2NvbFZlcnNpb24gPSB0aGlzLmNvbnN0cnVjdG9yLk1BWF9QUk9UT0NPTF9WRVJTSU9OO1xuICAgICAgICBjb25zdCBtZXNzYWdlSUQgPSAwO1xuICAgICAgICBjb25zdCBoZWFkZXIgPSBuZXcgU2RsUGFja2V0KHByb3RvY29sVmVyc2lvbi5nZXRNYWpvcigpLCBpc0VuY3J5cHRlZCwgRnJhbWVUeXBlLkNPTlRST0wsXG4gICAgICAgICAgICBzZXJ2aWNlVHlwZSwgU2RsUGFja2V0LkZSQU1FX0lORk9fU1RBUlRfU0VSVklDRSwgc2Vzc2lvbklELFxuICAgICAgICAgICAgMCwgbWVzc2FnZUlELCBudWxsKTtcbiAgICAgICAgaWYgKHNlcnZpY2VUeXBlID09PSBTZXJ2aWNlVHlwZS5BVURJTykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2VuZFBhY2tldChoZWFkZXIpO1xuICAgICAgICB9IGVsc2UgaWYgKHNlcnZpY2VUeXBlID09PSBTZXJ2aWNlVHlwZS5SUEMpIHtcbiAgICAgICAgICAgIGhlYWRlci5wdXRUYWcoQ29udHJvbEZyYW1lVGFncy5SUEMuU3RhcnRTZXJ2aWNlLlBST1RPQ09MX1ZFUlNJT04sIHByb3RvY29sVmVyc2lvbi50b1N0cmluZygpKTtcbiAgICAgICAgfSBlbHNlIGlmIChzZXJ2aWNlVHlwZSA9PT0gU2VydmljZVR5cGUuVklERU8pIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9zZGxQcm90b2NvbExpc3RlbmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdmlkZW9TdHJlYW1pbmdQYXJhbWV0ZXJzID0gdGhpcy5fc2RsUHJvdG9jb2xMaXN0ZW5lci5nZXREZXNpcmVkVmlkZW9QYXJhbXMoKTtcbiAgICAgICAgICAgICAgICBpZiAodmlkZW9TdHJlYW1pbmdQYXJhbWV0ZXJzICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRlc2lyZWRSZXNvbHV0aW9uID0gdmlkZW9TdHJlYW1pbmdQYXJhbWV0ZXJzLmdldFJlc29sdXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVzaXJlZEZvcm1hdCA9IHZpZGVvU3RyZWFtaW5nUGFyYW1ldGVycy5nZXRGb3JtYXQoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlc2lyZWRSZXNvbHV0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBoZWFkZXIucHV0VGFnKENvbnRyb2xGcmFtZVRhZ3MuVmlkZW8uU3RhcnRTZXJ2aWNlLldJRFRILCBkZXNpcmVkUmVzb2x1dGlvbi5nZXRSZXNvbHV0aW9uV2lkdGgoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBoZWFkZXIucHV0VGFnKENvbnRyb2xGcmFtZVRhZ3MuVmlkZW8uU3RhcnRTZXJ2aWNlLkhFSUdIVCwgZGVzaXJlZFJlc29sdXRpb24uZ2V0UmVzb2x1dGlvbkhlaWdodCgpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZGVzaXJlZEZvcm1hdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyLnB1dFRhZyhDb250cm9sRnJhbWVUYWdzLlZpZGVvLlN0YXJ0U2VydmljZS5WSURFT19DT0RFQywgZGVzaXJlZEZvcm1hdC5nZXRDb2RlYygpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlci5wdXRUYWcoQ29udHJvbEZyYW1lVGFncy5WaWRlby5TdGFydFNlcnZpY2UuVklERU9fUFJPVE9DT0wsIGRlc2lyZWRGb3JtYXQuZ2V0UHJvdG9jb2woKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zZW5kUGFja2V0KGhlYWRlcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NlcnZpY2UgdHlwZSBub3QgaW1wbGVtZW50ZWQnKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNlbmRQYWNrZXQoaGVhZGVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAgR2V0IHRoZSBtYXggdHJhbnNwb3J0IHVuaXQgb2YgYSBzcGVjaWZpYyBzZXJ2aWNlIHR5cGUuXG4gICAgICogQHBhcmFtIHsgU2VydmljZVR5cGUgfSBzZXJ2aWNlVHlwZVxuICAgICAqIEByZXR1cm4ge251bWJlcn0gbWF4IHRyYW5zcG9ydCB1bml0IGZvciB0aGUgZ2l2ZW4gc2VydmljZSB0eXBlXG4gICAgICovXG4gICAgZ2V0TXR1IChzZXJ2aWNlVHlwZSkge1xuICAgICAgICBjb25zdCByZXRWYWwgPSB0aGlzLl9tdHVzW3NlcnZpY2VUeXBlXTtcbiAgICAgICAgaWYgKHJldFZhbCkge1xuICAgICAgICAgICAgcmV0dXJuIHJldFZhbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gU2RsUHJvdG9jb2xCYXNlLlYxX1YyX01UVV9TSVpFO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0cmFuc3BvcnQgbWFuYWdlciBpcyBjb25uZWN0ZWQuXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn0gaXNDb25uZWN0ZWRcbiAgICAgKi9cbiAgICBpc0Nvbm5lY3RlZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnRNYW5hZ2VyICYmIHRoaXMuX3RyYW5zcG9ydE1hbmFnZXIuaXNDb25uZWN0ZWQobnVsbCwgbnVsbCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjdXJyZW50IHByb3RvY29sIHZlcnNpb24gaW4gdXNlLlxuICAgICAqIEByZXR1cm5zIHtWZXJzaW9ufSBwcm90b2NvbCB2ZXJzaW9uXG4gICAgICovXG4gICAgZ2V0UHJvdG9jb2xWZXJzaW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Byb3RvY29sVmVyc2lvbjtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIHdpbGwgc2V0IHRoZSBtYWpvciBwcm90b2NvbCB2ZXJzaW9uIHRoYXQgd2Ugc2hvdWxkIHVzZS5cbiAgICAgKiBJdCB3aWxsIGFsc28gc2V0IHRoZSBkZWZhdWx0IE1UVSBiYXNlZCBvbiB2ZXJzaW9uLlxuICAgICAqIEBwYXJhbSB7IG51bWJlciB9IHZlcnNpb24gbWFqb3IgdmVyc2lvbiB0byB1c2VcbiAgICAgKi9cbiAgICBfc2V0VmVyc2lvbiAodmVyc2lvbikge1xuICAgICAgICBpZiAodmVyc2lvbiA+IDUpIHtcbiAgICAgICAgICAgIHRoaXMuX3Byb3RvY29sVmVyc2lvbiA9IG5ldyBWZXJzaW9uKCc1LjEuMCcpOyAvLyBwcm90ZWN0IGZvciBmdXR1cmUsIHByb3h5IG9ubHkgc3VwcG9ydHMgdjUgb3IgbG93ZXJcbiAgICAgICAgICAgIHRoaXMuaGVhZGVyU2l6ZSA9IHRoaXMuY29uc3RydWN0b3IuVjJfSEVBREVSX1NJWkU7XG4gICAgICAgICAgICB0aGlzLl9tdHVzW1NlcnZpY2VUeXBlLlJQQ10gPSB0aGlzLmNvbnN0cnVjdG9yLlYzX1Y0X01UVV9TSVpFO1xuICAgICAgICB9IGVsc2UgaWYgKHZlcnNpb24gPT09IDUpIHtcbiAgICAgICAgICAgIHRoaXMuX3Byb3RvY29sVmVyc2lvbiA9IG5ldyBWZXJzaW9uKCc1LjAuMCcpO1xuICAgICAgICAgICAgdGhpcy5oZWFkZXJTaXplID0gdGhpcy5jb25zdHJ1Y3Rvci5WMl9IRUFERVJfU0laRTtcbiAgICAgICAgICAgIHRoaXMuX210dXNbU2VydmljZVR5cGUuUlBDXSA9IHRoaXMuY29uc3RydWN0b3IuVjNfVjRfTVRVX1NJWkU7XG4gICAgICAgIH0gZWxzZSBpZiAodmVyc2lvbiA9PT0gNCkge1xuICAgICAgICAgICAgdGhpcy5fcHJvdG9jb2xWZXJzaW9uID0gbmV3IFZlcnNpb24oJzQuMC4wJyk7XG4gICAgICAgICAgICB0aGlzLmhlYWRlclNpemUgPSB0aGlzLmNvbnN0cnVjdG9yLlYyX0hFQURFUl9TSVpFO1xuICAgICAgICAgICAgdGhpcy5fbXR1c1tTZXJ2aWNlVHlwZS5SUENdID0gdGhpcy5jb25zdHJ1Y3Rvci5WM19WNF9NVFVfU0laRTsgLy8gdmVyc2lvbnMgNCBzdXBwb3J0cyAxMjhrIE1UVVxuICAgICAgICB9IGVsc2UgaWYgKHZlcnNpb24gPT09IDMpIHtcbiAgICAgICAgICAgIHRoaXMuX3Byb3RvY29sVmVyc2lvbiA9IG5ldyBWZXJzaW9uKCczLjAuMCcpO1xuICAgICAgICAgICAgdGhpcy5oZWFkZXJTaXplID0gdGhpcy5jb25zdHJ1Y3Rvci5WMl9IRUFERVJfU0laRTtcbiAgICAgICAgICAgIHRoaXMuX210dXNbU2VydmljZVR5cGUuUlBDXSA9IHRoaXMuY29uc3RydWN0b3IuVjNfVjRfTVRVX1NJWkU7IC8vIHZlcnNpb25zIDMgc3VwcG9ydHMgMTI4ayBNVFVcbiAgICAgICAgfSBlbHNlIGlmICh2ZXJzaW9uID09PSAyKSB7XG4gICAgICAgICAgICB0aGlzLl9wcm90b2NvbFZlcnNpb24gPSBuZXcgVmVyc2lvbignMi4wLjAnKTtcbiAgICAgICAgICAgIHRoaXMuaGVhZGVyU2l6ZSA9IHRoaXMuY29uc3RydWN0b3IuVjJfSEVBREVSX1NJWkU7XG4gICAgICAgICAgICB0aGlzLl9tdHVzW1NlcnZpY2VUeXBlLlJQQ10gPSB0aGlzLmNvbnN0cnVjdG9yLlYxX1YyX01UVV9TSVpFIC0gdGhpcy5oZWFkZXJTaXplO1xuICAgICAgICB9IGVsc2UgaWYgKHZlcnNpb24gPT09IDEpIHtcbiAgICAgICAgICAgIHRoaXMuX3Byb3RvY29sVmVyc2lvbiA9IG5ldyBWZXJzaW9uKCcxLjAuMCcpO1xuICAgICAgICAgICAgdGhpcy5oZWFkZXJTaXplID0gdGhpcy5jb25zdHJ1Y3Rvci5WMV9IRUFERVJfU0laRTtcbiAgICAgICAgICAgIHRoaXMuX210dXNbU2VydmljZVR5cGUuUlBDXSA9IHRoaXMuY29uc3RydWN0b3IuVjFfVjJfTVRVX1NJWkUgLSB0aGlzLmhlYWRlclNpemU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZW5kcyBhbiBzZGxQYWNrZXQuXG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldFxuICAgICAqL1xuICAgIHNlbmRQYWNrZXQgKHNkbFBhY2tldCkge1xuICAgICAgICBpZiAodGhpcy5fdHJhbnNwb3J0TWFuYWdlcikge1xuICAgICAgICAgICAgdGhpcy5fdHJhbnNwb3J0TWFuYWdlci5zZW5kUGFja2V0KHNkbFBhY2tldCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBzZXNzaW9uSWQgaW4gdXNlLlxuICAgICAqIEByZXR1cm5zIHtOdW1iZXJ9XG4gICAgICovXG4gICAgX2dldFNlc3Npb25JZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zZGxQcm90b2NvbExpc3RlbmVyLmdldFNlc3Npb25JZCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIG5leHQgYXZhaWxhYmxlIG1lc3NhZ2VJRCBmb3Igc2VuZGluZyByZXF1ZXN0cy5cbiAgICAgKiBAcmV0dXJucyB7TnVtYmVyfVxuICAgICAqL1xuICAgIF9nZXROZXh0TWVzc2FnZUlEICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21lc3NhZ2VJRCsrO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRha2VzIGFuIHJwYyBtZXNzYWdlIGFuZCBzZW5kcyBhIHNpbmdsZSBvciBtdWx0aSBmcmFtZSBwYWNrZXRzLlxuICAgICAqIEBwYXJhbSB7UnBjUmVxdWVzdH0gcnBjTWVzc2FnZVxuICAgICAqL1xuICAgIHNlbmRScGMgKHJwY1JlcXVlc3QpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICAgIGNvbnN0IHNlc3Npb25JZCA9IHRoaXMuX2dldFNlc3Npb25JZCgpO1xuICAgICAgICBjb25zdCBtZXNzYWdlSUQgPSB0aGlzLl9nZXROZXh0TWVzc2FnZUlEKCk7XG4gICAgICAgIGNvbnN0IG10dSA9IHNlbGYuX210dXNbU2VydmljZVR5cGUuUlBDXTtcbiAgICAgICAgY29uc3QgdmVyc2lvbiA9IHNlbGYuX3Byb3RvY29sVmVyc2lvbi5nZXRNYWpvcigpO1xuICAgICAgICBjb25zdCBpc0VuY3J5cHRlZCA9IHJwY1JlcXVlc3QuZ2V0SXNFbmNyeXB0ZWQoKTtcblxuICAgICAgICBNZXNzYWdlRnJhbWVEaXNhc3NlbWJsZXIuYnVpbGRSUEMocnBjUmVxdWVzdCwgc2Vzc2lvbklkLCBtZXNzYWdlSUQsIG10dSwgdmVyc2lvbiwgaXNFbmNyeXB0ZWQsIGZ1bmN0aW9uIChzZGxQYWNrZXQpIHtcbiAgICAgICAgICAgIHNlbGYuc2VuZFBhY2tldChzZGxQYWNrZXQpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGVzIGluY29taW5nIHBhY2tldHMuXG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldFxuICAgICAqL1xuICAgIF9oYW5kbGVQYWNrZXRSZWNlaXZlZCAoc2RsUGFja2V0KSB7XG4gICAgICAgIGlmICh0aGlzLl9wcm90b2NvbFZlcnNpb24gPT09IG51bGwgfHwgdGhpcy5fcHJvdG9jb2xWZXJzaW9uLmdldE1ham9yKCkgPT09IDEpIHtcbiAgICAgICAgICAgIHRoaXMuX3NldFZlcnNpb24oc2RsUGFja2V0LmdldFZlcnNpb24oKSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZnJhbWVUeXBlID0gc2RsUGFja2V0LmdldEZyYW1lVHlwZSgpO1xuICAgICAgICBpZiAoZnJhbWVUeXBlID09PSBGcmFtZVR5cGUuQ09OVFJPTCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2hhbmRsZUNvbnRyb2xQYWNrZXQoc2RsUGFja2V0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2VGcmFtZUFzc2VtYmxlciA9IHRoaXMuX2dldE1lc3NhZ2VGcmFtZUFzc2VtYmxlcihzZGxQYWNrZXQpO1xuICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2VGcmFtZUFzc2VtYmxlci5oYW5kbGVGcmFtZShzZGxQYWNrZXQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlcyBub24tY29udHJvbCBwYWNrZXRzIGFmdGVyIHRoZXkgaGF2ZSBiZWVuIGFzc2VtYmxlZC5cbiAgICAgKiBAcGFyYW0ge1NkbFBhY2tldH0gc2RsUGFja2V0XG4gICAgICovXG4gICAgX2hhbmRsZU9uTWVzc2FnZUFzc2VtYmxlZCAoc2RsUGFja2V0KSB7XG4gICAgICAgIGNvbnN0IHNlcnZpY2VUeXBlID0gc2RsUGFja2V0LmdldFNlcnZpY2VUeXBlKCk7XG5cbiAgICAgICAgaWYgKHNlcnZpY2VUeXBlID09PSBTZXJ2aWNlVHlwZS5SUEMgfHwgc2VydmljZVR5cGUgPT09IFNlcnZpY2VUeXBlLkhZQlJJRCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2hhbmRsZVJQQ1BhY2tldChzZGxQYWNrZXQpO1xuICAgICAgICB9IGVsc2UgaWYgKHNlcnZpY2VUeXBlID09PSBTZXJ2aWNlVHlwZS5IWUJSSUQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVSUENQYWNrZXQoc2RsUGFja2V0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignVW5oYW5kbGVkIHNlcnZpY2UgdHlwZSAnLCBzZGxQYWNrZXQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBtZXNzYWdlIGZyYW1lIGFzc2VtYmxlciBmb3IgdGhlIHBhY2tldC5cbiAgICAgKiBAcGFyYW0ge1NkbFBhY2tldH0gc2RsUGFja2V0XG4gICAgICovXG4gICAgX2dldE1lc3NhZ2VGcmFtZUFzc2VtYmxlciAoc2RsUGFja2V0KSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICBsZXQgbWVzc2FnZUZyYW1lQXNzZW1ibGVyID0gc2VsZi5fbWVzc2FnZUZyYW1lQXNzZW1ibGVyc1tzZGxQYWNrZXQuZ2V0TWVzc2FnZUlEKCldO1xuICAgICAgICBpZiAoIW1lc3NhZ2VGcmFtZUFzc2VtYmxlcikge1xuICAgICAgICAgICAgbWVzc2FnZUZyYW1lQXNzZW1ibGVyID0gbmV3IE1lc3NhZ2VGcmFtZUFzc2VtYmxlcihmdW5jdGlvbiAoZXJyLCBzZGxQYWNrZXQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzZWxmLl9tZXNzYWdlRnJhbWVBc3NlbWJsZXJzW3NkbFBhY2tldC5nZXRNZXNzYWdlSUQoKV0gPSBudWxsOyAvLyBSZW1vdmUgdGhlIG1hcHBpbmdcbiAgICAgICAgICAgICAgICBzZWxmLl9oYW5kbGVPbk1lc3NhZ2VBc3NlbWJsZWQoc2RsUGFja2V0KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc2VsZi5fbWVzc2FnZUZyYW1lQXNzZW1ibGVyc1tzZGxQYWNrZXQuZ2V0TWVzc2FnZUlEKCldID0gbWVzc2FnZUZyYW1lQXNzZW1ibGVyO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2VGcmFtZUFzc2VtYmxlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGVzIGluY29taW5nIGNvbnRyb2wgcGFja2V0cy5cbiAgICAgKiBAcGFyYW0geyBTZGxQYWNrZXQgfSBzZGxQYWNrZXRcbiAgICAgKi9cbiAgICBfaGFuZGxlQ29udHJvbFBhY2tldCAoc2RsUGFja2V0KSB7XG4gICAgICAgIGNvbnN0IGZyYW1lSW5mbyA9IHNkbFBhY2tldC5nZXRGcmFtZUluZm8oKTtcblxuICAgICAgICBpZiAoZnJhbWVJbmZvID09PSBTZGxQYWNrZXQuRlJBTUVfSU5GT19IRUFSVF9CRUFUKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faGFuZGxlUHJvdG9jb2xIZWFydGJlYXQoc2RsUGFja2V0KTtcbiAgICAgICAgfSBlbHNlIGlmIChmcmFtZUluZm8gPT09IFNkbFBhY2tldC5GUkFNRV9JTkZPX0hFQVJUX0JFQVRfQUNLKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faGFuZGxlUHJvdG9jb2xIZWFydGJlYXRBQ0soc2RsUGFja2V0KTtcbiAgICAgICAgfSBlbHNlIGlmIChmcmFtZUluZm8gPT09IFNkbFBhY2tldC5GUkFNRV9JTkZPX1NUQVJUX1NFUlZJQ0VfQUNLKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faGFuZGxlU3RhcnRTZXJ2aWNlQUNLKHNkbFBhY2tldCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZnJhbWVJbmZvID09PSBTZGxQYWNrZXQuRlJBTUVfSU5GT19TVEFSVF9TRVJWSUNFX05BSykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2hhbmRsZVN0YXJ0U2VydmljZU5BSyhzZGxQYWNrZXQpO1xuICAgICAgICB9IGVsc2UgaWYgKGZyYW1lSW5mbyA9PT0gU2RsUGFja2V0LkZSQU1FX0lORk9fRU5EX1NFUlZJQ0VfQUNLKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faGFuZGxlRW5kU2VydmljZUFDSyhzZGxQYWNrZXQpO1xuICAgICAgICB9IGVsc2UgaWYgKGZyYW1lSW5mbyA9PT0gU2RsUGFja2V0LkZSQU1FX0lORk9fRU5EX1NFUlZJQ0UpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVFbmRTZXJ2aWNlKHNkbFBhY2tldCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZnJhbWVJbmZvID09PSBTZGxQYWNrZXQuRlJBTUVfSU5GT19FTkRfU0VSVklDRV9OQUspIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVFbmRTZXJ2aWNlTkFLKHNkbFBhY2tldCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1VuaGFuZGxlZCBjb250cm9sIHBhY2tldCcsIHsgZnJhbWVJbmZvIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGUgaGVhcnRiZWF0IChPbmx5IGF2YWlsYWJsZSBpbiBwcm90b2NvbCB2ZXJzaW9uIDMpXG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldFxuICAgICAqL1xuICAgIF9oYW5kbGVQcm90b2NvbEhlYXJ0YmVhdCAoc2RsUGFja2V0KSB7XG4gICAgICAgIGNvbnN0IGhlYXJ0YmVhdCA9IFNkbFBhY2tldEZhY3RvcnkuY3JlYXRlSGVhcnRiZWF0QUNLKFxuICAgICAgICAgICAgU2VydmljZVR5cGUuQ09OVFJPTCxcbiAgICAgICAgICAgIHRoaXMuX2dldFNlc3Npb25JZCgpLFxuICAgICAgICAgICAgdGhpcy5fcHJvdG9jb2xWZXJzaW9uLmdldE1ham9yKCkpO1xuICAgICAgICB0aGlzLnNlbmRQYWNrZXQoaGVhcnRiZWF0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGVzIGhlYXJ0YmVhdCBBQ0suXG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldFxuICAgICAqL1xuICAgIF9oYW5kbGVQcm90b2NvbEhlYXJ0YmVhdEFDSyAoc2RsUGFja2V0KSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBSZWNlaXZlZCBIZWFydGJlYXRBQ0sgLSAke3NkbFBhY2tldC50b1N0cmluZygpfWApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhhbmRsZXMgc3RhcnQgc2VydmljZSBBQ0suIFNldHMgdGhlIGFwcHJvcHJpYXRlIHZlcnNpb24sIE1UVSwgYW5kIG90aGVyXG4gICAgICogc2VydmljZSByZWxhdGVkIGluZm8uXG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldFxuICAgICAqL1xuICAgIF9oYW5kbGVTdGFydFNlcnZpY2VBQ0sgKHNkbFBhY2tldCkge1xuICAgICAgICBjb25zdCB2ZXJzaW9uID0gc2RsUGFja2V0LmdldFZlcnNpb24oKTtcbiAgICAgICAgY29uc3Qgc2VydmljZVR5cGUgPSBzZGxQYWNrZXQuZ2V0U2VydmljZVR5cGUoKTtcbiAgICAgICAgaWYgKHZlcnNpb24gPj0gNSkge1xuICAgICAgICAgICAgbGV0IG10dVRhZyA9IG51bGw7XG4gICAgICAgICAgICBpZiAoc2VydmljZVR5cGUgPT09IFNlcnZpY2VUeXBlLlJQQykge1xuICAgICAgICAgICAgICAgIG10dVRhZyA9IENvbnRyb2xGcmFtZVRhZ3MuUlBDLlN0YXJ0U2VydmljZUFDSy5NVFU7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHNlcnZpY2VUeXBlID09PSAoU2VydmljZVR5cGUuUENNKSkge1xuICAgICAgICAgICAgICAgIG10dVRhZyA9IENvbnRyb2xGcmFtZVRhZ3MuQXVkaW8uU3RhcnRTZXJ2aWNlQUNLLk1UVTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoc2VydmljZVR5cGUgPT09IChTZXJ2aWNlVHlwZS5OQVYpKSB7XG4gICAgICAgICAgICAgICAgbXR1VGFnID0gQ29udHJvbEZyYW1lVGFncy5WaWRlby5TdGFydFNlcnZpY2VBQ0suTVRVO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbXR1ID0gc2RsUGFja2V0LmdldFRhZyhtdHVUYWcpO1xuXG4gICAgICAgICAgICBpZiAobXR1ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbXR1c1tzZXJ2aWNlVHlwZV0gPSBtdHU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc2VydmljZVR5cGUgPT09IFNlcnZpY2VUeXBlLlJQQykge1xuICAgICAgICAgICAgICAgIHRoaXMuX3Nlc3Npb25JRCA9IHNkbFBhY2tldC5nZXRTZXNzaW9uSUQoKTtcbiAgICAgICAgICAgICAgICAvLyBUT0RPIGhhbmRsZSBvbGRlciB2ZXJzaW9ucyBvZiB0aGUgcHJvdG9jb2wgd2hlcmUgdGhpcyB3YXMganVzdCB0aGVpciBwYXlsb2FkLCBubyBCU09OXG4gICAgICAgICAgICAgICAgdGhpcy5faGFzaElEID0gc2RsUGFja2V0LmdldFRhZyhDb250cm9sRnJhbWVUYWdzLlJQQy5TdGFydFNlcnZpY2VBQ0suSEFTSF9JRCk7XG4gICAgICAgICAgICAgICAgY29uc3QgdmVyc2lvbiA9IHNkbFBhY2tldC5nZXRUYWcoQ29udHJvbEZyYW1lVGFncy5SUEMuU3RhcnRTZXJ2aWNlQUNLLlBST1RPQ09MX1ZFUlNJT04pO1xuICAgICAgICAgICAgICAgIGlmICh2ZXJzaW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEF0IHRoaXMgcG9pbnQgd2UgaGF2ZSBjb25maXJtZWQgdGhlIG5lZ290aWF0ZWQgdmVyc2lvbiBiZXR3ZWVuIHRoZSBtb2R1bGUgYW5kIHRoZSBwcm94eVxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wcm90b2NvbFZlcnNpb24gPSAobmV3IFZlcnNpb24oKSkuZnJvbVN0cmluZyh2ZXJzaW9uKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wcm90b2NvbFZlcnNpb24gPSBuZXcgVmVyc2lvbig1LCAwLCAwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHNlcnZpY2VUeXBlID09PSBTZXJ2aWNlVHlwZS5WSURFTykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9zZGxQcm90b2NvbExpc3RlbmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFjY2VwdGVkUmVzb2x1dGlvbiA9IG5ldyBJbWFnZVJlc29sdXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWNjZXB0ZWRGb3JtYXQgPSBuZXcgVmlkZW9TdHJlYW1pbmdGb3JtYXQoKTtcbiAgICAgICAgICAgICAgICAgICAgYWNjZXB0ZWRSZXNvbHV0aW9uLnNldFJlc29sdXRpb25IZWlnaHQoTWF0aC5mbG9vcihzZGxQYWNrZXQuZ2V0VGFnKENvbnRyb2xGcmFtZVRhZ3MuVmlkZW8uU3RhcnRTZXJ2aWNlQUNLLkhFSUdIVCkpKTtcbiAgICAgICAgICAgICAgICAgICAgYWNjZXB0ZWRSZXNvbHV0aW9uLnNldFJlc29sdXRpb25XaWR0aChNYXRoLmZsb29yKHNkbFBhY2tldC5nZXRUYWcoQ29udHJvbEZyYW1lVGFncy5WaWRlby5TdGFydFNlcnZpY2VBQ0suV0lEVEgpKSk7XG5cbiAgICAgICAgICAgICAgICAgICAgYWNjZXB0ZWRGb3JtYXQuc2V0Q29kZWMoc2RsUGFja2V0LmdldFRhZyhDb250cm9sRnJhbWVUYWdzLlZpZGVvLlN0YXJ0U2VydmljZUFDSy5WSURFT19DT0RFQykpO1xuICAgICAgICAgICAgICAgICAgICBhY2NlcHRlZEZvcm1hdC5zZXRQcm90b2NvbChzZGxQYWNrZXQuZ2V0VGFnKENvbnRyb2xGcmFtZVRhZ3MuVmlkZW8uU3RhcnRTZXJ2aWNlQUNLLlZJREVPX1BST1RPQ09MKSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFncmVlZFZpZGVvUGFyYW1zID0gdGhpcy5fc2RsUHJvdG9jb2xMaXN0ZW5lci5nZXREZXNpcmVkVmlkZW9QYXJhbXMoKTtcbiAgICAgICAgICAgICAgICAgICAgYWdyZWVkVmlkZW9QYXJhbXMuc2V0UmVzb2x1dGlvbihhY2NlcHRlZFJlc29sdXRpb24pO1xuICAgICAgICAgICAgICAgICAgICBhZ3JlZWRWaWRlb1BhcmFtcy5zZXRGb3JtYXQoYWNjZXB0ZWRGb3JtYXQpO1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3NkbFByb3RvY29sTGlzdGVuZXIuc2V0QWNjZXB0ZWRWaWRlb1BhcmFtcyhhZ3JlZWRWaWRlb1BhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3Byb3RvY29sVmVyc2lvbi5nZXRNYWpvcigpID4gMSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBzZGxQYWNrZXQuZ2V0UGF5bG9hZCgpO1xuICAgICAgICAgICAgICAgIGlmIChwYXlsb2FkICE9PSBudWxsICYmIHBheWxvYWQubGVuZ3RoID09PSA0KSB7IC8vIGhhc2hpZCB3aWxsIGJlIDQgYnl0ZXMgaW4gbGVuZ3RoXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhc2hJRCA9IEJpdENvbnZlcnRlci5hcnJheUJ1ZmZlclRvSW50MzIocGF5bG9hZC5idWZmZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3NkbFByb3RvY29sTGlzdGVuZXIub25Qcm90b2NvbFNlc3Npb25TdGFydGVkKHNlcnZpY2VUeXBlLFxuICAgICAgICAgICAgc2RsUGFja2V0LmdldFNlc3Npb25JRCgpLCB0aGlzLl9wcm90b2NvbFZlcnNpb24uZ2V0TWFqb3IoKSwgJycsIHRoaXMuX2hhc2hJRCwgc2RsUGFja2V0LmdldEVuY3J5cHRpb24oKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlcyBzdGFydCBzZXJ2aWNlIHJlamVjdGlvbi5cbiAgICAgKiBAcGFyYW0ge1NkbFBhY2tldH0gc2RsUGFja2V0XG4gICAgICovXG4gICAgX2hhbmRsZVN0YXJ0U2VydmljZU5BSyAoc2RsUGFja2V0KSB7XG4gICAgICAgIGNvbnN0IGVycm9yID0gYEdvdCBTdGFydFNlc3Npb25OQUNLIGZvciBwcm90b2NvbCBzZXNzaW9uSUQgJHtzZGxQYWNrZXQuZ2V0U2Vzc2lvbklEKCl9YDtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIEhhbmRsZXMgc2VydmljZSBlbmRlZCBieSBhcHAgcHJvY2Vzcy5cbiAgICAgKiBAcGFyYW0ge1NkbFBhY2tldH0gc2RsUGFja2V0XG4gICAgICovXG4gICAgX2hhbmRsZUVuZFNlcnZpY2VBQ0sgKHNkbFBhY2tldCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faGFuZGxlU2VydmljZUVuZGVkKHNkbFBhY2tldCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VydmljZSBlbmRlZCBieSBub24gYXBwIHByb2Nlc3Mgb3IgZm9yIHNvbWUgdW5leHBlY3RlZCByZWFzb24uXG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldFxuICAgICAqL1xuICAgIF9oYW5kbGVFbmRTZXJ2aWNlIChzZGxQYWNrZXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2hhbmRsZVNlcnZpY2VFbmRlZChzZGxQYWNrZXQpO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlcyBzZXJpdmNlIGVuZGluZy5cbiAgICAgKiBAcGFyYW0geyp9IHNkbFBhY2tldFxuICAgICAqL1xuICAgIF9oYW5kbGVTZXJ2aWNlRW5kZWQgKHNkbFBhY2tldCkge1xuICAgICAgICB0aGlzLl9zZGxQcm90b2NvbExpc3RlbmVyLm9uUHJvdG9jb2xTZXNzaW9uRW5kZWQoc2RsUGFja2V0LmdldFNlcnZpY2VUeXBlKCksIHNkbFBhY2tldC5nZXRTZXNzaW9uSUQoKSwgJycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhhbmRsZXMgc2VydmljZSBlbmQgcmVqZWN0aW9uLlxuICAgICAqIEBwYXJhbSB7U2RsUGFja2V0fSBzZGxQYWNrZXRcbiAgICAgKi9cbiAgICBfaGFuZGxlRW5kU2VydmljZU5BSyAoc2RsUGFja2V0KSB7XG4gICAgICAgIGNvbnN0IHNlcnZpY2VUeXBlID0gc2RsUGFja2V0LmdldFNlcnZpY2VUeXBlKCk7XG4gICAgICAgIGNvbnN0IHByb3RvY29sVmVyc2lvbiA9IHNkbFBhY2tldC5nZXRWZXJzaW9uKCk7XG4gICAgICAgIGlmIChwcm90b2NvbFZlcnNpb24gPj0gNSkge1xuICAgICAgICAgICAgbGV0IHJlamVjdGVkVGFnID0gbnVsbDtcbiAgICAgICAgICAgIGlmIChzZXJ2aWNlVHlwZSA9PT0gU2VydmljZVR5cGUuQVVESU8pIHtcbiAgICAgICAgICAgICAgICByZWplY3RlZFRhZyA9IENvbnRyb2xGcmFtZVRhZ3MuQXVkaW8uRW5kU2VydmljZU5BSy5SRUpFQ1RFRF9QQVJBTVM7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHNlcnZpY2VUeXBlID09PSBTZXJ2aWNlVHlwZS5WSURFTykge1xuICAgICAgICAgICAgICAgIHJlamVjdGVkVGFnID0gQ29udHJvbEZyYW1lVGFncy5WaWRlby5FbmRTZXJ2aWNlTkFLLlJFSkVDVEVEX1BBUkFNUztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHJlamVjdGVkUGFyYW1zID0gc2RsUGFja2V0LmdldFRhZyhyZWplY3RlZFRhZyk7XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShyZWplY3RlZFBhcmFtcykgJiYgcmVqZWN0ZWRQYXJhbXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0dvdCBFbmRTZXNzaW9uTkFLIHdpdGggcmVqZWN0ZWQgcGFyYW1zJywgcmVqZWN0ZWRQYXJhbXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3NkbFByb3RvY29sTGlzdGVuZXIub25Qcm90b2NvbFNlc3Npb25FbmRlZE5BQ0tlZChzZXJ2aWNlVHlwZSwgc2RsUGFja2V0LmdldFNlc3Npb25JRCgpLCAnJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlcyBpbmNvbWluZyBhc3NlbWJsZWQgcnBjIHBhY2tldC5cbiAgICAgKiBOb3RpZmllcyBzZGxQcm90b2NvbExpc3RlbmVyIG9mIHRoZSBldmVudCBhZnRlciBhc3NlbWJsZWluZyBhbiBScGNNZXNzYWdlXG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldFxuICAgICAqL1xuICAgIF9oYW5kbGVSUENQYWNrZXQgKHNkbFBhY2tldCkge1xuICAgICAgICBjb25zdCBycGNNZXNzYWdlID0gUnBjQ3JlYXRvci5jb25zdHJ1Y3Qoc2RsUGFja2V0KTtcbiAgICAgICAgaWYgKHJwY01lc3NhZ2UgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX3NkbFByb3RvY29sTGlzdGVuZXIub25ScGNNZXNzYWdlUmVjZWl2ZWQocnBjTWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFbmRzIHRoZSBkZWZhdWx0IHNlc3Npb24uXG4gICAgICovXG4gICAgZW5kU2Vzc2lvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNlc3Npb25JZCA9IHRoaXMuX2dldFNlc3Npb25JZCgpO1xuICAgICAgICBjb25zdCBoYXNoSUQgPSB0aGlzLl9oYXNoSUQ7XG4gICAgICAgIGNvbnN0IHNlcnZpY2VUeXBlID0gU2VydmljZVR5cGUuUlBDO1xuICAgICAgICBjb25zdCBtZXNzYWdlSUQgPSB0aGlzLl9nZXROZXh0TWVzc2FnZUlEKCk7XG4gICAgICAgIGNvbnN0IHZlcnNpb24gPSB0aGlzLl9wcm90b2NvbFZlcnNpb24uZ2V0TWFqb3IoKTtcbiAgICAgICAgY29uc3Qgc2RsUGFja2V0ID0gU2RsUGFja2V0RmFjdG9yeS5jcmVhdGVFbmRTZXNzaW9uKHNlcnZpY2VUeXBlLCBzZXNzaW9uSWQsIG1lc3NhZ2VJRCwgdmVyc2lvbiwgaGFzaElEKTtcbiAgICAgICAgdGhpcy5zZW5kUGFja2V0KHNkbFBhY2tldCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRW5kcyBhIHNwZWNpZmljIHNlcnZpY2VcbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZSAtIFNlcnZpY2UgdHlwZSBiZWluZyBlbmRlZC4gV2hlbiB0aGUgUlBDIHNlcnZpY2UgaXMgZW5kZWQgdGhlIGVudGlyZSBzZXNzaW9uIGVuZHMuXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlc3Npb25JZCAtIHJlcHJlc2VudHMgYSBieXRlXG4gICAgICovXG4gICAgZW5kU2VydmljZSAoc2VydmljZVR5cGUsIHNlc3Npb25JZCkge1xuICAgICAgICBpZiAoc2VydmljZVR5cGUgPT09IFNlcnZpY2VUeXBlLlJQQykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5kU2Vzc2lvbigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgaGFzaElEID0gdGhpcy5faGFzaElEO1xuICAgICAgICAgICAgY29uc3QgbWVzc2FnZUlEID0gdGhpcy5fZ2V0TmV4dE1lc3NhZ2VJRCgpO1xuICAgICAgICAgICAgY29uc3QgdmVyc2lvbiA9IHRoaXMuX3Byb3RvY29sVmVyc2lvbi5nZXRNYWpvcigpO1xuICAgICAgICAgICAgY29uc3Qgc2RsUGFja2V0ID0gU2RsUGFja2V0RmFjdG9yeS5jcmVhdGVFbmRTZXNzaW9uKHNlcnZpY2VUeXBlLCBzZXNzaW9uSWQsIG1lc3NhZ2VJRCwgdmVyc2lvbiwgaGFzaElEKTtcbiAgICAgICAgICAgIHRoaXMuc2VuZFBhY2tldChzZGxQYWNrZXQpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG4vKipcbiAqIE9yaWdpbmFsIGhlYWRlciBzaXplIGJhc2VkIG9uIHZlcnNpb24gMS4wLjAgb25seVxuICovXG5TZGxQcm90b2NvbEJhc2UuVjFfSEVBREVSX1NJWkUgPSA4O1xuLyoqXG4gKiBMYXJnZXIgaGVhZGVyIHNpemUgdGhhdCBpcyB1c2VkIGJ5IHZlcnNpb25zIDIuMC4wIGFuZCB1cFxuICovXG5TZGxQcm90b2NvbEJhc2UuVjJfSEVBREVSX1NJWkUgPSAxMjtcblxuU2RsUHJvdG9jb2xCYXNlLlYxX1YyX01UVV9TSVpFID0gMTUwMDtcblNkbFByb3RvY29sQmFzZS5WM19WNF9NVFVfU0laRSA9IDEzMTA3MjtcblxuLyoqXG4gKiBNYXggc3VwcG9ydGVkIHByb3RvY29sIHZlcnNpb24gaW4gdGhpcyByZWxlYXNlIG9mIHRoZSBsaWJyYXJ5XG4qL1xuU2RsUHJvdG9jb2xCYXNlLk1BWF9QUk9UT0NPTF9WRVJTSU9OID0gbmV3IFZlcnNpb24oNSwgMiwgMCk7XG5cbmV4cG9ydCB7IFNkbFByb3RvY29sQmFzZSB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtFbnVtfSBUcmFuc3BvcnRUeXBlXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBUcmFuc3BvcnRUeXBlIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBwYXJhbSB7U3RyaW5nfVxuICAgICovXG4gICAgc3RhdGljIGdldCBXRUJTT0NLRVRfQ0xJRU5UICgpIHtcbiAgICAgICAgcmV0dXJuIFRyYW5zcG9ydFR5cGUuX01BUC5XRUJTT0NLRVRfQ0xJRU5UO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQHBhcmFtIHtTdHJpbmd9XG4gICAgKi9cbiAgICBzdGF0aWMgZ2V0IFdFQlNPQ0tFVF9TRVJWRVIgKCkge1xuICAgICAgICByZXR1cm4gVHJhbnNwb3J0VHlwZS5fTUFQLldFQlNPQ0tFVF9TRVJWRVI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge1N0cmluZ31cbiAgICAqL1xuICAgIHN0YXRpYyBnZXQgQ1VTVE9NICgpIHtcbiAgICAgICAgcmV0dXJuIFRyYW5zcG9ydFR5cGUuX01BUC5DVVNUT007XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAqIEBwYXJhbSB2YWx1ZSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFRyYW5zcG9ydFR5cGUuX3ZhbHVlRm9yS2V5KGtleSwgVHJhbnNwb3J0VHlwZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gVHJhbnNwb3J0VHlwZS5fa2V5Rm9yVmFsdWUodmFsdWUsIFRyYW5zcG9ydFR5cGUuX01BUCk7XG4gICAgfVxufVxuXG5UcmFuc3BvcnRUeXBlLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnV0VCU09DS0VUX0NMSUVOVCc6ICdXRUJTT0NLRVRfQ0xJRU5UJyxcbiAgICAnV0VCU09DS0VUX1NFUlZFUic6ICdXRUJTT0NLRVRfU0VSVkVSJyxcbiAgICAnQ1VTVE9NJzogJ0NVU1RPTScsXG59KTtcblxuZXhwb3J0IHsgVHJhbnNwb3J0VHlwZSB9OyIsIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4gKlxuICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4gKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4gKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuICogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4gKiBkaXN0cmlidXRpb24uXG4gKlxuICogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiAqIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuICogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4gKlxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiAqIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4gKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4gKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4gKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuICogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4gKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuICogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiAqIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4gKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqL1xuXG5pbXBvcnQgeyBGcmFtZVR5cGUgfSBmcm9tICcuLi9wcm90b2NvbC9lbnVtcy9GcmFtZVR5cGUuanMnO1xuaW1wb3J0IHsgU2RsUGFja2V0IH0gZnJvbSAnLi4vcHJvdG9jb2wvU2RsUGFja2V0LmpzJztcbmltcG9ydCB7IFNkbFByb3RvY29sQmFzZSB9IGZyb20gJy4uL3Byb3RvY29sL1NkbFByb3RvY29sQmFzZS5qcyc7XG5cbi8qKlxuICogUGFyc2VzIGluY29taW5nIGJ5dGVzIGFjY29yZGluZyB0byB0aGUgcHJvdG9jb2wgc3BlYy5cbiAqL1xuY2xhc3MgU2RsUHNtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHRoaXMucmVzZXQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGFuZ2VzIGFsbCBpbnRlcm5hbCBtZW1iZXJzIHRvIGRlZmF1bHRcbiAgICAgKi9cbiAgICByZXNldCAoKSB7XG4gICAgICAgIHRoaXMuX3N0YXRlID0gU2RsUHNtLlNUQVJUX1NUQVRFO1xuICAgICAgICB0aGlzLl92ZXJzaW9uID0gMDtcbiAgICAgICAgdGhpcy5fZW5jcnlwdGlvbiA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9mcmFtZVR5cGUgPSBGcmFtZVR5cGUuU0lOR0xFO1xuICAgICAgICB0aGlzLl9zZXJ2aWNlVHlwZSA9IDA7XG4gICAgICAgIHRoaXMuX2NvbnRyb2xGcmFtZUluZm8gPSBudWxsO1xuICAgICAgICB0aGlzLl9zZXNzaW9uSUQgPSBudWxsO1xuICAgICAgICB0aGlzLl9kdW1wU2l6ZSA9IG51bGw7XG4gICAgICAgIHRoaXMuX2RhdGFMZW5ndGggPSAwO1xuICAgICAgICB0aGlzLl9tZXNzYWdlSUQgPSAwO1xuICAgICAgICB0aGlzLl9wYXlsb2FkID0gbnVsbDtcbiAgICB9XG5cblxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfSAtIFN0YXRlIHJlcHJlc2VudGVkIGJ5IGEgTnVtYmVyXG4gICAgICovXG4gICAgZ2V0U3RhdGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U2RsUGFja2V0fSAtIFJldHVybnMgbnVsbCBpZiBub3QgY29tcGxldGVcbiAgICAgKi9cblxuICAgIGdldEZvcm1lZFBhY2tldCAoKSB7XG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gU2RsUHNtLkZJTklTSEVEX1NUQVRFKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFNkbFBhY2tldCh0aGlzLl92ZXJzaW9uLCB0aGlzLl9lbmNyeXB0aW9uLCB0aGlzLl9mcmFtZVR5cGUsIHRoaXMuX3NlcnZpY2VUeXBlLCB0aGlzLl9jb250cm9sRnJhbWVJbmZvLCB0aGlzLl9zZXNzaW9uSUQsIHRoaXMuX2RhdGFMZW5ndGgsIHRoaXMuX21lc3NhZ2VJRCwgdGhpcy5fcGF5bG9hZCwgMCwgdGhpcy5fZGF0YUxlbmd0aCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhhbmRsZXMgdGhlIG5leHQgYnl0ZSBpbiB0aGUgc3RyZWFtIG9mIGRhdGEuXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGRhdGEgLSBSZXByZXNlbnRzIGEgYnl0ZVxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59IC0gVHJ1ZSBpZiBzdWNjZXNzZnVsLCBmYWxzZSBvdGhlcndpc2VcbiAgICAgKi9cbiAgICBoYW5kbGVCeXRlIChkYXRhKSB7XG4gICAgICAgIHRoaXMuX3N0YXRlID0gdGhpcy5fdHJhbnNpdGlvbk9uSW5wdXQoZGF0YSwgdGhpcy5fc3RhdGUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFNkbFBzbS5FUlJPUl9TVEFURSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSByYXdCeXRlIC0gUmVwcmVzZW50cyBhIGJ5dGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc3RhdGVcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgX3RyYW5zaXRpb25PbklucHV0IChyYXdCeXRlLCBzdGF0ZSkge1xuICAgICAgICBpZiAoc3RhdGUgPT09IFNkbFBzbS5TVEFSVF9TVEFURSkgeyAvLyBieXRlIDFcbiAgICAgICAgICAgIHRoaXMuX3ZlcnNpb24gPSAocmF3Qnl0ZSAmIFNkbFBzbS5WRVJTSU9OX01BU0spID4+IDQ7XG4gICAgICAgICAgICBpZiAodGhpcy5fdmVyc2lvbiA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBTZGxQc20uRVJST1JfU1RBVEU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuX2VuY3J5cHRpb24gPSAoMSA9PT0gKChyYXdCeXRlICYgU2RsUHNtLkVOQ1JZUFRJT05fTUFTSykgPj4gMykpO1xuICAgICAgICAgICAgdGhpcy5fZnJhbWVUeXBlID0gcmF3Qnl0ZSAmIFNkbFBzbS5GUkFNRV9UWVBFX01BU0s7XG5cbiAgICAgICAgICAgIGlmICgodGhpcy5fdmVyc2lvbiA8IDEgfHwgdGhpcy5fdmVyc2lvbiA+IDUpICYmIHRoaXMuX2ZyYW1lVHlwZSAhPT0gRnJhbWVUeXBlLkNPTlRST0wpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gU2RsUHNtLkVSUk9SX1NUQVRFO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5fZnJhbWVUeXBlIDwgRnJhbWVUeXBlLkNPTlRST0wgfHwgdGhpcy5fZnJhbWVUeXBlID4gRnJhbWVUeXBlLkNPTlNFQ1VUSVZFKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFNkbFBzbS5FUlJPUl9TVEFURTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBTZGxQc20uU0VSVklDRV9UWVBFX1NUQVRFO1xuICAgICAgICB9IGVsc2UgaWYgKHN0YXRlID09PSBTZGxQc20uU0VSVklDRV9UWVBFX1NUQVRFKSB7IC8vIGJ5dGUgMlxuICAgICAgICAgICAgdGhpcy5fc2VydmljZVR5cGUgPSAocmF3Qnl0ZSAmIDB4RkYpO1xuXG4gICAgICAgICAgICByZXR1cm4gU2RsUHNtLkNPTlRST0xfRlJBTUVfSU5GT19TVEFURTtcbiAgICAgICAgfSBlbHNlIGlmIChzdGF0ZSA9PT0gU2RsUHNtLkNPTlRST0xfRlJBTUVfSU5GT19TVEFURSkgeyAvLyBieXRlIDNcbiAgICAgICAgICAgIHRoaXMuX2NvbnRyb2xGcmFtZUluZm8gPSByYXdCeXRlICYgMHhGRjtcblxuICAgICAgICAgICAgc3dpdGNoICh0aGlzLl9mcmFtZVR5cGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlIEZyYW1lVHlwZS5DT05UUk9MOlxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIEZyYW1lVHlwZS5TSU5HTEU6IC8vIEZhbGwgdGhyb3VnaCBzaW5jZSB0aGV5IGFyZSBib3RoIHRoZSBzYW1lXG4gICAgICAgICAgICAgICAgY2FzZSBGcmFtZVR5cGUuRklSU1Q6XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9jb250cm9sRnJhbWVJbmZvICE9PSAweDAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gU2RsUHNtLkVSUk9SX1NUQVRFO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgRnJhbWVUeXBlLkNPTlNFQ1VUSVZFOlxuICAgICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBTZGxQc20uRVJST1JfU1RBVEU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gU2RsUHNtLlNFU1NJT05fSURfU1RBVEU7XG4gICAgICAgIH0gZWxzZSBpZiAoc3RhdGUgPT09IFNkbFBzbS5TRVNTSU9OX0lEX1NUQVRFKSB7IC8vIGJ5dGUgNFxuICAgICAgICAgICAgdGhpcy5fc2Vzc2lvbklEID0gKHJhd0J5dGUgJiAweEZGKTtcbiAgICAgICAgICAgIHJldHVybiBTZGxQc20uREFUQV9TSVpFXzFfU1RBVEU7XG4gICAgICAgIH0gZWxzZSBpZiAoc3RhdGUgPT09IFNkbFBzbS5EQVRBX1NJWkVfMV9TVEFURSkgeyAvLyBieXRlIDVcbiAgICAgICAgICAgIHRoaXMuX2RhdGFMZW5ndGggKz0gKHJhd0J5dGUgJiAweEZGKSA8PCAyNDtcbiAgICAgICAgICAgIHJldHVybiBTZGxQc20uREFUQV9TSVpFXzJfU1RBVEU7XG4gICAgICAgIH0gZWxzZSBpZiAoc3RhdGUgPT09IFNkbFBzbS5EQVRBX1NJWkVfMl9TVEFURSkgeyAvLyBieXRlIDZcbiAgICAgICAgICAgIHRoaXMuX2RhdGFMZW5ndGggKz0gKHJhd0J5dGUgJiAweEZGKSA8PCAxNjsgLy8gIyAyIGJ5dGVzIHggOCBiaXRzXG4gICAgICAgICAgICByZXR1cm4gU2RsUHNtLkRBVEFfU0laRV8zX1NUQVRFO1xuICAgICAgICB9IGVsc2UgaWYgKHN0YXRlID09PSBTZGxQc20uREFUQV9TSVpFXzNfU1RBVEUpIHsgLy8gYnl0ZSA3XG4gICAgICAgICAgICB0aGlzLl9kYXRhTGVuZ3RoICs9IChyYXdCeXRlICYgMHhGRikgPDwgODsgLy8gIyAgMSBieXRlIHggOCBiaXRzXG4gICAgICAgICAgICByZXR1cm4gU2RsUHNtLkRBVEFfU0laRV80X1NUQVRFO1xuICAgICAgICB9IGVsc2UgaWYgKHN0YXRlID09PSBTZGxQc20uREFUQV9TSVpFXzRfU1RBVEUpIHsgLy8gYnl0ZSA4XG4gICAgICAgICAgICB0aGlzLl9kYXRhTGVuZ3RoICs9IChyYXdCeXRlICYgMHhGRik7IC8vICMgMiBieXRlcyB4IDggYml0c1xuXG4gICAgICAgICAgICBzd2l0Y2ggKHRoaXMuX2ZyYW1lVHlwZSkgeyAvLyBJZiBhbGwgaXMgY29ycmVjdCB3ZSBzaG91bGQgYnJlYWsgb3V0IG9mIHRoaXMgc3dpdGNoIHN0YXRlbWVudFxuICAgICAgICAgICAgICAgIGNhc2UgRnJhbWVUeXBlLlNJTkdMRTpcbiAgICAgICAgICAgICAgICBjYXNlIEZyYW1lVHlwZS5DT05TRUNVVElWRTpcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBGcmFtZVR5cGUuQ09OVFJPTDpcbiAgICAgICAgICAgICAgICAvLyBPaywgd2VsbCBoZXJlJ3Mgc29tZSBpbnRlcmVzdGluZyBiaXQgb2Yga25vd2xlZGdlLiBCZWNhdXNlIHRoZSBzdGFydCBzZXNzaW9uIHJlcXVlc3QgaXMgZnJvbSB0aGUgcGhvbmUgd2l0aCBubyBrbm93bGVkZ2Ugb2YgdmVyc2lvbiBpdCBzZW5kcyBvdXRcbiAgICAgICAgICAgICAgICAvLyBhIHYxIHBhY2tldC4gVEhFUkVGT1JFIHRoZXJlIGlzIG5vIG1lc3NhZ2UgaWQgZmllbGQuICoqKiogTm93IHlvdSBrbm93IGFuZCBrbm93aW5nIGlzIGhhbGYgdGhlIGJhdHRsZSAqKioqXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl92ZXJzaW9uID09PSAxICYmIHRoaXMuX2NvbnRyb2xGcmFtZUluZm8gPT09IFNkbFBhY2tldC5GUkFNRV9JTkZPX1NUQVJUX1NFUlZJQ0UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9kYXRhTGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNkbFBzbS5GSU5JU0hFRF9TVEFURTsgLy8gV2UgYXJlIGRvbmUgaWYgd2UgZG9uJ3QgaGF2ZSBhbnkgcGF5bG9hZFxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX2RhdGFMZW5ndGggPD0gU2RsUHJvdG9jb2xCYXNlLlYxX1YyX01UVV9TSVpFIC0gU2RsUHJvdG9jb2xCYXNlLlYxX0hFQURFUl9TSVpFKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGF5bG9hZCA9IG5ldyBVaW50OEFycmF5KHRoaXMuX2RhdGFMZW5ndGgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gU2RsUHNtLkVSUk9SX1NUQVRFO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZHVtcFNpemUgPSB0aGlzLl9kYXRhTGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNkbFBzbS5EQVRBX1BVTVBfU1RBVEU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICBjYXNlIEZyYW1lVHlwZS5GSVJTVDpcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX2RhdGFMZW5ndGggIT09IFNkbFBzbS5GSVJTVF9GUkFNRV9EQVRBX1NJWkUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBTZGxQc20uRVJST1JfU1RBVEU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNkbFBzbS5FUlJPUl9TVEFURTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuX3ZlcnNpb24gPT09IDEpIHsgLy8gVmVyc2lvbiAxIHBhY2tldHMgd2lsbCBub3QgaGF2ZSBtZXNzYWdlIGlkJ3NcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fZGF0YUxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gU2RsUHNtLkZJTklTSEVEX1NUQVRFOyAvLyBXZSBhcmUgZG9uZSBpZiB3ZSBkb24ndCBoYXZlIGFueSBwYXlsb2FkXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9kYXRhTGVuZ3RoIDw9IFNkbFByb3RvY29sQmFzZS5WMV9WMl9NVFVfU0laRSAtIFNkbFByb3RvY29sQmFzZS5WMV9IRUFERVJfU0laRSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wYXlsb2FkID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5fZGF0YUxlbmd0aCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNkbFBzbS5FUlJPUl9TVEFURTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5fZHVtcFNpemUgPSB0aGlzLl9kYXRhTGVuZ3RoO1xuICAgICAgICAgICAgICAgIHJldHVybiBTZGxQc20uREFUQV9QVU1QX1NUQVRFO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gU2RsUHNtLk1FU1NBR0VfMV9TVEFURTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChzdGF0ZSA9PT0gU2RsUHNtLk1FU1NBR0VfMV9TVEFURSkgeyAvLyBieXRlIDksIGJ5dGVzIDktMTIgYXZhaWxhYmxlIGluIHZlcnNpb24gMisuXG4gICAgICAgICAgICB0aGlzLl9tZXNzYWdlSUQgKz0gKHJhd0J5dGUgJiAweEZGKSA8PCAyNDtcbiAgICAgICAgICAgIHJldHVybiBTZGxQc20uTUVTU0FHRV8yX1NUQVRFO1xuICAgICAgICB9IGVsc2UgaWYgKHN0YXRlID09PSBTZGxQc20uTUVTU0FHRV8yX1NUQVRFKSB7IC8vIGJ5dGUgMTBcbiAgICAgICAgICAgIHRoaXMuX21lc3NhZ2VJRCArPSAocmF3Qnl0ZSAmIDB4RkYpIDw8IDE2O1xuICAgICAgICAgICAgcmV0dXJuIFNkbFBzbS5NRVNTQUdFXzNfU1RBVEU7XG4gICAgICAgIH0gZWxzZSBpZiAoc3RhdGUgPT09IFNkbFBzbS5NRVNTQUdFXzNfU1RBVEUpIHsgLy8gYnl0ZSAxMVxuICAgICAgICAgICAgdGhpcy5fbWVzc2FnZUlEICs9IChyYXdCeXRlICYgMHhGRikgPDwgODtcbiAgICAgICAgICAgIHJldHVybiBTZGxQc20uTUVTU0FHRV80X1NUQVRFO1xuICAgICAgICB9IGVsc2UgaWYgKHN0YXRlID09PSBTZGxQc20uTUVTU0FHRV80X1NUQVRFKSB7IC8vIGJ5dGUgMTJcbiAgICAgICAgICAgIHRoaXMuX21lc3NhZ2VJRCArPSAocmF3Qnl0ZSAmIDB4RkYpO1xuICAgICAgICAgICAgaWYgKHRoaXMuX2RhdGFMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gU2RsUHNtLkZJTklTSEVEX1NUQVRFO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fZHVtcFNpemUgPSB0aGlzLl9kYXRhTGVuZ3RoO1xuICAgICAgICAgICAgdGhpcy5fcGF5bG9hZCA9IG5ldyBVaW50OEFycmF5KHRoaXMuX2RhdGFMZW5ndGgpO1xuICAgICAgICAgICAgcmV0dXJuIFNkbFBzbS5EQVRBX1BVTVBfU1RBVEU7XG4gICAgICAgIH0gZWxzZSBpZiAoc3RhdGUgPT09IFNkbFBzbS5EQVRBX1BVTVBfU1RBVEUpIHsgLy8gYnl0ZSAxM1xuICAgICAgICAgICAgdGhpcy5fcGF5bG9hZFt0aGlzLl9kYXRhTGVuZ3RoIC0gdGhpcy5fZHVtcFNpemVdID0gcmF3Qnl0ZTtcbiAgICAgICAgICAgIHRoaXMuX2R1bXBTaXplIC09IDE7XG4gICAgICAgICAgICAvLyBEbyB3ZSBoYXZlIGFueSBtb3JlIGJ5dGVzIHRvIHJlYWQgaW4/XG4gICAgICAgICAgICBpZiAodGhpcy5fZHVtcFNpemUgPiAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFNkbFBzbS5EQVRBX1BVTVBfU1RBVEU7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX2R1bXBTaXplID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFNkbFBzbS5GSU5JU0hFRF9TVEFURTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFNkbFBzbS5FUlJPUl9TVEFURTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuU2RsUHNtLlNUQVJUX1NUQVRFICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAweDA7XG5TZGxQc20uU0VSVklDRV9UWVBFX1NUQVRFICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDI7XG5TZGxQc20uQ09OVFJPTF9GUkFNRV9JTkZPX1NUQVRFICAgICAgICAgICAgICAgICA9IDB4MDM7XG5TZGxQc20uU0VTU0lPTl9JRF9TVEFURSAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDQ7XG5TZGxQc20uREFUQV9TSVpFXzFfU1RBVEUgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDU7XG5TZGxQc20uREFUQV9TSVpFXzJfU1RBVEUgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDY7XG5TZGxQc20uREFUQV9TSVpFXzNfU1RBVEUgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDc7XG5TZGxQc20uREFUQV9TSVpFXzRfU1RBVEUgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDg7XG5TZGxQc20uTUVTU0FHRV8xX1NUQVRFICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDk7XG5TZGxQc20uTUVTU0FHRV8yX1NUQVRFICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEE7XG5TZGxQc20uTUVTU0FHRV8zX1NUQVRFICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEI7XG5TZGxQc20uTUVTU0FHRV80X1NUQVRFICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEM7XG5TZGxQc20uREFUQV9QVU1QX1NUQVRFICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MEQ7XG5TZGxQc20uRklOSVNIRURfU1RBVEUgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4RkY7XG5TZGxQc20uRVJST1JfU1RBVEUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IC0xO1xuXG5TZGxQc20uRklSU1RfRlJBTUVfREFUQV9TSVpFICAgICAgICAgICAgICAgICAgICA9IDB4MDg7XG5TZGxQc20uVkVSU0lPTl9NQVNLICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4RjA7IC8vIDQgaGlnaGVzdCBiaXRzXG5TZGxQc20uRU5DUllQVElPTl9NQVNLICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDg7IC8vIDR0aCBsb3dlc3QgYml0XG5TZGxQc20uRlJBTUVfVFlQRV9NQVNLICAgICAgICAgICAgICAgICAgICAgICAgICA9IDB4MDc7IC8vIDMgbG93ZXN0IGJpdHNcblxuZXhwb3J0IHsgU2RsUHNtIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFNkbFBzbSB9IGZyb20gJy4vU2RsUHNtLmpzJztcblxuY2xhc3MgVHJhbnNwb3J0QmFzZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtCYXNlVHJhbnNwb3J0Q29uZmlnfSB0cmFuc3BvcnRDb25maWdcbiAgICAgKiBAcGFyYW0ge1RyYW5zcG9ydENhbGxiYWNrfSB0cmFuc3BvcnRDYWxsYmFja1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICh0cmFuc3BvcnRDb25maWcsIHRyYW5zcG9ydENhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX3NkbFBzbSA9IG5ldyBTZGxQc20oKTtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q29uZmlnID0gdHJhbnNwb3J0Q29uZmlnO1xuICAgICAgICB0aGlzLl90cmFuc3BvcnRDYWxsYmFjayA9IHRyYW5zcG9ydENhbGxiYWNrO1xuICAgIH1cblxuICAgIHN0YXJ0ICgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdzdGFydCBtZXRob2QgbXVzdCBiZSBvdmVycmlkZGVuJyk7XG4gICAgfVxuXG4gICAgc3RvcCAoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignc3RvcCBtZXRob2QgbXVzdCBiZSBvdmVycmlkZGVuJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldFxuICAgICAqL1xuICAgIHNlbmRQYWNrZXQgKHNkbFBhY2tldCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NlbmRQYWNrZXQgbWV0aG9kIG11c3QgYmUgb3ZlcnJpZGRlbicpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VHJhbnNwb3J0Q2FsbGJhY2t9IGNhbGxiYWNrXG4gICAgICovXG4gICAgc2V0VHJhbnNwb3J0Q2FsbGJhY2sgKGNhbGxiYWNrKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignc2V0VHJhbnNwb3J0Q2FsbGJhY2sgbWV0aG9kIG11c3QgYmUgb3ZlcnJpZGRlbicpO1xuICAgIH1cbn1cblxuZXhwb3J0IHsgVHJhbnNwb3J0QmFzZSB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFRyYW5zcG9ydEJhc2UgfSBmcm9tICcuL1RyYW5zcG9ydEJhc2UuanMnO1xuaW1wb3J0IHsgU2RsUHNtIH0gZnJvbSAnLi9TZGxQc20uanMnO1xuXG5jbGFzcyBXZWJTb2NrZXRDbGllbnQgZXh0ZW5kcyBUcmFuc3BvcnRCYXNlIHtcbiAgICBjb25zdHJ1Y3RvciAoY29uZmlnLCB0cmFuc3BvcnRDYWxsYmFjaykge1xuICAgICAgICBzdXBlcihjb25maWcsIHRyYW5zcG9ydENhbGxiYWNrKTtcbiAgICAgICAgdGhpcy5fcXVldWUgPSBbXTtcbiAgICAgICAgdGhpcy5faXNSdW5uaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3dzVXJsID0gYCR7Y29uZmlnLmdldEhvc3QoKX06JHtjb25maWcuZ2V0UG9ydCgpfWA7XG4gICAgICAgIHRoaXMuX3dzID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1RyYW5zcG9ydENhbGxiYWNrfSBjYWxsYmFja1xuICAgICAqL1xuICAgIHNldFRyYW5zcG9ydENhbGxiYWNrIChjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl90cmFuc3BvcnRDYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9wZW5zIHRoZSB0cmFuc3BvcnQgY29ubmVjdGlvblxuICAgICAqL1xuICAgIHN0YXJ0ICgpIHtcbiAgICAgICAgdGhpcy5faW5pdCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEluaXRpYXRlcyBhIHdlYnNvY2tldCBjb25uZWN0aW9uIHRvIHRoZSB1cmwgcGFzc2VkIGluIGFuZCBsaXN0ZW5zIGZvciBtZXNzYWdlc1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgX2luaXQgKCkge1xuICAgICAgICB0aGlzLl93cyAgPSBuZXcgV2ViU29ja2V0KHRoaXMuX3dzVXJsKTtcblxuICAgICAgICB0aGlzLl93cy5vbm9wZW4gPSAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLl90cmFuc3BvcnRDYWxsYmFjay5vbkNvbm5lY3Rpb25Fc3RhYmxpc2hlZCgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuX3dzLm9uZXJyb3IgPSAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBjb25uZWN0JywgZXJyb3IpO1xuICAgICAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2sub25FcnJvcigpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuX3dzLm9ubWVzc2FnZSA9IChtc2cpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2hhbmRsZUluY29taW5nKG1zZyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5fd3Mub25jbG9zZSA9ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX3RyYW5zcG9ydENhbGxiYWNrLm9uQ29ubmVjdGlvblRlcm1pbmF0ZWQoKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDbG9zZXMgdGhlIHRyYW5zcG9ydCBjb25uZWN0aW9uXG4gICAgICovXG4gICAgc3RvcCAoKSB7XG4gICAgICAgIHRoaXMuX3dzLmNsb3NlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGNvbnRlbnRzIGluIHRoZSBwYWNrZXQgc2hvdWxkIGJlIHNlbnQgb3V0IHRocm91Z2ggdGhlIHRyYW5zcG9ydFxuICAgICAqIEBwYXJhbSB7U2RsUGFja2V0fSBwYWNrZXRcbiAgICAgKi9cbiAgICBzZW5kUGFja2V0IChwYWNrZXQpIHtcbiAgICAgICAgY29uc3QgYnl0ZXMgPSBwYWNrZXQudG9QYWNrZXQoKTtcbiAgICAgICAgdGhpcy5fd3Muc2VuZChieXRlcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBpcyBjYWxsZWQgd2hlbmV2ZXIgYSBuZXcgbWVzc2FnZSBjb21lcyBpblxuICAgICAqIEBwYXJhbSB7TWVzc2FnZUV2ZW50fSBtc2dcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9oYW5kbGVJbmNvbWluZyAobXNnKSB7XG4gICAgICAgIHRoaXMuX3F1ZXVlLnB1c2gobXNnLmRhdGEpO1xuICAgICAgICB0aGlzLl9tdWx0aUJ5dGVIYW5kbGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJvY2Vzc2VzIHJlY2VpdmVkIGRhdGEgZnJvbSB0aGUgaW50ZXJuYWwgcXVldWVcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9tdWx0aUJ5dGVIYW5kbGVyICgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2lzUnVubmluZykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2lzUnVubmluZyA9IHRydWU7XG5cbiAgICAgICAgd2hpbGUgKHRoaXMuX3F1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IG1zZ0RhdGEgPSB0aGlzLl9xdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgbmV3IFJlc3BvbnNlKG1zZ0RhdGEpLmFycmF5QnVmZmVyKCkudGhlbigoYXJyYXlCdWZmZXIpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB1aW50OCA9IG5ldyBVaW50OEFycmF5KGFycmF5QnVmZmVyKTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGJ5dGUgb2YgdWludDgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlQnl0ZShieXRlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2lzUnVubmluZyA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZlZWRzIGEgYnl0ZSB0aHJvdWdoIHRoZSBpbnRlcm5hbCBQU01cbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYnl0ZSAtIHVuc2lnbmVkIDgtYml0IGludGVnZXJcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9oYW5kbGVCeXRlIChieXRlKSB7XG4gICAgICAgIGNvbnN0IHN1Y2Nlc3MgPSB0aGlzLl9zZGxQc20uaGFuZGxlQnl0ZShieXRlKTtcbiAgICAgICAgaWYgKCFzdWNjZXNzKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdmYWlsZWQnLCB0aGlzLl9zZGxQc20pO1xuICAgICAgICAgICAgdGhpcy5fc2RsUHNtLnJlc2V0KCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaXNGaW5pc2hlZCA9IHRoaXMuX3NkbFBzbS5nZXRTdGF0ZSgpID09PSBTZGxQc20uRklOSVNIRURfU1RBVEU7XG5cbiAgICAgICAgaWYgKGlzRmluaXNoZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhY2tldCA9IHRoaXMuX3NkbFBzbS5nZXRGb3JtZWRQYWNrZXQoKTtcbiAgICAgICAgICAgIHRoaXMuX3NkbFBzbS5yZXNldCgpO1xuICAgICAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2sub25QYWNrZXRSZWNlaXZlZChwYWNrZXQpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5cbmV4cG9ydCB7IFdlYlNvY2tldENsaWVudCB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5jbGFzcyBUcmFuc3BvcnRDYWxsYmFjayB7XG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICB0aGlzLl9vbkNvbm5lY3Rpb25Fc3RhYmxpc2hlZCA9IG51bGw7XG4gICAgICAgIHRoaXMuX29uRXJyb3IgPSBudWxsO1xuICAgICAgICB0aGlzLl9vbkNvbm5lY3Rpb25UZXJtaW5hdGVkID0gbnVsbDtcbiAgICAgICAgdGhpcy5fb25QYWNrZXRSZWNlaXZlZCA9IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBzZXRPbkNvbm5lY3Rpb25Fc3RhYmxpc2hlZCAobGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5fb25Db25uZWN0aW9uRXN0YWJsaXNoZWQgPSBsaXN0ZW5lcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBsaXN0ZW5lclxuICAgICAqL1xuICAgIHNldE9uRXJyb3IgKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMuX29uRXJyb3IgPSBsaXN0ZW5lcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBsaXN0ZW5lclxuICAgICAqL1xuICAgIHNldE9uQ29ubmVjdGlvblRlcm1pbmF0ZWQgKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMuX29uQ29ubmVjdGlvblRlcm1pbmF0ZWQgPSBsaXN0ZW5lcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBsaXN0ZW5lclxuICAgICAqL1xuICAgIHNldE9uUGFja2V0UmVjZWl2ZWQgKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMuX29uUGFja2V0UmVjZWl2ZWQgPSBsaXN0ZW5lcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGVyIGZvciB3aGVuIGEgY29ubmVjdGlvbiBpcyBzdWNjZXNzZnVsXG4gICAgICovXG4gICAgb25Db25uZWN0aW9uRXN0YWJsaXNoZWQgKCkge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX29uQ29ubmVjdGlvbkVzdGFibGlzaGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9vbkNvbm5lY3Rpb25Fc3RhYmxpc2hlZCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlciBmb3Igd2hlbiBhIGNvbm5lY3Rpb24gaXMgc3VjY2Vzc2Z1bFxuICAgICAqL1xuICAgIG9uRXJyb3IgKCkge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX29uRXJyb3IgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuX29uRXJyb3IoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhhbmRsZXIgZm9yIHdoZW4gYSBjb25uZWN0aW9uIGlzIGRyb3BwZWRcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gcmVhc29uXG4gICAgICovXG4gICAgb25Db25uZWN0aW9uVGVybWluYXRlZCAocmVhc29uKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fb25Db25uZWN0aW9uVGVybWluYXRlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5fb25Db25uZWN0aW9uVGVybWluYXRlZChyZWFzb24pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlciBmb3Igd2hlbiBhIHBhY2tldCBpcyByZWNlaXZlZFxuICAgICAqIEBwYXJhbSB7U2RsUGFja2V0fSBwYWNrZXRcbiAgICAgKi9cbiAgICBvblBhY2tldFJlY2VpdmVkIChwYWNrZXQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9vblBhY2tldFJlY2VpdmVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9vblBhY2tldFJlY2VpdmVkKHBhY2tldCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cblxuZXhwb3J0IHsgVHJhbnNwb3J0Q2FsbGJhY2sgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgVHJhbnNwb3J0VHlwZSB9IGZyb20gJy4vZW51bXMvVHJhbnNwb3J0VHlwZS5qcyc7XG5pbXBvcnQgeyBXZWJTb2NrZXRDbGllbnQgfSBmcm9tICcuL1dlYlNvY2tldENsaWVudC5qcyc7XG5pbXBvcnQgeyBUcmFuc3BvcnRDYWxsYmFjayB9IGZyb20gJy4vVHJhbnNwb3J0Q2FsbGJhY2suanMnO1xuXG5jbGFzcyBUcmFuc3BvcnRNYW5hZ2VyQmFzZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtCYXNlVHJhbnNwb3J0Q29uZmlnfSBiYXNlVHJhbnNwb3J0Q29uZmlnXG4gICAgICogQHBhcmFtIHtUcmFuc3BvcnRMaXN0ZW5lcn0gdHJhbnNwb3J0TGlzdGVuZXJcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoYmFzZVRyYW5zcG9ydENvbmZpZywgdHJhbnNwb3J0TGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q29uZmlnID0gYmFzZVRyYW5zcG9ydENvbmZpZztcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0TGlzdGVuZXIgPSB0cmFuc3BvcnRMaXN0ZW5lcjtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0ID0gbnVsbDtcbiAgICAgICAgdGhpcy5faXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2sgPSBuZXcgVHJhbnNwb3J0Q2FsbGJhY2soKTtcblxuICAgICAgICB0aGlzLl90cmFuc3BvcnRDYWxsYmFjay5zZXRPbkNvbm5lY3Rpb25Fc3RhYmxpc2hlZCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9pc0Nvbm5lY3RlZCA9IHRydWU7XG4gICAgICAgICAgICB0cmFuc3BvcnRMaXN0ZW5lci5vblRyYW5zcG9ydENvbm5lY3RlZCgpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2suc2V0T25Db25uZWN0aW9uVGVybWluYXRlZCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9pc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2suc2V0T25QYWNrZXRSZWNlaXZlZCh0aGlzLm9uUGFja2V0UmVjZWl2ZWQuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgaWYgKHRoaXMuX3RyYW5zcG9ydENvbmZpZy5nZXRUcmFuc3BvcnRUeXBlKCkgPT09IFRyYW5zcG9ydFR5cGUuV0VCU09DS0VUX0NMSUVOVCkge1xuICAgICAgICAgICAgdGhpcy5fdHJhbnNwb3J0ID0gbmV3IFdlYlNvY2tldENsaWVudCh0aGlzLl90cmFuc3BvcnRDb25maWcsIHRoaXMuX3RyYW5zcG9ydENhbGxiYWNrKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLl90cmFuc3BvcnRDb25maWcuZ2V0VHJhbnNwb3J0VHlwZSgpID09PSBUcmFuc3BvcnRUeXBlLkNVU1RPTSkge1xuICAgICAgICAgICAgdGhpcy5fdHJhbnNwb3J0ID0gdGhpcy5fdHJhbnNwb3J0Q29uZmlnLmdldFRyYW5zcG9ydCgpO1xuICAgICAgICAgICAgdGhpcy5fdHJhbnNwb3J0LnNldFRyYW5zcG9ydENhbGxiYWNrKHRoaXMuX3RyYW5zcG9ydENhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uVHJhbnNwb3J0Q29ubmVjdGVkICgpIHtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0TGlzdGVuZXIub25UcmFuc3BvcnRDb25uZWN0ZWQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jXG4gICAgICovXG4gICAgb25UcmFuc3BvcnREaXNjb25uZWN0ZWQgKGZ1bmMpIHtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0TGlzdGVuZXIub25UcmFuc3BvcnREaXNjb25uZWN0ZWQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jXG4gICAgICovXG4gICAgb25FcnJvciAoZnVuYykge1xuICAgICAgICB0aGlzLl90cmFuc3BvcnRMaXN0ZW5lci5vbkVycm9yKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTZGxQYWNrZXR9IHNkbFBhY2tldFxuICAgICAqL1xuICAgIG9uUGFja2V0UmVjZWl2ZWQgKHNkbFBhY2tldCkge1xuICAgICAgICB0aGlzLl90cmFuc3BvcnRMaXN0ZW5lci5vblBhY2tldFJlY2VpdmVkKHNkbFBhY2tldCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT3BlbnMgdGhlIHRyYW5zcG9ydCBjb25uZWN0aW9uXG4gICAgICovXG4gICAgc3RhcnQgKCkge1xuICAgICAgICBpZiAodGhpcy5fdHJhbnNwb3J0ICE9PSBudWxsICYmIHR5cGVvZiB0aGlzLl90cmFuc3BvcnQuc3RhcnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuX3RyYW5zcG9ydC5zdGFydCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2xvc2VzIHRoZSB0cmFuc3BvcnQgY29ubmVjdGlvblxuICAgICAqL1xuICAgIHN0b3AgKCkge1xuICAgICAgICBpZiAodGhpcy5fdHJhbnNwb3J0ICE9PSBudWxsICYmIHR5cGVvZiB0aGlzLl90cmFuc3BvcnQuc3RvcCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5fdHJhbnNwb3J0LnN0b3AoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBjb250ZW50cyBpbiB0aGUgcGFja2V0IHNob3VsZCBiZSBzZW50IG91dCB0aHJvdWdoIHRoZSB0cmFuc3BvcnRcbiAgICAgKiBAcGFyYW0ge1NkbFBhY2tldH0gcGFja2V0XG4gICAgICovXG4gICAgc2VuZFBhY2tldCAocGFja2V0KSB7XG4gICAgICAgIGlmICh0aGlzLl90cmFuc3BvcnQgIT09IG51bGwgJiYgdHlwZW9mIHRoaXMuX3RyYW5zcG9ydC5zZW5kUGFja2V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl90cmFuc3BvcnQuc2VuZFBhY2tldChwYWNrZXQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtUcmFuc3BvcnRUeXBlfSB0cmFuc3BvcnRUeXBlXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGFkZHJlc3NcbiAgICAgKi9cbiAgICBpc0Nvbm5lY3RlZCAodHJhbnNwb3J0VHlwZSwgYWRkcmVzcykge1xuICAgICAgICByZXR1cm4gdGhpcy5faXNDb25uZWN0ZWQ7XG4gICAgfVxufVxuXG5leHBvcnQgeyBUcmFuc3BvcnRNYW5hZ2VyQmFzZSB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5jbGFzcyBTc2xDb25maWcge1xuICAgIGNvbnN0cnVjdG9yIChwZW1DZXJ0aWZpY2F0ZSA9IG51bGwsIHByaXZhdGVLZXkgPSBudWxsLCBwYXNzd29yZCA9IG51bGwpIHtcbiAgICAgICAgdGhpcy5fcGVtQ2VydGlmaWNhdGUgPSBwZW1DZXJ0aWZpY2F0ZTtcbiAgICAgICAgdGhpcy5fcHJpdmF0ZUtleSA9IHByaXZhdGVLZXk7XG4gICAgICAgIHRoaXMuX3Bhc3N3b3JkID0gcGFzc3dvcmQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBSZXR1cm5zIHRoZSBQRU0gQ2VydGlmaWNhdGVcbiAgICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICAqL1xuICAgIGdldFBlbUNlcnRpZmljYXRlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BlbUNlcnRpZmljYXRlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogUmV0dXJucyB0aGUgUHJpdmF0ZSBLZXlcbiAgICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICAqL1xuICAgIGdldFByaXZhdGVLZXkgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcHJpdmF0ZUtleTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIFJldHVybnMgdGhlIHBhc3N3b3JkXG4gICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAgKi9cbiAgICBnZXRQYXNzd29yZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXNzd29yZDtcbiAgICB9XG59XG5cbmV4cG9ydCB7IFNzbENvbmZpZyB9O1xuIiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmNvbnN0IHsgVHJhbnNwb3J0QmFzZSB9ID0gcmVxdWlyZSgnLi9UcmFuc3BvcnRCYXNlLmpzJyk7XG5jb25zdCB7IFNzbENvbmZpZyB9ID0gcmVxdWlyZSgnLi9Tc2xDb25maWcuanMnKTtcbmNvbnN0IHsgU2RsUHNtIH0gPSByZXF1aXJlKCcuL1NkbFBzbS5qcycpO1xuY29uc3QgV2ViU29ja2V0ID0gcmVxdWlyZSgnd3MnKTtcbmNvbnN0IGh0dHBzID0gcmVxdWlyZSgnaHR0cHMnKTtcblxuY2xhc3MgV2ViU29ja2V0U2VydmVyIGV4dGVuZHMgVHJhbnNwb3J0QmFzZSB7XG4gICAgY29uc3RydWN0b3IgKHRyYW5zcG9ydENvbmZpZywgdHJhbnNwb3J0Q2FsbGJhY2sgPSBudWxsKSB7XG4gICAgICAgIHN1cGVyKHRyYW5zcG9ydENvbmZpZywgdHJhbnNwb3J0Q2FsbGJhY2spO1xuICAgICAgICB0aGlzLl93cyA9IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtUcmFuc3BvcnRDYWxsYmFja30gY2FsbGJhY2tcbiAgICAgKi9cbiAgICBzZXRUcmFuc3BvcnRDYWxsYmFjayAoY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdGFydCBsaXN0ZW5pbmcgZm9yIGNvbm5lY3Rpb25zIHRvIHRoZSBXZWJTb2NrZXQgU2VydmVyXG4gICAgICogQHJldHVybiB7V2ViU29ja2V0U2VydmVyfVxuICAgICAqL1xuICAgIHN0YXJ0ICgpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q29uZmlnLmdldFNzbENvbmZpZygpIGluc3RhbmNlb2YgU3NsQ29uZmlnXG4gICAgICAgICAgICAmJiB0aGlzLl90cmFuc3BvcnRDb25maWcuZ2V0U3NsQ29uZmlnKCkuZ2V0UGVtQ2VydGlmaWNhdGUoKSAhPT0gbnVsbFxuICAgICAgICAgICAgJiYgdGhpcy5fdHJhbnNwb3J0Q29uZmlnLmdldFNzbENvbmZpZygpLmdldFByaXZhdGVLZXkoKSAhPT0gbnVsbFxuICAgICAgICApIHtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBhIFdlYlNvY2tldCBTZWN1cmUgU2VydmVyXG4gICAgICAgICAgICBjb25zdCBzZXJ2ZXIgPSBodHRwcy5jcmVhdGVTZXJ2ZXIoe1xuICAgICAgICAgICAgICAgIGNlcnQ6IHRoaXMuX3RyYW5zcG9ydENvbmZpZy5nZXRTc2xDb25maWcoKS5nZXRQZW1DZXJ0aWZpY2F0ZSgpLFxuICAgICAgICAgICAgICAgIGtleTogdGhpcy5fdHJhbnNwb3J0Q29uZmlnLmdldFNzbENvbmZpZygpLmdldFByaXZhdGVLZXkoKSxcbiAgICAgICAgICAgICAgICBwYXNzcGhyYXNlOiB0aGlzLl90cmFuc3BvcnRDb25maWcuZ2V0U3NsQ29uZmlnKCkuZ2V0UGFzc3dvcmQoKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fd3MgPSBuZXcgV2ViU29ja2V0LlNlcnZlcih7XG4gICAgICAgICAgICAgICAgc2VydmVyLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBzZXJ2ZXIubGlzdGVuKHRoaXMuX3RyYW5zcG9ydENvbmZpZy5nZXRQb3J0KCkpO1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFdTUyBzdGFydGVkIG9uIHBvcnQgJHt0aGlzLl90cmFuc3BvcnRDb25maWcuZ2V0UG9ydCgpfWApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gY3JlYXRlIGEgV2ViU29ja2V0IFNlcnZlclxuICAgICAgICAgICAgdGhpcy5fd3MgPSBuZXcgV2ViU29ja2V0LlNlcnZlcih7XG4gICAgICAgICAgICAgICAgcG9ydDogdGhpcy5fdHJhbnNwb3J0Q29uZmlnLmdldFBvcnQoKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFdTIHN0YXJ0ZWQgb24gcG9ydCAke3RoaXMuX3RyYW5zcG9ydENvbmZpZy5nZXRQb3J0KCl9YCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBFdmVudCBsaXN0ZW5lciBmb3IgaW5jb21pbmcgV2ViU29ja2V0IGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuX3dzLm9uKCdjb25uZWN0aW9uJywgKGNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdjb25uZWN0aW9uIGVzdGFibGlzaGVkJyk7XG5cbiAgICAgICAgICAgIC8vIEV2ZW50IGxpc3RlbmVyIGZvciBhbiBpbmNvbWluZyBtZXNzYWdlXG4gICAgICAgICAgICBjb25uZWN0aW9uLm9uKCdtZXNzYWdlJywgKG1lc3NhZ2UpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVNZXNzYWdlKG1lc3NhZ2UpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIEV2ZW50IGxpc3RlbmVyIGZvciBhIGNsb3NlZCBjb25uZWN0aW9uXG4gICAgICAgICAgICBjb25uZWN0aW9uLm9uKCdjbG9zZScsICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnc2VydmVyIHJlY2VpdmVkIGNsb3NlIGV2ZW50Jyk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX3RyYW5zcG9ydENhbGxiYWNrICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3RyYW5zcG9ydENhbGxiYWNrLm9uQ29ubmVjdGlvblRlcm1pbmF0ZWQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gRXZlbnQgbGlzdGVuZXIgZm9yIGVycm9yc1xuICAgICAgICAgICAgY29ubmVjdGlvbi5vbignZXJyb3InLCAoZXJyb3JFdmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdzZXJ2ZXIgcmVjZWl2ZWQgZXJyb3IgZXZlbnQnKTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2sgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2sub25FcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBQb25nIGhlYXJ0YmVhdCBsaXN0ZW5lclxuICAgICAgICAgICAgY29ubmVjdGlvbi5vbigncG9uZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnc2VydmVyIHJlY2VpdmVkIHBvbmcgZXZlbnQnKTtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uLmlzQWxpdmUgPSB0cnVlO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIFRyaWdnZXIgZXZlbnQgZm9yIGNvbm5lY3Rpb24gZXN0YWJsaXNoZWRcbiAgICAgICAgICAgIC8vIEZJWE1FOiBwYXNzIGEgY2xpZW50IGNvbnRleHQgdG8gdGhlIHRyYW5zcG9ydCBsaXN0ZW5lcj9cbiAgICAgICAgICAgIGlmICh0aGlzLl90cmFuc3BvcnRDYWxsYmFjayAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RyYW5zcG9ydENhbGxiYWNrLm9uQ29ubmVjdGlvbkVzdGFibGlzaGVkKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25uZWN0aW9uLmlzQWxpdmUgPSB0cnVlO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBEZXRlY3QgYnJva2VuIGNvbm5lY3Rpb25zXG4gICAgICAgIGlmICh0aGlzLl90cmFuc3BvcnRDb25maWcuZ2V0Q29ubmVjdGlvbkxvc3RUaW1lb3V0KCkgPiAwKSB7XG4gICAgICAgICAgICBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd3MuY2xpZW50cy5mb3JFYWNoKGZ1bmN0aW9uIGVhY2ggKGNsaWVudCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY2xpZW50LmlzQWxpdmUgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnc2VydmVyIGRlZW1lZCBjbGllbnQgZGVhZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNsaWVudC50ZXJtaW5hdGUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIEFzc3VtZSB0aGUgY2xpZW50IGlzIGRlYWQgYW5kIGFzayBpdCBpZiBpdCdzIGFsaXZlXG4gICAgICAgICAgICAgICAgICAgIGNsaWVudC5pc0FsaXZlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdzZXJ2ZXIgc2VuZGluZyBwaW5nIHRvIGNsaWVudCcpO1xuICAgICAgICAgICAgICAgICAgICBjbGllbnQucGluZyhmdW5jdGlvbiAoKSB7fSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9LCB0aGlzLl90cmFuc3BvcnRDb25maWcuZ2V0Q29ubmVjdGlvbkxvc3RUaW1lb3V0KCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3RvcHMgdGhlIFdlYlNvY2tldCBTZXJ2ZXIgZnJvbSBsaXN0ZW5pbmcgYW5kIGNsb3NlcyBleGlzdGluZyBjb25uZWN0aW9uc1xuICAgICAqIEByZXR1cm4ge1dlYlNvY2tldFNlcnZlcn1cbiAgICAgKi9cbiAgICBzdG9wICgpIHtcbiAgICAgICAgaWYgKHRoaXMuX3dzICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl93cy5jbG9zZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VuZHMgYSBwYWNrZXQgdG8gYWxsIGNvbm5lY3RlZCBXZWJTb2NrZXQgY2xpZW50c1xuICAgICAqIEZJWE1FOiBTZW5kaW5nIHBhY2tldHMgc2hvdWxkIGJlIGlzb2xhdGVkIHRvIGEgY2xpZW50IHJhdGhlciB0aGFuIHRhcmdldGluZyBhbGwgY2xpZW50c1xuICAgICAqIEByZXR1cm4ge1dlYlNvY2tldFNlcnZlcn1cbiAgICAgKi9cbiAgICBzZW5kUGFja2V0IChzZGxQYWNrZXQpIHtcbiAgICAgICAgaWYgKHRoaXMuX3dzICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl93cy5jbGllbnRzLmZvckVhY2goZnVuY3Rpb24gZWFjaCAoY2xpZW50KSB7XG4gICAgICAgICAgICAgICAgaWYgKGNsaWVudC5yZWFkeVN0YXRlID09PSBXZWJTb2NrZXQuT1BFTikge1xuICAgICAgICAgICAgICAgICAgICBjbGllbnQuc2VuZChzZGxQYWNrZXQudG9QYWNrZXQoKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGlzIGNhbGxlZCB3aGVuZXZlciBhIG5ldyBtZXNzYWdlIGNvbWVzIGluXG4gICAgICogQHBhcmFtIHtNZXNzYWdlRXZlbnR9IG1lc3NhZ2VcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9oYW5kbGVNZXNzYWdlIChtZXNzYWdlKSB7XG4gICAgICAgIC8vIFJlcXVpcmUgbWVzc2FnZXMgdG8gYmUgYmluYXJ5IG9iamVjdHNcbiAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSAnb2JqZWN0JyB8fCBtZXNzYWdlLmNvbnN0cnVjdG9yLm5hbWUgIT09ICdCdWZmZXInKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBQYXJzZSB0aGUgbWVzc2FnZVxuICAgICAgICBsZXQgc3RhdGVQcm9ncmVzcyA9IGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBtZXNzYWdlSW5kZXggPSAwOyBtZXNzYWdlSW5kZXggPCBtZXNzYWdlLmxlbmd0aDsgbWVzc2FnZUluZGV4KyspIHtcbiAgICAgICAgICAgIHN0YXRlUHJvZ3Jlc3MgPSB0aGlzLl9zZGxQc20uaGFuZGxlQnl0ZShtZXNzYWdlW21lc3NhZ2VJbmRleF0pO1xuXG4gICAgICAgICAgICBpZiAoIXN0YXRlUHJvZ3Jlc3MpIHsgLy8gV2UgYXJlIHRyeWluZyB0byB3ZWVkIHRocm91Z2ggdGhlIGJhZCBwYWNrZXQgaW5mbyB1bnRpbCB3ZSBnZXQgc29tZXRoaW5nXG4gICAgICAgICAgICAgICAgdGhpcy5fc2RsUHNtLnJlc2V0KCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX3NkbFBzbS5nZXRTdGF0ZSgpID09PSBTZGxQc20uRklOSVNIRURfU1RBVEUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYWNrZXQgPSB0aGlzLl9zZGxQc20uZ2V0Rm9ybWVkUGFja2V0KCk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX3RyYW5zcG9ydENhbGxiYWNrICE9PSBudWxsICYmIHBhY2tldCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl90cmFuc3BvcnRDYWxsYmFjay5vblBhY2tldFJlY2VpdmVkKHBhY2tldCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5fc2RsUHNtLnJlc2V0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAgIFdlYlNvY2tldFNlcnZlcixcbn07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmNvbnN0IHsgVHJhbnNwb3J0TWFuYWdlckJhc2UgfSA9IHJlcXVpcmUoJy4vVHJhbnNwb3J0TWFuYWdlckJhc2UuanMnKTtcbmNvbnN0IHsgVHJhbnNwb3J0VHlwZSB9ID0gcmVxdWlyZSgnLi9lbnVtcy9UcmFuc3BvcnRUeXBlLmpzJyk7XG5jb25zdCB7IFdlYlNvY2tldFNlcnZlciB9ID0gcmVxdWlyZSgnLi9XZWJTb2NrZXRTZXJ2ZXIuanMnKTtcblxuY2xhc3MgVHJhbnNwb3J0TWFuYWdlciBleHRlbmRzIFRyYW5zcG9ydE1hbmFnZXJCYXNlIHtcbiAgICBjb25zdHJ1Y3RvciAodHJhbnNwb3J0Q29uZmlnLCB0cmFuc3BvcnRMaXN0ZW5lcikge1xuICAgICAgICBzdXBlcih0cmFuc3BvcnRDb25maWcsIHRyYW5zcG9ydExpc3RlbmVyKTtcblxuICAgICAgICBpZiAodGhpcy5fdHJhbnNwb3J0Q29uZmlnLmdldFRyYW5zcG9ydFR5cGUoKSA9PT0gVHJhbnNwb3J0VHlwZS5XRUJTT0NLRVRfU0VSVkVSKSB7XG4gICAgICAgICAgICB0aGlzLl90cmFuc3BvcnQgPSBuZXcgV2ViU29ja2V0U2VydmVyKHRoaXMuX3RyYW5zcG9ydENvbmZpZywgdGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2spO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX3RyYW5zcG9ydCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCB0cmFuc3BvcnQgdHlwZScpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAgIFRyYW5zcG9ydE1hbmFnZXIsXG59OyIsIlxuaW1wb3J0IHsgU2RsUHJvdG9jb2xCYXNlIH0gZnJvbSAnLi9TZGxQcm90b2NvbEJhc2UuanMnO1xuaW1wb3J0IHsgVHJhbnNwb3J0TWFuYWdlciB9IGZyb20gJy4vLi4vdHJhbnNwb3J0L1RyYW5zcG9ydE1hbmFnZXIuanMnO1xuXG5cbmNsYXNzIFNkbFByb3RvY29sIGV4dGVuZHMgU2RsUHJvdG9jb2xCYXNlIHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1RyYW5zcG9ydENvbmZpZ0Jhc2V9IGJhc2VUcmFuc3BvcnRDb25maWdcbiAgICAgKiBAcGFyYW0ge1NkbFByb3RvY29sTGlzdGVuZXJ9IHNkbFByb3RvY29sTGlzdGVuZXJcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoYmFzZVRyYW5zcG9ydENvbmZpZywgc2RsUHJvdG9jb2xMaXN0ZW5lcikge1xuICAgICAgICBzdXBlcihiYXNlVHJhbnNwb3J0Q29uZmlnLCBzZGxQcm90b2NvbExpc3RlbmVyKTtcbiAgICAgICAgdGhpcy5zZXRUcmFuc3BvcnRNYW5hZ2VyKG5ldyBUcmFuc3BvcnRNYW5hZ2VyKHRoaXMuX3RyYW5zcG9ydENvbmZpZywgdGhpcy5fdHJhbnNwb3J0TGlzdGVuZXIpKTtcbiAgICB9XG59XG5cbmV4cG9ydCB7IFNkbFByb3RvY29sIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFNlcnZpY2VUeXBlIH0gZnJvbSAnLi4vcHJvdG9jb2wvZW51bXMvU2VydmljZVR5cGUuanMnO1xuXG5jbGFzcyBTZXJ2aWNlTGlzdGVuZXJNYXAge1xuICAgIC8qKlxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHRoaXMuX2xpc3RlbmVycyA9IHt9O1xuXG4gICAgICAgIC8vIGluaXRpYWxpemUgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIGZvciBlYWNoIHNlcnZpY2UgdHlwZVxuICAgICAgICB0aGlzLl9saXN0ZW5lcnNbU2VydmljZVR5cGUuQ09OVFJPTF0gPSBbXTtcbiAgICAgICAgdGhpcy5fbGlzdGVuZXJzW1NlcnZpY2VUeXBlLlJQQ10gPSBbXTtcbiAgICAgICAgdGhpcy5fbGlzdGVuZXJzW1NlcnZpY2VUeXBlLkFVRElPXSA9IFtdO1xuICAgICAgICB0aGlzLl9saXN0ZW5lcnNbU2VydmljZVR5cGUuVklERU9dID0gW107XG4gICAgICAgIHRoaXMuX2xpc3RlbmVyc1tTZXJ2aWNlVHlwZS5IWUJSSURdID0gW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTZXJ2aWNlVHlwZX0gc2VydmljZVR5cGVcbiAgICAgKiBAcGFyYW0ge1NkbFNlcnZpY2VMaXN0ZW5lcn0gc2VydmljZUxpc3RlbmVyXG4gICAgICovXG4gICAgYWRkTGlzdGVuZXIgKHNlcnZpY2VUeXBlLCBzZXJ2aWNlTGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKCFzZXJ2aWNlVHlwZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2xpc3RlbmVyc1tzZXJ2aWNlVHlwZV0ucHVzaChzZXJ2aWNlTGlzdGVuZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHBhcmFtIHtTZGxTZXJ2aWNlTGlzdGVuZXJ9IHNlcnZpY2VMaXN0ZW5lclxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59IC0gd2hldGhlciB0aGUgc2VydmljZSBnb3QgcmVtb3ZlZFxuICAgICAqL1xuICAgIHJlbW92ZUxpc3RlbmVyIChzZXJ2aWNlVHlwZSwgc2VydmljZUxpc3RlbmVyKSB7XG4gICAgICAgIGlmICghc2VydmljZVR5cGUpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBsaXN0ZW5lckFycmF5ID0gdGhpcy5fbGlzdGVuZXJzW3NlcnZpY2VUeXBlXTtcbiAgICAgICAgbGV0IHJlbW92ZWQgPSBmYWxzZTtcbiAgICAgICAgLy8gcmVtb3ZlIG1hdGNoaW5nIHJlZmVyZW5jZXMgdG8gdGhlIHBhc3NlZCBpbiBzZXJ2aWNlIGxpc3RlbmVyXG4gICAgICAgIHRoaXMuX2xpc3RlbmVyc1tzZXJ2aWNlVHlwZV0gPSBsaXN0ZW5lckFycmF5LmZpbHRlcihsaXN0ZW5lciA9PiB7XG4gICAgICAgICAgICByZW1vdmVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHJldHVybiBsaXN0ZW5lciAhPT0gc2VydmljZUxpc3RlbmVyO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJlbW92ZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VuZHMgdGhpcyBldmVudCB0byBhbGwgbGlzdGVuZXJzIGJlbG9uZ2luZyB0byBhIHNwZWNpZmljIHNlcnZpY2UgdHlwZVxuICAgICAqIEBwYXJhbSB7U2RsU2Vzc2lvbn0gc2Vzc2lvblxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBpc0VuY3J5cHRlZFxuICAgICAqL1xuICAgIHNlbmRFdmVudFNlcnZpY2VTdGFydGVkIChzZXNzaW9uLCBzZXJ2aWNlVHlwZSwgaXNFbmNyeXB0ZWQpIHtcbiAgICAgICAgY29uc3QgbGlzdGVuZXJBcnJheSA9IHRoaXMuX2xpc3RlbmVyc1tzZXJ2aWNlVHlwZV07XG4gICAgICAgIGZvciAoY29uc3QgaW5kZXggaW4gbGlzdGVuZXJBcnJheSkge1xuICAgICAgICAgICAgbGlzdGVuZXJBcnJheVtpbmRleF0ub25TZXJ2aWNlU3RhcnRlZChzZXNzaW9uLCBzZXJ2aWNlVHlwZSwgaXNFbmNyeXB0ZWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VuZHMgdGhpcyBldmVudCB0byBhbGwgbGlzdGVuZXJzIGJlbG9uZ2luZyB0byBhIHNwZWNpZmljIHNlcnZpY2UgdHlwZVxuICAgICAqIEBwYXJhbSB7U2RsU2Vzc2lvbn0gc2Vzc2lvblxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICovXG4gICAgc2VuZEV2ZW50U2VydmljZUVuZGVkIChzZXNzaW9uLCBzZXJ2aWNlVHlwZSkge1xuICAgICAgICBjb25zdCBsaXN0ZW5lckFycmF5ID0gdGhpcy5fbGlzdGVuZXJzW3NlcnZpY2VUeXBlXTtcbiAgICAgICAgZm9yIChjb25zdCBpbmRleCBpbiBsaXN0ZW5lckFycmF5KSB7XG4gICAgICAgICAgICBsaXN0ZW5lckFycmF5W2luZGV4XS5vblNlcnZpY2VFbmRlZChzZXNzaW9uLCBzZXJ2aWNlVHlwZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZW5kcyB0aGlzIGV2ZW50IHRvIGFsbCBsaXN0ZW5lcnMgYmVsb25naW5nIHRvIGEgc3BlY2lmaWMgc2VydmljZSB0eXBlXG4gICAgICogQHBhcmFtIHtTZGxTZXNzaW9ufSBzZXNzaW9uXG4gICAgICogQHBhcmFtIHtTZXJ2aWNlVHlwZX0gc2VydmljZVR5cGVcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gcmVhc29uXG4gICAgICovXG4gICAgc2VuZEV2ZW50U2VydmljZUVycm9yIChzZXNzaW9uLCBzZXJ2aWNlVHlwZSwgcmVhc29uKSB7XG4gICAgICAgIGNvbnN0IGxpc3RlbmVyQXJyYXkgPSB0aGlzLl9saXN0ZW5lcnNbc2VydmljZVR5cGVdO1xuICAgICAgICBmb3IgKGNvbnN0IGluZGV4IGluIGxpc3RlbmVyQXJyYXkpIHtcbiAgICAgICAgICAgIGxpc3RlbmVyQXJyYXlbaW5kZXhdLm9uU2VydmljZUVycm9yKHNlc3Npb24sIHNlcnZpY2VUeXBlLCByZWFzb24pO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgeyBTZXJ2aWNlTGlzdGVuZXJNYXAgfTtcbiIsImltcG9ydCB7IFZpZGVvU3RyZWFtaW5nRm9ybWF0IH0gZnJvbSAnLi4vLi4vcnBjL3N0cnVjdHMvVmlkZW9TdHJlYW1pbmdGb3JtYXQnO1xuaW1wb3J0IHsgVmlkZW9TdHJlYW1pbmdDb2RlYyB9IGZyb20gJy4uLy4uL3JwYy9lbnVtcy9WaWRlb1N0cmVhbWluZ0NvZGVjJztcbmltcG9ydCB7IFZpZGVvU3RyZWFtaW5nUHJvdG9jb2wgfSBmcm9tICcuLi8uLi9ycGMvZW51bXMvVmlkZW9TdHJlYW1pbmdQcm90b2NvbCc7XG5pbXBvcnQgeyBJbWFnZVJlc29sdXRpb24gfSBmcm9tICcuLi8uLi9ycGMvc3RydWN0cy9JbWFnZVJlc29sdXRpb24nO1xuXG4vKlxuICogQ29weXJpZ2h0IChjKSAyMDE5IExpdmlvLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4gKlxuICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4gKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4gKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuICogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4gKiBkaXN0cmlidXRpb24uXG4gKlxuICogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiAqIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuICogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4gKlxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiAqIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4gKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4gKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4gKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuICogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4gKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuICogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiAqIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4gKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqL1xuXG5jb25zdCBERUZBVUxUX1BST1RPQ09MID0gVmlkZW9TdHJlYW1pbmdQcm90b2NvbC5SQVc7XG5jb25zdCBERUZBVUxUX0NPREVDID0gVmlkZW9TdHJlYW1pbmdDb2RlYy5IMjY0O1xuY29uc3QgREVGQVVMVF9XSURUSCA9IDEwMjQ7XG5jb25zdCBERUZBVUxUX0hFSUdIVCA9IDU3NjtcbmNvbnN0IERFRkFVTFRfREVOU0lUWSA9IDI0MDtcbmNvbnN0IERFRkFVTFRfRlJBTUVSQVRFID0gMzA7XG5jb25zdCBERUZBVUxUX0JJVFJBVEUgPSA1MTIwMDA7XG5jb25zdCBERUZBVUxUX0lOVEVSVkFMID0gNTtcbmNvbnN0IERFRkFVTFRfU0NBTEUgPSAxLjA7XG5cbmNsYXNzIFZpZGVvU3RyZWFtaW5nUGFyYW1ldGVycyB7XG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZGlzcGxheURlbnNpdHlcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZnJhbWVSYXRlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdHJhdGVcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gaW50ZXJ2YWxcbiAgICAgKiBAcGFyYW0ge0ltYWdlUmVzb2x1dGlvbn0gcmVzb2x1dGlvblxuICAgICAqIEBwYXJhbSB7VmlkZW9TdHJlYW1pbmdGb3JtYXR9IGZvcm1hdFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChkaXNwbGF5RGVuc2l0eSA9IG51bGwsIGZyYW1lUmF0ZSA9IG51bGwsIGJpdHJhdGUgPSBudWxsLCBpbnRlcnZhbCA9IG51bGwsIHJlc29sdXRpb24gPSBudWxsLCBmb3JtYXQgPSBudWxsKSB7XG4gICAgICAgIHRoaXMuX2Rpc3BsYXlEZW5zaXR5ID0gZGlzcGxheURlbnNpdHkgfHwgREVGQVVMVF9ERU5TSVRZO1xuICAgICAgICB0aGlzLl9mcmFtZVJhdGUgPSBmcmFtZVJhdGUgfHwgREVGQVVMVF9GUkFNRVJBVEU7XG4gICAgICAgIHRoaXMuX2JpdHJhdGUgPSBiaXRyYXRlIHx8IERFRkFVTFRfQklUUkFURTtcbiAgICAgICAgdGhpcy5faW50ZXJ2YWwgPSBpbnRlcnZhbCB8fCBERUZBVUxUX0lOVEVSVkFMO1xuXG4gICAgICAgIGlmICghKHJlc29sdXRpb24gaW5zdGFuY2VvZiBJbWFnZVJlc29sdXRpb24pKSB7XG4gICAgICAgICAgICByZXNvbHV0aW9uID0gbmV3IEltYWdlUmVzb2x1dGlvbigpO1xuICAgICAgICAgICAgcmVzb2x1dGlvbi5zZXRSZXNvbHV0aW9uV2lkdGgoREVGQVVMVF9XSURUSCk7XG4gICAgICAgICAgICByZXNvbHV0aW9uLnNldFJlc29sdXRpb25IZWlnaHQoREVGQVVMVF9IRUlHSFQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3Jlc29sdXRpb24gPSByZXNvbHV0aW9uO1xuXG4gICAgICAgIGlmICghKGZvcm1hdCBpbnN0YW5jZW9mIFZpZGVvU3RyZWFtaW5nRm9ybWF0KSkge1xuICAgICAgICAgICAgZm9ybWF0ID0gbmV3IFZpZGVvU3RyZWFtaW5nRm9ybWF0KCk7XG4gICAgICAgICAgICBmb3JtYXQuc2V0UHJvdG9jb2woREVGQVVMVF9QUk9UT0NPTCk7XG4gICAgICAgICAgICBmb3JtYXQuc2V0Q29kZWMoREVGQVVMVF9DT0RFQyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9mb3JtYXQgPSBmb3JtYXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXBkYXRlIHRoZSB2YWx1ZXMgY29udGFpbmVkIGluIHRoZSBjYXBhYmlsaXR5IHRoYXQgc2hvdWxkIGhhdmUgYmVlbiByZXR1cm5lZCB0aHJvdWdoIHRoZSBTeXN0ZW1DYXBhYmlsaXR5TWFuYWdlci5cbiAgICAgKiBUaGlzIHVwZGF0ZSB3aWxsIHVzZSB0aGUgbW9zdCBwcmVmZXJyZWQgc3RyZWFtaW5nIGZvcm1hdCBmcm9tIHRoZSBtb2R1bGUuXG4gICAgICogQHBhcmFtIHtWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHl9IGNhcGFiaWxpdHkgdGhlIHZpZGVvIHN0cmVhbWluZyBjYXBhYmlsaXR5IHJldHVybmVkIGZyb20gdGhlIFN5c3RlbUNhcGFiaWxpdHlNYW5hZ2VyXG4gICAgICovXG4gICAgdXBkYXRlIChjYXBhYmlsaXR5KSB7XG4gICAgICAgIGlmIChjYXBhYmlsaXR5LmdldE1heEJpdHJhdGUoKSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fYml0cmF0ZSA9IGNhcGFiaWxpdHkuZ2V0TWF4Qml0cmF0ZSgpICogMTAwMDsgLy8gTk9URTogdGhlIHVuaXQgb2YgbWF4Qml0cmF0ZSBpbiBnZXRTeXN0ZW1DYXBhYmlsaXR5IGlzIGticHMuXG4gICAgICAgIH1cbiAgICAgICAgbGV0IHNjYWxlID0gREVGQVVMVF9TQ0FMRTtcbiAgICAgICAgaWYgKGNhcGFiaWxpdHkuZ2V0U2NhbGUoKSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgc2NhbGUgPSBjYXBhYmlsaXR5LmdldFNjYWxlKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzb2x1dGlvbiA9IGNhcGFiaWxpdHkuZ2V0UHJlZmVycmVkUmVzb2x1dGlvbigpO1xuICAgICAgICBpZiAocmVzb2x1dGlvbiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKHJlc29sdXRpb24uZ2V0UmVzb2x1dGlvbkhlaWdodCgpICE9PSBudWxsICYmIHJlc29sdXRpb24uZ2V0UmVzb2x1dGlvbkhlaWdodCgpID4gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3Jlc29sdXRpb24uc2V0UmVzb2x1dGlvbkhlaWdodChNYXRoLmZsb29yKChyZXNvbHV0aW9uLmdldFJlc29sdXRpb25IZWlnaHQoKSAvIHNjYWxlKSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHJlc29sdXRpb24uZ2V0UmVzb2x1dGlvbldpZHRoKCkgIT09IG51bGwgJiYgcmVzb2x1dGlvbi5nZXRSZXNvbHV0aW9uV2lkdGgoKSA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yZXNvbHV0aW9uLnNldFJlc29sdXRpb25XaWR0aChNYXRoLmZsb29yKChyZXNvbHV0aW9uLmdldFJlc29sdXRpb25XaWR0aCgpIC8gc2NhbGUpKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZm9ybWF0cyA9IGNhcGFiaWxpdHkuZ2V0U3VwcG9ydGVkRm9ybWF0cygpO1xuICAgICAgICBpZiAoZm9ybWF0cyAhPT0gbnVsbCAmJiBmb3JtYXRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuX2Zvcm1hdCA9IGZvcm1hdHNbMF07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBkaXNwbGF5RGVuc2l0eVxuICAgICAqIEByZXR1cm4ge1ZpZGVvU3RyZWFtaW5nUGFyYW1ldGVyc31cbiAgICAgKi9cbiAgICBzZXREaXNwbGF5RGVuc2l0eSAoZGlzcGxheURlbnNpdHkpIHtcbiAgICAgICAgdGhpcy5fZGlzcGxheURlbnNpdHkgPSBkaXNwbGF5RGVuc2l0eTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7bnVtYmVyfVxuICAgICAqL1xuICAgIGdldERpc3BsYXlEZW5zaXR5ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rpc3BsYXlEZW5zaXR5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBmcmFtZVJhdGVcbiAgICAgKiBAcmV0dXJuIHtWaWRlb1N0cmVhbWluZ1BhcmFtZXRlcnN9XG4gICAgICovXG4gICAgc2V0RnJhbWVSYXRlIChmcmFtZVJhdGUpIHtcbiAgICAgICAgdGhpcy5fZnJhbWVSYXRlID0gZnJhbWVSYXRlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge251bWJlcn1cbiAgICAgKi9cbiAgICBnZXRGcmFtZVJhdGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZnJhbWVSYXRlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRyYXRlXG4gICAgICogQHJldHVybiB7VmlkZW9TdHJlYW1pbmdQYXJhbWV0ZXJzfVxuICAgICAqL1xuICAgIHNldEJpdHJhdGUgKGJpdHJhdGUpIHtcbiAgICAgICAgdGhpcy5fYml0cmF0ZSA9IGJpdHJhdGU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtudW1iZXJ9XG4gICAgICovXG4gICAgZ2V0Qml0cmF0ZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaXRyYXRlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpbnRlcnZhbFxuICAgICAqIEByZXR1cm4ge1ZpZGVvU3RyZWFtaW5nUGFyYW1ldGVyc31cbiAgICAgKi9cbiAgICBzZXRJbnRlcnZhbCAoaW50ZXJ2YWwpIHtcbiAgICAgICAgdGhpcy5faW50ZXJ2YWwgPSBpbnRlcnZhbDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7bnVtYmVyfVxuICAgICAqL1xuICAgIGdldEludGVydmFsICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ludGVydmFsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmlkZW9TdHJlYW1pbmdGb3JtYXR9IGZvcm1hdFxuICAgICAqIEByZXR1cm4ge1ZpZGVvU3RyZWFtaW5nUGFyYW1ldGVyc31cbiAgICAgKi9cbiAgICBzZXRGb3JtYXQgKGZvcm1hdCkge1xuICAgICAgICB0aGlzLl9mb3JtYXQgPSBmb3JtYXQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZpZGVvU3RyZWFtaW5nRm9ybWF0fVxuICAgICAqL1xuICAgIGdldEZvcm1hdCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mb3JtYXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb25cbiAgICAgKiBAcmV0dXJuIHtWaWRlb1N0cmVhbWluZ1BhcmFtZXRlcnN9XG4gICAgICovXG4gICAgc2V0UmVzb2x1dGlvbiAocmVzb2x1dGlvbikge1xuICAgICAgICB0aGlzLl9yZXNvbHV0aW9uID0gcmVzb2x1dGlvbjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7bnVtYmVyfVxuICAgICAqL1xuICAgIGdldFJlc29sdXRpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmVzb2x1dGlvbjtcbiAgICB9XG59XG5cbmV4cG9ydCB7IFZpZGVvU3RyZWFtaW5nUGFyYW1ldGVycyB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBTZGxQcm90b2NvbExpc3RlbmVyIH0gZnJvbSAnLi4vcHJvdG9jb2wvU2RsUHJvdG9jb2xMaXN0ZW5lci5qcyc7XG5pbXBvcnQgeyBTZGxQcm90b2NvbCB9IGZyb20gJy4uL3Byb3RvY29sL1NkbFByb3RvY29sLmpzJztcbmltcG9ydCB7IFNlcnZpY2VUeXBlIH0gZnJvbSAnLi4vcHJvdG9jb2wvZW51bXMvU2VydmljZVR5cGUuanMnO1xuaW1wb3J0IHsgU2VydmljZUxpc3RlbmVyTWFwIH0gZnJvbSAnLi9TZXJ2aWNlTGlzdGVuZXJNYXAuanMnO1xuaW1wb3J0IHsgVmlkZW9TdHJlYW1pbmdQYXJhbWV0ZXJzIH0gZnJvbSAnLi4vc3RyZWFtaW5nL3ZpZGVvL1ZpZGVvU3RyZWFtaW5nUGFyYW1ldGVycy5qcyc7XG5cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBTZGxTZXNzaW9uXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBzdGFydFxuICogQHByb3BlcnR5IHtGdW5jdGlvbn0gZ2V0U2Vzc2lvbklkXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBvblByb3RvY29sU2Vzc2lvblN0YXJ0ZWRcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IG9uUHJvdG9jb2xTZXNzaW9uRW5kZWRcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IG9uUHJvdG9jb2xTZXNzaW9uRW5kZWROQUNLZWRcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IG9uUnBjTWVzc2FnZVJlY2VpdmVkXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBlbmRTZXNzaW9uXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBzZW5kUnBjXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBnZXRNdHVcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGNsb3NlXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBzdGFydFNlcnZpY2VcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGVuZFNlcnZpY2VcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGdldEN1cnJlbnRUcmFuc3BvcnRUeXBlXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBnZXRJc0Nvbm5lY3RlZFxuICogQHByb3BlcnR5IHtGdW5jdGlvbn0gZ2V0UHJvdG9jb2xWZXJzaW9uXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBnZXRUcmFuc3BvcnRDb25maWdcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGdldFNlc3Npb25IYXNoSWRcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGFkZFNlcnZpY2VMaXN0ZW5lclxuICogQHByb3BlcnR5IHtGdW5jdGlvbn0gcmVtb3ZlU2VydmljZUxpc3RlbmVyXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBnZXRTZXJ2aWNlTGlzdGVuZXJzXG4gKi9cbmNsYXNzIFNkbFNlc3Npb24ge1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VHJhbnNwb3J0Q29uZmlnQmFzZX0gYmFzZVRyYW5zcG9ydENvbmZpZ1xuICAgICAqIEBwYXJhbSB7U2RsU2Vzc2lvbkxpc3RlbmVyfSBzZGxTZXNzaW9uTGlzdGVuZXJcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoYmFzZVRyYW5zcG9ydENvbmZpZywgc2RsU2Vzc2lvbkxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMuX2Jhc2VUcmFuc3BvcnRDb25maWcgPSBiYXNlVHJhbnNwb3J0Q29uZmlnO1xuICAgICAgICB0aGlzLl9zZXNzaW9uSWQgPSBudWxsO1xuICAgICAgICB0aGlzLl9zZXNzaW9uSGFzaElkID0gbnVsbDtcbiAgICAgICAgdGhpcy5fc2RsU2Vzc2lvbkxpc3RlbmVyID0gc2RsU2Vzc2lvbkxpc3RlbmVyO1xuICAgICAgICB0aGlzLl9iYXNlVHJhbnNwb3J0Q29uZmlnID0gYmFzZVRyYW5zcG9ydENvbmZpZztcblxuICAgICAgICAvLyBhIGhhc2ggd2hlcmUgZWFjaCBrZXkgaXMgYSBzZXJ2aWNlIHR5cGUsIGFuZCBoYXMgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIGF0dGFjaGVkXG4gICAgICAgIHRoaXMuX3NlcnZpY2VMaXN0ZW5lcnMgPSBuZXcgU2VydmljZUxpc3RlbmVyTWFwKCk7XG5cbiAgICAgICAgdGhpcy5fc2RsUHJvdG9jb2xMaXN0ZW5lciA9IHRoaXMuX3NldHVwU2RsUHJvdG9jb2xMaXN0ZW5lcigpO1xuXG4gICAgICAgIHRoaXMuX3NkbFByb3RvY29sID0gbmV3IFNkbFByb3RvY29sKGJhc2VUcmFuc3BvcnRDb25maWcsIHRoaXMuX3NkbFByb3RvY29sTGlzdGVuZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1NkbFByb3RvY29sTGlzdGVuZXJ9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBfc2V0dXBTZGxQcm90b2NvbExpc3RlbmVyICgpIHtcbiAgICAgICAgY29uc3Qgc2RsUHJvdG9jb2xMaXN0ZW5lciA9IG5ldyBTZGxQcm90b2NvbExpc3RlbmVyKCk7XG4gICAgICAgIHNkbFByb3RvY29sTGlzdGVuZXIuc2V0R2V0U2Vzc2lvbklkKHRoaXMuZ2V0U2Vzc2lvbklkLmJpbmQodGhpcykpO1xuICAgICAgICBzZGxQcm90b2NvbExpc3RlbmVyLnNldE9uUHJvdG9jb2xTZXNzaW9uU3RhcnRlZCh0aGlzLm9uUHJvdG9jb2xTZXNzaW9uU3RhcnRlZC5iaW5kKHRoaXMpKTtcbiAgICAgICAgc2RsUHJvdG9jb2xMaXN0ZW5lci5zZXRPblByb3RvY29sU2Vzc2lvbkVuZGVkKHRoaXMub25Qcm90b2NvbFNlc3Npb25FbmRlZC5iaW5kKHRoaXMpKTtcbiAgICAgICAgc2RsUHJvdG9jb2xMaXN0ZW5lci5zZXRPblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkKHRoaXMub25Qcm90b2NvbFNlc3Npb25FbmRlZE5BQ0tlZC5iaW5kKHRoaXMpKTtcbiAgICAgICAgc2RsUHJvdG9jb2xMaXN0ZW5lci5zZXRPblJwY01lc3NhZ2VSZWNlaXZlZCh0aGlzLm9uUnBjTWVzc2FnZVJlY2VpdmVkLmJpbmQodGhpcykpO1xuICAgICAgICBzZGxQcm90b2NvbExpc3RlbmVyLnNldE9uVHJhbnNwb3J0Q29ubmVjdGVkKHRoaXMub25UcmFuc3BvcnRDb25uZWN0ZWQuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgc2RsUHJvdG9jb2xMaXN0ZW5lci5zZXRHZXREZXNpcmVkVmlkZW9QYXJhbXModGhpcy5nZXREZXNpcmVkVmlkZW9QYXJhbXMuYmluZCh0aGlzKSk7XG4gICAgICAgIHNkbFByb3RvY29sTGlzdGVuZXIuc2V0U2V0QWNjZXB0ZWRWaWRlb1BhcmFtcyh0aGlzLnNldEFjY2VwdGVkVmlkZW9QYXJhbXMuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgcmV0dXJuIHNkbFByb3RvY29sTGlzdGVuZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3RhcnRzIHVwIHRoZSBTREwgcHJvdG9jb2wgY2xhc3MuIEl0IHdpbGwga2ljayBvZmYgdGhlIHRyYW5zcG9ydCBtYW5hZ2VyIGFuZCB1bmRlcmx5aW5nIHRyYW5zcG9ydC5cbiAgICAgKi9cbiAgICBzdGFydCAoKSB7XG4gICAgICAgIHRoaXMuX3NkbFByb3RvY29sLnN0YXJ0KCk7XG4gICAgfVxuXG4gICAgLyoqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCRUdJTjogICAgU2RsUHJvdG9jb2xMaXN0ZW5lciBpbXBsZW1lbnRlZCBtZXRob2RzXG4gICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn0gIC0gcmVwcmVzZW50cyBhIGJ5dGVcbiAgICAgKi9cbiAgICBnZXRTZXNzaW9uSWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2Vzc2lvbklkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV2ZW50IGZpcmVkIHdoZW4gdHJhbnNwb3J0IChlZyB0Y3AsIHdzLCBibHVldG9vdGgpIGhhcyBjb25uZWN0ZWQuXG4gICAgICovXG4gICAgb25UcmFuc3BvcnRDb25uZWN0ZWQgKCkge1xuICAgICAgICB0aGlzLl9zZGxTZXNzaW9uTGlzdGVuZXIub25UcmFuc3BvcnRDb25uZWN0ZWQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzZXNzaW9uSWQgLSByZXByZXNlbnRzIGEgYnl0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB2ZXJzaW9uIC0gcmVwcmVzZW50cyBhIGJ5dGVcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gY29ycmVsYXRpb25JZFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBoYXNoSWRcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGlzRW5jcnlwdGVkXG4gICAgICovXG4gICAgb25Qcm90b2NvbFNlc3Npb25TdGFydGVkIChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklkLCB2ZXJzaW9uLCBjb3JyZWxhdGlvbklkLCBoYXNoSWQsIGlzRW5jcnlwdGVkKSB7XG4gICAgICAgIHRoaXMuX3Nlc3Npb25JZCA9IHNlc3Npb25JZDtcblxuICAgICAgICBpZiAoc2VydmljZVR5cGUgPT09IFNlcnZpY2VUeXBlLlJQQykge1xuICAgICAgICAgICAgdGhpcy5fc2Vzc2lvbkhhc2hJZCA9IGhhc2hJZDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3NkbFNlc3Npb25MaXN0ZW5lci5vblByb3RvY29sU2Vzc2lvblN0YXJ0ZWQoc2VydmljZVR5cGUsIHNlc3Npb25JZCwgdmVyc2lvbiwgY29ycmVsYXRpb25JZCwgaGFzaElkLCBpc0VuY3J5cHRlZCk7XG4gICAgICAgIHRoaXMuX3NlcnZpY2VMaXN0ZW5lcnMuc2VuZEV2ZW50U2VydmljZVN0YXJ0ZWQodGhpcywgc2VydmljZVR5cGUsIGlzRW5jcnlwdGVkKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzZXNzaW9uSWQgLSByZXByZXNlbnRzIGEgYnl0ZVxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBjb3JyZWxhdGlvbklkXG4gICAgICovXG4gICAgb25Qcm90b2NvbFNlc3Npb25FbmRlZCAoc2VydmljZVR5cGUsIHNlc3Npb25JZCwgY29ycmVsYXRpb25JZCkge1xuICAgICAgICB0aGlzLl9zZGxTZXNzaW9uTGlzdGVuZXIub25Qcm90b2NvbFNlc3Npb25FbmRlZChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklkLCBjb3JyZWxhdGlvbklkKTtcbiAgICAgICAgdGhpcy5fc2VydmljZUxpc3RlbmVycy5zZW5kRXZlbnRTZXJ2aWNlRW5kZWQodGhpcywgc2VydmljZVR5cGUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlc3Npb25JZCAtIHJlcHJlc2VudHMgYSBieXRlXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGNvcnJlbGF0aW9uSWRcbiAgICAgKi9cbiAgICBvblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkIChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklkLCBjb3JyZWxhdGlvbklkKSB7XG4gICAgICAgIHRoaXMuX3NkbFNlc3Npb25MaXN0ZW5lci5vblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkKHNlcnZpY2VUeXBlLCBzZXNzaW9uSWQsIGNvcnJlbGF0aW9uSWQpO1xuICAgICAgICB0aGlzLl9zZXJ2aWNlTGlzdGVuZXJzLnNlbmRFdmVudFNlcnZpY2VFcnJvcih0aGlzLCBzZXJ2aWNlVHlwZSwgYEVuZCAke3NlcnZpY2VUeXBlLnRvU3RyaW5nKCl9IFNlcnZpY2UgTkFDSydlZGApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7UnBjTWVzc2FnZX0gcnBjTWVzc2FnZVxuICAgICAqL1xuICAgIG9uUnBjTWVzc2FnZVJlY2VpdmVkIChycGNNZXNzYWdlKSB7XG4gICAgICAgIHRoaXMuX3NkbFNlc3Npb25MaXN0ZW5lci5vblJwY01lc3NhZ2VSZWNlaXZlZChycGNNZXNzYWdlKTtcbiAgICB9XG5cblxuICAgIC8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRU5EOiAgICBTZGxQcm90b2NvbExpc3RlbmVyIGltcGxlbWVudGVkIG1ldGhvZHNcbiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4gICAgZW5kU2Vzc2lvbiAoKSB7XG4gICAgICAgIHRoaXMuX3NkbFByb3RvY29sLmVuZFNlc3Npb24oKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1JwY01lc3NhZ2V9IHJwY01lc3NhZ2VcbiAgICAgKi9cbiAgICBzZW5kUnBjIChycGNNZXNzYWdlKSB7XG4gICAgICAgIHRoaXMuX3NkbFByb3RvY29sLnNlbmRScGMocnBjTWVzc2FnZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VuZHMgYW4gc2RsUGFja2V0LlxuICAgICAqIEBwYXJhbSB7U2RsUGFja2V0fSBzZGxQYWNrZXRcbiAgICAgKi9cbiAgICBzZW5kUGFja2V0IChzZGxQYWNrZXQpIHtcbiAgICAgICAgdGhpcy5fc2RsUHJvdG9jb2wuc2VuZFBhY2tldChzZGxQYWNrZXQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHJldHVybiB7TnVtYmVyfSBtYXggdHJhbnNwb3J0IHVuaXQgZm9yIHRoZSBnaXZlbiBzZXJ2aWNlIHR5cGVcbiAgICAgKi9cbiAgICBnZXRNdHUgKHNlcnZpY2VUeXBlKSB7XG4gICAgICAgIHRoaXMuX3NkbFByb3RvY29sLmdldE10dShzZXJ2aWNlVHlwZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRW5kcyB0aGUgY3VycmVudCBzZXNzaW9uXG4gICAgICovXG4gICAgY2xvc2UgKCkge1xuICAgICAgICB0aGlzLl9zZGxQcm90b2NvbC5lbmRTZXNzaW9uKHRoaXMuX3Nlc3Npb25JZCwgdGhpcy5fc2Vzc2lvbkhhc2hJZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtTZXJ2aWNlVHlwZX0gc2VydmljZVR5cGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc2Vzc2lvbklkIC0gcmVwcmVzZW50cyBhIGJ5dGVcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGlzRW5jcnlwdGVkXG4gICAgICovXG4gICAgc3RhcnRTZXJ2aWNlIChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklkLCBpc0VuY3J5cHRlZCkge1xuICAgICAgICB0aGlzLl9zZGxQcm90b2NvbC5zdGFydFNlcnZpY2Uoc2VydmljZVR5cGUsIHNlc3Npb25JZCwgaXNFbmNyeXB0ZWQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlc3Npb25JZCAtIHJlcHJlc2VudHMgYSBieXRlXG4gICAgICovXG4gICAgZW5kU2VydmljZSAoc2VydmljZVR5cGUsIHNlc3Npb25JZCkge1xuICAgICAgICB0aGlzLl9zZGxQcm90b2NvbC5lbmRTZXJ2aWNlKHNlcnZpY2VUeXBlLCBzZXNzaW9uSWQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1RyYW5zcG9ydFR5cGV9XG4gICAgICovXG4gICAgZ2V0Q3VycmVudFRyYW5zcG9ydFR5cGUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmFzZVRyYW5zcG9ydENvbmZpZy5nZXRUcmFuc3BvcnRUeXBlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn0gaXNDb25uZWN0ZWRcbiAgICAgKi9cbiAgICBnZXRJc0Nvbm5lY3RlZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zZGxQcm90b2NvbC5pc0Nvbm5lY3RlZCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1ZlcnNpb259XG4gICAgICovXG4gICAgZ2V0UHJvdG9jb2xWZXJzaW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NkbFByb3RvY29sLmdldFByb3RvY29sVmVyc2lvbigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1RyYW5zcG9ydENvbmZpZ0Jhc2V9XG4gICAgICovXG4gICAgZ2V0VHJhbnNwb3J0Q29uZmlnICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Jhc2VUcmFuc3BvcnRDb25maWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIGdldFNlc3Npb25IYXNoSWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2Vzc2lvbkhhc2hJZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZVxuICAgICAqIEBwYXJhbSB7U2RsU2VydmljZUxpc3RlbmVyfSBzZGxTZXJ2aWNlTGlzdGVuZXJcbiAgICAgKi9cbiAgICBhZGRTZXJ2aWNlTGlzdGVuZXIgKHNlcnZpY2VUeXBlLCBzZGxTZXJ2aWNlTGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5fc2VydmljZUxpc3RlbmVycy5hZGRMaXN0ZW5lcihzZXJ2aWNlVHlwZSwgc2RsU2VydmljZUxpc3RlbmVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZVxuICAgICAqIEBwYXJhbSB7U2RsU2VydmljZUxpc3RlbmVyfSBzZGxTZXJ2aWNlTGlzdGVuZXJcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufSAtIHdoZXRoZXIgdGhlIHJlbW92YWwgd2FzIHN1Y2Nlc3NmdWxcbiAgICAgKi9cbiAgICByZW1vdmVTZXJ2aWNlTGlzdGVuZXIgKHNlcnZpY2VUeXBlLCBzZGxTZXJ2aWNlTGlzdGVuZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NlcnZpY2VMaXN0ZW5lcnMucmVtb3ZlTGlzdGVuZXIoc2VydmljZVR5cGUsIHNkbFNlcnZpY2VMaXN0ZW5lcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U2VydmljZUxpc3RlbmVyTWFwfVxuICAgICAqL1xuICAgIGdldFNlcnZpY2VMaXN0ZW5lcnMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2VydmljZUxpc3RlbmVycztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7VmlkZW9TdHJlYW1pbmdQYXJhbWV0ZXJzfSBwYXJhbXNcbiAgICAgKi9cbiAgICBzZXREZXNpcmVkVmlkZW9QYXJhbXMgKHBhcmFtcykge1xuICAgICAgICB0aGlzLl9kZXNpcmVkVmlkZW9QYXJhbXMgPSBwYXJhbXM7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnRseSBzZXQgZGVzaXJlZCB2aWRlbyBzdHJlYW1pbmcgcGFyYW1ldGVycy4gSWYgdGhlcmUgaGF2ZW4ndCBiZWVuIGFueSBzZXQsXG4gICAgICogdGhlIGRlZmF1bHQgb3B0aW9ucyB3aWxsIGJlIHJldHVybmVkIGFuZCBzZXQgZm9yIHRoaXMgaW5zdGFuY2UuXG4gICAgICogQHJldHVybiB7VmlkZW9TdHJlYW1pbmdQYXJhbWV0ZXJzfSB0aGUgZGVzaXJlZCB2aWRlbyBzdHJlYW1pbmcgcGFyYW1ldGVyc1xuICAgICAqL1xuICAgIGdldERlc2lyZWRWaWRlb1BhcmFtcyAoKSB7XG4gICAgICAgIGlmICghKHRoaXMuX2Rlc2lyZWRWaWRlb1BhcmFtcyBpbnN0YW5jZW9mIFZpZGVvU3RyZWFtaW5nUGFyYW1ldGVycykpIHtcbiAgICAgICAgICAgIHRoaXMuX2Rlc2lyZWRWaWRlb1BhcmFtcyA9IG5ldyBWaWRlb1N0cmVhbWluZ1BhcmFtZXRlcnMoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fZGVzaXJlZFZpZGVvUGFyYW1zO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmlkZW9TdHJlYW1pbmdQYXJhbWV0ZXJzfSBwYXJhbXNcbiAgICAgKi9cbiAgICBzZXRBY2NlcHRlZFZpZGVvUGFyYW1zIChwYXJhbXMpIHtcbiAgICAgICAgdGhpcy5fZGVzaXJlZFZpZGVvUGFyYW1zID0gcGFyYW1zO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5cbmV4cG9ydCB7IFNkbFNlc3Npb24gfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBTZGxTZXNzaW9uTGlzdGVuZXJcbiAqL1xuY2xhc3MgU2RsU2Vzc2lvbkxpc3RlbmVyIHtcbiAgICAvKipcblx0ICogQGNvbnN0cnVjdG9yXG5cdCAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgdGhpcy5fb25Qcm90b2NvbFNlc3Npb25TdGFydGVkID0gbnVsbDtcbiAgICAgICAgdGhpcy5fb25Qcm90b2NvbFNlc3Npb25FbmRlZCA9IG51bGw7XG4gICAgICAgIHRoaXMuX29uUHJvdG9jb2xTZXNzaW9uRW5kZWROQUNLZWQgPSBudWxsO1xuICAgICAgICB0aGlzLl9vblJwY01lc3NhZ2VSZWNlaXZlZCA9IG51bGw7XG4gICAgICAgIHRoaXMuX29uVHJhbnNwb3J0Q29ubmVjdGVkID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBsaXN0ZW5lclxuICAgICAqL1xuICAgIHNldE9uUHJvdG9jb2xTZXNzaW9uU3RhcnRlZCAobGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5fb25Qcm90b2NvbFNlc3Npb25TdGFydGVkID0gbGlzdGVuZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBzZXRPblByb3RvY29sU2Vzc2lvbkVuZGVkIChsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLl9vblByb3RvY29sU2Vzc2lvbkVuZGVkID0gbGlzdGVuZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBzZXRPblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkIChsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLl9vblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkID0gbGlzdGVuZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBzZXRPblJwY01lc3NhZ2VSZWNlaXZlZCAobGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5fb25ScGNNZXNzYWdlUmVjZWl2ZWQgPSBsaXN0ZW5lcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBsaXN0ZW5lclxuICAgICAqL1xuICAgIHNldE9uVHJhbnNwb3J0Q29ubmVjdGVkIChsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLl9vblRyYW5zcG9ydENvbm5lY3RlZCA9IGxpc3RlbmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlc3Npb25JRCAtIHJlcHJlc2VudHMgYSBieXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHZlcnNpb24gLSByZXByZXNlbnRzIGEgYnl0ZVxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBjb3JyZWxhdGlvbklEXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGhhc2hJRFxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNFbmNyeXB0ZWRcbiAgICAgKi9cbiAgICBvblByb3RvY29sU2Vzc2lvblN0YXJ0ZWQgKHNlcnZpY2VUeXBlLCBzZXNzaW9uSUQsIHZlcnNpb24sIGNvcnJlbGF0aW9uSUQsIGhhc2hJRCwgaXNFbmNyeXB0ZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9vblByb3RvY29sU2Vzc2lvblN0YXJ0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuX29uUHJvdG9jb2xTZXNzaW9uU3RhcnRlZChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklELCB2ZXJzaW9uLCBjb3JyZWxhdGlvbklELCBoYXNoSUQsIGlzRW5jcnlwdGVkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlc3Npb25JRCAtIHJlcHJlc2VudHMgYSBieXRlXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGNvcnJlbGF0aW9uSURcbiAgICAgKi9cbiAgICBvblByb3RvY29sU2Vzc2lvbkVuZGVkIChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklELCBjb3JyZWxhdGlvbklEKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fb25Qcm90b2NvbFNlc3Npb25FbmRlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5fb25Qcm90b2NvbFNlc3Npb25FbmRlZChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklELCBjb3JyZWxhdGlvbklEKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7U2VydmljZVR5cGV9IHNlcnZpY2VUeXBlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNlc3Npb25JRCAtIHJlcHJlc2VudHMgYSBieXRlXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGNvcnJlbGF0aW9uSURcbiAgICAgKi9cbiAgICBvblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkIChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklELCBjb3JyZWxhdGlvbkkpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9vblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9vblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkKHNlcnZpY2VUeXBlLCBzZXNzaW9uSUQsIGNvcnJlbGF0aW9uSSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1JwY01lc3NhZ2V9IHJwY01lc3NhZ2VcbiAgICAgKi9cbiAgICBvblJwY01lc3NhZ2VSZWNlaXZlZCAocnBjTWVzc2FnZSkge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX29uUnBjTWVzc2FnZVJlY2VpdmVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9vblJwY01lc3NhZ2VSZWNlaXZlZChycGNNZXNzYWdlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEludm9rZWQgd2hlbiB0aGUgYXBwIGFuZCBjb3JlIGNvbm5lY3RcbiAgICAgKi9cbiAgICBvblRyYW5zcG9ydENvbm5lY3RlZCAoKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fb25UcmFuc3BvcnRDb25uZWN0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuX29uVHJhbnNwb3J0Q29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCB7IFNkbFNlc3Npb25MaXN0ZW5lciB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEFycmF5VG9vbHNcbiAqL1xuY2xhc3MgQXJyYXlUb29scyB7XG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyB0aGUgaXRlbSBmcm9tIHRoZSBhcnJheS5cbiAgICAgKiBUaGlzIGRvZXMgbm90IG11dGF0ZSB0aGUgcGFzc2VkIGluIGFycmF5LlxuICAgICAqIE9ubHkgdGhlIHJldHVybmVkIGFycmF5IGhhcyB0aGUgdmFsdWUgcmVtb3ZlZC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheVxuICAgICAqIEBwYXJhbSB7YW55fSB2YWx1ZVxuICAgICAqIEByZXR1cm4ge0FycmF5fVxuICAgICAqL1xuICAgIHN0YXRpYyBhcnJheVJlbW92ZSAoYXJyYXksIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBhcnJheS5maWx0ZXIoZnVuY3Rpb24gKGVsZSkge1xuICAgICAgICAgICAgcmV0dXJuIGVsZSAhPT0gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbmV4cG9ydCB7IEFycmF5VG9vbHMgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgUmVnaXN0ZXJBcHBJbnRlcmZhY2UgfSBmcm9tICcuLi8uLi9ycGMvbWVzc2FnZXMvUmVnaXN0ZXJBcHBJbnRlcmZhY2UuanMnO1xuaW1wb3J0IHsgUnBjUmVxdWVzdCB9IGZyb20gJy4uLy4uL3JwYy9ScGNSZXF1ZXN0LmpzJztcbmltcG9ydCB7IFJwY1Jlc3BvbnNlIH0gZnJvbSAnLi4vLi4vcnBjL1JwY1Jlc3BvbnNlLmpzJztcbmltcG9ydCB7IFJwY0xpc3RlbmVyIH0gZnJvbSAnLi4vLi4vcnBjL1JwY0xpc3RlbmVyLmpzJztcbmltcG9ydCB7IFNkbFNlc3Npb24gfSBmcm9tICcuLi8uLi9zZXNzaW9uL1NkbFNlc3Npb24uanMnO1xuaW1wb3J0IHsgU2RsU2Vzc2lvbkxpc3RlbmVyIH0gZnJvbSAnLi4vLi4vc2Vzc2lvbi9TZGxTZXNzaW9uTGlzdGVuZXIuanMnO1xuaW1wb3J0IHsgVmVyc2lvbiB9IGZyb20gJy4uLy4uL3V0aWwvVmVyc2lvbi5qcyc7XG5pbXBvcnQgeyBBcnJheVRvb2xzIH0gZnJvbSAnLi4vLi4vdXRpbC9BcnJheVRvb2xzLmpzJztcbmltcG9ydCB7IFNkbE1zZ1ZlcnNpb24gfSBmcm9tICcuLi8uLi9ycGMvc3RydWN0cy9TZGxNc2dWZXJzaW9uLmpzJztcbmltcG9ydCB7IEZ1bmN0aW9uSUQgfSBmcm9tICcuLi8uLi9ycGMvZW51bXMvRnVuY3Rpb25JRC5qcyc7XG5pbXBvcnQgeyBTZXJ2aWNlVHlwZSB9IGZyb20gJy4uLy4uL3Byb3RvY29sL2VudW1zL1NlcnZpY2VUeXBlLmpzJztcblxuLyoqXG4gKiBOT1RFOiBUaGlzIGNvdWxkIGFsbCBjaGFuZ2UgYW5kIHNob3VsZCBvbmx5IGJlIHVzZWQgZm9yIHRlc3RpbmcuXG4gKiBUaGlzIGNsYXNzIHNob3VsZCBhbHNvIGJlIG1hcmtlZCBwcml2YXRlIGFuZCBiZWhpbmQgdGhlIFNkbE1hbmFnZXIgQVBJXG4gKlxuICogdXNhZ2Ugc2hvdWxkIGJlOlxuICogdmFyIGxjbSA9IG5ldyBMaWZlY3ljbGVNYW5hZ2VyKGFwcENvbmZpZywgbGlmZWN5Y2xlTGlzdGVuZXIpO1xuICogbGNtLnNldFJwY0xpc3RlbmVyKCAuLi4gKTtcbiAqIGxjbS5zdGFydCgpO1xuICogLi4uLlxuICpcbiAqIGxpZmVjeWNsZUxpc3RlbmVyLk9uUHJveHlDb25uZWN0ZWQoKXtcbiAqICAvL1Bvc3NpYmxlIHRvIHN0YXJ0IHNlbmRpbmcgUlBDcywgSE1JIGxldmVsIHNob3VsZCBiZSBOT05FIHRvIHN0YXJ0XG4gKlxuICogfVxuICpcbiAqL1xuY2xhc3MgTGlmZWN5Y2xlTWFuYWdlciB7XG4gICAgLyoqXG4gICAgKiBAcGFyYW0ge0FwcENvbmZpZ30gc2RsQ29uZmlnXG4gICAgKiBAcGFyYW0ge0xpZmVjeWNsZUxpc3RlbmVyfSBsaWZlY3ljbGVMaXN0ZW5lclxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoYXBwQ29uZmlnLCBsaWZlY3ljbGVMaXN0ZW5lcikge1xuICAgICAgICBpZiAoYXBwQ29uZmlnID09PSBudWxsIHx8IGxpZmVjeWNsZUxpc3RlbmVyID09PSBudWxsXG4gICAgICAgICAgICB8fCBhcHBDb25maWcgPT09IHVuZGVmaW5lZCB8fCBsaWZlY3ljbGVMaXN0ZW5lciA9PT0gdW5kZWZpbmVkXG4gICAgICAgICkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQYXJhbXMgbXVzdCBub3QgYmUgbnVsbCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fYXBwQ29uZmlnID0gYXBwQ29uZmlnO1xuICAgICAgICB0aGlzLl9saWZlY3ljbGVMaXN0ZW5lciA9IGxpZmVjeWNsZUxpc3RlbmVyO1xuICAgICAgICB0aGlzLl9zZGxTZXNzaW9uID0gbmV3IFNkbFNlc3Npb24odGhpcy5fYXBwQ29uZmlnLmdldFRyYW5zcG9ydENvbmZpZygpLCB0aGlzLl9jcmVhdGVTZXNzaW9uTGlzdGVuZXIoKSk7XG5cbiAgICAgICAgLy8gVGhpcyBpcyBieSBkZWZhdWx0IHVudGlsIHdlIHJlY2VpdmUgdGhlIFJBSSBSZXNwb25zZVxuICAgICAgICB0aGlzLl9ycGNTcGVjVmVyc2lvbiA9IG5ldyBWZXJzaW9uKDEsIDAsIDApO1xuXG4gICAgICAgIHRoaXMuX2N1cnJlbnRITUlTdGF0dXMgPSBudWxsO1xuICAgICAgICB0aGlzLl9maXJzdFRpbWVGdWxsID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fcmVzcG9uc2VMaXN0ZW5lcnMgPSBuZXcgTWFwKCk7XG4gICAgICAgIHRoaXMuX21heENvcnJlbGF0aW9uSWQgPSAwOyAvLyBUT0RPIHJlbW92ZSB3aGVuIGNvcnJlbGF0aW9uIGdlbiBpcyBpbXBsZW1lbnRlZFxuICAgICAgICB0aGlzLl9ycGNMaXN0ZW5lcnMgPSBuZXcgTWFwKCk7IC8vIDxOdW1iZXIsIEFycmF5PFJwY0xpc3RlbmVyPj5cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTZGxTZXNzaW9uTGlzdGVuZXJ9XG4gICAgICovXG4gICAgX2NyZWF0ZVNlc3Npb25MaXN0ZW5lciAoKSB7XG4gICAgICAgIGNvbnN0IHNlc3Npb25MaXN0ZW5lciA9IG5ldyBTZGxTZXNzaW9uTGlzdGVuZXIoKTtcbiAgICAgICAgc2Vzc2lvbkxpc3RlbmVyLnNldE9uUHJvdG9jb2xTZXNzaW9uU3RhcnRlZCgoc2VydmljZVR5cGUsIHNlc3Npb25JRCwgdmVyc2lvbiwgY29ycmVsYXRpb25JRCwgaGFzaElELCBpc0VuY3J5cHRlZCkgPT4ge1xuICAgICAgICAgICAgLy8gU2Vzc2lvbiBoYXMgYmVlbiBzdGFydGVkXG4gICAgICAgICAgICAvLyBUT0RPIGNoZWNrIG1pbiBwcm90b2NvbCBzcGVjIHZlcnNpb25cbiAgICAgICAgICAgIGlmIChzZXJ2aWNlVHlwZSA9PT0gU2VydmljZVR5cGUuUlBDKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2FwcENvbmZpZyAhPT0gbnVsbCAmJiB0aGlzLl9hcHBDb25maWcgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBUT0RPIGNhbGwgcHJlcGFyZSBvbiBjb25maWcgdG8gbWFrZSBzdXJlIGl0IGlzIHNhdGlzZmFjdG9yeVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbmRScGNNZXNzYWdlKHRoaXMuX2NyZWF0ZVJlZ2lzdGVyQXBwSW50ZXJmYWNlKCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHNlc3Npb25MaXN0ZW5lci5zZXRPblByb3RvY29sU2Vzc2lvbkVuZGVkKChzZXJ2aWNlVHlwZSwgc2Vzc2lvbklELCBjb3JyZWxhdGlvbklEKSA9PiB7XG4gICAgICAgICAgICAvLyBTZXNzaW9uIGhhcyBiZWVuIGVuZGVkXG4gICAgICAgIH0pO1xuICAgICAgICBzZXNzaW9uTGlzdGVuZXIuc2V0T25Qcm90b2NvbFNlc3Npb25FbmRlZE5BQ0tlZCgoc2VydmljZVR5cGUsIHNlc3Npb25JRCwgY29ycmVsYXRpb25JRCkgPT4ge1xuICAgICAgICAgICAgLy8gVE9ETyBpbSBub3Qgc3VyZSB3aHkgd2UgaGF2ZSB0aGlzXG4gICAgICAgIH0pO1xuICAgICAgICBzZXNzaW9uTGlzdGVuZXIuc2V0T25ScGNNZXNzYWdlUmVjZWl2ZWQoKHJwY01lc3NhZ2UpID0+IHtcbiAgICAgICAgICAgIC8vIE1lc3NhZ2UgaGFzIGJlZW4gcmVjZWl2ZWRcbiAgICAgICAgICAgIHRoaXMuX2hhbmRsZVJwYyhycGNNZXNzYWdlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHNlc3Npb25MaXN0ZW5lci5zZXRPblRyYW5zcG9ydENvbm5lY3RlZCgoKSA9PiB7XG4gICAgICAgICAgICAvLyB0cmFuc3BvcnQgaGFzIGJlZW4gY29ubmVjdGVkXG4gICAgICAgICAgICB0aGlzLl9zZGxTZXNzaW9uLnN0YXJ0U2VydmljZShTZXJ2aWNlVHlwZS5SUEMsIDAsIGZhbHNlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHNlc3Npb25MaXN0ZW5lcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0geyBScGNNZXNzYWdlIH0gcnBjTWVzc2FnZVxuICAgICAqL1xuICAgIF9oYW5kbGVScGMgKHJwY01lc3NhZ2UpIHtcbiAgICAgICAgaWYgKHJwY01lc3NhZ2UgPT09IG51bGwgfHwgcnBjTWVzc2FnZSA9PT0gdW5kZWZpbmVkIHx8IHJwY01lc3NhZ2UuZ2V0RnVuY3Rpb25OYW1lKCkgPT09IG51bGwgfHwgcnBjTWVzc2FnZS5nZXRGdW5jdGlvbk5hbWUoKSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmdW5jdGlvbklEID0gRnVuY3Rpb25JRC52YWx1ZUZvcktleShycGNNZXNzYWdlLmdldEZ1bmN0aW9uTmFtZSgpKTsgLy8gdGhpcyBpcyB0aGUgbnVtYmVyIHZhbHVlXG4gICAgICAgIGNvbnN0IGxpc3RlbmVyQXJyYXkgPSB0aGlzLl9ycGNMaXN0ZW5lcnMuZ2V0KGZ1bmN0aW9uSUQpO1xuICAgICAgICBpZiAobGlzdGVuZXJBcnJheSAhPT0gbnVsbCAmJiBsaXN0ZW5lckFycmF5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGxpc3RlbmVyQXJyYXkuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgICAgIGl0ZW0ub25ScGNNZXNzYWdlKHJwY01lc3NhZ2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBIYW5kbGUgaW5kaXZpZHVhbCBSUEMgbGlzdGVuZXJzIGZvciByZXF1ZXN0L3Jlc3BvbnNlIHBhaXJzXG4gICAgICAgIGlmIChycGNNZXNzYWdlIGluc3RhbmNlb2YgUnBjUmVzcG9uc2UpIHtcbiAgICAgICAgICAgIC8vIG51bGwgY2hlY2sgbm90IG5lZWRlZC4gaXRzIGFsd2F5cyBkZWZpbmVkIGluIHRoZSBjb25zdHJ1Y3RvclxuICAgICAgICAgICAgaWYgKHRoaXMuX3Jlc3BvbnNlTGlzdGVuZXJzLmhhcyhycGNNZXNzYWdlLmdldENvcnJlbGF0aW9uSWQoKSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yZXNwb25zZUxpc3RlbmVycy5nZXQocnBjTWVzc2FnZS5nZXRDb3JyZWxhdGlvbklkKCkpLnJlc29sdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICogQHJldHVybiB7TGlmZWN5Y2xlTWFuYWdlcn1cbiAgICAqL1xuICAgIHN0YXJ0ICgpIHtcbiAgICAgICAgdGhpcy5fc2V0dXBJbnRlcm5hbFJwY0xpc3RlbmVycygpO1xuICAgICAgICB0aGlzLl9zZGxTZXNzaW9uLnN0YXJ0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHN0b3AgKCkge1xuICAgICAgICB0aGlzLl9zZGxTZXNzaW9uLmNsb3NlKCk7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25JRH0gZnVuY3Rpb25JRFxuICAgICAqIEBwYXJhbSB7UnBjTGlzdGVuZXJ9IHJwY0xpc3RlbmVyXG4gICAgICovXG4gICAgYWRkUnBjTGlzdGVuZXIgKGZ1bmN0aW9uSUQsIHJwY0xpc3RlbmVyKSB7XG4gICAgICAgIGxldCBsaXN0ZW5lckFycmF5ID0gdGhpcy5fcnBjTGlzdGVuZXJzLmdldChmdW5jdGlvbklEKTtcbiAgICAgICAgLy8gSWYgbm8gYXJyYXkgZXhpc3RzIHlldCBmb3IgdGhpcyBmdW5jdGlvbiBpZCwgY3JlYXRlIG9uZVxuICAgICAgICBpZiAobGlzdGVuZXJBcnJheSA9PT0gbnVsbCB8fCBsaXN0ZW5lckFycmF5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3JwY0xpc3RlbmVycy5zZXQoZnVuY3Rpb25JRCwgW10pO1xuICAgICAgICAgICAgbGlzdGVuZXJBcnJheSA9IHRoaXMuX3JwY0xpc3RlbmVycy5nZXQoZnVuY3Rpb25JRCk7XG4gICAgICAgIH1cbiAgICAgICAgbGlzdGVuZXJBcnJheS5wdXNoKHJwY0xpc3RlbmVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25JRH0gZnVuY3Rpb25JRFxuICAgICAqIEBwYXJhbSB7UnBjTGlzdGVuZXJ9IHJwY0xpc3RlbmVyXG4gICAgICovXG4gICAgcmVtb3ZlUnBjTGlzdGVuZXIgKGZ1bmN0aW9uSUQsIHJwY0xpc3RlbmVyKSB7XG4gICAgICAgIGlmIChycGNMaXN0ZW5lciAhPT0gbnVsbCAmJiBycGNMaXN0ZW5lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjb25zdCBsaXN0ZW5lckFycmF5ID0gdGhpcy5fcnBjTGlzdGVuZXJzLmdldChmdW5jdGlvbklEKTtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lckFycmF5ICE9PSBudWxsICYmIGxpc3RlbmVyQXJyYXkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3JwY0xpc3RlbmVycy5zZXQoZnVuY3Rpb25JRCwgQXJyYXlUb29scy5hcnJheVJlbW92ZShsaXN0ZW5lckFycmF5LCBycGNMaXN0ZW5lcikpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1JwY01lc3NhZ2V9IHJwY01lc3NhZ2VcbiAgICAgKi9cbiAgICBzZW5kUnBjTWVzc2FnZSAocnBjTWVzc2FnZSkge1xuICAgICAgICBpZiAocnBjTWVzc2FnZSAhPT0gbnVsbCAmJiBycGNNZXNzYWdlICE9PSB1bmRlZmluZWQgJiYgdGhpcy5fc2RsU2Vzc2lvbi5nZXRJc0Nvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAvLyBUT0RPIHdlIHN0aWxsIG5lZWQgdG8gbWFrZSBwcm9wZXIgY2hhbmdlcyB0byBoYW5kbGUgc3BlY2lmaWMgY2FzZXMgZm9yIFJQQ3MgaWUgUExBWV9QQVVTRSAvIE9LXG5cbiAgICAgICAgICAgIC8vIFRPRE8gY3JlYXRlIGEgY29ycmVsYXRpb24gaWQgZ2VuZXJhdG9yIGFuZCBoYW5kbGUgdGhpcyBpbiB0aGUgUlBDIGNsYXNzZXNcbiAgICAgICAgICAgIGlmIChycGNNZXNzYWdlIGluc3RhbmNlb2YgUnBjUmVxdWVzdCkge1xuICAgICAgICAgICAgICAgIGlmIChycGNNZXNzYWdlLmdldEZ1bmN0aW9uTmFtZSAhPT0gRnVuY3Rpb25JRC5SZWdpc3RlckFwcEludGVyZmFjZSkgeyAvLyBSQUkgaGFzIGEgYSBwcm90ZWN0ZWQgaWRcbiAgICAgICAgICAgICAgICAgICAgcnBjTWVzc2FnZS5zZXRDb3JyZWxhdGlvbklkKCsrdGhpcy5fbWF4Q29ycmVsYXRpb25JZCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gVE9ETzogY2FuJ3QgdXRpbGl6ZSB0aGUgYWJpbGl0eSBvZiBwcm9taXNlcyBsaWtlIHRoaXNcbiAgICAgICAgICAgICAgICBpZiAocnBjTWVzc2FnZS5nZXRPblJQQ1Jlc3BvbnNlUHJvbWlzZSgpICE9PSBudWxsICYmIHJwY01lc3NhZ2UuZ2V0T25SUENSZXNwb25zZVByb21pc2UoKSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFNldCB0aGUgaW5kaXZpZHVhbCByZXNwb25zZSBsaXN0ZW5lciBmb3IgdGhpcyBSUEMgbWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZXNwb25zZUxpc3RlbmVycy5zZXQocnBjTWVzc2FnZS5nZXRDb3JyZWxhdGlvbklkKCksIHJwY01lc3NhZ2UuZ2V0T25SUENSZXNwb25zZVByb21pc2UoKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fc2RsU2Vzc2lvbi5zZW5kUnBjKHJwY01lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgfVxuXG5cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2V9XG4gICAgICovXG4gICAgZ2V0UmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlO1xuICAgIH1cblxuXG5cbiAgICAvKipcbiAgICAqIEByZXR1cm4ge1JlZ2lzdGVyQXBwSW50ZXJmYWNlfVxuICAgICovXG4gICAgX2NyZWF0ZVJlZ2lzdGVyQXBwSW50ZXJmYWNlICgpIHtcbiAgICAgICAgY29uc3QgcmVnaXN0ZXJBcHBJbnRlcmZhY2UgPSBuZXcgUmVnaXN0ZXJBcHBJbnRlcmZhY2UoKTtcbiAgICAgICAgcmVnaXN0ZXJBcHBJbnRlcmZhY2Uuc2V0U2RsTXNnVmVyc2lvbihuZXcgU2RsTXNnVmVyc2lvbigpLnNldE1ham9yVmVyc2lvbihMaWZlY3ljbGVNYW5hZ2VyLk1BWF9SUENfVkVSU0lPTi5nZXRNYWpvcigpKS5zZXRNaW5vclZlcnNpb24oTGlmZWN5Y2xlTWFuYWdlci5NQVhfUlBDX1ZFUlNJT04uZ2V0TWlub3IoKSkuc2V0UGF0Y2hWZXJzaW9uKExpZmVjeWNsZU1hbmFnZXIuTUFYX1JQQ19WRVJTSU9OLmdldFBhdGNoKCkpKVxuICAgICAgICAgICAgLnNldEFwcE5hbWUodGhpcy5fYXBwQ29uZmlnLmdldEFwcE5hbWUoKSlcbiAgICAgICAgICAgIC5zZXRGdWxsQXBwSWQodGhpcy5fYXBwQ29uZmlnLmdldEFwcElkKCkpXG4gICAgICAgICAgICAuc2V0TmduTWVkaWFTY3JlZW5BcHBOYW1lKHRoaXMuX2FwcENvbmZpZy5nZXRTaG9ydEFwcE5hbWUoKSlcbiAgICAgICAgICAgIC5zZXRBcHBITUlUeXBlKHRoaXMuX2FwcENvbmZpZy5nZXRBcHBUeXBlcygpKVxuICAgICAgICAgICAgLnNldExhbmd1YWdlRGVzaXJlZCh0aGlzLl9hcHBDb25maWcuZ2V0TGFuZ3VhZ2VEZXNpcmVkKCkpXG4gICAgICAgICAgICAuc2V0SG1pRGlzcGxheUxhbmd1YWdlRGVzaXJlZCh0aGlzLl9hcHBDb25maWcuZ2V0SG1pRGlzcGxheUxhbmd1YWdlRGVzaXJlZCgpKVxuICAgICAgICAgICAgLnNldElzTWVkaWFBcHBsaWNhdGlvbih0aGlzLl9hcHBDb25maWcuaXNNZWRpYUFwcCgpKVxuICAgICAgICAgICAgLnNldERheUNvbG9yU2NoZW1lKHRoaXMuX2FwcENvbmZpZy5nZXREYXlDb2xvclNjaGVtZSgpKVxuICAgICAgICAgICAgLnNldE5pZ2h0Q29sb3JTY2hlbWUodGhpcy5fYXBwQ29uZmlnLmdldE5pZ2h0Q29sb3JTY2hlbWUoKSlcbiAgICAgICAgICAgIC5zZXRDb3JyZWxhdGlvbklkKExpZmVjeWNsZU1hbmFnZXIuUkVHSVNURVJfQVBQX0lOVEVSRkFDRV9DT1JSRUxBVElPTl9JRCk7XG5cbiAgICAgICAgLy8gVE9ETyBBZGQgYWxsIHBvc3NpYmxlIGl0ZW1zXG5cbiAgICAgICAgcmV0dXJuIHJlZ2lzdGVyQXBwSW50ZXJmYWNlO1xuICAgIH1cblxuXG4gICAgLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqIElOVEVSTkFMIC0gUlBDIExJU1RFTkVSUyAhISBTVEFSVCAhISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4gICAgX3NldHVwSW50ZXJuYWxScGNMaXN0ZW5lcnMgKCkge1xuICAgICAgICB0aGlzLl9ycGNMaXN0ZW5lciA9IG5ldyBScGNMaXN0ZW5lcigpLnNldE9uUnBjTWVzc2FnZShycGNNZXNzYWdlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGZ1bmN0aW9uSUQgPSBGdW5jdGlvbklELnZhbHVlRm9yS2V5KHJwY01lc3NhZ2UuZ2V0RnVuY3Rpb25OYW1lKCkpOyAvLyB0aGlzIGlzIHRoZSBudW1iZXIgdmFsdWVcblxuXG4gICAgICAgICAgICBzd2l0Y2ggKGZ1bmN0aW9uSUQpIHtcbiAgICAgICAgICAgICAgICBjYXNlIEZ1bmN0aW9uSUQuUmVnaXN0ZXJBcHBJbnRlcmZhY2U6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3NSYWlSZXNwb25zZShycGNNZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBGdW5jdGlvbklELk9uSE1JU3RhdHVzOiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHNlbmQgYSBzaW5nbGUgb25Qcm94eUNvbm5lY3RlZCwgd2hlbiB3ZSBnbyBmcm9tIGEgbnVsbCBITUkgbGV2ZWwgdG8gYSBkZWZpbmVkIEhNSSBsZXZlbFxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaG91bGRJbml0ID0gcnBjTWVzc2FnZS5nZXRIbWlMZXZlbCgpICE9PSBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgICAmJiBycGNNZXNzYWdlLmdldEhtaUxldmVsKCkgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICAgICAgJiYgdGhpcy5fY3VycmVudEhNSVN0YXR1cyA9PT0gbnVsbDtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jdXJyZW50SE1JU3RhdHVzID0gcnBjTWVzc2FnZS5nZXRIbWlMZXZlbCgpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9saWZlY3ljbGVMaXN0ZW5lciAhPT0gbnVsbCAmJiB0aGlzLl9saWZlY3ljbGVMaXN0ZW5lciAhPT0gdW5kZWZpbmVkICYmIHNob3VsZEluaXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2xpZmVjeWNsZUxpc3RlbmVyLm9uUHJveHlDb25uZWN0ZWQodGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgLy8gUlBDIG5vdCBoYW5kbGVkIHlldCBpbiBMQ01cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5hZGRScGNMaXN0ZW5lcihGdW5jdGlvbklELlJlZ2lzdGVyQXBwSW50ZXJmYWNlLCB0aGlzLl9ycGNMaXN0ZW5lcik7XG4gICAgICAgIHRoaXMuYWRkUnBjTGlzdGVuZXIoRnVuY3Rpb25JRC5PbkhNSVN0YXR1cywgdGhpcy5fcnBjTGlzdGVuZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHtSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlfSByZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlXG4gICAgICovXG4gICAgX3Byb2Nlc3NSYWlSZXNwb25zZSAocmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZSkge1xuICAgICAgICAvLyBDYWNoZSB0aGlzIFJBSSBSZXNwb25zZSBhcyBpdCBjYW4gYmUgdXNlZCBsYXRlclxuICAgICAgICB0aGlzLl9yZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlID0gcmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZTtcblxuICAgICAgICAvLyAgVE9ETyBLRVlfU0RMX01TR19WRVJTSU9OIHZzIEtFWV9TWU5DX01TR19WRVJTSU9OIHNkbFZlcnNpb246ICd7R0lUX0NPTU1JVH0nLCBJIHRoaW5rIHRoZSBrZXkgbmFtZSBjaGFuZ2VcbiAgICAgICAgLy8gaXMgbWVhbnQgdG8gbWFrZSB0aGluZ3MgY2xlYXJlciBhYm91dCB0aGlzIGJlaW5nIGFuIHNkbCB2ZXJzaW9uIHdoaWNoIGlzIG5vdCBzcGVjaWZpYyB0byBmb3JkJ3Mgc3luYy5cbiAgICAgICAgLy8gVGhlcmUgaXMgYSBrZXkgY2FsbGVkIHNkbFZlcnNpb24gdGhhdCBpcyByZXNwb25kaW5nIHdpdGgge0dJVF9DT01NSVR9IHRoYXQgSSdtIHVuc3VyZSB3aGF0IGl0IGlzIHN1cHBvc2VkIHRvIGRvLlxuICAgICAgICBjb25zdCBtc2dWZXJzaW9uID0gcmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZS5nZXRTZGxNc2dWZXJzaW9uKCk7XG5cbiAgICAgICAgaWYgKG1zZ1ZlcnNpb24gIT09IG51bGwgJiYgbXNnVmVyc2lvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLl9ycGNTcGVjVmVyc2lvbiA9IG5ldyBWZXJzaW9uKG1zZ1ZlcnNpb24uZ2V0TWFqb3JWZXJzaW9uKCksIG1zZ1ZlcnNpb24uZ2V0TWFqb3JWZXJzaW9uKCksIG1zZ1ZlcnNpb24uZ2V0UGF0Y2hWZXJzaW9uKCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fcnBjU3BlY1ZlcnNpb24gPSBMaWZlY3ljbGVNYW5hZ2VyLk1BWF9SUENfVkVSU0lPTjtcbiAgICAgICAgfVxuXG5cbiAgICAgICAgLy8gVE9ETyBjaGVjayBhZ2FpbnN0IG1pbiBSUEMgc3BlYyB2ZXJzaW9uIGNvbmZpZ1xuXG4gICAgICAgIC8vIFRPRE8gcGFyc2UgUkFJIGZvciBzeXN0ZW0gY2FwYWJpbGl0aWVzXG4gICAgfVxufVxuXG5MaWZlY3ljbGVNYW5hZ2VyLk1BWF9SUENfVkVSU0lPTiA9IG5ldyBWZXJzaW9uKDYsIDAsIDApO1xuTGlmZWN5Y2xlTWFuYWdlci5SRUdJU1RFUl9BUFBfSU5URVJGQUNFX0NPUlJFTEFUSU9OX0lEID0gNjU1Mjk7XG5MaWZlY3ljbGVNYW5hZ2VyLlVOUkVHSVNURVJfQVBQX0lOVEVSRkFDRV9DT1JSRUxBVElPTl9JRCA9IDY1NTMwO1xuXG5cbmV4cG9ydCB7IExpZmVjeWNsZU1hbmFnZXIgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gQXBwU2VydmljZVR5cGVcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIEFwcFNlcnZpY2VUeXBlIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE1FRElBICgpIHtcbiAgICAgICAgcmV0dXJuIEFwcFNlcnZpY2VUeXBlLl9NQVAuTUVESUE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgV0VBVEhFUiAoKSB7XG4gICAgICAgIHJldHVybiBBcHBTZXJ2aWNlVHlwZS5fTUFQLldFQVRIRVI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTkFWSUdBVElPTiAoKSB7XG4gICAgICAgIHJldHVybiBBcHBTZXJ2aWNlVHlwZS5fTUFQLk5BVklHQVRJT047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gQXBwU2VydmljZVR5cGUuX3ZhbHVlRm9yS2V5KGtleSwgQXBwU2VydmljZVR5cGUuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBBcHBTZXJ2aWNlVHlwZS5fa2V5Rm9yVmFsdWUodmFsdWUsIEFwcFNlcnZpY2VUeXBlLl9NQVApO1xuICAgIH1cbn1cblxuQXBwU2VydmljZVR5cGUuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdNRURJQSc6ICdNRURJQScsXG4gICAgJ1dFQVRIRVInOiAnV0VBVEhFUicsXG4gICAgJ05BVklHQVRJT04nOiAnTkFWSUdBVElPTicsXG59KTtcblxuZXhwb3J0IHsgQXBwU2VydmljZVR5cGUgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBSZWZsZWN0cyB0aGUgc3RhdHVzIG9mIGEgdmVoaWNsZSBtYWludGVuYW5jZSBtb2RlLlxuICogQHR5cGVkZWYge0VudW19IE1haW50ZW5hbmNlTW9kZVN0YXR1c1xuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgTWFpbnRlbmFuY2VNb2RlU3RhdHVzIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE1NU19OT1JNQUwgKCkge1xuICAgICAgICByZXR1cm4gTWFpbnRlbmFuY2VNb2RlU3RhdHVzLl9NQVAuTU1TX05PUk1BTDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBNTVNfTkVBUiAoKSB7XG4gICAgICAgIHJldHVybiBNYWludGVuYW5jZU1vZGVTdGF0dXMuX01BUC5NTVNfTkVBUjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBNTVNfQUNUSVZFICgpIHtcbiAgICAgICAgcmV0dXJuIE1haW50ZW5hbmNlTW9kZVN0YXR1cy5fTUFQLk1NU19BQ1RJVkU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTU1TX0ZFQVRVUkVfTk9UX1BSRVNFTlQgKCkge1xuICAgICAgICByZXR1cm4gTWFpbnRlbmFuY2VNb2RlU3RhdHVzLl9NQVAuTU1TX0ZFQVRVUkVfTk9UX1BSRVNFTlQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVudW0ga2V5XG4gICAgICogQHBhcmFtIGtleSAtIEEga2V5IHRvIGZpbmQgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSB2YWx1ZSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgdmFsdWVGb3JLZXkgKGtleSkge1xuICAgICAgICByZXR1cm4gTWFpbnRlbmFuY2VNb2RlU3RhdHVzLl92YWx1ZUZvcktleShrZXksIE1haW50ZW5hbmNlTW9kZVN0YXR1cy5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIE1haW50ZW5hbmNlTW9kZVN0YXR1cy5fa2V5Rm9yVmFsdWUodmFsdWUsIE1haW50ZW5hbmNlTW9kZVN0YXR1cy5fTUFQKTtcbiAgICB9XG59XG5cbk1haW50ZW5hbmNlTW9kZVN0YXR1cy5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ01NU19OT1JNQUwnOiAnTk9STUFMJyxcbiAgICAnTU1TX05FQVInOiAnTkVBUicsXG4gICAgJ01NU19BQ1RJVkUnOiAnQUNUSVZFJyxcbiAgICAnTU1TX0ZFQVRVUkVfTk9UX1BSRVNFTlQnOiAnRkVBVFVSRV9OT1RfUFJFU0VOVCcsXG59KTtcblxuZXhwb3J0IHsgTWFpbnRlbmFuY2VNb2RlU3RhdHVzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogRW51bWVyYXRpb24gdGhhdCBkZXNjcmliZXMgcG9zc2libGUgcGVybWlzc2lvbiBzdGF0ZXMgb2YgYSBwb2xpY3kgdGFibGUgZW50cnkuXG4gKiBAdHlwZWRlZiB7RW51bX0gUGVybWlzc2lvblN0YXR1c1xuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgUGVybWlzc2lvblN0YXR1cyBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBQU19BTExPV0VEICgpIHtcbiAgICAgICAgcmV0dXJuIFBlcm1pc3Npb25TdGF0dXMuX01BUC5QU19BTExPV0VEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFBTX0RJU0FMTE9XRUQgKCkge1xuICAgICAgICByZXR1cm4gUGVybWlzc2lvblN0YXR1cy5fTUFQLlBTX0RJU0FMTE9XRUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUFNfVVNFUl9ESVNBTExPV0VEICgpIHtcbiAgICAgICAgcmV0dXJuIFBlcm1pc3Npb25TdGF0dXMuX01BUC5QU19VU0VSX0RJU0FMTE9XRUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUFNfVVNFUl9DT05TRU5UX1BFTkRJTkcgKCkge1xuICAgICAgICByZXR1cm4gUGVybWlzc2lvblN0YXR1cy5fTUFQLlBTX1VTRVJfQ09OU0VOVF9QRU5ESU5HO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFBlcm1pc3Npb25TdGF0dXMuX3ZhbHVlRm9yS2V5KGtleSwgUGVybWlzc2lvblN0YXR1cy5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFBlcm1pc3Npb25TdGF0dXMuX2tleUZvclZhbHVlKHZhbHVlLCBQZXJtaXNzaW9uU3RhdHVzLl9NQVApO1xuICAgIH1cbn1cblxuUGVybWlzc2lvblN0YXR1cy5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ1BTX0FMTE9XRUQnOiAnQUxMT1dFRCcsXG4gICAgJ1BTX0RJU0FMTE9XRUQnOiAnRElTQUxMT1dFRCcsXG4gICAgJ1BTX1VTRVJfRElTQUxMT1dFRCc6ICdVU0VSX0RJU0FMTE9XRUQnLFxuICAgICdQU19VU0VSX0NPTlNFTlRfUEVORElORyc6ICdVU0VSX0NPTlNFTlRfUEVORElORycsXG59KTtcblxuZXhwb3J0IHsgUGVybWlzc2lvblN0YXR1cyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIFByZWRlZmluZWQgc2NyZWVuIGxheW91dC5cbiAqIEB0eXBlZGVmIHtFbnVtfSBQcmVkZWZpbmVkTGF5b3V0XG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBQcmVkZWZpbmVkTGF5b3V0IGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlZmF1bHQgbWVkaWEgLyBub24tbWVkaWEgc2NyZWVuLiBDYW4gYmUgc2V0IGFzIGEgcm9vdCBzY3JlZW4uXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgREVGQVVMVCAoKSB7XG4gICAgICAgIHJldHVybiBQcmVkZWZpbmVkTGF5b3V0Ll9NQVAuREVGQVVMVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZWZhdWx0IE1lZGlhIHNjcmVlbi4gQ2FuIGJlIHNldCBhcyBhIHJvb3Qgc2NyZWVuLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE1FRElBICgpIHtcbiAgICAgICAgcmV0dXJuIFByZWRlZmluZWRMYXlvdXQuX01BUC5NRURJQTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZWZhdWx0IE5vbi1tZWRpYSBzY3JlZW4uIENhbiBiZSBzZXQgYXMgYSByb290IHNjcmVlbi5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBOT05fTUVESUEgKCkge1xuICAgICAgICByZXR1cm4gUHJlZGVmaW5lZExheW91dC5fTUFQLk5PTl9NRURJQTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDdXN0b20gcm9vdCBtZWRpYSBzY3JlZW4gY29udGFpbmluZyBhcHAtZGVmaW5lZCBvbnNjcmVlbiBwcmVzZXRzLiBDYW4gYmUgc2V0IGFzIGEgcm9vdCBzY3JlZW4uXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgT05TQ1JFRU5fUFJFU0VUUyAoKSB7XG4gICAgICAgIHJldHVybiBQcmVkZWZpbmVkTGF5b3V0Ll9NQVAuT05TQ1JFRU5fUFJFU0VUUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDdXN0b20gcm9vdCB0ZW1wbGF0ZSBzY3JlZW4gY29udGFpbmluZyBmdWxsIHNjcmVlbiBtYXAgd2l0aCBuYXZpZ2F0aW9uIGNvbnRyb2xzLiBDYW4gYmUgc2V0IGFzIGEgcm9vdCBzY3JlZW4uXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTkFWX0ZVTExTQ1JFRU5fTUFQICgpIHtcbiAgICAgICAgcmV0dXJuIFByZWRlZmluZWRMYXlvdXQuX01BUC5OQVZfRlVMTFNDUkVFTl9NQVA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3VzdG9tIHJvb3QgdGVtcGxhdGUgc2NyZWVuIGNvbnRhaW5pbmcgdmlkZW8gcmVwcmVzZW50ZWQgbGlzdC4gQ2FuIGJlIHNldCBhcyBhIHJvb3Qgc2NyZWVuLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5BVl9MSVNUICgpIHtcbiAgICAgICAgcmV0dXJuIFByZWRlZmluZWRMYXlvdXQuX01BUC5OQVZfTElTVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDdXN0b20gcm9vdCB0ZW1wbGF0ZSBzY3JlZW4gY29udGFpbmluZyB2aWRlbyByZXByZXNlbnRlZCBrZXlib2FyZC4gQ2FuIGJlIHNldCBhcyBhIHJvb3Qgc2NyZWVuLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IE5BVl9LRVlCT0FSRCAoKSB7XG4gICAgICAgIHJldHVybiBQcmVkZWZpbmVkTGF5b3V0Ll9NQVAuTkFWX0tFWUJPQVJEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEN1c3RvbSByb290IHRlbXBsYXRlIHNjcmVlbiBjb250YWluaW5nIGhhbGYtc2NyZWVuIGdyYXBoaWMgd2l0aCBsaW5lcyBvZiB0ZXh0LiBDYW4gYmUgc2V0IGFzIGEgcm9vdCBzY3JlZW4uXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgR1JBUEhJQ19XSVRIX1RFWFQgKCkge1xuICAgICAgICByZXR1cm4gUHJlZGVmaW5lZExheW91dC5fTUFQLkdSQVBISUNfV0lUSF9URVhUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEN1c3RvbSByb290IHRlbXBsYXRlIHNjcmVlbiBjb250YWluaW5nIGxpbmVzIG9mIHRleHQgd2l0aCBoYWxmLXNjcmVlbiBncmFwaGljLiBDYW4gYmUgc2V0IGFzIGEgcm9vdCBzY3JlZW4uXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVEVYVF9XSVRIX0dSQVBISUMgKCkge1xuICAgICAgICByZXR1cm4gUHJlZGVmaW5lZExheW91dC5fTUFQLlRFWFRfV0lUSF9HUkFQSElDO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEN1c3RvbSByb290IHRlbXBsYXRlIHNjcmVlbiBjb250YWluaW5nIG9ubHkgdGlsZWQgU29mdEJ1dHRvbnMuIENhbiBiZSBzZXQgYXMgYSByb290IHNjcmVlbi5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBUSUxFU19PTkxZICgpIHtcbiAgICAgICAgcmV0dXJuIFByZWRlZmluZWRMYXlvdXQuX01BUC5USUxFU19PTkxZO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEN1c3RvbSByb290IHRlbXBsYXRlIHNjcmVlbiBjb250YWluaW5nIG9ubHkgdGV4dCBTb2Z0QnV0dG9ucy4gQ2FuIGJlIHNldCBhcyBhIHJvb3Qgc2NyZWVuLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFRFWFRCVVRUT05TX09OTFkgKCkge1xuICAgICAgICByZXR1cm4gUHJlZGVmaW5lZExheW91dC5fTUFQLlRFWFRCVVRUT05TX09OTFk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3VzdG9tIHJvb3QgdGVtcGxhdGUgc2NyZWVuIGNvbnRhaW5pbmcgaGFsZi1zY3JlZW4gZ3JhcGhpYyB3aXRoIHRpbGVkIFNvZnRCdXR0b25zLiBDYW4gYmUgc2V0IGFzIGEgcm9vdCBzY3JlZW4uXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgR1JBUEhJQ19XSVRIX1RJTEVTICgpIHtcbiAgICAgICAgcmV0dXJuIFByZWRlZmluZWRMYXlvdXQuX01BUC5HUkFQSElDX1dJVEhfVElMRVM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3VzdG9tIHJvb3QgdGVtcGxhdGUgc2NyZWVuIGNvbnRhaW5pbmcgdGlsZWQgU29mdEJ1dHRvbnMgd2l0aCBoYWxmLXNjcmVlbiBncmFwaGljLiBDYW4gYmUgc2V0IGFzIGEgcm9vdCBzY3JlZW4uXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVElMRVNfV0lUSF9HUkFQSElDICgpIHtcbiAgICAgICAgcmV0dXJuIFByZWRlZmluZWRMYXlvdXQuX01BUC5USUxFU19XSVRIX0dSQVBISUM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3VzdG9tIHJvb3QgdGVtcGxhdGUgc2NyZWVuIGNvbnRhaW5pbmcgaGFsZi1zY3JlZW4gZ3JhcGhpYyB3aXRoIHRleHQgYW5kIFNvZnRCdXR0b25zLiBDYW4gYmUgc2V0IGFzIGEgcm9vdFxuICAgICAqIHNjcmVlbi5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBHUkFQSElDX1dJVEhfVEVYVF9BTkRfU09GVEJVVFRPTlMgKCkge1xuICAgICAgICByZXR1cm4gUHJlZGVmaW5lZExheW91dC5fTUFQLkdSQVBISUNfV0lUSF9URVhUX0FORF9TT0ZUQlVUVE9OUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDdXN0b20gcm9vdCB0ZW1wbGF0ZSBzY3JlZW4gY29udGFpbmluZyB0ZXh0IGFuZCBTb2Z0QnV0dG9ucyB3aXRoIGhhbGYtc2NyZWVuIGdyYXBoaWMuIENhbiBiZSBzZXQgYXMgYSByb290XG4gICAgICogc2NyZWVuLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFRFWFRfQU5EX1NPRlRCVVRUT05TX1dJVEhfR1JBUEhJQyAoKSB7XG4gICAgICAgIHJldHVybiBQcmVkZWZpbmVkTGF5b3V0Ll9NQVAuVEVYVF9BTkRfU09GVEJVVFRPTlNfV0lUSF9HUkFQSElDO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEN1c3RvbSByb290IHRlbXBsYXRlIHNjcmVlbiBjb250YWluaW5nIGhhbGYtc2NyZWVuIGdyYXBoaWMgd2l0aCB0ZXh0IG9ubHkgU29mdEJ1dHRvbnMuIENhbiBiZSBzZXQgYXMgYSByb290XG4gICAgICogc2NyZWVuLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEdSQVBISUNfV0lUSF9URVhUQlVUVE9OUyAoKSB7XG4gICAgICAgIHJldHVybiBQcmVkZWZpbmVkTGF5b3V0Ll9NQVAuR1JBUEhJQ19XSVRIX1RFWFRCVVRUT05TO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEN1c3RvbSByb290IHRlbXBsYXRlIHNjcmVlbiBjb250YWluaW5nIHRleHQgb25seSBTb2Z0QnV0dG9ucyB3aXRoIGhhbGYtc2NyZWVuIGdyYXBoaWMuIENhbiBiZSBzZXQgYXMgYSByb290XG4gICAgICogc2NyZWVuLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFRFWFRCVVRUT05TX1dJVEhfR1JBUEhJQyAoKSB7XG4gICAgICAgIHJldHVybiBQcmVkZWZpbmVkTGF5b3V0Ll9NQVAuVEVYVEJVVFRPTlNfV0lUSF9HUkFQSElDO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEN1c3RvbSByb290IHRlbXBsYXRlIHNjcmVlbiBjb250YWluaW5nIGEgbGFyZ2UgZ3JhcGhpYyBhbmQgU29mdEJ1dHRvbnMuIENhbiBiZSBzZXQgYXMgYSByb290IHNjcmVlbi5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBMQVJHRV9HUkFQSElDX1dJVEhfU09GVEJVVFRPTlMgKCkge1xuICAgICAgICByZXR1cm4gUHJlZGVmaW5lZExheW91dC5fTUFQLkxBUkdFX0dSQVBISUNfV0lUSF9TT0ZUQlVUVE9OUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDdXN0b20gcm9vdCB0ZW1wbGF0ZSBzY3JlZW4gY29udGFpbmluZyB0d28gZ3JhcGhpY3MgYW5kIFNvZnRCdXR0b25zLiBDYW4gYmUgc2V0IGFzIGEgcm9vdCBzY3JlZW4uXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgRE9VQkxFX0dSQVBISUNfV0lUSF9TT0ZUQlVUVE9OUyAoKSB7XG4gICAgICAgIHJldHVybiBQcmVkZWZpbmVkTGF5b3V0Ll9NQVAuRE9VQkxFX0dSQVBISUNfV0lUSF9TT0ZUQlVUVE9OUztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDdXN0b20gcm9vdCB0ZW1wbGF0ZSBzY3JlZW4gY29udGFpbmluZyBvbmx5IGEgbGFyZ2UgZ3JhcGhpYy4gQ2FuIGJlIHNldCBhcyBhIHJvb3Qgc2NyZWVuLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IExBUkdFX0dSQVBISUNfT05MWSAoKSB7XG4gICAgICAgIHJldHVybiBQcmVkZWZpbmVkTGF5b3V0Ll9NQVAuTEFSR0VfR1JBUEhJQ19PTkxZO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFByZWRlZmluZWRMYXlvdXQuX3ZhbHVlRm9yS2V5KGtleSwgUHJlZGVmaW5lZExheW91dC5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFByZWRlZmluZWRMYXlvdXQuX2tleUZvclZhbHVlKHZhbHVlLCBQcmVkZWZpbmVkTGF5b3V0Ll9NQVApO1xuICAgIH1cbn1cblxuUHJlZGVmaW5lZExheW91dC5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0RFRkFVTFQnOiAnREVGQVVMVCcsXG4gICAgJ01FRElBJzogJ01FRElBJyxcbiAgICAnTk9OX01FRElBJzogJ05PTi1NRURJQScsXG4gICAgJ09OU0NSRUVOX1BSRVNFVFMnOiAnT05TQ1JFRU5fUFJFU0VUUycsXG4gICAgJ05BVl9GVUxMU0NSRUVOX01BUCc6ICdOQVZfRlVMTFNDUkVFTl9NQVAnLFxuICAgICdOQVZfTElTVCc6ICdOQVZfTElTVCcsXG4gICAgJ05BVl9LRVlCT0FSRCc6ICdOQVZfS0VZQk9BUkQnLFxuICAgICdHUkFQSElDX1dJVEhfVEVYVCc6ICdHUkFQSElDX1dJVEhfVEVYVCcsXG4gICAgJ1RFWFRfV0lUSF9HUkFQSElDJzogJ1RFWFRfV0lUSF9HUkFQSElDJyxcbiAgICAnVElMRVNfT05MWSc6ICdUSUxFU19PTkxZJyxcbiAgICAnVEVYVEJVVFRPTlNfT05MWSc6ICdURVhUQlVUVE9OU19PTkxZJyxcbiAgICAnR1JBUEhJQ19XSVRIX1RJTEVTJzogJ0dSQVBISUNfV0lUSF9USUxFUycsXG4gICAgJ1RJTEVTX1dJVEhfR1JBUEhJQyc6ICdUSUxFU19XSVRIX0dSQVBISUMnLFxuICAgICdHUkFQSElDX1dJVEhfVEVYVF9BTkRfU09GVEJVVFRPTlMnOiAnR1JBUEhJQ19XSVRIX1RFWFRfQU5EX1NPRlRCVVRUT05TJyxcbiAgICAnVEVYVF9BTkRfU09GVEJVVFRPTlNfV0lUSF9HUkFQSElDJzogJ1RFWFRfQU5EX1NPRlRCVVRUT05TX1dJVEhfR1JBUEhJQycsXG4gICAgJ0dSQVBISUNfV0lUSF9URVhUQlVUVE9OUyc6ICdHUkFQSElDX1dJVEhfVEVYVEJVVFRPTlMnLFxuICAgICdURVhUQlVUVE9OU19XSVRIX0dSQVBISUMnOiAnVEVYVEJVVFRPTlNfV0lUSF9HUkFQSElDJyxcbiAgICAnTEFSR0VfR1JBUEhJQ19XSVRIX1NPRlRCVVRUT05TJzogJ0xBUkdFX0dSQVBISUNfV0lUSF9TT0ZUQlVUVE9OUycsXG4gICAgJ0RPVUJMRV9HUkFQSElDX1dJVEhfU09GVEJVVFRPTlMnOiAnRE9VQkxFX0dSQVBISUNfV0lUSF9TT0ZUQlVUVE9OUycsXG4gICAgJ0xBUkdFX0dSQVBISUNfT05MWSc6ICdMQVJHRV9HUkFQSElDX09OTFknLFxufSk7XG5cbmV4cG9ydCB7IFByZWRlZmluZWRMYXlvdXQgfTsiLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbi8qXG4qIENvcHlyaWdodCAoYykgMjAyMCwgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgU21hcnREZXZpY2VMaW5rIENvbnNvcnRpdW0gSW5jLiBub3IgdGhlIG5hbWVzIG9mXG4qIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWRcbiogZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBFbnVtIH0gZnJvbSAnLi4vLi4vdXRpbC9FbnVtLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7RW51bX0gUHJlZGVmaW5lZFdpbmRvd3NcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBfTUFQXG4gKi9cbmNsYXNzIFByZWRlZmluZWRXaW5kb3dzIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBkZWZhdWx0IHdpbmRvdyBpcyBhIG1haW4gd2luZG93IHByZS1jcmVhdGVkIG9uIGJlaGFsZiBvZiB0aGUgYXBwLlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IERFRkFVTFRfV0lORE9XICgpIHtcbiAgICAgICAgcmV0dXJuIFByZWRlZmluZWRXaW5kb3dzLl9NQVAuREVGQVVMVF9XSU5ET1c7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIHByaW1hcnkgd2lkZ2V0IG9mIHRoZSBhcHAuXG4gICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgUFJJTUFSWV9XSURHRVQgKCkge1xuICAgICAgICByZXR1cm4gUHJlZGVmaW5lZFdpbmRvd3MuX01BUC5QUklNQVJZX1dJREdFVDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBQcmVkZWZpbmVkV2luZG93cy5fdmFsdWVGb3JLZXkoa2V5LCBQcmVkZWZpbmVkV2luZG93cy5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFByZWRlZmluZWRXaW5kb3dzLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgUHJlZGVmaW5lZFdpbmRvd3MuX01BUCk7XG4gICAgfVxufVxuXG5QcmVkZWZpbmVkV2luZG93cy5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ0RFRkFVTFRfV0lORE9XJzogMCxcbiAgICAnUFJJTUFSWV9XSURHRVQnOiAxLFxufSk7XG5cbmV4cG9ydCB7IFByZWRlZmluZWRXaW5kb3dzIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYge0VudW19IFRpbWVyTW9kZVxuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgVGltZXJNb2RlIGV4dGVuZHMgRW51bSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhdXNlcyB0aGUgbWVkaWEgY2xvY2sgdGltZXIgdG8gdXBkYXRlIGZyb20gMDowMCB0byBhIHNwZWNpZmllZCB0aW1lXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVVAgKCkge1xuICAgICAgICByZXR1cm4gVGltZXJNb2RlLl9NQVAuVVA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2F1c2VzIHRoZSBtZWRpYSBjbG9jayB0aW1lciB0byB1cGRhdGUgZnJvbSBhIHNwZWNpZmllZCB0aW1lIHRvIDA6MDBcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICovXG4gICAgc3RhdGljIGdldCBET1dOICgpIHtcbiAgICAgICAgcmV0dXJuIFRpbWVyTW9kZS5fTUFQLkRPV047XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW5kaWNhdGVzIHRvIG5vdCB1c2UgdGhlIG1lZGlhIGNsb2NrIHRpbWVyXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgTk9ORSAoKSB7XG4gICAgICAgIHJldHVybiBUaW1lck1vZGUuX01BUC5OT05FO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFRpbWVyTW9kZS5fdmFsdWVGb3JLZXkoa2V5LCBUaW1lck1vZGUuX01BUCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBrZXkgZm9yIHRoZSBnaXZlbiBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIHZhbHVlIC0gQSBwcmltaXRpdmUgdmFsdWUgdG8gZmluZCB0aGUgbWF0Y2hpbmcga2V5IGZvciBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIGtleSBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBUaW1lck1vZGUuX2tleUZvclZhbHVlKHZhbHVlLCBUaW1lck1vZGUuX01BUCk7XG4gICAgfVxufVxuXG5UaW1lck1vZGUuX01BUCA9IE9iamVjdC5mcmVlemUoe1xuICAgICdVUCc6ICdVUCcsXG4gICAgJ0RPV04nOiAnRE9XTicsXG4gICAgJ05PTkUnOiAnTk9ORScsXG59KTtcblxuZXhwb3J0IHsgVGltZXJNb2RlIH07IiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4vKlxuKiBDb3B5cmlnaHQgKGMpIDIwMjAsIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIFNtYXJ0RGV2aWNlTGluayBDb25zb3J0aXVtIEluYy4gbm9yIHRoZSBuYW1lcyBvZlxuKiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4qIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4uLy4uL3V0aWwvRW51bS5qcyc7XG5cbi8qKlxuICogUmVmbGVjdHMgdGhlIHN0YXR1cyBvZiBnaXZlbiB2ZWhpY2xlIGNvbXBvbmVudC5cbiAqIEB0eXBlZGVmIHtFbnVtfSBWZWhpY2xlRGF0YUFjdGl2ZVN0YXR1c1xuICogQHByb3BlcnR5IHtPYmplY3R9IF9NQVBcbiAqL1xuY2xhc3MgVmVoaWNsZURhdGFBY3RpdmVTdGF0dXMgZXh0ZW5kcyBFbnVtIHtcbiAgICAvKipcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVkRBU19JTkFDVElWRV9OT1RfQ09ORklSTUVEICgpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhQWN0aXZlU3RhdHVzLl9NQVAuVkRBU19JTkFDVElWRV9OT1RfQ09ORklSTUVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZEQVNfSU5BQ1RJVkVfQ09ORklSTUVEICgpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhQWN0aXZlU3RhdHVzLl9NQVAuVkRBU19JTkFDVElWRV9DT05GSVJNRUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVkRBU19BQ1RJVkVfTk9UX0NPTkZJUk1FRCAoKSB7XG4gICAgICAgIHJldHVybiBWZWhpY2xlRGF0YUFjdGl2ZVN0YXR1cy5fTUFQLlZEQVNfQUNUSVZFX05PVF9DT05GSVJNRUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgVkRBU19BQ1RJVkVfQ09ORklSTUVEICgpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhQWN0aXZlU3RhdHVzLl9NQVAuVkRBU19BQ1RJVkVfQ09ORklSTUVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IFZEQVNfRkFVTFQgKCkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFBY3RpdmVTdGF0dXMuX01BUC5WREFTX0ZBVUxUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIHRoZSBnaXZlbiBlbnVtIGtleVxuICAgICAqIEBwYXJhbSBrZXkgLSBBIGtleSB0byBmaW5kIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEgdmFsdWUgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIHZhbHVlRm9yS2V5IChrZXkpIHtcbiAgICAgICAgcmV0dXJuIFZlaGljbGVEYXRhQWN0aXZlU3RhdHVzLl92YWx1ZUZvcktleShrZXksIFZlaGljbGVEYXRhQWN0aXZlU3RhdHVzLl9NQVApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUga2V5IGZvciB0aGUgZ2l2ZW4gZW51bSB2YWx1ZVxuICAgICAqIEBwYXJhbSB2YWx1ZSAtIEEgcHJpbWl0aXZlIHZhbHVlIHRvIGZpbmQgdGhlIG1hdGNoaW5nIGtleSBmb3IgaW4gdGhlIG1hcCBvZiB0aGUgc3ViY2xhc3NcbiAgICAgKiBAcmV0dXJuIHsqfSAtIFJldHVybnMgYSBrZXkgaWYgZm91bmQsIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGtleUZvclZhbHVlICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gVmVoaWNsZURhdGFBY3RpdmVTdGF0dXMuX2tleUZvclZhbHVlKHZhbHVlLCBWZWhpY2xlRGF0YUFjdGl2ZVN0YXR1cy5fTUFQKTtcbiAgICB9XG59XG5cblZlaGljbGVEYXRhQWN0aXZlU3RhdHVzLl9NQVAgPSBPYmplY3QuZnJlZXplKHtcbiAgICAnVkRBU19JTkFDVElWRV9OT1RfQ09ORklSTUVEJzogJ0lOQUNUSVZFX05PVF9DT05GSVJNRUQnLFxuICAgICdWREFTX0lOQUNUSVZFX0NPTkZJUk1FRCc6ICdJTkFDVElWRV9DT05GSVJNRUQnLFxuICAgICdWREFTX0FDVElWRV9OT1RfQ09ORklSTUVEJzogJ0FDVElWRV9OT1RfQ09ORklSTUVEJyxcbiAgICAnVkRBU19BQ1RJVkVfQ09ORklSTUVEJzogJ0FDVElWRV9DT05GSVJNRUQnLFxuICAgICdWREFTX0ZBVUxUJzogJ0ZBVUxUJyxcbn0pO1xuXG5leHBvcnQgeyBWZWhpY2xlRGF0YUFjdGl2ZVN0YXR1cyB9OyIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuLypcbiogQ29weXJpZ2h0IChjKSAyMDIwLCBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSwgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBTbWFydERldmljZUxpbmsgQ29uc29ydGl1bSBJbmMuIG5vciB0aGUgbmFtZXMgb2ZcbiogaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZFxuKiBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IEVudW0gfSBmcm9tICcuLi8uLi91dGlsL0VudW0uanMnO1xuXG4vKipcbiAqIEVudW1lcmF0aW9uIGxpbmtpbmcgbWVzc2FnZSB0eXBlcyB3aXRoIGZ1bmN0aW9uIHR5cGVzIGluIFdpUHJvIHByb3RvY29sLiBBc3N1bWVzIGVudW1lcmF0aW9uIHN0YXJ0cyBhdCB2YWx1ZSAwLlxuICogQHR5cGVkZWYge0VudW19IG1lc3NhZ2VUeXBlXG4gKiBAcHJvcGVydHkge09iamVjdH0gX01BUFxuICovXG5jbGFzcyBtZXNzYWdlVHlwZSBleHRlbmRzIEVudW0ge1xuICAgIC8qKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCByZXF1ZXN0ICgpIHtcbiAgICAgICAgcmV0dXJuIG1lc3NhZ2VUeXBlLl9NQVAucmVxdWVzdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICovXG4gICAgc3RhdGljIGdldCByZXNwb25zZSAoKSB7XG4gICAgICAgIHJldHVybiBtZXNzYWdlVHlwZS5fTUFQLnJlc3BvbnNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge051bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IG5vdGlmaWNhdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBtZXNzYWdlVHlwZS5fTUFQLm5vdGlmaWNhdGlvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZW51bSBrZXlcbiAgICAgKiBAcGFyYW0ga2V5IC0gQSBrZXkgdG8gZmluZCBpbiB0aGUgbWFwIG9mIHRoZSBzdWJjbGFzc1xuICAgICAqIEByZXR1cm4geyp9IC0gUmV0dXJucyBhIHZhbHVlIGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyB2YWx1ZUZvcktleSAoa2V5KSB7XG4gICAgICAgIHJldHVybiBtZXNzYWdlVHlwZS5fdmFsdWVGb3JLZXkoa2V5LCBtZXNzYWdlVHlwZS5fTUFQKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGtleSBmb3IgdGhlIGdpdmVuIGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBBIHByaW1pdGl2ZSB2YWx1ZSB0byBmaW5kIHRoZSBtYXRjaGluZyBrZXkgZm9yIGluIHRoZSBtYXAgb2YgdGhlIHN1YmNsYXNzXG4gICAgICogQHJldHVybiB7Kn0gLSBSZXR1cm5zIGEga2V5IGlmIGZvdW5kLCBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBrZXlGb3JWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIG1lc3NhZ2VUeXBlLl9rZXlGb3JWYWx1ZSh2YWx1ZSwgbWVzc2FnZVR5cGUuX01BUCk7XG4gICAgfVxufVxuXG5tZXNzYWdlVHlwZS5fTUFQID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgJ3JlcXVlc3QnOiAwLFxuICAgICdyZXNwb25zZSc6IDEsXG4gICAgJ25vdGlmaWNhdGlvbic6IDIsXG59KTtcblxuZXhwb3J0IHsgbWVzc2FnZVR5cGUgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBTZGxTZXJ2aWNlTGlzdGVuZXJcbiAqL1xuY2xhc3MgU2RsU2VydmljZUxpc3RlbmVyIHtcbiAgICAvKipcblx0ICogQGNvbnN0cnVjdG9yXG5cdCAqL1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgdGhpcy5fb25TZXJ2aWNlU3RhcnRlZCA9IG51bGw7XG4gICAgICAgIHRoaXMuX29uU2VydmljZUVuZGVkID0gbnVsbDtcbiAgICAgICAgdGhpcy5fb25TZXJ2aWNlRXJyb3IgPSBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyXG4gICAgICovXG4gICAgc2V0T25TZXJ2aWNlU3RhcnRlZCAobGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5fb25TZXJ2aWNlU3RhcnRlZCA9IGxpc3RlbmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyXG4gICAgICovXG4gICAgc2V0T25TZXJ2aWNlRW5kZWQgKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMuX29uU2VydmljZUVuZGVkID0gbGlzdGVuZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBzZXRPblNlcnZpY2VFcnJvciAobGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5fb25TZXJ2aWNlRXJyb3IgPSBsaXN0ZW5lcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NkbFNlc3Npb259IHNlc3Npb25cbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZVxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNFbmNyeXB0ZWRcbiAgICAgKi9cbiAgICBvblNlcnZpY2VTdGFydGVkIChzZXNzaW9uLCBzZXJ2aWNlVHlwZSwgaXNFbmNyeXB0ZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9vblNlcnZpY2VTdGFydGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9vblNlcnZpY2VTdGFydGVkKHNlc3Npb24sIHNlcnZpY2VUeXBlLCBpc0VuY3J5cHRlZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NkbFNlc3Npb259IHNlc3Npb25cbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZVxuICAgICAqL1xuICAgIG9uU2VydmljZUVuZGVkIChzZXNzaW9uLCBzZXJ2aWNlVHlwZSkge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX29uU2VydmljZUVuZGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9vblNlcnZpY2VFbmRlZChzZXNzaW9uLCBzZXJ2aWNlVHlwZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1NkbFNlc3Npb259IHNlc3Npb25cbiAgICAgKiBAcGFyYW0ge1NlcnZpY2VUeXBlfSBzZXJ2aWNlVHlwZVxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSByZWFzb25cbiAgICAgKi9cbiAgICBvblNlcnZpY2VFcnJvciAoc2Vzc2lvbiwgc2VydmljZVR5cGUsIHJlYXNvbikge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX29uU2VydmljZUVycm9yID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9vblNlcnZpY2VFcnJvcihzZXNzaW9uLCBzZXJ2aWNlVHlwZSwgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IHsgU2RsU2VydmljZUxpc3RlbmVyIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFRyYW5zcG9ydEJhc2UgfSBmcm9tICcuL1RyYW5zcG9ydEJhc2UuanMnO1xuaW1wb3J0IHsgU2RsUHNtIH0gZnJvbSAnLi9TZGxQc20uanMnO1xuXG5jbGFzcyBDdXN0b21UcmFuc3BvcnQgZXh0ZW5kcyBUcmFuc3BvcnRCYXNlIHtcbiAgICBjb25zdHJ1Y3RvciAodHJhbnNwb3J0Q29uZmlnLCB0cmFuc3BvcnRDYWxsYmFjayA9IG51bGwpIHtcbiAgICAgICAgc3VwZXIodHJhbnNwb3J0Q29uZmlnLCB0cmFuc3BvcnRDYWxsYmFjayk7XG4gICAgICAgIHRoaXMuX3F1ZXVlID0gW107XG4gICAgICAgIHRoaXMuX2lzUnVubmluZyA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VHJhbnNwb3J0Q2FsbGJhY2t9IGNhbGxiYWNrXG4gICAgICovXG4gICAgc2V0VHJhbnNwb3J0Q2FsbGJhY2sgKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX3RyYW5zcG9ydENhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyaWdnZXJzIHRoZSB0cmFuc3BvcnQgY2FsbGJhY2sgZm9yIGNvbm5lY3Rpb24gZXN0YWJsaXNoZWRcbiAgICAgKi9cbiAgICBzdGFydCAoKSB7XG4gICAgICAgIGlmICh0aGlzLl90cmFuc3BvcnRDYWxsYmFjayAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2sub25Db25uZWN0aW9uRXN0YWJsaXNoZWQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyaWdnZXJzIHRoZSB0cmFuc3BvcnQgY2FsbGJhY2sgZm9yIGNvbm5lY3Rpb24gdGVybWluYXRlZFxuICAgICAqL1xuICAgIHN0b3AgKCkge1xuICAgICAgICBpZiAodGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2sgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX3RyYW5zcG9ydENhbGxiYWNrLm9uQ29ubmVjdGlvblRlcm1pbmF0ZWQoJ1RyYW5zcG9ydCB0b2xkIHRvIHN0b3AnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyaWdnZXJzIHRoZSB0cmFuc3BvcnQgY2FsbGJhY2sgZm9yIGFuIGVycm9yXG4gICAgICovXG4gICAgb25FcnJvciAoKSB7XG4gICAgICAgIGlmICh0aGlzLl90cmFuc3BvcnRDYWxsYmFjayAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2sub25FcnJvcigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGNvbnRlbnRzIGluIHRoZSBwYWNrZXQgc2hvdWxkIGJlIHNlbnQgb3V0IHRocm91Z2ggdGhlIHRyYW5zcG9ydFxuICAgICAqIEBwYXJhbSB7U2RsUGFja2V0fSBwYWNrZXRcbiAgICAgKi9cbiAgICBzZW5kUGFja2V0IChwYWNrZXQpIHtcbiAgICAgICAgY29uc3QgYnl0ZXMgPSBwYWNrZXQudG9QYWNrZXQoKTtcbiAgICAgICAgdGhpcy5vblNlbmRQYWNrZXQoYnl0ZXMsIDAsIGJ5dGVzLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGFwcCBpbnN0YW50aWF0aW5nIHRoaXMgY2xhc3MgbmVlZHMgdG8gaW1wbGVtZW50IHRoaXMgbWV0aG9kISBzZW5kUGFja2V0IGNhbGxzIHRoaXMgbWV0aG9kXG4gICAgICogQHBhcmFtIHtVSW50OEFycmF5fSBieXRlc1xuICAgICAqL1xuICAgIG9uU2VuZFBhY2tldCAoYnl0ZXMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdvblNlbmRQYWNrZXQgbWV0aG9kIG11c3QgYmUgb3ZlcnJpZGRlbicpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgYnl0ZSBidWZmZXIgd2FzIHBhc3NlZCBoZXJlIGZvciBwcm9jZXNzaW5nXG4gICAgICogQHBhcmFtIHtVaW50OEFycmF5fSBtZXNzYWdlXG4gICAgICovXG4gICAgb25CeXRlQnVmZmVyUmVjZWl2ZWQgKG1lc3NhZ2UpIHtcbiAgICAgICAgdGhpcy5fcXVldWUucHVzaChtZXNzYWdlKTtcbiAgICAgICAgdGhpcy5fbXVsdGlCeXRlSGFuZGxlcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByb2Nlc3NlcyByZWNlaXZlZCBkYXRhIGZyb20gdGhlIGludGVybmFsIHF1ZXVlXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBfbXVsdGlCeXRlSGFuZGxlciAoKSB7XG4gICAgICAgIGlmICh0aGlzLl9pc1J1bm5pbmcpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9pc1J1bm5pbmcgPSB0cnVlO1xuXG4gICAgICAgIHdoaWxlICh0aGlzLl9xdWV1ZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zdCB1aW50OCA9IHRoaXMuX3F1ZXVlLnNoaWZ0KCk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGJ5dGUgb2YgdWludDgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVCeXRlKGJ5dGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5faXNSdW5uaW5nID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmVlZHMgYSBieXRlIHRocm91Z2ggdGhlIGludGVybmFsIFBTTVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBieXRlIC0gdW5zaWduZWQgOC1iaXQgaW50ZWdlclxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgX2hhbmRsZUJ5dGUgKGJ5dGUpIHtcbiAgICAgICAgY29uc3Qgc2RsUHNtID0gdGhpcy5fc2RsUHNtO1xuXG4gICAgICAgIGNvbnN0IHN1Y2Nlc3MgPSBzZGxQc20uaGFuZGxlQnl0ZShieXRlKTtcbiAgICAgICAgaWYgKCFzdWNjZXNzKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdmYWlsZWQnLCBzZGxQc20pO1xuICAgICAgICAgICAgc2RsUHNtLnJlc2V0KCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaXNGaW5pc2hlZCA9IHNkbFBzbS5nZXRTdGF0ZSgpID09PSBTZGxQc20uRklOSVNIRURfU1RBVEU7XG5cbiAgICAgICAgaWYgKGlzRmluaXNoZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhY2tldCA9IHNkbFBzbS5nZXRGb3JtZWRQYWNrZXQoKTtcbiAgICAgICAgICAgIHNkbFBzbS5yZXNldCgpO1xuICAgICAgICAgICAgaWYgKHRoaXMuX3RyYW5zcG9ydENhbGxiYWNrICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdHJhbnNwb3J0Q2FsbGJhY2sub25QYWNrZXRSZWNlaXZlZChwYWNrZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG5cbmV4cG9ydCB7IEN1c3RvbVRyYW5zcG9ydCB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFRyYW5zcG9ydENvbmZpZ0Jhc2VcbiAqIEBwcm9wZXJ0eSB7VHJhbnNwb3J0VHlwZX0gX3RyYW5zcG9ydFR5cGVcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGdldFRyYW5zcG9ydFR5cGVcbiAqL1xuY2xhc3MgVHJhbnNwb3J0Q29uZmlnQmFzZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtUcmFuc3BvcnRUeXBlfSB0cmFuc3BvcnRUeXBlIC0gZW51bVxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yICh0cmFuc3BvcnRUeXBlKSB7XG4gICAgICAgIHRoaXMuX3RyYW5zcG9ydFR5cGUgPSB0cmFuc3BvcnRUeXBlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4ge1RyYW5zcG9ydFR5cGV9XG4gICAgICovXG4gICAgZ2V0VHJhbnNwb3J0VHlwZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnRUeXBlO1xuICAgIH1cbn1cblxuZXhwb3J0IHsgVHJhbnNwb3J0Q29uZmlnQmFzZSB9OyIsIi8qXG4qIENvcHlyaWdodCAoYykgMjAxOSwgTGl2aW8sIEluYy5cbiogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbipcbiogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4qIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiogbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiogdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiogZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlXG4qIGRpc3RyaWJ1dGlvbi5cbipcbiogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgTGl2aW8gSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiogbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlXG4qIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuKlxuKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4qIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4qIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbiogTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1NcbiogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiogQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbiogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbiogUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBUcmFuc3BvcnRDb25maWdCYXNlIH0gZnJvbSAnLi9UcmFuc3BvcnRDb25maWdCYXNlLmpzJztcbmltcG9ydCB7IFRyYW5zcG9ydFR5cGUgfSBmcm9tICcuL2VudW1zL1RyYW5zcG9ydFR5cGUuanMnO1xuXG5jbGFzcyBDdXN0b21UcmFuc3BvcnRDb25maWcgZXh0ZW5kcyBUcmFuc3BvcnRDb25maWdCYXNlIHtcbiAgICAvKipcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICogQHBhcmFtIHtDdXN0b21UcmFuc3BvcnR9IGN1c3RvbVRyYW5zcG9ydCAtIEFuIGluc3RhbmNlIG9mIGEgY3VzdG9tIHRyYW5zcG9ydFxuICAgICovXG4gICAgY29uc3RydWN0b3IgKGN1c3RvbVRyYW5zcG9ydCkge1xuICAgICAgICBzdXBlcihUcmFuc3BvcnRUeXBlLkNVU1RPTSk7XG4gICAgICAgIHRoaXMuX2N1c3RvbVRyYW5zcG9ydCA9IGN1c3RvbVRyYW5zcG9ydDtcbiAgICB9XG5cbiAgICBnZXRUcmFuc3BvcnRUeXBlICgpIHtcbiAgICAgICAgcmV0dXJuIFRyYW5zcG9ydFR5cGUuQ1VTVE9NO1xuICAgIH1cblxuICAgIGdldFRyYW5zcG9ydCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jdXN0b21UcmFuc3BvcnQ7XG4gICAgfVxufVxuXG5leHBvcnQgeyBDdXN0b21UcmFuc3BvcnRDb25maWcgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgVHJhbnNwb3J0VHlwZSB9IGZyb20gJy4vZW51bXMvVHJhbnNwb3J0VHlwZS5qcyc7XG5pbXBvcnQgeyBUcmFuc3BvcnRDb25maWdCYXNlIH0gZnJvbSAnLi9UcmFuc3BvcnRDb25maWdCYXNlLmpzJztcblxuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFRyYW5zcG9ydENvbmZpZ0Jhc2VcbiAqIEBwcm9wZXJ0eSB7VHJhbnNwb3J0VHlwZX0gX3RyYW5zcG9ydFR5cGVcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGdldFRyYW5zcG9ydFR5cGVcbiAqL1xuY2xhc3MgV2ViU29ja2V0Q2xpZW50Q29uZmlnIGV4dGVuZHMgVHJhbnNwb3J0Q29uZmlnQmFzZSB7XG4gICAgLyoqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtUcmFuc3BvcnRUeXBlfSB0cmFuc3BvcnRUeXBlIC0gZW51bVxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yIChob3N0LCBwb3J0KSB7XG4gICAgICAgIHN1cGVyKFRyYW5zcG9ydFR5cGUuV0VCU09DS0VUX0NMSUVOVCk7XG5cbiAgICAgICAgdGhpcy5faG9zdCA9IGhvc3Q7XG4gICAgICAgIHRoaXMuX3BvcnQgPSBwb3J0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4gU3RyaW5nXG4gICAgICovXG4gICAgZ2V0SG9zdCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ob3N0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm4gTnVtYmVyXG4gICAgICovXG4gICAgZ2V0UG9ydCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wb3J0O1xuICAgIH1cbn1cblxuZXhwb3J0IHsgV2ViU29ja2V0Q2xpZW50Q29uZmlnIH07IiwiLypcbiogQ29weXJpZ2h0IChjKSAyMDE5LCBMaXZpbywgSW5jLlxuKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4qXG4qIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuKiBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbipcbiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuKiB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZ1xuKiBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGVcbiogZGlzdHJpYnV0aW9uLlxuKlxuKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBMaXZpbyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuKiBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmVcbiogd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4qXG4qIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4qIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRVxuKiBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4qIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4qIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuKiBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuKiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRVxuKiBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmNsYXNzIFRyYW5zcG9ydFJlY29yZCB7XG4gICAgLyoqXG4gICAgKiBAY29uc3RydWN0b3JcbiAgICAqIEBwYXJhbSB7VHJhbnNwb3J0VHlwZX0gdHJhbnNwb3J0VHlwZSAtIFRoZSB0eXBlIG9mIHRoZSB0cmFuc3BvcnRcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBhZGRyZXNzXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvciAodHJhbnNwb3J0VHlwZSwgYWRkcmVzcykge1xuICAgICAgICB0aGlzLl90eXBlID0gdHJhbnNwb3J0VHlwZTtcbiAgICAgICAgdGhpcy5fYWRkcmVzcyA9IGFkZHJlc3M7XG4gICAgfVxuXG4gICAgZ2V0VHlwZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlO1xuICAgIH1cblxuICAgIGdldEFkZHJlc3MgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkcmVzcztcbiAgICB9XG5cbiAgICBlcXVhbHMgKG9iaikge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgb2JqIGluc3RhbmNlb2YgVHJhbnNwb3J0UmVjb3JkXG4gICAgICAgICAgICAmJiBvYmouZ2V0VHlwZSAhPT0gbnVsbFxuICAgICAgICAgICAgJiYgb2JqLmdldFR5cGUoKSA9PT0gdGhpcy5nZXRUeXBlKClcbiAgICAgICAgICAgICYmIG9iai5nZXRBZGRyZXNzKCkgPT09IHRoaXMuZ2V0QWRkcmVzcygpXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgdG9TdHJpbmcgKCkge1xuICAgICAgICByZXR1cm4gYFRyYW5zcG9ydCBUeXBlOiAke3RoaXMuX3R5cGUubmFtZSgpfSBcXG4gQWRkcmVzczogJHt0aGlzLl9hZGRyZXNzfWA7XG4gICAgfVxufVxuXG5leHBvcnQgeyBUcmFuc3BvcnRSZWNvcmQgfTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuY29uc3QgeyBUcmFuc3BvcnRDb25maWdCYXNlIH0gPSByZXF1aXJlKCcuL1RyYW5zcG9ydENvbmZpZ0Jhc2UuanMnKTtcbmNvbnN0IHsgVHJhbnNwb3J0VHlwZSB9ID0gcmVxdWlyZSgnLi9lbnVtcy9UcmFuc3BvcnRUeXBlLmpzJyk7XG5cbmNsYXNzIFdlYlNvY2tldFNlcnZlckNvbmZpZyBleHRlbmRzIFRyYW5zcG9ydENvbmZpZ0Jhc2Uge1xuICAgIC8qKlxuICAgICogQGNvbnN0cnVjdG9yXG4gICAgKiBAcGFyYW0ge051bWJlcn0gcG9ydCAtIFRoZSBwb3J0IHRvIGxpc3RlbiBmb3IgV2ViU29ja2V0IGNvbm5lY3Rpb25zIG9uLlxuICAgICogQHBhcmFtIHtOdW1iZXJ9IGNvbm5lY3Rpb25Mb3N0VGltZW91dCAtIFRoZSB0aW1lb3V0IGZvciBhIGNvbm5lY3Rpb24gbG9zdCwgcmVwcmVzZW50ZWQgaW4gbWlsbGlzZWNvbmRzLiBEZWZhdWx0IDYwMDAwLiBJZiBhIHZhbHVlIGxlc3MgdGhhbiAwIGlzIHVzZWQsIHRoZW4gdGhlIHdlYnNvY2tldCB3aWxsIHdhaXQgaW5kZWZpbml0ZWx5LlxuICAgICovXG4gICAgY29uc3RydWN0b3IgKHBvcnQgPSAzMDAwLCBjb25uZWN0aW9uTG9zdFRpbWVvdXQgPSA2MDAwMCwgc3NsQ29uZmlnID0gbnVsbCkge1xuICAgICAgICBzdXBlcihUcmFuc3BvcnRUeXBlLldFQlNPQ0tFVF9TRVJWRVIpO1xuICAgICAgICB0aGlzLl9wb3J0ID0gcG9ydDtcbiAgICAgICAgdGhpcy5fY29ubmVjdGlvbkxvc3RUaW1lb3V0ID0gY29ubmVjdGlvbkxvc3RUaW1lb3V0O1xuICAgICAgICB0aGlzLl9zc2xDb25maWcgPSBzc2xDb25maWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBSZXR1cm5zIHRoZSB3ZWJzb2NrZXQgbGlzdGVuZXIgcG9ydFxuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgZ2V0UG9ydCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wb3J0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICogUmV0dXJucyB0aGUgd2Vic29ja2V0IGNvbm5lY3Rpb24gbG9zdCB0aW1lb3V0IHZhbHVlIGluIG1pbGxpc2Vjb25kc1xuICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICovXG4gICAgZ2V0Q29ubmVjdGlvbkxvc3RUaW1lb3V0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nvbm5lY3Rpb25Mb3N0VGltZW91dDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIFJldHVybnMgdGhlIFNTTCBjb25maWd1cmF0aW9uXG4gICAgKiBAcmV0dXJuIHtTc2xDb25maWd9XG4gICAgKi9cbiAgICBnZXRTc2xDb25maWcgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3NsQ29uZmlnO1xuICAgIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgV2ViU29ja2V0U2VydmVyQ29uZmlnLFxufTsiLCIvKlxuKiBDb3B5cmlnaHQgKGMpIDIwMTksIExpdmlvLCBJbmMuXG4qIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4qXG4qIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbipcbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4qIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4qIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nXG4qIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZVxuKiBkaXN0cmlidXRpb24uXG4qXG4qIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIExpdmlvIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXG4qIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZVxuKiB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbipcbiogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4qIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1JcbiogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiogU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4qIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4qIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4qIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4qIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuaW1wb3J0IHsgQXBwQ29uZmlnIH0gZnJvbSAnLi90bXAvbWFuYWdlci9BcHBDb25maWcuanMnO1xuaW1wb3J0IHsgTGlmZWN5Y2xlTGlzdGVuZXIgfSBmcm9tICcuL3RtcC9tYW5hZ2VyL2xpZmVjeWNsZS9MaWZlY3ljbGVMaXN0ZW5lci5qcyc7XG5pbXBvcnQgeyBMaWZlY3ljbGVNYW5hZ2VyIH0gZnJvbSAnLi90bXAvbWFuYWdlci9saWZlY3ljbGUvTGlmZWN5Y2xlTWFuYWdlci5qcyc7XG5pbXBvcnQgeyBCaW5hcnlGcmFtZUhlYWRlciB9IGZyb20gJy4vdG1wL3Byb3RvY29sL0JpbmFyeUZyYW1lSGVhZGVyLmpzJztcbmltcG9ydCB7IE1lc3NhZ2VGcmFtZUFzc2VtYmxlciB9IGZyb20gJy4vdG1wL3Byb3RvY29sL01lc3NhZ2VGcmFtZUFzc2VtYmxlci5qcyc7XG5pbXBvcnQgeyBNZXNzYWdlRnJhbWVEaXNhc3NlbWJsZXIgfSBmcm9tICcuL3RtcC9wcm90b2NvbC9NZXNzYWdlRnJhbWVEaXNhc3NlbWJsZXIuanMnO1xuaW1wb3J0IHsgU2RsUGFja2V0IH0gZnJvbSAnLi90bXAvcHJvdG9jb2wvU2RsUGFja2V0LmpzJztcbmltcG9ydCB7IFNkbFBhY2tldEZhY3RvcnkgfSBmcm9tICcuL3RtcC9wcm90b2NvbC9TZGxQYWNrZXRGYWN0b3J5LmpzJztcbmltcG9ydCB7IFNkbFByb3RvY29sIH0gZnJvbSAnLi90bXAvcHJvdG9jb2wvU2RsUHJvdG9jb2wuanMnO1xuaW1wb3J0IHsgU2RsUHJvdG9jb2xCYXNlIH0gZnJvbSAnLi90bXAvcHJvdG9jb2wvU2RsUHJvdG9jb2xCYXNlLmpzJztcbmltcG9ydCB7IFNkbFByb3RvY29sTGlzdGVuZXIgfSBmcm9tICcuL3RtcC9wcm90b2NvbC9TZGxQcm90b2NvbExpc3RlbmVyLmpzJztcbmltcG9ydCB7IENvbnRyb2xGcmFtZVRhZ3MgfSBmcm9tICcuL3RtcC9wcm90b2NvbC9lbnVtcy9Db250cm9sRnJhbWVUYWdzLmpzJztcbmltcG9ydCB7IEZyYW1lVHlwZSB9IGZyb20gJy4vdG1wL3Byb3RvY29sL2VudW1zL0ZyYW1lVHlwZS5qcyc7XG5pbXBvcnQgeyBTZXJ2aWNlVHlwZSB9IGZyb20gJy4vdG1wL3Byb3RvY29sL2VudW1zL1NlcnZpY2VUeXBlLmpzJztcbmltcG9ydCB7IFJwY0NyZWF0b3IgfSBmcm9tICcuL3RtcC9ycGMvUnBjQ3JlYXRvci5qcyc7XG5pbXBvcnQgeyBScGNMaXN0ZW5lciB9IGZyb20gJy4vdG1wL3JwYy9ScGNMaXN0ZW5lci5qcyc7XG5pbXBvcnQgeyBScGNNZXNzYWdlIH0gZnJvbSAnLi90bXAvcnBjL1JwY01lc3NhZ2UuanMnO1xuaW1wb3J0IHsgUnBjTm90aWZpY2F0aW9uIH0gZnJvbSAnLi90bXAvcnBjL1JwY05vdGlmaWNhdGlvbi5qcyc7XG5pbXBvcnQgeyBScGNSZXF1ZXN0IH0gZnJvbSAnLi90bXAvcnBjL1JwY1JlcXVlc3QuanMnO1xuaW1wb3J0IHsgUnBjUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvUnBjUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgUnBjU3RydWN0IH0gZnJvbSAnLi90bXAvcnBjL1JwY1N0cnVjdC5qcyc7XG5pbXBvcnQgeyBBbWJpZW50TGlnaHRTdGF0dXMgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvQW1iaWVudExpZ2h0U3RhdHVzLmpzJztcbmltcG9ydCB7IEFwcEhNSVR5cGUgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvQXBwSE1JVHlwZS5qcyc7XG5pbXBvcnQgeyBBcHBJbnRlcmZhY2VVbnJlZ2lzdGVyZWRSZWFzb24gfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvQXBwSW50ZXJmYWNlVW5yZWdpc3RlcmVkUmVhc29uLmpzJztcbmltcG9ydCB7IEFwcFNlcnZpY2VUeXBlIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL0FwcFNlcnZpY2VUeXBlLmpzJztcbmltcG9ydCB7IEF1ZGlvU3RyZWFtaW5nSW5kaWNhdG9yIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL0F1ZGlvU3RyZWFtaW5nSW5kaWNhdG9yLmpzJztcbmltcG9ydCB7IEF1ZGlvU3RyZWFtaW5nU3RhdGUgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvQXVkaW9TdHJlYW1pbmdTdGF0ZS5qcyc7XG5pbXBvcnQgeyBBdWRpb1R5cGUgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvQXVkaW9UeXBlLmpzJztcbmltcG9ydCB7IEJpdHNQZXJTYW1wbGUgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvQml0c1BlclNhbXBsZS5qcyc7XG5pbXBvcnQgeyBCdXR0b25FdmVudE1vZGUgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvQnV0dG9uRXZlbnRNb2RlLmpzJztcbmltcG9ydCB7IEJ1dHRvbk5hbWUgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvQnV0dG9uTmFtZS5qcyc7XG5pbXBvcnQgeyBCdXR0b25QcmVzc01vZGUgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvQnV0dG9uUHJlc3NNb2RlLmpzJztcbmltcG9ydCB7IENhck1vZGVTdGF0dXMgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvQ2FyTW9kZVN0YXR1cy5qcyc7XG5pbXBvcnQgeyBDaGFyYWN0ZXJTZXQgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvQ2hhcmFjdGVyU2V0LmpzJztcbmltcG9ydCB7IENvbXBhc3NEaXJlY3Rpb24gfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvQ29tcGFzc0RpcmVjdGlvbi5qcyc7XG5pbXBvcnQgeyBDb21wb25lbnRWb2x1bWVTdGF0dXMgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvQ29tcG9uZW50Vm9sdW1lU3RhdHVzLmpzJztcbmltcG9ydCB7IERlZnJvc3Rab25lIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL0RlZnJvc3Rab25lLmpzJztcbmltcG9ydCB7IERlbGl2ZXJ5TW9kZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9EZWxpdmVyeU1vZGUuanMnO1xuaW1wb3J0IHsgRGV2aWNlTGV2ZWxTdGF0dXMgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvRGV2aWNlTGV2ZWxTdGF0dXMuanMnO1xuaW1wb3J0IHsgRGltZW5zaW9uIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL0RpbWVuc2lvbi5qcyc7XG5pbXBvcnQgeyBEaXJlY3Rpb24gfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvRGlyZWN0aW9uLmpzJztcbmltcG9ydCB7IERpc3BsYXlNb2RlIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL0Rpc3BsYXlNb2RlLmpzJztcbmltcG9ydCB7IERpc3BsYXlUeXBlIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL0Rpc3BsYXlUeXBlLmpzJztcbmltcG9ydCB7IERpc3RhbmNlVW5pdCB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9EaXN0YW5jZVVuaXQuanMnO1xuaW1wb3J0IHsgRHJpdmVyRGlzdHJhY3Rpb25TdGF0ZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9Ecml2ZXJEaXN0cmFjdGlvblN0YXRlLmpzJztcbmltcG9ydCB7IEVDYWxsQ29uZmlybWF0aW9uU3RhdHVzIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL0VDYWxsQ29uZmlybWF0aW9uU3RhdHVzLmpzJztcbmltcG9ydCB7IEVsZWN0cm9uaWNQYXJrQnJha2VTdGF0dXMgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvRWxlY3Ryb25pY1BhcmtCcmFrZVN0YXR1cy5qcyc7XG5pbXBvcnQgeyBFbWVyZ2VuY3lFdmVudFR5cGUgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvRW1lcmdlbmN5RXZlbnRUeXBlLmpzJztcbmltcG9ydCB7IEZpbGVUeXBlIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL0ZpbGVUeXBlLmpzJztcbmltcG9ydCB7IEZ1ZWxDdXRvZmZTdGF0dXMgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvRnVlbEN1dG9mZlN0YXR1cy5qcyc7XG5pbXBvcnQgeyBGdWVsVHlwZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9GdWVsVHlwZS5qcyc7XG5pbXBvcnQgeyBGdW5jdGlvbklEIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL0Z1bmN0aW9uSUQuanMnO1xuaW1wb3J0IHsgR2xvYmFsUHJvcGVydHkgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvR2xvYmFsUHJvcGVydHkuanMnO1xuaW1wb3J0IHsgSE1JTGV2ZWwgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvSE1JTGV2ZWwuanMnO1xuaW1wb3J0IHsgSG1pWm9uZUNhcGFiaWxpdGllcyB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9IbWlab25lQ2FwYWJpbGl0aWVzLmpzJztcbmltcG9ydCB7IEh5YnJpZEFwcFByZWZlcmVuY2UgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvSHlicmlkQXBwUHJlZmVyZW5jZS5qcyc7XG5pbXBvcnQgeyBJZ25pdGlvblN0YWJsZVN0YXR1cyB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9JZ25pdGlvblN0YWJsZVN0YXR1cy5qcyc7XG5pbXBvcnQgeyBJZ25pdGlvblN0YXR1cyB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9JZ25pdGlvblN0YXR1cy5qcyc7XG5pbXBvcnQgeyBJbWFnZUZpZWxkTmFtZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9JbWFnZUZpZWxkTmFtZS5qcyc7XG5pbXBvcnQgeyBJbWFnZVR5cGUgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvSW1hZ2VUeXBlLmpzJztcbmltcG9ydCB7IEludGVyYWN0aW9uTW9kZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9JbnRlcmFjdGlvbk1vZGUuanMnO1xuaW1wb3J0IHsgS2V5Ym9hcmRFdmVudCB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9LZXlib2FyZEV2ZW50LmpzJztcbmltcG9ydCB7IEtleWJvYXJkTGF5b3V0IH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL0tleWJvYXJkTGF5b3V0LmpzJztcbmltcG9ydCB7IEtleXByZXNzTW9kZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9LZXlwcmVzc01vZGUuanMnO1xuaW1wb3J0IHsgTGFuZ3VhZ2UgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvTGFuZ3VhZ2UuanMnO1xuaW1wb3J0IHsgTGF5b3V0TW9kZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9MYXlvdXRNb2RlLmpzJztcbmltcG9ydCB7IExpZ2h0TmFtZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9MaWdodE5hbWUuanMnO1xuaW1wb3J0IHsgTGlnaHRTdGF0dXMgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvTGlnaHRTdGF0dXMuanMnO1xuaW1wb3J0IHsgTWFpbnRlbmFuY2VNb2RlU3RhdHVzIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL01haW50ZW5hbmNlTW9kZVN0YXR1cy5qcyc7XG5pbXBvcnQgeyBNYXNzYWdlQ3VzaGlvbiB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9NYXNzYWdlQ3VzaGlvbi5qcyc7XG5pbXBvcnQgeyBNYXNzYWdlTW9kZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9NYXNzYWdlTW9kZS5qcyc7XG5pbXBvcnQgeyBNYXNzYWdlWm9uZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9NYXNzYWdlWm9uZS5qcyc7XG5pbXBvcnQgeyBNZWRpYUNsb2NrRm9ybWF0IH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL01lZGlhQ2xvY2tGb3JtYXQuanMnO1xuaW1wb3J0IHsgTWVkaWFUeXBlIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL01lZGlhVHlwZS5qcyc7XG5pbXBvcnQgeyBNZW51TGF5b3V0IH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL01lbnVMYXlvdXQuanMnO1xuaW1wb3J0IHsgTWV0YWRhdGFUeXBlIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL01ldGFkYXRhVHlwZS5qcyc7XG5pbXBvcnQgeyBNb2R1bGVUeXBlIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL01vZHVsZVR5cGUuanMnO1xuaW1wb3J0IHsgTmF2aWdhdGlvbkFjdGlvbiB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9OYXZpZ2F0aW9uQWN0aW9uLmpzJztcbmltcG9ydCB7IE5hdmlnYXRpb25KdW5jdGlvbiB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9OYXZpZ2F0aW9uSnVuY3Rpb24uanMnO1xuaW1wb3J0IHsgUFJOREwgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvUFJOREwuanMnO1xuaW1wb3J0IHsgUGVybWlzc2lvblN0YXR1cyB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9QZXJtaXNzaW9uU3RhdHVzLmpzJztcbmltcG9ydCB7IFBvd2VyTW9kZVF1YWxpZmljYXRpb25TdGF0dXMgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvUG93ZXJNb2RlUXVhbGlmaWNhdGlvblN0YXR1cy5qcyc7XG5pbXBvcnQgeyBQb3dlck1vZGVTdGF0dXMgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvUG93ZXJNb2RlU3RhdHVzLmpzJztcbmltcG9ydCB7IFByZWRlZmluZWRMYXlvdXQgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvUHJlZGVmaW5lZExheW91dC5qcyc7XG5pbXBvcnQgeyBQcmVkZWZpbmVkV2luZG93cyB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9QcmVkZWZpbmVkV2luZG93cy5qcyc7XG5pbXBvcnQgeyBQcmVyZWNvcmRlZFNwZWVjaCB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9QcmVyZWNvcmRlZFNwZWVjaC5qcyc7XG5pbXBvcnQgeyBQcmltYXJ5QXVkaW9Tb3VyY2UgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvUHJpbWFyeUF1ZGlvU291cmNlLmpzJztcbmltcG9ydCB7IFJhZGlvQmFuZCB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9SYWRpb0JhbmQuanMnO1xuaW1wb3J0IHsgUmFkaW9TdGF0ZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9SYWRpb1N0YXRlLmpzJztcbmltcG9ydCB7IFJlcXVlc3RUeXBlIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL1JlcXVlc3RUeXBlLmpzJztcbmltcG9ydCB7IFJlc3VsdCB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9SZXN1bHQuanMnO1xuaW1wb3J0IHsgUnBjVHlwZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9ScGNUeXBlLmpzJztcbmltcG9ydCB7IFNhbXBsaW5nUmF0ZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9TYW1wbGluZ1JhdGUuanMnO1xuaW1wb3J0IHsgU2VhdE1lbW9yeUFjdGlvblR5cGUgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvU2VhdE1lbW9yeUFjdGlvblR5cGUuanMnO1xuaW1wb3J0IHsgU2VydmljZVVwZGF0ZVJlYXNvbiB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9TZXJ2aWNlVXBkYXRlUmVhc29uLmpzJztcbmltcG9ydCB7IFNvZnRCdXR0b25UeXBlIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL1NvZnRCdXR0b25UeXBlLmpzJztcbmltcG9ydCB7IFNwZWVjaENhcGFiaWxpdGllcyB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9TcGVlY2hDYXBhYmlsaXRpZXMuanMnO1xuaW1wb3J0IHsgU3VwcG9ydGVkU2VhdCB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9TdXBwb3J0ZWRTZWF0LmpzJztcbmltcG9ydCB7IFN5c3RlbUFjdGlvbiB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9TeXN0ZW1BY3Rpb24uanMnO1xuaW1wb3J0IHsgU3lzdGVtQ2FwYWJpbGl0eVR5cGUgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvU3lzdGVtQ2FwYWJpbGl0eVR5cGUuanMnO1xuaW1wb3J0IHsgU3lzdGVtQ29udGV4dCB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9TeXN0ZW1Db250ZXh0LmpzJztcbmltcG9ydCB7IFRCVFN0YXRlIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL1RCVFN0YXRlLmpzJztcbmltcG9ydCB7IFRQTVMgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvVFBNUy5qcyc7XG5pbXBvcnQgeyBUZW1wZXJhdHVyZVVuaXQgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvVGVtcGVyYXR1cmVVbml0LmpzJztcbmltcG9ydCB7IFRleHRBbGlnbm1lbnQgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvVGV4dEFsaWdubWVudC5qcyc7XG5pbXBvcnQgeyBUZXh0RmllbGROYW1lIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL1RleHRGaWVsZE5hbWUuanMnO1xuaW1wb3J0IHsgVGltZXJNb2RlIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL1RpbWVyTW9kZS5qcyc7XG5pbXBvcnQgeyBUb3VjaFR5cGUgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvVG91Y2hUeXBlLmpzJztcbmltcG9ydCB7IFRyaWdnZXJTb3VyY2UgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvVHJpZ2dlclNvdXJjZS5qcyc7XG5pbXBvcnQgeyBUdXJuU2lnbmFsIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL1R1cm5TaWduYWwuanMnO1xuaW1wb3J0IHsgVXBkYXRlTW9kZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9VcGRhdGVNb2RlLmpzJztcbmltcG9ydCB7IFZlaGljbGVEYXRhQWN0aXZlU3RhdHVzIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL1ZlaGljbGVEYXRhQWN0aXZlU3RhdHVzLmpzJztcbmltcG9ydCB7IFZlaGljbGVEYXRhRXZlbnRTdGF0dXMgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvVmVoaWNsZURhdGFFdmVudFN0YXR1cy5qcyc7XG5pbXBvcnQgeyBWZWhpY2xlRGF0YU5vdGlmaWNhdGlvblN0YXR1cyB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9WZWhpY2xlRGF0YU5vdGlmaWNhdGlvblN0YXR1cy5qcyc7XG5pbXBvcnQgeyBWZWhpY2xlRGF0YVJlc3VsdENvZGUgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvVmVoaWNsZURhdGFSZXN1bHRDb2RlLmpzJztcbmltcG9ydCB7IFZlaGljbGVEYXRhU3RhdHVzIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL1ZlaGljbGVEYXRhU3RhdHVzLmpzJztcbmltcG9ydCB7IFZlaGljbGVEYXRhVHlwZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9WZWhpY2xlRGF0YVR5cGUuanMnO1xuaW1wb3J0IHsgVmVudGlsYXRpb25Nb2RlIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL1ZlbnRpbGF0aW9uTW9kZS5qcyc7XG5pbXBvcnQgeyBWaWRlb1N0cmVhbWluZ0NvZGVjIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL1ZpZGVvU3RyZWFtaW5nQ29kZWMuanMnO1xuaW1wb3J0IHsgVmlkZW9TdHJlYW1pbmdQcm90b2NvbCB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9WaWRlb1N0cmVhbWluZ1Byb3RvY29sLmpzJztcbmltcG9ydCB7IFZpZGVvU3RyZWFtaW5nU3RhdGUgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvVmlkZW9TdHJlYW1pbmdTdGF0ZS5qcyc7XG5pbXBvcnQgeyBWckNhcGFiaWxpdGllcyB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9WckNhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBXYXJuaW5nTGlnaHRTdGF0dXMgfSBmcm9tICcuL3RtcC9ycGMvZW51bXMvV2FybmluZ0xpZ2h0U3RhdHVzLmpzJztcbmltcG9ydCB7IFdheVBvaW50VHlwZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9XYXlQb2ludFR5cGUuanMnO1xuaW1wb3J0IHsgV2luZG93VHlwZSB9IGZyb20gJy4vdG1wL3JwYy9lbnVtcy9XaW5kb3dUeXBlLmpzJztcbmltcG9ydCB7IFdpcGVyU3RhdHVzIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL1dpcGVyU3RhdHVzLmpzJztcbmltcG9ydCB7IG1lc3NhZ2VUeXBlIH0gZnJvbSAnLi90bXAvcnBjL2VudW1zL21lc3NhZ2VUeXBlLmpzJztcbmltcG9ydCB7IEFkZENvbW1hbmQgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvQWRkQ29tbWFuZC5qcyc7XG5pbXBvcnQgeyBBZGRDb21tYW5kUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvQWRkQ29tbWFuZFJlc3BvbnNlLmpzJztcbmltcG9ydCB7IEFkZFN1Yk1lbnUgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvQWRkU3ViTWVudS5qcyc7XG5pbXBvcnQgeyBBZGRTdWJNZW51UmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvQWRkU3ViTWVudVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IEFsZXJ0IH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL0FsZXJ0LmpzJztcbmltcG9ydCB7IEFsZXJ0TWFuZXV2ZXIgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvQWxlcnRNYW5ldXZlci5qcyc7XG5pbXBvcnQgeyBBbGVydE1hbmV1dmVyUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvQWxlcnRNYW5ldXZlclJlc3BvbnNlLmpzJztcbmltcG9ydCB7IEFsZXJ0UmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvQWxlcnRSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBCdXR0b25QcmVzcyB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9CdXR0b25QcmVzcy5qcyc7XG5pbXBvcnQgeyBCdXR0b25QcmVzc1Jlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL0J1dHRvblByZXNzUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgQ2FuY2VsSW50ZXJhY3Rpb24gfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvQ2FuY2VsSW50ZXJhY3Rpb24uanMnO1xuaW1wb3J0IHsgQ2FuY2VsSW50ZXJhY3Rpb25SZXNwb25zZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9DYW5jZWxJbnRlcmFjdGlvblJlc3BvbnNlLmpzJztcbmltcG9ydCB7IENoYW5nZVJlZ2lzdHJhdGlvbiB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9DaGFuZ2VSZWdpc3RyYXRpb24uanMnO1xuaW1wb3J0IHsgQ2hhbmdlUmVnaXN0cmF0aW9uUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvQ2hhbmdlUmVnaXN0cmF0aW9uUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgQ2xvc2VBcHBsaWNhdGlvbiB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9DbG9zZUFwcGxpY2F0aW9uLmpzJztcbmltcG9ydCB7IENsb3NlQXBwbGljYXRpb25SZXNwb25zZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9DbG9zZUFwcGxpY2F0aW9uUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgQ3JlYXRlSW50ZXJhY3Rpb25DaG9pY2VTZXQgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvQ3JlYXRlSW50ZXJhY3Rpb25DaG9pY2VTZXQuanMnO1xuaW1wb3J0IHsgQ3JlYXRlSW50ZXJhY3Rpb25DaG9pY2VTZXRSZXNwb25zZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9DcmVhdGVJbnRlcmFjdGlvbkNob2ljZVNldFJlc3BvbnNlLmpzJztcbmltcG9ydCB7IENyZWF0ZVdpbmRvdyB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9DcmVhdGVXaW5kb3cuanMnO1xuaW1wb3J0IHsgQ3JlYXRlV2luZG93UmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvQ3JlYXRlV2luZG93UmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgRGVsZXRlQ29tbWFuZCB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9EZWxldGVDb21tYW5kLmpzJztcbmltcG9ydCB7IERlbGV0ZUNvbW1hbmRSZXNwb25zZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9EZWxldGVDb21tYW5kUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgRGVsZXRlRmlsZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9EZWxldGVGaWxlLmpzJztcbmltcG9ydCB7IERlbGV0ZUZpbGVSZXNwb25zZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9EZWxldGVGaWxlUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgRGVsZXRlSW50ZXJhY3Rpb25DaG9pY2VTZXQgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvRGVsZXRlSW50ZXJhY3Rpb25DaG9pY2VTZXQuanMnO1xuaW1wb3J0IHsgRGVsZXRlSW50ZXJhY3Rpb25DaG9pY2VTZXRSZXNwb25zZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9EZWxldGVJbnRlcmFjdGlvbkNob2ljZVNldFJlc3BvbnNlLmpzJztcbmltcG9ydCB7IERlbGV0ZVN1Yk1lbnUgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvRGVsZXRlU3ViTWVudS5qcyc7XG5pbXBvcnQgeyBEZWxldGVTdWJNZW51UmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvRGVsZXRlU3ViTWVudVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IERlbGV0ZVdpbmRvdyB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9EZWxldGVXaW5kb3cuanMnO1xuaW1wb3J0IHsgRGVsZXRlV2luZG93UmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvRGVsZXRlV2luZG93UmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgRGlhZ25vc3RpY01lc3NhZ2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvRGlhZ25vc3RpY01lc3NhZ2UuanMnO1xuaW1wb3J0IHsgRGlhZ25vc3RpY01lc3NhZ2VSZXNwb25zZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9EaWFnbm9zdGljTWVzc2FnZVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IERpYWxOdW1iZXIgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvRGlhbE51bWJlci5qcyc7XG5pbXBvcnQgeyBEaWFsTnVtYmVyUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvRGlhbE51bWJlclJlc3BvbnNlLmpzJztcbmltcG9ydCB7IEVuY29kZWRTeW5jUERhdGEgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvRW5jb2RlZFN5bmNQRGF0YS5qcyc7XG5pbXBvcnQgeyBFbmNvZGVkU3luY1BEYXRhUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvRW5jb2RlZFN5bmNQRGF0YVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IEVuZEF1ZGlvUGFzc1RocnUgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvRW5kQXVkaW9QYXNzVGhydS5qcyc7XG5pbXBvcnQgeyBFbmRBdWRpb1Bhc3NUaHJ1UmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvRW5kQXVkaW9QYXNzVGhydVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IEdlbmVyaWNSZXNwb25zZVJlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL0dlbmVyaWNSZXNwb25zZVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IEdldEFwcFNlcnZpY2VEYXRhIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL0dldEFwcFNlcnZpY2VEYXRhLmpzJztcbmltcG9ydCB7IEdldEFwcFNlcnZpY2VEYXRhUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvR2V0QXBwU2VydmljZURhdGFSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBHZXRDbG91ZEFwcFByb3BlcnRpZXMgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvR2V0Q2xvdWRBcHBQcm9wZXJ0aWVzLmpzJztcbmltcG9ydCB7IEdldENsb3VkQXBwUHJvcGVydGllc1Jlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL0dldENsb3VkQXBwUHJvcGVydGllc1Jlc3BvbnNlLmpzJztcbmltcG9ydCB7IEdldERUQ3MgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvR2V0RFRDcy5qcyc7XG5pbXBvcnQgeyBHZXREVENzUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvR2V0RFRDc1Jlc3BvbnNlLmpzJztcbmltcG9ydCB7IEdldEZpbGUgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvR2V0RmlsZS5qcyc7XG5pbXBvcnQgeyBHZXRGaWxlUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvR2V0RmlsZVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IEdldEludGVyaW9yVmVoaWNsZURhdGEgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvR2V0SW50ZXJpb3JWZWhpY2xlRGF0YS5qcyc7XG5pbXBvcnQgeyBHZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudCB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9HZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudC5qcyc7XG5pbXBvcnQgeyBHZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudFJlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL0dldEludGVyaW9yVmVoaWNsZURhdGFDb25zZW50UmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgR2V0SW50ZXJpb3JWZWhpY2xlRGF0YVJlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL0dldEludGVyaW9yVmVoaWNsZURhdGFSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBHZXRTeXN0ZW1DYXBhYmlsaXR5IH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL0dldFN5c3RlbUNhcGFiaWxpdHkuanMnO1xuaW1wb3J0IHsgR2V0U3lzdGVtQ2FwYWJpbGl0eVJlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL0dldFN5c3RlbUNhcGFiaWxpdHlSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBHZXRWZWhpY2xlRGF0YSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9HZXRWZWhpY2xlRGF0YS5qcyc7XG5pbXBvcnQgeyBHZXRWZWhpY2xlRGF0YVJlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL0dldFZlaGljbGVEYXRhUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgR2V0V2F5UG9pbnRzIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL0dldFdheVBvaW50cy5qcyc7XG5pbXBvcnQgeyBHZXRXYXlQb2ludHNSZXNwb25zZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9HZXRXYXlQb2ludHNSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBMaXN0RmlsZXMgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvTGlzdEZpbGVzLmpzJztcbmltcG9ydCB7IExpc3RGaWxlc1Jlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL0xpc3RGaWxlc1Jlc3BvbnNlLmpzJztcbmltcG9ydCB7IE9uQXBwSW50ZXJmYWNlVW5yZWdpc3RlcmVkIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL09uQXBwSW50ZXJmYWNlVW5yZWdpc3RlcmVkLmpzJztcbmltcG9ydCB7IE9uQXBwU2VydmljZURhdGEgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvT25BcHBTZXJ2aWNlRGF0YS5qcyc7XG5pbXBvcnQgeyBPbkF1ZGlvUGFzc1RocnUgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvT25BdWRpb1Bhc3NUaHJ1LmpzJztcbmltcG9ydCB7IE9uQnV0dG9uRXZlbnQgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvT25CdXR0b25FdmVudC5qcyc7XG5pbXBvcnQgeyBPbkJ1dHRvblByZXNzIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL09uQnV0dG9uUHJlc3MuanMnO1xuaW1wb3J0IHsgT25Db21tYW5kIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL09uQ29tbWFuZC5qcyc7XG5pbXBvcnQgeyBPbkRyaXZlckRpc3RyYWN0aW9uIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL09uRHJpdmVyRGlzdHJhY3Rpb24uanMnO1xuaW1wb3J0IHsgT25FbmNvZGVkU3luY1BEYXRhIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL09uRW5jb2RlZFN5bmNQRGF0YS5qcyc7XG5pbXBvcnQgeyBPbkhNSVN0YXR1cyB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9PbkhNSVN0YXR1cy5qcyc7XG5pbXBvcnQgeyBPbkhhc2hDaGFuZ2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvT25IYXNoQ2hhbmdlLmpzJztcbmltcG9ydCB7IE9uSW50ZXJpb3JWZWhpY2xlRGF0YSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9PbkludGVyaW9yVmVoaWNsZURhdGEuanMnO1xuaW1wb3J0IHsgT25LZXlib2FyZElucHV0IH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL09uS2V5Ym9hcmRJbnB1dC5qcyc7XG5pbXBvcnQgeyBPbkxhbmd1YWdlQ2hhbmdlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL09uTGFuZ3VhZ2VDaGFuZ2UuanMnO1xuaW1wb3J0IHsgT25QZXJtaXNzaW9uc0NoYW5nZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9PblBlcm1pc3Npb25zQ2hhbmdlLmpzJztcbmltcG9ydCB7IE9uUkNTdGF0dXMgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvT25SQ1N0YXR1cy5qcyc7XG5pbXBvcnQgeyBPblN5c3RlbUNhcGFiaWxpdHlVcGRhdGVkIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL09uU3lzdGVtQ2FwYWJpbGl0eVVwZGF0ZWQuanMnO1xuaW1wb3J0IHsgT25TeXN0ZW1SZXF1ZXN0IH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL09uU3lzdGVtUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBPblRCVENsaWVudFN0YXRlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL09uVEJUQ2xpZW50U3RhdGUuanMnO1xuaW1wb3J0IHsgT25Ub3VjaEV2ZW50IH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL09uVG91Y2hFdmVudC5qcyc7XG5pbXBvcnQgeyBPblZlaGljbGVEYXRhIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL09uVmVoaWNsZURhdGEuanMnO1xuaW1wb3J0IHsgT25XYXlQb2ludENoYW5nZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9PbldheVBvaW50Q2hhbmdlLmpzJztcbmltcG9ydCB7IFBlcmZvcm1BcHBTZXJ2aWNlSW50ZXJhY3Rpb24gfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvUGVyZm9ybUFwcFNlcnZpY2VJbnRlcmFjdGlvbi5qcyc7XG5pbXBvcnQgeyBQZXJmb3JtQXBwU2VydmljZUludGVyYWN0aW9uUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvUGVyZm9ybUFwcFNlcnZpY2VJbnRlcmFjdGlvblJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFBlcmZvcm1BdWRpb1Bhc3NUaHJ1IH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1BlcmZvcm1BdWRpb1Bhc3NUaHJ1LmpzJztcbmltcG9ydCB7IFBlcmZvcm1BdWRpb1Bhc3NUaHJ1UmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvUGVyZm9ybUF1ZGlvUGFzc1RocnVSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBQZXJmb3JtSW50ZXJhY3Rpb24gfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvUGVyZm9ybUludGVyYWN0aW9uLmpzJztcbmltcG9ydCB7IFBlcmZvcm1JbnRlcmFjdGlvblJlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1BlcmZvcm1JbnRlcmFjdGlvblJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFB1Ymxpc2hBcHBTZXJ2aWNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1B1Ymxpc2hBcHBTZXJ2aWNlLmpzJztcbmltcG9ydCB7IFB1Ymxpc2hBcHBTZXJ2aWNlUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvUHVibGlzaEFwcFNlcnZpY2VSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBQdXRGaWxlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1B1dEZpbGUuanMnO1xuaW1wb3J0IHsgUHV0RmlsZVJlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1B1dEZpbGVSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBSZWFkRElEIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1JlYWRESUQuanMnO1xuaW1wb3J0IHsgUmVhZERJRFJlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1JlYWRESURSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBSZWdpc3RlckFwcEludGVyZmFjZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9SZWdpc3RlckFwcEludGVyZmFjZS5qcyc7XG5pbXBvcnQgeyBSZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1JlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgUmVsZWFzZUludGVyaW9yVmVoaWNsZURhdGFNb2R1bGUgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvUmVsZWFzZUludGVyaW9yVmVoaWNsZURhdGFNb2R1bGUuanMnO1xuaW1wb3J0IHsgUmVsZWFzZUludGVyaW9yVmVoaWNsZURhdGFNb2R1bGVSZXNwb25zZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9SZWxlYXNlSW50ZXJpb3JWZWhpY2xlRGF0YU1vZHVsZVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFJlc2V0R2xvYmFsUHJvcGVydGllcyB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9SZXNldEdsb2JhbFByb3BlcnRpZXMuanMnO1xuaW1wb3J0IHsgUmVzZXRHbG9iYWxQcm9wZXJ0aWVzUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvUmVzZXRHbG9iYWxQcm9wZXJ0aWVzUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgU2Nyb2xsYWJsZU1lc3NhZ2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvU2Nyb2xsYWJsZU1lc3NhZ2UuanMnO1xuaW1wb3J0IHsgU2Nyb2xsYWJsZU1lc3NhZ2VSZXNwb25zZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9TY3JvbGxhYmxlTWVzc2FnZVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFNlbmRIYXB0aWNEYXRhIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1NlbmRIYXB0aWNEYXRhLmpzJztcbmltcG9ydCB7IFNlbmRIYXB0aWNEYXRhUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvU2VuZEhhcHRpY0RhdGFSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBTZW5kTG9jYXRpb24gfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvU2VuZExvY2F0aW9uLmpzJztcbmltcG9ydCB7IFNlbmRMb2NhdGlvblJlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1NlbmRMb2NhdGlvblJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFNldEFwcEljb24gfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvU2V0QXBwSWNvbi5qcyc7XG5pbXBvcnQgeyBTZXRBcHBJY29uUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvU2V0QXBwSWNvblJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFNldENsb3VkQXBwUHJvcGVydGllcyB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9TZXRDbG91ZEFwcFByb3BlcnRpZXMuanMnO1xuaW1wb3J0IHsgU2V0Q2xvdWRBcHBQcm9wZXJ0aWVzUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvU2V0Q2xvdWRBcHBQcm9wZXJ0aWVzUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgU2V0RGlzcGxheUxheW91dCB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9TZXREaXNwbGF5TGF5b3V0LmpzJztcbmltcG9ydCB7IFNldERpc3BsYXlMYXlvdXRSZXNwb25zZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9TZXREaXNwbGF5TGF5b3V0UmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgU2V0R2xvYmFsUHJvcGVydGllcyB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9TZXRHbG9iYWxQcm9wZXJ0aWVzLmpzJztcbmltcG9ydCB7IFNldEdsb2JhbFByb3BlcnRpZXNSZXNwb25zZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9TZXRHbG9iYWxQcm9wZXJ0aWVzUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgU2V0SW50ZXJpb3JWZWhpY2xlRGF0YSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9TZXRJbnRlcmlvclZlaGljbGVEYXRhLmpzJztcbmltcG9ydCB7IFNldEludGVyaW9yVmVoaWNsZURhdGFSZXNwb25zZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9TZXRJbnRlcmlvclZlaGljbGVEYXRhUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgU2V0TWVkaWFDbG9ja1RpbWVyIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1NldE1lZGlhQ2xvY2tUaW1lci5qcyc7XG5pbXBvcnQgeyBTZXRNZWRpYUNsb2NrVGltZXJSZXNwb25zZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9TZXRNZWRpYUNsb2NrVGltZXJSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBTaG93IH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1Nob3cuanMnO1xuaW1wb3J0IHsgU2hvd0FwcE1lbnUgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvU2hvd0FwcE1lbnUuanMnO1xuaW1wb3J0IHsgU2hvd0FwcE1lbnVSZXNwb25zZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9TaG93QXBwTWVudVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFNob3dDb25zdGFudFRCVCB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9TaG93Q29uc3RhbnRUQlQuanMnO1xuaW1wb3J0IHsgU2hvd0NvbnN0YW50VEJUUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvU2hvd0NvbnN0YW50VEJUUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgU2hvd1Jlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1Nob3dSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBTbGlkZXIgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvU2xpZGVyLmpzJztcbmltcG9ydCB7IFNsaWRlclJlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1NsaWRlclJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFNwZWFrIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1NwZWFrLmpzJztcbmltcG9ydCB7IFNwZWFrUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvU3BlYWtSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBTdWJzY3JpYmVCdXR0b24gfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvU3Vic2NyaWJlQnV0dG9uLmpzJztcbmltcG9ydCB7IFN1YnNjcmliZUJ1dHRvblJlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1N1YnNjcmliZUJ1dHRvblJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFN1YnNjcmliZVZlaGljbGVEYXRhIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1N1YnNjcmliZVZlaGljbGVEYXRhLmpzJztcbmltcG9ydCB7IFN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvU3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBTdWJzY3JpYmVXYXlQb2ludHMgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvU3Vic2NyaWJlV2F5UG9pbnRzLmpzJztcbmltcG9ydCB7IFN1YnNjcmliZVdheVBvaW50c1Jlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1N1YnNjcmliZVdheVBvaW50c1Jlc3BvbnNlLmpzJztcbmltcG9ydCB7IFN5c3RlbVJlcXVlc3QgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvU3lzdGVtUmVxdWVzdC5qcyc7XG5pbXBvcnQgeyBTeXN0ZW1SZXF1ZXN0UmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvU3lzdGVtUmVxdWVzdFJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFVucHVibGlzaEFwcFNlcnZpY2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvVW5wdWJsaXNoQXBwU2VydmljZS5qcyc7XG5pbXBvcnQgeyBVbnB1Ymxpc2hBcHBTZXJ2aWNlUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvVW5wdWJsaXNoQXBwU2VydmljZVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFVucmVnaXN0ZXJBcHBJbnRlcmZhY2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvVW5yZWdpc3RlckFwcEludGVyZmFjZS5qcyc7XG5pbXBvcnQgeyBVbnJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvVW5yZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlLmpzJztcbmltcG9ydCB7IFVuc3Vic2NyaWJlQnV0dG9uIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1Vuc3Vic2NyaWJlQnV0dG9uLmpzJztcbmltcG9ydCB7IFVuc3Vic2NyaWJlQnV0dG9uUmVzcG9uc2UgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvVW5zdWJzY3JpYmVCdXR0b25SZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBVbnN1YnNjcmliZVZlaGljbGVEYXRhIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1Vuc3Vic2NyaWJlVmVoaWNsZURhdGEuanMnO1xuaW1wb3J0IHsgVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1Vuc3Vic2NyaWJlVmVoaWNsZURhdGFSZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBVbnN1YnNjcmliZVdheVBvaW50cyB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9VbnN1YnNjcmliZVdheVBvaW50cy5qcyc7XG5pbXBvcnQgeyBVbnN1YnNjcmliZVdheVBvaW50c1Jlc3BvbnNlIH0gZnJvbSAnLi90bXAvcnBjL21lc3NhZ2VzL1Vuc3Vic2NyaWJlV2F5UG9pbnRzUmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgVXBkYXRlVHVybkxpc3QgfSBmcm9tICcuL3RtcC9ycGMvbWVzc2FnZXMvVXBkYXRlVHVybkxpc3QuanMnO1xuaW1wb3J0IHsgVXBkYXRlVHVybkxpc3RSZXNwb25zZSB9IGZyb20gJy4vdG1wL3JwYy9tZXNzYWdlcy9VcGRhdGVUdXJuTGlzdFJlc3BvbnNlLmpzJztcbmltcG9ydCB7IEFpcmJhZ1N0YXR1cyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0FpcmJhZ1N0YXR1cy5qcyc7XG5pbXBvcnQgeyBBcHBJbmZvIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvQXBwSW5mby5qcyc7XG5pbXBvcnQgeyBBcHBTZXJ2aWNlQ2FwYWJpbGl0eSB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0FwcFNlcnZpY2VDYXBhYmlsaXR5LmpzJztcbmltcG9ydCB7IEFwcFNlcnZpY2VEYXRhIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvQXBwU2VydmljZURhdGEuanMnO1xuaW1wb3J0IHsgQXBwU2VydmljZU1hbmlmZXN0IH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvQXBwU2VydmljZU1hbmlmZXN0LmpzJztcbmltcG9ydCB7IEFwcFNlcnZpY2VSZWNvcmQgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9BcHBTZXJ2aWNlUmVjb3JkLmpzJztcbmltcG9ydCB7IEFwcFNlcnZpY2VzQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvQXBwU2VydmljZXNDYXBhYmlsaXRpZXMuanMnO1xuaW1wb3J0IHsgQXVkaW9Db250cm9sQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvQXVkaW9Db250cm9sQ2FwYWJpbGl0aWVzLmpzJztcbmltcG9ydCB7IEF1ZGlvQ29udHJvbERhdGEgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9BdWRpb0NvbnRyb2xEYXRhLmpzJztcbmltcG9ydCB7IEF1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXMgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9BdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzLmpzJztcbmltcG9ydCB7IEJlbHRTdGF0dXMgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9CZWx0U3RhdHVzLmpzJztcbmltcG9ydCB7IEJvZHlJbmZvcm1hdGlvbiB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0JvZHlJbmZvcm1hdGlvbi5qcyc7XG5pbXBvcnQgeyBCdXR0b25DYXBhYmlsaXRpZXMgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9CdXR0b25DYXBhYmlsaXRpZXMuanMnO1xuaW1wb3J0IHsgQ2hvaWNlIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvQ2hvaWNlLmpzJztcbmltcG9ydCB7IENsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMuanMnO1xuaW1wb3J0IHsgQ2xpbWF0ZUNvbnRyb2xEYXRhIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvQ2xpbWF0ZUNvbnRyb2xEYXRhLmpzJztcbmltcG9ydCB7IENsb3VkQXBwUHJvcGVydGllcyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0Nsb3VkQXBwUHJvcGVydGllcy5qcyc7XG5pbXBvcnQgeyBDbHVzdGVyTW9kZVN0YXR1cyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0NsdXN0ZXJNb2RlU3RhdHVzLmpzJztcbmltcG9ydCB7IENvb3JkaW5hdGUgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9Db29yZGluYXRlLmpzJztcbmltcG9ydCB7IERJRFJlc3VsdCB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0RJRFJlc3VsdC5qcyc7XG5pbXBvcnQgeyBEYXRlVGltZSB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0RhdGVUaW1lLmpzJztcbmltcG9ydCB7IERldmljZUluZm8gfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9EZXZpY2VJbmZvLmpzJztcbmltcG9ydCB7IERldmljZVN0YXR1cyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0RldmljZVN0YXR1cy5qcyc7XG5pbXBvcnQgeyBEaXNwbGF5Q2FwYWJpbGl0aWVzIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvRGlzcGxheUNhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBEaXNwbGF5Q2FwYWJpbGl0eSB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0Rpc3BsYXlDYXBhYmlsaXR5LmpzJztcbmltcG9ydCB7IEVDYWxsSW5mbyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0VDYWxsSW5mby5qcyc7XG5pbXBvcnQgeyBFbWVyZ2VuY3lFdmVudCB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0VtZXJnZW5jeUV2ZW50LmpzJztcbmltcG9ydCB7IEVxdWFsaXplclNldHRpbmdzIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvRXF1YWxpemVyU2V0dGluZ3MuanMnO1xuaW1wb3J0IHsgRnVlbFJhbmdlIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvRnVlbFJhbmdlLmpzJztcbmltcG9ydCB7IEdQU0RhdGEgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9HUFNEYXRhLmpzJztcbmltcG9ydCB7IEdyaWQgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9HcmlkLmpzJztcbmltcG9ydCB7IEhNSUNhcGFiaWxpdGllcyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0hNSUNhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBITUlQZXJtaXNzaW9ucyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0hNSVBlcm1pc3Npb25zLmpzJztcbmltcG9ydCB7IEhNSVNldHRpbmdzQ29udHJvbENhcGFiaWxpdGllcyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0hNSVNldHRpbmdzQ29udHJvbENhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBITUlTZXR0aW5nc0NvbnRyb2xEYXRhIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvSE1JU2V0dGluZ3NDb250cm9sRGF0YS5qcyc7XG5pbXBvcnQgeyBIYXB0aWNSZWN0IH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvSGFwdGljUmVjdC5qcyc7XG5pbXBvcnQgeyBIZWFkTGFtcFN0YXR1cyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0hlYWRMYW1wU3RhdHVzLmpzJztcbmltcG9ydCB7IEltYWdlIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvSW1hZ2UuanMnO1xuaW1wb3J0IHsgSW1hZ2VGaWVsZCB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0ltYWdlRmllbGQuanMnO1xuaW1wb3J0IHsgSW1hZ2VSZXNvbHV0aW9uIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvSW1hZ2VSZXNvbHV0aW9uLmpzJztcbmltcG9ydCB7IEtleWJvYXJkUHJvcGVydGllcyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0tleWJvYXJkUHJvcGVydGllcy5qcyc7XG5pbXBvcnQgeyBMaWdodENhcGFiaWxpdGllcyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0xpZ2h0Q2FwYWJpbGl0aWVzLmpzJztcbmltcG9ydCB7IExpZ2h0Q29udHJvbENhcGFiaWxpdGllcyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL0xpZ2h0Q29udHJvbENhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBMaWdodENvbnRyb2xEYXRhIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvTGlnaHRDb250cm9sRGF0YS5qcyc7XG5pbXBvcnQgeyBMaWdodFN0YXRlIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvTGlnaHRTdGF0ZS5qcyc7XG5pbXBvcnQgeyBMb2NhdGlvbkRldGFpbHMgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9Mb2NhdGlvbkRldGFpbHMuanMnO1xuaW1wb3J0IHsgTWFzc2FnZUN1c2hpb25GaXJtbmVzcyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL01hc3NhZ2VDdXNoaW9uRmlybW5lc3MuanMnO1xuaW1wb3J0IHsgTWFzc2FnZU1vZGVEYXRhIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvTWFzc2FnZU1vZGVEYXRhLmpzJztcbmltcG9ydCB7IE1lZGlhU2VydmljZURhdGEgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9NZWRpYVNlcnZpY2VEYXRhLmpzJztcbmltcG9ydCB7IE1lZGlhU2VydmljZU1hbmlmZXN0IH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvTWVkaWFTZXJ2aWNlTWFuaWZlc3QuanMnO1xuaW1wb3J0IHsgTWVudVBhcmFtcyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL01lbnVQYXJhbXMuanMnO1xuaW1wb3J0IHsgTWV0YWRhdGFUYWdzIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvTWV0YWRhdGFUYWdzLmpzJztcbmltcG9ydCB7IE1vZHVsZURhdGEgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9Nb2R1bGVEYXRhLmpzJztcbmltcG9ydCB7IE1vZHVsZUluZm8gfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9Nb2R1bGVJbmZvLmpzJztcbmltcG9ydCB7IE15S2V5IH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvTXlLZXkuanMnO1xuaW1wb3J0IHsgTmF2aWdhdGlvbkNhcGFiaWxpdHkgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9OYXZpZ2F0aW9uQ2FwYWJpbGl0eS5qcyc7XG5pbXBvcnQgeyBOYXZpZ2F0aW9uSW5zdHJ1Y3Rpb24gfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9OYXZpZ2F0aW9uSW5zdHJ1Y3Rpb24uanMnO1xuaW1wb3J0IHsgTmF2aWdhdGlvblNlcnZpY2VEYXRhIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvTmF2aWdhdGlvblNlcnZpY2VEYXRhLmpzJztcbmltcG9ydCB7IE5hdmlnYXRpb25TZXJ2aWNlTWFuaWZlc3QgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9OYXZpZ2F0aW9uU2VydmljZU1hbmlmZXN0LmpzJztcbmltcG9ydCB7IE9BU0lTQWRkcmVzcyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL09BU0lTQWRkcmVzcy5qcyc7XG5pbXBvcnQgeyBQYXJhbWV0ZXJQZXJtaXNzaW9ucyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1BhcmFtZXRlclBlcm1pc3Npb25zLmpzJztcbmltcG9ydCB7IFBlcm1pc3Npb25JdGVtIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvUGVybWlzc2lvbkl0ZW0uanMnO1xuaW1wb3J0IHsgUGhvbmVDYXBhYmlsaXR5IH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvUGhvbmVDYXBhYmlsaXR5LmpzJztcbmltcG9ydCB7IFByZXNldEJhbmtDYXBhYmlsaXRpZXMgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9QcmVzZXRCYW5rQ2FwYWJpbGl0aWVzLmpzJztcbmltcG9ydCB7IFJHQkNvbG9yIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvUkdCQ29sb3IuanMnO1xuaW1wb3J0IHsgUmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvUmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzLmpzJztcbmltcG9ydCB7IFJhZGlvQ29udHJvbERhdGEgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9SYWRpb0NvbnRyb2xEYXRhLmpzJztcbmltcG9ydCB7IFJkc0RhdGEgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9SZHNEYXRhLmpzJztcbmltcG9ydCB7IFJlY3RhbmdsZSB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1JlY3RhbmdsZS5qcyc7XG5pbXBvcnQgeyBSZW1vdGVDb250cm9sQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvUmVtb3RlQ29udHJvbENhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBTY3JlZW5QYXJhbXMgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9TY3JlZW5QYXJhbXMuanMnO1xuaW1wb3J0IHsgU2RsTXNnVmVyc2lvbiB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1NkbE1zZ1ZlcnNpb24uanMnO1xuaW1wb3J0IHsgU2VhdENvbnRyb2xDYXBhYmlsaXRpZXMgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9TZWF0Q29udHJvbENhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBTZWF0Q29udHJvbERhdGEgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9TZWF0Q29udHJvbERhdGEuanMnO1xuaW1wb3J0IHsgU2VhdExvY2F0aW9uIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvU2VhdExvY2F0aW9uLmpzJztcbmltcG9ydCB7IFNlYXRMb2NhdGlvbkNhcGFiaWxpdHkgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9TZWF0TG9jYXRpb25DYXBhYmlsaXR5LmpzJztcbmltcG9ydCB7IFNlYXRNZW1vcnlBY3Rpb24gfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9TZWF0TWVtb3J5QWN0aW9uLmpzJztcbmltcG9ydCB7IFNpbmdsZVRpcmVTdGF0dXMgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9TaW5nbGVUaXJlU3RhdHVzLmpzJztcbmltcG9ydCB7IFNpc0RhdGEgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9TaXNEYXRhLmpzJztcbmltcG9ydCB7IFNvZnRCdXR0b24gfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9Tb2Z0QnV0dG9uLmpzJztcbmltcG9ydCB7IFNvZnRCdXR0b25DYXBhYmlsaXRpZXMgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9Tb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzLmpzJztcbmltcG9ydCB7IFN0YXJ0VGltZSB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1N0YXJ0VGltZS5qcyc7XG5pbXBvcnQgeyBTdGF0aW9uSUROdW1iZXIgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9TdGF0aW9uSUROdW1iZXIuanMnO1xuaW1wb3J0IHsgU3lzdGVtQ2FwYWJpbGl0eSB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1N5c3RlbUNhcGFiaWxpdHkuanMnO1xuaW1wb3J0IHsgVFRTQ2h1bmsgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9UVFNDaHVuay5qcyc7XG5pbXBvcnQgeyBUZW1wZXJhdHVyZSB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1RlbXBlcmF0dXJlLmpzJztcbmltcG9ydCB7IFRlbXBsYXRlQ29sb3JTY2hlbWUgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9UZW1wbGF0ZUNvbG9yU2NoZW1lLmpzJztcbmltcG9ydCB7IFRlbXBsYXRlQ29uZmlndXJhdGlvbiB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1RlbXBsYXRlQ29uZmlndXJhdGlvbi5qcyc7XG5pbXBvcnQgeyBUZXh0RmllbGQgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9UZXh0RmllbGQuanMnO1xuaW1wb3J0IHsgVGlyZVN0YXR1cyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1RpcmVTdGF0dXMuanMnO1xuaW1wb3J0IHsgVG91Y2hDb29yZCB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1RvdWNoQ29vcmQuanMnO1xuaW1wb3J0IHsgVG91Y2hFdmVudCB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1RvdWNoRXZlbnQuanMnO1xuaW1wb3J0IHsgVG91Y2hFdmVudENhcGFiaWxpdGllcyB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1RvdWNoRXZlbnRDYXBhYmlsaXRpZXMuanMnO1xuaW1wb3J0IHsgVHVybiB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1R1cm4uanMnO1xuaW1wb3J0IHsgVmVoaWNsZURhdGFSZXN1bHQgfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9WZWhpY2xlRGF0YVJlc3VsdC5qcyc7XG5pbXBvcnQgeyBWZWhpY2xlVHlwZSB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1ZlaGljbGVUeXBlLmpzJztcbmltcG9ydCB7IFZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eSB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1ZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eS5qcyc7XG5pbXBvcnQgeyBWaWRlb1N0cmVhbWluZ0Zvcm1hdCB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1ZpZGVvU3RyZWFtaW5nRm9ybWF0LmpzJztcbmltcG9ydCB7IFZySGVscEl0ZW0gfSBmcm9tICcuL3RtcC9ycGMvc3RydWN0cy9WckhlbHBJdGVtLmpzJztcbmltcG9ydCB7IFdlYXRoZXJBbGVydCB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1dlYXRoZXJBbGVydC5qcyc7XG5pbXBvcnQgeyBXZWF0aGVyRGF0YSB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1dlYXRoZXJEYXRhLmpzJztcbmltcG9ydCB7IFdlYXRoZXJTZXJ2aWNlRGF0YSB9IGZyb20gJy4vdG1wL3JwYy9zdHJ1Y3RzL1dlYXRoZXJTZXJ2aWNlRGF0YS5qcyc7XG5pbXBvcnQgeyBXZWF0aGVyU2VydmljZU1hbmlmZXN0IH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvV2VhdGhlclNlcnZpY2VNYW5pZmVzdC5qcyc7XG5pbXBvcnQgeyBXaW5kb3dDYXBhYmlsaXR5IH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvV2luZG93Q2FwYWJpbGl0eS5qcyc7XG5pbXBvcnQgeyBXaW5kb3dUeXBlQ2FwYWJpbGl0aWVzIH0gZnJvbSAnLi90bXAvcnBjL3N0cnVjdHMvV2luZG93VHlwZUNhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBTZGxTZXJ2aWNlTGlzdGVuZXIgfSBmcm9tICcuL3RtcC9zZXNzaW9uL1NkbFNlcnZpY2VMaXN0ZW5lci5qcyc7XG5pbXBvcnQgeyBTZGxTZXNzaW9uIH0gZnJvbSAnLi90bXAvc2Vzc2lvbi9TZGxTZXNzaW9uLmpzJztcbmltcG9ydCB7IFNkbFNlc3Npb25MaXN0ZW5lciB9IGZyb20gJy4vdG1wL3Nlc3Npb24vU2RsU2Vzc2lvbkxpc3RlbmVyLmpzJztcbmltcG9ydCB7IFNlcnZpY2VMaXN0ZW5lck1hcCB9IGZyb20gJy4vdG1wL3Nlc3Npb24vU2VydmljZUxpc3RlbmVyTWFwLmpzJztcbmltcG9ydCB7IFZpZGVvU3RyZWFtaW5nUGFyYW1ldGVycyB9IGZyb20gJy4vdG1wL3N0cmVhbWluZy92aWRlby9WaWRlb1N0cmVhbWluZ1BhcmFtZXRlcnMuanMnO1xuaW1wb3J0IHsgQ3VzdG9tVHJhbnNwb3J0IH0gZnJvbSAnLi90bXAvdHJhbnNwb3J0L0N1c3RvbVRyYW5zcG9ydC5qcyc7XG5pbXBvcnQgeyBDdXN0b21UcmFuc3BvcnRDb25maWcgfSBmcm9tICcuL3RtcC90cmFuc3BvcnQvQ3VzdG9tVHJhbnNwb3J0Q29uZmlnLmpzJztcbmltcG9ydCB7IFNkbFBzbSB9IGZyb20gJy4vdG1wL3RyYW5zcG9ydC9TZGxQc20uanMnO1xuaW1wb3J0IHsgU3NsQ29uZmlnIH0gZnJvbSAnLi90bXAvdHJhbnNwb3J0L1NzbENvbmZpZy5qcyc7XG5pbXBvcnQgeyBUcmFuc3BvcnRCYXNlIH0gZnJvbSAnLi90bXAvdHJhbnNwb3J0L1RyYW5zcG9ydEJhc2UuanMnO1xuaW1wb3J0IHsgVHJhbnNwb3J0Q2FsbGJhY2sgfSBmcm9tICcuL3RtcC90cmFuc3BvcnQvVHJhbnNwb3J0Q2FsbGJhY2suanMnO1xuaW1wb3J0IHsgVHJhbnNwb3J0Q29uZmlnQmFzZSB9IGZyb20gJy4vdG1wL3RyYW5zcG9ydC9UcmFuc3BvcnRDb25maWdCYXNlLmpzJztcbmltcG9ydCB7IFRyYW5zcG9ydExpc3RlbmVyIH0gZnJvbSAnLi90bXAvdHJhbnNwb3J0L1RyYW5zcG9ydExpc3RlbmVyLmpzJztcbmltcG9ydCB7IFRyYW5zcG9ydE1hbmFnZXIgfSBmcm9tICcuL3RtcC90cmFuc3BvcnQvVHJhbnNwb3J0TWFuYWdlci5qcyc7XG5pbXBvcnQgeyBUcmFuc3BvcnRNYW5hZ2VyQmFzZSB9IGZyb20gJy4vdG1wL3RyYW5zcG9ydC9UcmFuc3BvcnRNYW5hZ2VyQmFzZS5qcyc7XG5pbXBvcnQgeyBXZWJTb2NrZXRDbGllbnQgfSBmcm9tICcuL3RtcC90cmFuc3BvcnQvV2ViU29ja2V0Q2xpZW50LmpzJztcbmltcG9ydCB7IFdlYlNvY2tldENsaWVudENvbmZpZyB9IGZyb20gJy4vdG1wL3RyYW5zcG9ydC9XZWJTb2NrZXRDbGllbnRDb25maWcuanMnO1xuaW1wb3J0IHsgVHJhbnNwb3J0VHlwZSB9IGZyb20gJy4vdG1wL3RyYW5zcG9ydC9lbnVtcy9UcmFuc3BvcnRUeXBlLmpzJztcbmltcG9ydCB7IFRyYW5zcG9ydFJlY29yZCB9IGZyb20gJy4vdG1wL3RyYW5zcG9ydC91dGlsL1RyYW5zcG9ydFJlY29yZC5qcyc7XG5pbXBvcnQgeyBBcnJheVRvb2xzIH0gZnJvbSAnLi90bXAvdXRpbC9BcnJheVRvb2xzLmpzJztcbmltcG9ydCB7IEJpdENvbnZlcnRlciB9IGZyb20gJy4vdG1wL3V0aWwvQml0Q29udmVydGVyLmpzJztcbmltcG9ydCB7IEJzb24gfSBmcm9tICcuL3RtcC91dGlsL0Jzb24uanMnO1xuaW1wb3J0IHsgRW51bSB9IGZyb20gJy4vdG1wL3V0aWwvRW51bS5qcyc7XG5pbXBvcnQgeyBKc29uUnBjTWFyc2hhbGxlciB9IGZyb20gJy4vdG1wL3V0aWwvSnNvblJwY01hcnNoYWxsZXIuanMnO1xuaW1wb3J0IHsgVGV4dEVuY29kZXIgfSBmcm9tICcuL3RtcC91dGlsL1RleHRFbmNvZGVyLmpzJztcbmltcG9ydCB7IFZlcnNpb24gfSBmcm9tICcuL3RtcC91dGlsL1ZlcnNpb24uanMnO1xuaW1wb3J0IHsgV2ViU29ja2V0U2VydmVyIH0gZnJvbSAnLi90bXAvdHJhbnNwb3J0L1dlYlNvY2tldFNlcnZlci5qcyc7XG5pbXBvcnQgeyBXZWJTb2NrZXRTZXJ2ZXJDb25maWcgfSBmcm9tICcuL3RtcC90cmFuc3BvcnQvV2ViU29ja2V0U2VydmVyQ29uZmlnLmpzJztcblxuY29uc3QgU0RMID0ge1xuICAgIG1hbmFnZXI6IHtcbiAgICAgICAgQXBwQ29uZmlnLFxuICAgICAgICBsaWZlY3ljbGU6IHtcbiAgICAgICAgICAgIExpZmVjeWNsZUxpc3RlbmVyLFxuICAgICAgICAgICAgTGlmZWN5Y2xlTWFuYWdlcixcbiAgICAgICAgfSxcbiAgICB9LFxuICAgIHByb3RvY29sOiB7XG4gICAgICAgIEJpbmFyeUZyYW1lSGVhZGVyLFxuICAgICAgICBNZXNzYWdlRnJhbWVBc3NlbWJsZXIsXG4gICAgICAgIE1lc3NhZ2VGcmFtZURpc2Fzc2VtYmxlcixcbiAgICAgICAgU2RsUGFja2V0LFxuICAgICAgICBTZGxQYWNrZXRGYWN0b3J5LFxuICAgICAgICBTZGxQcm90b2NvbCxcbiAgICAgICAgU2RsUHJvdG9jb2xCYXNlLFxuICAgICAgICBTZGxQcm90b2NvbExpc3RlbmVyLFxuICAgICAgICBlbnVtczoge1xuICAgICAgICAgICAgQ29udHJvbEZyYW1lVGFncyxcbiAgICAgICAgICAgIEZyYW1lVHlwZSxcbiAgICAgICAgICAgIFNlcnZpY2VUeXBlLFxuICAgICAgICB9LFxuICAgIH0sXG4gICAgcnBjOiB7XG4gICAgICAgIFJwY0NyZWF0b3IsXG4gICAgICAgIFJwY0xpc3RlbmVyLFxuICAgICAgICBScGNNZXNzYWdlLFxuICAgICAgICBScGNOb3RpZmljYXRpb24sXG4gICAgICAgIFJwY1JlcXVlc3QsXG4gICAgICAgIFJwY1Jlc3BvbnNlLFxuICAgICAgICBScGNTdHJ1Y3QsXG4gICAgICAgIGVudW1zOiB7XG4gICAgICAgICAgICBBbWJpZW50TGlnaHRTdGF0dXMsXG4gICAgICAgICAgICBBcHBITUlUeXBlLFxuICAgICAgICAgICAgQXBwSW50ZXJmYWNlVW5yZWdpc3RlcmVkUmVhc29uLFxuICAgICAgICAgICAgQXBwU2VydmljZVR5cGUsXG4gICAgICAgICAgICBBdWRpb1N0cmVhbWluZ0luZGljYXRvcixcbiAgICAgICAgICAgIEF1ZGlvU3RyZWFtaW5nU3RhdGUsXG4gICAgICAgICAgICBBdWRpb1R5cGUsXG4gICAgICAgICAgICBCaXRzUGVyU2FtcGxlLFxuICAgICAgICAgICAgQnV0dG9uRXZlbnRNb2RlLFxuICAgICAgICAgICAgQnV0dG9uTmFtZSxcbiAgICAgICAgICAgIEJ1dHRvblByZXNzTW9kZSxcbiAgICAgICAgICAgIENhck1vZGVTdGF0dXMsXG4gICAgICAgICAgICBDaGFyYWN0ZXJTZXQsXG4gICAgICAgICAgICBDb21wYXNzRGlyZWN0aW9uLFxuICAgICAgICAgICAgQ29tcG9uZW50Vm9sdW1lU3RhdHVzLFxuICAgICAgICAgICAgRGVmcm9zdFpvbmUsXG4gICAgICAgICAgICBEZWxpdmVyeU1vZGUsXG4gICAgICAgICAgICBEZXZpY2VMZXZlbFN0YXR1cyxcbiAgICAgICAgICAgIERpbWVuc2lvbixcbiAgICAgICAgICAgIERpcmVjdGlvbixcbiAgICAgICAgICAgIERpc3BsYXlNb2RlLFxuICAgICAgICAgICAgRGlzcGxheVR5cGUsXG4gICAgICAgICAgICBEaXN0YW5jZVVuaXQsXG4gICAgICAgICAgICBEcml2ZXJEaXN0cmFjdGlvblN0YXRlLFxuICAgICAgICAgICAgRUNhbGxDb25maXJtYXRpb25TdGF0dXMsXG4gICAgICAgICAgICBFbGVjdHJvbmljUGFya0JyYWtlU3RhdHVzLFxuICAgICAgICAgICAgRW1lcmdlbmN5RXZlbnRUeXBlLFxuICAgICAgICAgICAgRmlsZVR5cGUsXG4gICAgICAgICAgICBGdWVsQ3V0b2ZmU3RhdHVzLFxuICAgICAgICAgICAgRnVlbFR5cGUsXG4gICAgICAgICAgICBGdW5jdGlvbklELFxuICAgICAgICAgICAgR2xvYmFsUHJvcGVydHksXG4gICAgICAgICAgICBITUlMZXZlbCxcbiAgICAgICAgICAgIEhtaVpvbmVDYXBhYmlsaXRpZXMsXG4gICAgICAgICAgICBIeWJyaWRBcHBQcmVmZXJlbmNlLFxuICAgICAgICAgICAgSWduaXRpb25TdGFibGVTdGF0dXMsXG4gICAgICAgICAgICBJZ25pdGlvblN0YXR1cyxcbiAgICAgICAgICAgIEltYWdlRmllbGROYW1lLFxuICAgICAgICAgICAgSW1hZ2VUeXBlLFxuICAgICAgICAgICAgSW50ZXJhY3Rpb25Nb2RlLFxuICAgICAgICAgICAgS2V5Ym9hcmRFdmVudCxcbiAgICAgICAgICAgIEtleWJvYXJkTGF5b3V0LFxuICAgICAgICAgICAgS2V5cHJlc3NNb2RlLFxuICAgICAgICAgICAgTGFuZ3VhZ2UsXG4gICAgICAgICAgICBMYXlvdXRNb2RlLFxuICAgICAgICAgICAgTGlnaHROYW1lLFxuICAgICAgICAgICAgTGlnaHRTdGF0dXMsXG4gICAgICAgICAgICBNYWludGVuYW5jZU1vZGVTdGF0dXMsXG4gICAgICAgICAgICBNYXNzYWdlQ3VzaGlvbixcbiAgICAgICAgICAgIE1hc3NhZ2VNb2RlLFxuICAgICAgICAgICAgTWFzc2FnZVpvbmUsXG4gICAgICAgICAgICBNZWRpYUNsb2NrRm9ybWF0LFxuICAgICAgICAgICAgTWVkaWFUeXBlLFxuICAgICAgICAgICAgTWVudUxheW91dCxcbiAgICAgICAgICAgIE1ldGFkYXRhVHlwZSxcbiAgICAgICAgICAgIE1vZHVsZVR5cGUsXG4gICAgICAgICAgICBOYXZpZ2F0aW9uQWN0aW9uLFxuICAgICAgICAgICAgTmF2aWdhdGlvbkp1bmN0aW9uLFxuICAgICAgICAgICAgUFJOREwsXG4gICAgICAgICAgICBQZXJtaXNzaW9uU3RhdHVzLFxuICAgICAgICAgICAgUG93ZXJNb2RlUXVhbGlmaWNhdGlvblN0YXR1cyxcbiAgICAgICAgICAgIFBvd2VyTW9kZVN0YXR1cyxcbiAgICAgICAgICAgIFByZWRlZmluZWRMYXlvdXQsXG4gICAgICAgICAgICBQcmVkZWZpbmVkV2luZG93cyxcbiAgICAgICAgICAgIFByZXJlY29yZGVkU3BlZWNoLFxuICAgICAgICAgICAgUHJpbWFyeUF1ZGlvU291cmNlLFxuICAgICAgICAgICAgUmFkaW9CYW5kLFxuICAgICAgICAgICAgUmFkaW9TdGF0ZSxcbiAgICAgICAgICAgIFJlcXVlc3RUeXBlLFxuICAgICAgICAgICAgUmVzdWx0LFxuICAgICAgICAgICAgUnBjVHlwZSxcbiAgICAgICAgICAgIFNhbXBsaW5nUmF0ZSxcbiAgICAgICAgICAgIFNlYXRNZW1vcnlBY3Rpb25UeXBlLFxuICAgICAgICAgICAgU2VydmljZVVwZGF0ZVJlYXNvbixcbiAgICAgICAgICAgIFNvZnRCdXR0b25UeXBlLFxuICAgICAgICAgICAgU3BlZWNoQ2FwYWJpbGl0aWVzLFxuICAgICAgICAgICAgU3VwcG9ydGVkU2VhdCxcbiAgICAgICAgICAgIFN5c3RlbUFjdGlvbixcbiAgICAgICAgICAgIFN5c3RlbUNhcGFiaWxpdHlUeXBlLFxuICAgICAgICAgICAgU3lzdGVtQ29udGV4dCxcbiAgICAgICAgICAgIFRCVFN0YXRlLFxuICAgICAgICAgICAgVFBNUyxcbiAgICAgICAgICAgIFRlbXBlcmF0dXJlVW5pdCxcbiAgICAgICAgICAgIFRleHRBbGlnbm1lbnQsXG4gICAgICAgICAgICBUZXh0RmllbGROYW1lLFxuICAgICAgICAgICAgVGltZXJNb2RlLFxuICAgICAgICAgICAgVG91Y2hUeXBlLFxuICAgICAgICAgICAgVHJpZ2dlclNvdXJjZSxcbiAgICAgICAgICAgIFR1cm5TaWduYWwsXG4gICAgICAgICAgICBVcGRhdGVNb2RlLFxuICAgICAgICAgICAgVmVoaWNsZURhdGFBY3RpdmVTdGF0dXMsXG4gICAgICAgICAgICBWZWhpY2xlRGF0YUV2ZW50U3RhdHVzLFxuICAgICAgICAgICAgVmVoaWNsZURhdGFOb3RpZmljYXRpb25TdGF0dXMsXG4gICAgICAgICAgICBWZWhpY2xlRGF0YVJlc3VsdENvZGUsXG4gICAgICAgICAgICBWZWhpY2xlRGF0YVN0YXR1cyxcbiAgICAgICAgICAgIFZlaGljbGVEYXRhVHlwZSxcbiAgICAgICAgICAgIFZlbnRpbGF0aW9uTW9kZSxcbiAgICAgICAgICAgIFZpZGVvU3RyZWFtaW5nQ29kZWMsXG4gICAgICAgICAgICBWaWRlb1N0cmVhbWluZ1Byb3RvY29sLFxuICAgICAgICAgICAgVmlkZW9TdHJlYW1pbmdTdGF0ZSxcbiAgICAgICAgICAgIFZyQ2FwYWJpbGl0aWVzLFxuICAgICAgICAgICAgV2FybmluZ0xpZ2h0U3RhdHVzLFxuICAgICAgICAgICAgV2F5UG9pbnRUeXBlLFxuICAgICAgICAgICAgV2luZG93VHlwZSxcbiAgICAgICAgICAgIFdpcGVyU3RhdHVzLFxuICAgICAgICAgICAgbWVzc2FnZVR5cGUsXG4gICAgICAgIH0sXG4gICAgICAgIG1lc3NhZ2VzOiB7XG4gICAgICAgICAgICBBZGRDb21tYW5kLFxuICAgICAgICAgICAgQWRkQ29tbWFuZFJlc3BvbnNlLFxuICAgICAgICAgICAgQWRkU3ViTWVudSxcbiAgICAgICAgICAgIEFkZFN1Yk1lbnVSZXNwb25zZSxcbiAgICAgICAgICAgIEFsZXJ0LFxuICAgICAgICAgICAgQWxlcnRNYW5ldXZlcixcbiAgICAgICAgICAgIEFsZXJ0TWFuZXV2ZXJSZXNwb25zZSxcbiAgICAgICAgICAgIEFsZXJ0UmVzcG9uc2UsXG4gICAgICAgICAgICBCdXR0b25QcmVzcyxcbiAgICAgICAgICAgIEJ1dHRvblByZXNzUmVzcG9uc2UsXG4gICAgICAgICAgICBDYW5jZWxJbnRlcmFjdGlvbixcbiAgICAgICAgICAgIENhbmNlbEludGVyYWN0aW9uUmVzcG9uc2UsXG4gICAgICAgICAgICBDaGFuZ2VSZWdpc3RyYXRpb24sXG4gICAgICAgICAgICBDaGFuZ2VSZWdpc3RyYXRpb25SZXNwb25zZSxcbiAgICAgICAgICAgIENsb3NlQXBwbGljYXRpb24sXG4gICAgICAgICAgICBDbG9zZUFwcGxpY2F0aW9uUmVzcG9uc2UsXG4gICAgICAgICAgICBDcmVhdGVJbnRlcmFjdGlvbkNob2ljZVNldCxcbiAgICAgICAgICAgIENyZWF0ZUludGVyYWN0aW9uQ2hvaWNlU2V0UmVzcG9uc2UsXG4gICAgICAgICAgICBDcmVhdGVXaW5kb3csXG4gICAgICAgICAgICBDcmVhdGVXaW5kb3dSZXNwb25zZSxcbiAgICAgICAgICAgIERlbGV0ZUNvbW1hbmQsXG4gICAgICAgICAgICBEZWxldGVDb21tYW5kUmVzcG9uc2UsXG4gICAgICAgICAgICBEZWxldGVGaWxlLFxuICAgICAgICAgICAgRGVsZXRlRmlsZVJlc3BvbnNlLFxuICAgICAgICAgICAgRGVsZXRlSW50ZXJhY3Rpb25DaG9pY2VTZXQsXG4gICAgICAgICAgICBEZWxldGVJbnRlcmFjdGlvbkNob2ljZVNldFJlc3BvbnNlLFxuICAgICAgICAgICAgRGVsZXRlU3ViTWVudSxcbiAgICAgICAgICAgIERlbGV0ZVN1Yk1lbnVSZXNwb25zZSxcbiAgICAgICAgICAgIERlbGV0ZVdpbmRvdyxcbiAgICAgICAgICAgIERlbGV0ZVdpbmRvd1Jlc3BvbnNlLFxuICAgICAgICAgICAgRGlhZ25vc3RpY01lc3NhZ2UsXG4gICAgICAgICAgICBEaWFnbm9zdGljTWVzc2FnZVJlc3BvbnNlLFxuICAgICAgICAgICAgRGlhbE51bWJlcixcbiAgICAgICAgICAgIERpYWxOdW1iZXJSZXNwb25zZSxcbiAgICAgICAgICAgIEVuY29kZWRTeW5jUERhdGEsXG4gICAgICAgICAgICBFbmNvZGVkU3luY1BEYXRhUmVzcG9uc2UsXG4gICAgICAgICAgICBFbmRBdWRpb1Bhc3NUaHJ1LFxuICAgICAgICAgICAgRW5kQXVkaW9QYXNzVGhydVJlc3BvbnNlLFxuICAgICAgICAgICAgR2VuZXJpY1Jlc3BvbnNlUmVzcG9uc2UsXG4gICAgICAgICAgICBHZXRBcHBTZXJ2aWNlRGF0YSxcbiAgICAgICAgICAgIEdldEFwcFNlcnZpY2VEYXRhUmVzcG9uc2UsXG4gICAgICAgICAgICBHZXRDbG91ZEFwcFByb3BlcnRpZXMsXG4gICAgICAgICAgICBHZXRDbG91ZEFwcFByb3BlcnRpZXNSZXNwb25zZSxcbiAgICAgICAgICAgIEdldERUQ3MsXG4gICAgICAgICAgICBHZXREVENzUmVzcG9uc2UsXG4gICAgICAgICAgICBHZXRGaWxlLFxuICAgICAgICAgICAgR2V0RmlsZVJlc3BvbnNlLFxuICAgICAgICAgICAgR2V0SW50ZXJpb3JWZWhpY2xlRGF0YSxcbiAgICAgICAgICAgIEdldEludGVyaW9yVmVoaWNsZURhdGFDb25zZW50LFxuICAgICAgICAgICAgR2V0SW50ZXJpb3JWZWhpY2xlRGF0YUNvbnNlbnRSZXNwb25zZSxcbiAgICAgICAgICAgIEdldEludGVyaW9yVmVoaWNsZURhdGFSZXNwb25zZSxcbiAgICAgICAgICAgIEdldFN5c3RlbUNhcGFiaWxpdHksXG4gICAgICAgICAgICBHZXRTeXN0ZW1DYXBhYmlsaXR5UmVzcG9uc2UsXG4gICAgICAgICAgICBHZXRWZWhpY2xlRGF0YSxcbiAgICAgICAgICAgIEdldFZlaGljbGVEYXRhUmVzcG9uc2UsXG4gICAgICAgICAgICBHZXRXYXlQb2ludHMsXG4gICAgICAgICAgICBHZXRXYXlQb2ludHNSZXNwb25zZSxcbiAgICAgICAgICAgIExpc3RGaWxlcyxcbiAgICAgICAgICAgIExpc3RGaWxlc1Jlc3BvbnNlLFxuICAgICAgICAgICAgT25BcHBJbnRlcmZhY2VVbnJlZ2lzdGVyZWQsXG4gICAgICAgICAgICBPbkFwcFNlcnZpY2VEYXRhLFxuICAgICAgICAgICAgT25BdWRpb1Bhc3NUaHJ1LFxuICAgICAgICAgICAgT25CdXR0b25FdmVudCxcbiAgICAgICAgICAgIE9uQnV0dG9uUHJlc3MsXG4gICAgICAgICAgICBPbkNvbW1hbmQsXG4gICAgICAgICAgICBPbkRyaXZlckRpc3RyYWN0aW9uLFxuICAgICAgICAgICAgT25FbmNvZGVkU3luY1BEYXRhLFxuICAgICAgICAgICAgT25ITUlTdGF0dXMsXG4gICAgICAgICAgICBPbkhhc2hDaGFuZ2UsXG4gICAgICAgICAgICBPbkludGVyaW9yVmVoaWNsZURhdGEsXG4gICAgICAgICAgICBPbktleWJvYXJkSW5wdXQsXG4gICAgICAgICAgICBPbkxhbmd1YWdlQ2hhbmdlLFxuICAgICAgICAgICAgT25QZXJtaXNzaW9uc0NoYW5nZSxcbiAgICAgICAgICAgIE9uUkNTdGF0dXMsXG4gICAgICAgICAgICBPblN5c3RlbUNhcGFiaWxpdHlVcGRhdGVkLFxuICAgICAgICAgICAgT25TeXN0ZW1SZXF1ZXN0LFxuICAgICAgICAgICAgT25UQlRDbGllbnRTdGF0ZSxcbiAgICAgICAgICAgIE9uVG91Y2hFdmVudCxcbiAgICAgICAgICAgIE9uVmVoaWNsZURhdGEsXG4gICAgICAgICAgICBPbldheVBvaW50Q2hhbmdlLFxuICAgICAgICAgICAgUGVyZm9ybUFwcFNlcnZpY2VJbnRlcmFjdGlvbixcbiAgICAgICAgICAgIFBlcmZvcm1BcHBTZXJ2aWNlSW50ZXJhY3Rpb25SZXNwb25zZSxcbiAgICAgICAgICAgIFBlcmZvcm1BdWRpb1Bhc3NUaHJ1LFxuICAgICAgICAgICAgUGVyZm9ybUF1ZGlvUGFzc1RocnVSZXNwb25zZSxcbiAgICAgICAgICAgIFBlcmZvcm1JbnRlcmFjdGlvbixcbiAgICAgICAgICAgIFBlcmZvcm1JbnRlcmFjdGlvblJlc3BvbnNlLFxuICAgICAgICAgICAgUHVibGlzaEFwcFNlcnZpY2UsXG4gICAgICAgICAgICBQdWJsaXNoQXBwU2VydmljZVJlc3BvbnNlLFxuICAgICAgICAgICAgUHV0RmlsZSxcbiAgICAgICAgICAgIFB1dEZpbGVSZXNwb25zZSxcbiAgICAgICAgICAgIFJlYWRESUQsXG4gICAgICAgICAgICBSZWFkRElEUmVzcG9uc2UsXG4gICAgICAgICAgICBSZWdpc3RlckFwcEludGVyZmFjZSxcbiAgICAgICAgICAgIFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UsXG4gICAgICAgICAgICBSZWxlYXNlSW50ZXJpb3JWZWhpY2xlRGF0YU1vZHVsZSxcbiAgICAgICAgICAgIFJlbGVhc2VJbnRlcmlvclZlaGljbGVEYXRhTW9kdWxlUmVzcG9uc2UsXG4gICAgICAgICAgICBSZXNldEdsb2JhbFByb3BlcnRpZXMsXG4gICAgICAgICAgICBSZXNldEdsb2JhbFByb3BlcnRpZXNSZXNwb25zZSxcbiAgICAgICAgICAgIFNjcm9sbGFibGVNZXNzYWdlLFxuICAgICAgICAgICAgU2Nyb2xsYWJsZU1lc3NhZ2VSZXNwb25zZSxcbiAgICAgICAgICAgIFNlbmRIYXB0aWNEYXRhLFxuICAgICAgICAgICAgU2VuZEhhcHRpY0RhdGFSZXNwb25zZSxcbiAgICAgICAgICAgIFNlbmRMb2NhdGlvbixcbiAgICAgICAgICAgIFNlbmRMb2NhdGlvblJlc3BvbnNlLFxuICAgICAgICAgICAgU2V0QXBwSWNvbixcbiAgICAgICAgICAgIFNldEFwcEljb25SZXNwb25zZSxcbiAgICAgICAgICAgIFNldENsb3VkQXBwUHJvcGVydGllcyxcbiAgICAgICAgICAgIFNldENsb3VkQXBwUHJvcGVydGllc1Jlc3BvbnNlLFxuICAgICAgICAgICAgU2V0RGlzcGxheUxheW91dCxcbiAgICAgICAgICAgIFNldERpc3BsYXlMYXlvdXRSZXNwb25zZSxcbiAgICAgICAgICAgIFNldEdsb2JhbFByb3BlcnRpZXMsXG4gICAgICAgICAgICBTZXRHbG9iYWxQcm9wZXJ0aWVzUmVzcG9uc2UsXG4gICAgICAgICAgICBTZXRJbnRlcmlvclZlaGljbGVEYXRhLFxuICAgICAgICAgICAgU2V0SW50ZXJpb3JWZWhpY2xlRGF0YVJlc3BvbnNlLFxuICAgICAgICAgICAgU2V0TWVkaWFDbG9ja1RpbWVyLFxuICAgICAgICAgICAgU2V0TWVkaWFDbG9ja1RpbWVyUmVzcG9uc2UsXG4gICAgICAgICAgICBTaG93LFxuICAgICAgICAgICAgU2hvd0FwcE1lbnUsXG4gICAgICAgICAgICBTaG93QXBwTWVudVJlc3BvbnNlLFxuICAgICAgICAgICAgU2hvd0NvbnN0YW50VEJULFxuICAgICAgICAgICAgU2hvd0NvbnN0YW50VEJUUmVzcG9uc2UsXG4gICAgICAgICAgICBTaG93UmVzcG9uc2UsXG4gICAgICAgICAgICBTbGlkZXIsXG4gICAgICAgICAgICBTbGlkZXJSZXNwb25zZSxcbiAgICAgICAgICAgIFNwZWFrLFxuICAgICAgICAgICAgU3BlYWtSZXNwb25zZSxcbiAgICAgICAgICAgIFN1YnNjcmliZUJ1dHRvbixcbiAgICAgICAgICAgIFN1YnNjcmliZUJ1dHRvblJlc3BvbnNlLFxuICAgICAgICAgICAgU3Vic2NyaWJlVmVoaWNsZURhdGEsXG4gICAgICAgICAgICBTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLFxuICAgICAgICAgICAgU3Vic2NyaWJlV2F5UG9pbnRzLFxuICAgICAgICAgICAgU3Vic2NyaWJlV2F5UG9pbnRzUmVzcG9uc2UsXG4gICAgICAgICAgICBTeXN0ZW1SZXF1ZXN0LFxuICAgICAgICAgICAgU3lzdGVtUmVxdWVzdFJlc3BvbnNlLFxuICAgICAgICAgICAgVW5wdWJsaXNoQXBwU2VydmljZSxcbiAgICAgICAgICAgIFVucHVibGlzaEFwcFNlcnZpY2VSZXNwb25zZSxcbiAgICAgICAgICAgIFVucmVnaXN0ZXJBcHBJbnRlcmZhY2UsXG4gICAgICAgICAgICBVbnJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UsXG4gICAgICAgICAgICBVbnN1YnNjcmliZUJ1dHRvbixcbiAgICAgICAgICAgIFVuc3Vic2NyaWJlQnV0dG9uUmVzcG9uc2UsXG4gICAgICAgICAgICBVbnN1YnNjcmliZVZlaGljbGVEYXRhLFxuICAgICAgICAgICAgVW5zdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlLFxuICAgICAgICAgICAgVW5zdWJzY3JpYmVXYXlQb2ludHMsXG4gICAgICAgICAgICBVbnN1YnNjcmliZVdheVBvaW50c1Jlc3BvbnNlLFxuICAgICAgICAgICAgVXBkYXRlVHVybkxpc3QsXG4gICAgICAgICAgICBVcGRhdGVUdXJuTGlzdFJlc3BvbnNlLFxuICAgICAgICB9LFxuICAgICAgICBzdHJ1Y3RzOiB7XG4gICAgICAgICAgICBBaXJiYWdTdGF0dXMsXG4gICAgICAgICAgICBBcHBJbmZvLFxuICAgICAgICAgICAgQXBwU2VydmljZUNhcGFiaWxpdHksXG4gICAgICAgICAgICBBcHBTZXJ2aWNlRGF0YSxcbiAgICAgICAgICAgIEFwcFNlcnZpY2VNYW5pZmVzdCxcbiAgICAgICAgICAgIEFwcFNlcnZpY2VSZWNvcmQsXG4gICAgICAgICAgICBBcHBTZXJ2aWNlc0NhcGFiaWxpdGllcyxcbiAgICAgICAgICAgIEF1ZGlvQ29udHJvbENhcGFiaWxpdGllcyxcbiAgICAgICAgICAgIEF1ZGlvQ29udHJvbERhdGEsXG4gICAgICAgICAgICBBdWRpb1Bhc3NUaHJ1Q2FwYWJpbGl0aWVzLFxuICAgICAgICAgICAgQmVsdFN0YXR1cyxcbiAgICAgICAgICAgIEJvZHlJbmZvcm1hdGlvbixcbiAgICAgICAgICAgIEJ1dHRvbkNhcGFiaWxpdGllcyxcbiAgICAgICAgICAgIENob2ljZSxcbiAgICAgICAgICAgIENsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzLFxuICAgICAgICAgICAgQ2xpbWF0ZUNvbnRyb2xEYXRhLFxuICAgICAgICAgICAgQ2xvdWRBcHBQcm9wZXJ0aWVzLFxuICAgICAgICAgICAgQ2x1c3Rlck1vZGVTdGF0dXMsXG4gICAgICAgICAgICBDb29yZGluYXRlLFxuICAgICAgICAgICAgRElEUmVzdWx0LFxuICAgICAgICAgICAgRGF0ZVRpbWUsXG4gICAgICAgICAgICBEZXZpY2VJbmZvLFxuICAgICAgICAgICAgRGV2aWNlU3RhdHVzLFxuICAgICAgICAgICAgRGlzcGxheUNhcGFiaWxpdGllcyxcbiAgICAgICAgICAgIERpc3BsYXlDYXBhYmlsaXR5LFxuICAgICAgICAgICAgRUNhbGxJbmZvLFxuICAgICAgICAgICAgRW1lcmdlbmN5RXZlbnQsXG4gICAgICAgICAgICBFcXVhbGl6ZXJTZXR0aW5ncyxcbiAgICAgICAgICAgIEZ1ZWxSYW5nZSxcbiAgICAgICAgICAgIEdQU0RhdGEsXG4gICAgICAgICAgICBHcmlkLFxuICAgICAgICAgICAgSE1JQ2FwYWJpbGl0aWVzLFxuICAgICAgICAgICAgSE1JUGVybWlzc2lvbnMsXG4gICAgICAgICAgICBITUlTZXR0aW5nc0NvbnRyb2xDYXBhYmlsaXRpZXMsXG4gICAgICAgICAgICBITUlTZXR0aW5nc0NvbnRyb2xEYXRhLFxuICAgICAgICAgICAgSGFwdGljUmVjdCxcbiAgICAgICAgICAgIEhlYWRMYW1wU3RhdHVzLFxuICAgICAgICAgICAgSW1hZ2UsXG4gICAgICAgICAgICBJbWFnZUZpZWxkLFxuICAgICAgICAgICAgSW1hZ2VSZXNvbHV0aW9uLFxuICAgICAgICAgICAgS2V5Ym9hcmRQcm9wZXJ0aWVzLFxuICAgICAgICAgICAgTGlnaHRDYXBhYmlsaXRpZXMsXG4gICAgICAgICAgICBMaWdodENvbnRyb2xDYXBhYmlsaXRpZXMsXG4gICAgICAgICAgICBMaWdodENvbnRyb2xEYXRhLFxuICAgICAgICAgICAgTGlnaHRTdGF0ZSxcbiAgICAgICAgICAgIExvY2F0aW9uRGV0YWlscyxcbiAgICAgICAgICAgIE1hc3NhZ2VDdXNoaW9uRmlybW5lc3MsXG4gICAgICAgICAgICBNYXNzYWdlTW9kZURhdGEsXG4gICAgICAgICAgICBNZWRpYVNlcnZpY2VEYXRhLFxuICAgICAgICAgICAgTWVkaWFTZXJ2aWNlTWFuaWZlc3QsXG4gICAgICAgICAgICBNZW51UGFyYW1zLFxuICAgICAgICAgICAgTWV0YWRhdGFUYWdzLFxuICAgICAgICAgICAgTW9kdWxlRGF0YSxcbiAgICAgICAgICAgIE1vZHVsZUluZm8sXG4gICAgICAgICAgICBNeUtleSxcbiAgICAgICAgICAgIE5hdmlnYXRpb25DYXBhYmlsaXR5LFxuICAgICAgICAgICAgTmF2aWdhdGlvbkluc3RydWN0aW9uLFxuICAgICAgICAgICAgTmF2aWdhdGlvblNlcnZpY2VEYXRhLFxuICAgICAgICAgICAgTmF2aWdhdGlvblNlcnZpY2VNYW5pZmVzdCxcbiAgICAgICAgICAgIE9BU0lTQWRkcmVzcyxcbiAgICAgICAgICAgIFBhcmFtZXRlclBlcm1pc3Npb25zLFxuICAgICAgICAgICAgUGVybWlzc2lvbkl0ZW0sXG4gICAgICAgICAgICBQaG9uZUNhcGFiaWxpdHksXG4gICAgICAgICAgICBQcmVzZXRCYW5rQ2FwYWJpbGl0aWVzLFxuICAgICAgICAgICAgUkdCQ29sb3IsXG4gICAgICAgICAgICBSYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMsXG4gICAgICAgICAgICBSYWRpb0NvbnRyb2xEYXRhLFxuICAgICAgICAgICAgUmRzRGF0YSxcbiAgICAgICAgICAgIFJlY3RhbmdsZSxcbiAgICAgICAgICAgIFJlbW90ZUNvbnRyb2xDYXBhYmlsaXRpZXMsXG4gICAgICAgICAgICBTY3JlZW5QYXJhbXMsXG4gICAgICAgICAgICBTZGxNc2dWZXJzaW9uLFxuICAgICAgICAgICAgU2VhdENvbnRyb2xDYXBhYmlsaXRpZXMsXG4gICAgICAgICAgICBTZWF0Q29udHJvbERhdGEsXG4gICAgICAgICAgICBTZWF0TG9jYXRpb24sXG4gICAgICAgICAgICBTZWF0TG9jYXRpb25DYXBhYmlsaXR5LFxuICAgICAgICAgICAgU2VhdE1lbW9yeUFjdGlvbixcbiAgICAgICAgICAgIFNpbmdsZVRpcmVTdGF0dXMsXG4gICAgICAgICAgICBTaXNEYXRhLFxuICAgICAgICAgICAgU29mdEJ1dHRvbixcbiAgICAgICAgICAgIFNvZnRCdXR0b25DYXBhYmlsaXRpZXMsXG4gICAgICAgICAgICBTdGFydFRpbWUsXG4gICAgICAgICAgICBTdGF0aW9uSUROdW1iZXIsXG4gICAgICAgICAgICBTeXN0ZW1DYXBhYmlsaXR5LFxuICAgICAgICAgICAgVFRTQ2h1bmssXG4gICAgICAgICAgICBUZW1wZXJhdHVyZSxcbiAgICAgICAgICAgIFRlbXBsYXRlQ29sb3JTY2hlbWUsXG4gICAgICAgICAgICBUZW1wbGF0ZUNvbmZpZ3VyYXRpb24sXG4gICAgICAgICAgICBUZXh0RmllbGQsXG4gICAgICAgICAgICBUaXJlU3RhdHVzLFxuICAgICAgICAgICAgVG91Y2hDb29yZCxcbiAgICAgICAgICAgIFRvdWNoRXZlbnQsXG4gICAgICAgICAgICBUb3VjaEV2ZW50Q2FwYWJpbGl0aWVzLFxuICAgICAgICAgICAgVHVybixcbiAgICAgICAgICAgIFZlaGljbGVEYXRhUmVzdWx0LFxuICAgICAgICAgICAgVmVoaWNsZVR5cGUsXG4gICAgICAgICAgICBWaWRlb1N0cmVhbWluZ0NhcGFiaWxpdHksXG4gICAgICAgICAgICBWaWRlb1N0cmVhbWluZ0Zvcm1hdCxcbiAgICAgICAgICAgIFZySGVscEl0ZW0sXG4gICAgICAgICAgICBXZWF0aGVyQWxlcnQsXG4gICAgICAgICAgICBXZWF0aGVyRGF0YSxcbiAgICAgICAgICAgIFdlYXRoZXJTZXJ2aWNlRGF0YSxcbiAgICAgICAgICAgIFdlYXRoZXJTZXJ2aWNlTWFuaWZlc3QsXG4gICAgICAgICAgICBXaW5kb3dDYXBhYmlsaXR5LFxuICAgICAgICAgICAgV2luZG93VHlwZUNhcGFiaWxpdGllcyxcbiAgICAgICAgfSxcbiAgICB9LFxuICAgIHNlc3Npb246IHtcbiAgICAgICAgU2RsU2VydmljZUxpc3RlbmVyLFxuICAgICAgICBTZGxTZXNzaW9uLFxuICAgICAgICBTZGxTZXNzaW9uTGlzdGVuZXIsXG4gICAgICAgIFNlcnZpY2VMaXN0ZW5lck1hcCxcbiAgICB9LFxuICAgIHN0cmVhbWluZzoge1xuICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgVmlkZW9TdHJlYW1pbmdQYXJhbWV0ZXJzLFxuICAgICAgICB9LFxuICAgIH0sXG4gICAgdHJhbnNwb3J0OiB7XG4gICAgICAgIEN1c3RvbVRyYW5zcG9ydCxcbiAgICAgICAgQ3VzdG9tVHJhbnNwb3J0Q29uZmlnLFxuICAgICAgICBTZGxQc20sXG4gICAgICAgIFNzbENvbmZpZyxcbiAgICAgICAgVHJhbnNwb3J0QmFzZSxcbiAgICAgICAgVHJhbnNwb3J0Q2FsbGJhY2ssXG4gICAgICAgIFRyYW5zcG9ydENvbmZpZ0Jhc2UsXG4gICAgICAgIFRyYW5zcG9ydExpc3RlbmVyLFxuICAgICAgICBUcmFuc3BvcnRNYW5hZ2VyLFxuICAgICAgICBUcmFuc3BvcnRNYW5hZ2VyQmFzZSxcbiAgICAgICAgV2ViU29ja2V0Q2xpZW50LFxuICAgICAgICBXZWJTb2NrZXRDbGllbnRDb25maWcsXG4gICAgICAgIGVudW1zOiB7XG4gICAgICAgICAgICBUcmFuc3BvcnRUeXBlLFxuICAgICAgICB9LFxuICAgICAgICB1dGlsOiB7XG4gICAgICAgICAgICBUcmFuc3BvcnRSZWNvcmQsXG4gICAgICAgIH0sXG4gICAgICAgIFdlYlNvY2tldFNlcnZlcixcbiAgICAgICAgV2ViU29ja2V0U2VydmVyQ29uZmlnLFxuICAgIH0sXG4gICAgdXRpbDoge1xuICAgICAgICBBcnJheVRvb2xzLFxuICAgICAgICBCaXRDb252ZXJ0ZXIsXG4gICAgICAgIEJzb24sXG4gICAgICAgIEVudW0sXG4gICAgICAgIEpzb25ScGNNYXJzaGFsbGVyLFxuICAgICAgICBUZXh0RW5jb2RlcixcbiAgICAgICAgVmVyc2lvbixcbiAgICB9LFxufTtcblxuZXhwb3J0IGRlZmF1bHQgU0RMOyJdLCJuYW1lcyI6WyJBcHBDb25maWciLCJjb25zdHJ1Y3RvciIsIl90cmFuc3BvcnRDb25maWciLCJfYXBwSWQiLCJfYXBwTmFtZSIsIl9pY29uTmFtZSIsIl9pY29uRmlsZSIsIl9zaG9ydEFwcE5hbWUiLCJfdHRzTmFtZSIsIl92clN5bm9ueW1zIiwiX2lzTWVkaWFBcHAiLCJfbGFuZ3VhZ2VEZXNpcmVkIiwiX2htaURpc3BsYXlMYW5ndWFnZURlc2lyZWQiLCJfYXBwVHlwZXMiLCJfZGF5Q29sb3JTY2hlbWUiLCJfbmlnaHRDb2xvclNjaGVtZSIsIl9taW5pbXVtUlBDVmVyc2lvbiIsIl9taW5pbXVtUHJvdG9jb2xWZXJzaW9uIiwic2V0VHJhbnNwb3J0Q29uZmlnIiwidHJhbnNwb3J0Q29uZmlnIiwiZ2V0VHJhbnNwb3J0Q29uZmlnIiwic2V0QXBwSWQiLCJhcHBJZCIsImdldEFwcElkIiwic2V0QXBwTmFtZSIsImFwcE5hbWUiLCJnZXRBcHBOYW1lIiwic2V0QXBwSWNvbiIsImljb25OYW1lIiwiZmlsZURhdGEiLCJnZXRBcHBJY29uTmFtZSIsImdldEFwcEljb25GaWxlRGF0YSIsInNldFNob3J0QXBwTmFtZSIsInNob3J0QXBwTmFtZSIsImdldFNob3J0QXBwTmFtZSIsInNldFR0c05hbWUiLCJ0dHNOYW1lIiwiZ2V0VHRzTmFtZSIsInNldFZyU3lub255bXMiLCJ2clN5bm9ueW1zIiwiZ2V0VnJTeW5vbnltcyIsInNldElzTWVkaWFBcHAiLCJpc01lZGlhQXBwIiwic2V0TGFuZ3VhZ2VEZXNpcmVkIiwibGFuZ3VhZ2VEZXNpcmVkIiwiZ2V0TGFuZ3VhZ2VEZXNpcmVkIiwic2V0SG1pRGlzcGxheUxhbmd1YWdlRGVzaXJlZCIsImhtaURpc3BsYXlMYW5ndWFnZURlc2lyZWQiLCJnZXRIbWlEaXNwbGF5TGFuZ3VhZ2VEZXNpcmVkIiwic2V0QXBwVHlwZXMiLCJhcHBUeXBlcyIsImdldEFwcFR5cGVzIiwic2V0RGF5Q29sb3JTY2hlbWUiLCJkYXlDb2xvclNjaGVtZSIsImdldERheUNvbG9yU2NoZW1lIiwic2V0TmlnaHRDb2xvclNjaGVtZSIsIm5pZ2h0Q29sb3JTY2hlbWUiLCJnZXROaWdodENvbG9yU2NoZW1lIiwic2V0TWluaW11bVJQQ1ZlcnNpb24iLCJtaW5pbXVtUlBDVmVyc2lvbiIsImdldE1pbmltdW1SUENWZXJzaW9uIiwic2V0TWluaW11bVByb3RvY29sVmVyc2lvbiIsIm1pbmltdW1Qcm90b2NvbFZlcnNpb24iLCJnZXRNaW5pbXVtUHJvdG9jb2xWZXJzaW9uIiwiTGlmZWN5Y2xlTGlzdGVuZXIiLCJfb25Qcm94eUNvbm5lY3RlZCIsIl9vblByb3h5Q2xvc2VkIiwiX29uU2VydmljZVN0YXJ0ZWQiLCJfb25TZXJ2aWNlRW5kZWQiLCJfb25FcnJvciIsInNldE9uUHJveHlDb25uZWN0ZWQiLCJsaXN0ZW5lciIsInNldE9uUHJveHlDbG9zZWQiLCJzZXRPblNlcnZpY2VTdGFydGVkIiwic2V0T25TZXJ2aWNlRW5kZWQiLCJzZXRPbkVycm9yIiwib25Qcm94eUNvbm5lY3RlZCIsImxpZmVjeWNsZU1hbmFnZXIiLCJvblByb3h5Q2xvc2VkIiwiaW5mbyIsInJlYXNvbiIsIm9uU2VydmljZVN0YXJ0ZWQiLCJzZXJ2aWNlVHlwZSIsInNlc3Npb25JRCIsImNvcnJlbGF0aW9uSUQiLCJfb25Qcm90b2NvbFNlc3Npb25FbmRlZE5BQ0tlZCIsIm9uU2VydmljZUVuZGVkIiwib25FcnJvciIsIkVudW0iLCJfa2V5Rm9yVmFsdWUiLCJ2YWx1ZSIsIm1hcCIsImtleSIsImtleUZvclZhbHVlIiwiRXJyb3IiLCJfdmFsdWVGb3JLZXkiLCJ2YWx1ZUZvcktleSIsIlJwY1N0cnVjdCIsInBhcmFtZXRlcnMiLCJfaXNGb3JtYXRSZXF1ZXN0ZWQiLCJfcnBjU3BlY1ZlcnNpb24iLCJfcGFyYW1ldGVycyIsImdldFBhcmFtZXRlcnMiLCJnZXRQYXJhbWV0ZXIiLCJzZXRQYXJhbWV0ZXIiLCJnZXRPYmplY3QiLCJ0Q2xhc3MiLCJmb3JtYXRPYmplY3QiLCJvYmoiLCJ1bmRlZmluZWQiLCJTdHJpbmciLCJPYmplY3QiLCJwcm90b3R5cGUiLCJBcnJheSIsImxlbmd0aCIsIm91dEFycmF5IiwiaXRlbSIsInB1c2giLCJ2YWxpZGF0ZVR5cGUiLCJpc0FycmF5IiwibmFtZSIsIkFwcEluZm8iLCJzZXRBcHBEaXNwbGF5TmFtZSIsIktFWV9BUFBfRElTUExBWV9OQU1FIiwiZ2V0QXBwRGlzcGxheU5hbWUiLCJzZXRBcHBCdW5kbGVJRCIsImlkIiwiS0VZX0FQUF9CVU5ETEVfSUQiLCJnZXRBcHBCdW5kbGVJRCIsInNldEFwcFZlcnNpb24iLCJ2ZXJzaW9uIiwiS0VZX0FQUF9WRVJTSU9OIiwiZ2V0QXBwVmVyc2lvbiIsImljb24iLCJLRVlfQVBQX0lDT04iLCJnZXRBcHBJY29uIiwiUkdCQ29sb3IiLCJzZXRSZWQiLCJyZWQiLCJLRVlfUkVEIiwiZ2V0UmVkIiwic2V0R3JlZW4iLCJncmVlbiIsIktFWV9HUkVFTiIsImdldEdyZWVuIiwic2V0Qmx1ZSIsImJsdWUiLCJLRVlfQkxVRSIsImdldEJsdWUiLCJUZW1wbGF0ZUNvbG9yU2NoZW1lIiwic2V0UHJpbWFyeUNvbG9yIiwiY29sb3IiLCJLRVlfUFJJTUFSWV9DT0xPUiIsImdldFByaW1hcnlDb2xvciIsInNldFNlY29uZGFyeUNvbG9yIiwiS0VZX1NFQ09OREFSWV9DT0xPUiIsImdldFNlY29uZGFyeUNvbG9yIiwic2V0QmFja2dyb3VuZENvbG9yIiwiS0VZX0JBQ0tHUk9VTkRfQ09MT1IiLCJnZXRCYWNrZ3JvdW5kQ29sb3IiLCJGdW5jdGlvbklEIiwiUkVTRVJWRUQiLCJfTUFQIiwiUmVnaXN0ZXJBcHBJbnRlcmZhY2UiLCJVbnJlZ2lzdGVyQXBwSW50ZXJmYWNlIiwiU2V0R2xvYmFsUHJvcGVydGllcyIsIlJlc2V0R2xvYmFsUHJvcGVydGllcyIsIkFkZENvbW1hbmQiLCJEZWxldGVDb21tYW5kIiwiQWRkU3ViTWVudSIsIkRlbGV0ZVN1Yk1lbnUiLCJDcmVhdGVJbnRlcmFjdGlvbkNob2ljZVNldCIsIlBlcmZvcm1JbnRlcmFjdGlvbiIsIkRlbGV0ZUludGVyYWN0aW9uQ2hvaWNlU2V0IiwiQWxlcnQiLCJTaG93IiwiU3BlYWsiLCJTZXRNZWRpYUNsb2NrVGltZXIiLCJQZXJmb3JtQXVkaW9QYXNzVGhydSIsIkVuZEF1ZGlvUGFzc1RocnUiLCJTdWJzY3JpYmVCdXR0b24iLCJVbnN1YnNjcmliZUJ1dHRvbiIsIlN1YnNjcmliZVZlaGljbGVEYXRhIiwiVW5zdWJzY3JpYmVWZWhpY2xlRGF0YSIsIkdldFZlaGljbGVEYXRhIiwiUmVhZERJRCIsIkdldERUQ3MiLCJTY3JvbGxhYmxlTWVzc2FnZSIsIlNsaWRlciIsIlNob3dDb25zdGFudFRCVCIsIkFsZXJ0TWFuZXV2ZXIiLCJVcGRhdGVUdXJuTGlzdCIsIkNoYW5nZVJlZ2lzdHJhdGlvbiIsIkdlbmVyaWNSZXNwb25zZSIsIlB1dEZpbGUiLCJEZWxldGVGaWxlIiwiTGlzdEZpbGVzIiwiU2V0QXBwSWNvbiIsIlNldERpc3BsYXlMYXlvdXQiLCJEaWFnbm9zdGljTWVzc2FnZSIsIlN5c3RlbVJlcXVlc3QiLCJTZW5kTG9jYXRpb24iLCJEaWFsTnVtYmVyIiwiQnV0dG9uUHJlc3MiLCJHZXRJbnRlcmlvclZlaGljbGVEYXRhIiwiU2V0SW50ZXJpb3JWZWhpY2xlRGF0YSIsIkdldFdheVBvaW50cyIsIlN1YnNjcmliZVdheVBvaW50cyIsIlVuc3Vic2NyaWJlV2F5UG9pbnRzIiwiR2V0U3lzdGVtQ2FwYWJpbGl0eSIsIlNlbmRIYXB0aWNEYXRhIiwiU2V0Q2xvdWRBcHBQcm9wZXJ0aWVzIiwiR2V0Q2xvdWRBcHBQcm9wZXJ0aWVzIiwiUHVibGlzaEFwcFNlcnZpY2UiLCJHZXRBcHBTZXJ2aWNlRGF0YSIsIkdldEZpbGUiLCJQZXJmb3JtQXBwU2VydmljZUludGVyYWN0aW9uIiwiVW5wdWJsaXNoQXBwU2VydmljZSIsIkNhbmNlbEludGVyYWN0aW9uIiwiQ2xvc2VBcHBsaWNhdGlvbiIsIlNob3dBcHBNZW51IiwiQ3JlYXRlV2luZG93IiwiRGVsZXRlV2luZG93IiwiR2V0SW50ZXJpb3JWZWhpY2xlRGF0YUNvbnNlbnQiLCJSZWxlYXNlSW50ZXJpb3JWZWhpY2xlRGF0YU1vZHVsZSIsIk9uSE1JU3RhdHVzIiwiT25BcHBJbnRlcmZhY2VVbnJlZ2lzdGVyZWQiLCJPbkJ1dHRvbkV2ZW50IiwiT25CdXR0b25QcmVzcyIsIk9uVmVoaWNsZURhdGEiLCJPbkNvbW1hbmQiLCJPblRCVENsaWVudFN0YXRlIiwiT25Ecml2ZXJEaXN0cmFjdGlvbiIsIk9uUGVybWlzc2lvbnNDaGFuZ2UiLCJPbkF1ZGlvUGFzc1RocnUiLCJPbkxhbmd1YWdlQ2hhbmdlIiwiT25LZXlib2FyZElucHV0IiwiT25Ub3VjaEV2ZW50IiwiT25TeXN0ZW1SZXF1ZXN0IiwiT25IYXNoQ2hhbmdlIiwiT25JbnRlcmlvclZlaGljbGVEYXRhIiwiT25XYXlQb2ludENoYW5nZSIsIk9uUkNTdGF0dXMiLCJPbkFwcFNlcnZpY2VEYXRhIiwiT25TeXN0ZW1DYXBhYmlsaXR5VXBkYXRlZCIsIkVuY29kZWRTeW5jUERhdGEiLCJTZGxQRGF0YSIsIk9uRW5jb2RlZFN5bmNQRGF0YSIsIk9uU3luY1BEYXRhIiwiZnJlZXplIiwiU3BlZWNoQ2FwYWJpbGl0aWVzIiwiU0NfVEVYVCIsIlNBUElfUEhPTkVNRVMiLCJMSFBMVVNfUEhPTkVNRVMiLCJQUkVfUkVDT1JERUQiLCJTSUxFTkNFIiwiRklMRSIsIlRUU0NodW5rIiwic2V0VGV4dCIsInRleHQiLCJLRVlfVEVYVCIsImdldFRleHQiLCJzZXRUeXBlIiwidHlwZSIsIktFWV9UWVBFIiwiZ2V0VHlwZSIsIlNkbE1zZ1ZlcnNpb24iLCJzZXRNYWpvclZlcnNpb24iLCJLRVlfTUFKT1JfVkVSU0lPTiIsImdldE1ham9yVmVyc2lvbiIsInNldE1pbm9yVmVyc2lvbiIsIktFWV9NSU5PUl9WRVJTSU9OIiwiZ2V0TWlub3JWZXJzaW9uIiwic2V0UGF0Y2hWZXJzaW9uIiwiS0VZX1BBVENIX1ZFUlNJT04iLCJnZXRQYXRjaFZlcnNpb24iLCJBcHBITUlUeXBlIiwiREVGQVVMVCIsIkNPTU1VTklDQVRJT04iLCJNRURJQSIsIk1FU1NBR0lORyIsIk5BVklHQVRJT04iLCJJTkZPUk1BVElPTiIsIlNPQ0lBTCIsIkJBQ0tHUk9VTkRfUFJPQ0VTUyIsIlRFU1RJTkciLCJTWVNURU0iLCJQUk9KRUNUSU9OIiwiUkVNT1RFX0NPTlRST0wiLCJMYW5ndWFnZSIsIkVOX1VTIiwiRVNfTVgiLCJGUl9DQSIsIkRFX0RFIiwiRVNfRVMiLCJFTl9HQiIsIlJVX1JVIiwiVFJfVFIiLCJQTF9QTCIsIkZSX0ZSIiwiSVRfSVQiLCJTVl9TRSIsIlBUX1BUIiwiTkxfTkwiLCJFTl9BVSIsIlpIX0NOIiwiWkhfVFciLCJKQV9KUCIsIkFSX1NBIiwiS09fS1IiLCJQVF9CUiIsIkNTX0NaIiwiREFfREsiLCJOT19OTyIsIk5MX0JFIiwiRUxfR1IiLCJIVV9IVSIsIkZJX0ZJIiwiU0tfU0siLCJFTl9JTiIsIlRIX1RIIiwiRU5fU0EiLCJIRV9JTCIsIlJPX1JPIiwiVUtfVUEiLCJJRF9JRCIsIlZJX1ZOIiwiTVNfTVkiLCJISV9JTiIsIlJwY01lc3NhZ2UiLCJzdG9yZSIsIl9pc0VuY3J5cHRlZCIsIl9ycGNUeXBlIiwicnBjVHlwZSIsIl9mdW5jdGlvbk5hbWUiLCJmdW5jdGlvbk5hbWUiLCJfY29ycmVsYXRpb25JRCIsInNldEJ1bGtEYXRhIiwiYnVsa0RhdGEiLCJnZXRSUENUeXBlIiwic2V0UlBDVHlwZSIsImdldEZ1bmN0aW9uTmFtZSIsInNldEZ1bmN0aW9uTmFtZSIsImdldENvcnJlbGF0aW9uSWQiLCJzZXRDb3JyZWxhdGlvbklkIiwiZ2V0QnVsa0RhdGEiLCJfYnVsa0RhdGEiLCJkYXRhIiwic2xpY2UiLCJnZXRJc0VuY3J5cHRlZCIsInNldElzRW5jcnlwdGVkIiwiYm9vbCIsIlJwY1R5cGUiLCJOT1RJRklDQVRJT04iLCJSRVNQT05TRSIsIlJFUVVFU1QiLCJScGNSZXF1ZXN0IiwiX3Byb21pc2UiLCJnZXRPblJQQ1Jlc3BvbnNlUHJvbWlzZSIsInNldE9uUlBDUmVzcG9uc2VQcm9taXNlIiwicHJvbWlzZSIsIlByb21pc2UiLCJEZXZpY2VJbmZvIiwic2V0SGFyZHdhcmUiLCJoYXJkd2FyZSIsIktFWV9IQVJEV0FSRSIsImdldEhhcmR3YXJlIiwic2V0RmlybXdhcmVSZXYiLCJyZXYiLCJLRVlfRklSTVdBUkVfUkVWIiwiZ2V0RmlybXdhcmVSZXYiLCJzZXRPcyIsIm9zIiwiS0VZX09TIiwiZ2V0T3MiLCJzZXRPc1ZlcnNpb24iLCJLRVlfT1NfVkVSU0lPTiIsImdldE9zVmVyc2lvbiIsInNldENhcnJpZXIiLCJjYXJyaWVyIiwiS0VZX0NBUlJJRVIiLCJnZXRDYXJyaWVyIiwic2V0TWF4TnVtYmVyUkZDT01NUG9ydHMiLCJwb3J0cyIsIktFWV9NQVhfTlVNQkVSX1JGQ09NTV9QT1JUUyIsImdldE1heE51bWJlclJGQ09NTVBvcnRzIiwic2V0RnVsbEFwcElkIiwiZnVsbEFwcElkIiwidG9Mb3dlckNhc2UiLCJLRVlfRlVMTF9BUFBfSUQiLCJhcHBJRCIsIkFQUF9JRF9NQVhfTEVOR1RIIiwicmVwbGFjZSIsInN1YnN0cmluZyIsIl9zZXRBcHBJZCIsImdldEZ1bGxBcHBJZCIsIktFWV9BUFBfSUQiLCJzZXRTZGxNc2dWZXJzaW9uIiwiS0VZX1NETF9NU0dfVkVSU0lPTiIsImdldFNkbE1zZ1ZlcnNpb24iLCJLRVlfQVBQX05BTUUiLCJLRVlfVFRTX05BTUUiLCJzZXROZ25NZWRpYVNjcmVlbkFwcE5hbWUiLCJLRVlfTkdOX01FRElBX1NDUkVFTl9BUFBfTkFNRSIsImdldE5nbk1lZGlhU2NyZWVuQXBwTmFtZSIsInN5bm9ueW1zIiwiS0VZX1ZSX1NZTk9OWU1TIiwic2V0SXNNZWRpYUFwcGxpY2F0aW9uIiwiYXBwbGljYXRpb24iLCJLRVlfSVNfTUVESUFfQVBQTElDQVRJT04iLCJnZXRJc01lZGlhQXBwbGljYXRpb24iLCJkZXNpcmVkIiwiS0VZX0xBTkdVQUdFX0RFU0lSRUQiLCJLRVlfSE1JX0RJU1BMQVlfTEFOR1VBR0VfREVTSVJFRCIsInNldEFwcEhNSVR5cGUiLCJLRVlfQVBQX0hNSV9UWVBFIiwiZ2V0QXBwSE1JVHlwZSIsInNldEhhc2hJRCIsIktFWV9IQVNIX0lEIiwiZ2V0SGFzaElEIiwic2V0RGV2aWNlSW5mbyIsIktFWV9ERVZJQ0VfSU5GTyIsImdldERldmljZUluZm8iLCJzZXRGdWxsQXBwSUQiLCJnZXRGdWxsQXBwSUQiLCJzZXRBcHBJbmZvIiwiS0VZX0FQUF9JTkZPIiwiZ2V0QXBwSW5mbyIsInNjaGVtZSIsIktFWV9EQVlfQ09MT1JfU0NIRU1FIiwiS0VZX05JR0hUX0NPTE9SX1NDSEVNRSIsIlJlc3VsdCIsIlNVQ0NFU1MiLCJVTlNVUFBPUlRFRF9SRVFVRVNUIiwiVU5TVVBQT1JURURfUkVTT1VSQ0UiLCJESVNBTExPV0VEIiwiUkVKRUNURUQiLCJBQk9SVEVEIiwiSUdOT1JFRCIsIlJFVFJZIiwiSU5fVVNFIiwiVkVISUNMRV9EQVRBX05PVF9BVkFJTEFCTEUiLCJUSU1FRF9PVVQiLCJJTlZBTElEX0RBVEEiLCJDSEFSX0xJTUlUX0VYQ0VFREVEIiwiSU5WQUxJRF9JRCIsIkRVUExJQ0FURV9OQU1FIiwiQVBQTElDQVRJT05fTk9UX1JFR0lTVEVSRUQiLCJXUk9OR19MQU5HVUFHRSIsIk9VVF9PRl9NRU1PUlkiLCJUT09fTUFOWV9QRU5ESU5HX1JFUVVFU1RTIiwiVE9PX01BTllfQVBQTElDQVRJT05TIiwiQVBQTElDQVRJT05fUkVHSVNURVJFRF9BTFJFQURZIiwiV0FSTklOR1MiLCJHRU5FUklDX0VSUk9SIiwiVVNFUl9ESVNBTExPV0VEIiwiVFJVTkNBVEVEX0RBVEEiLCJVTlNVUFBPUlRFRF9WRVJTSU9OIiwiVkVISUNMRV9EQVRBX05PVF9BTExPV0VEIiwiRklMRV9OT1RfRk9VTkQiLCJDQU5DRUxfUk9VVEUiLCJTQVZFRCIsIklOVkFMSURfQ0VSVCIsIkVYUElSRURfQ0VSVCIsIlJFU1VNRV9GQUlMRUQiLCJEQVRBX05PVF9BVkFJTEFCTEUiLCJSRUFEX09OTFkiLCJDT1JSVVBURURfREFUQSIsIkVOQ1JZUFRJT05fTkVFREVEIiwiUnBjUmVzcG9uc2UiLCJnZXRTdWNjZXNzIiwiS0VZX1NVQ0NFU1MiLCJzZXRTdWNjZXNzIiwic3VjY2VzcyIsImdldEluZm8iLCJLRVlfSU5GTyIsInNldEluZm8iLCJnZXRSZXN1bHRDb2RlIiwiS0VZX1JFU1VMVF9DT0RFIiwic2V0UmVzdWx0Q29kZSIsInJlc3VsdENvZGUiLCJScGNMaXN0ZW5lciIsIl9vblJwY01lc3NhZ2UiLCJzZXRPblJwY01lc3NhZ2UiLCJmdW5jIiwib25ScGNNZXNzYWdlIiwicnBjTWVzc2FnZSIsIlNkbFByb3RvY29sTGlzdGVuZXIiLCJfb25ScGNNZXNzYWdlUmVjZWl2ZWQiLCJfb25Qcm90b2NvbFNlc3Npb25TdGFydGVkIiwiX29uUHJvdG9jb2xTZXNzaW9uRW5kZWQiLCJfZ2V0U2Vzc2lvbklkIiwiX29uVHJhbnNwb3J0Q29ubmVjdGVkIiwic2V0T25UcmFuc3BvcnRDb25uZWN0ZWQiLCJzZXRPblJwY01lc3NhZ2VSZWNlaXZlZCIsIm9uUnBjTWVzc2FnZVJlY2VpdmVkIiwic2V0T25Qcm90b2NvbFNlc3Npb25TdGFydGVkIiwib25UcmFuc3BvcnRDb25uZWN0ZWQiLCJvblByb3RvY29sU2Vzc2lvblN0YXJ0ZWQiLCJzZXNzaW9uSWQiLCJjb3JyZWxhdGlvbklkIiwiaGFzaElkIiwiaXNFbmNyeXB0ZWQiLCJzZXRPblByb3RvY29sU2Vzc2lvbkVuZGVkIiwib25Qcm90b2NvbFNlc3Npb25FbmRlZCIsInNldE9uUHJvdG9jb2xTZXNzaW9uRW5kZWROQUNLZWQiLCJvblByb3RvY29sU2Vzc2lvbkVuZGVkTkFDS2VkIiwic2V0R2V0U2Vzc2lvbklkIiwiZ2V0dGVyIiwiZ2V0U2Vzc2lvbklkIiwic2V0R2V0RGVzaXJlZFZpZGVvUGFyYW1zIiwiX2dldERlc2lyZWRWaWRlb1BhcmFtcyIsImdldERlc2lyZWRWaWRlb1BhcmFtcyIsInNldFNldEFjY2VwdGVkVmlkZW9QYXJhbXMiLCJzZXR0ZXIiLCJfc2V0QWNjZXB0ZWRWaWRlb1BhcmFtcyIsInNldEFjY2VwdGVkVmlkZW9QYXJhbXMiLCJwYXJhbXMiLCJGcmFtZVR5cGUiLCJDT05UUk9MIiwiRklSU1QiLCJDT05TRUNVVElWRSIsIlNJTkdMRSIsImV4cG9ydHMiLCJtb2R1bGVzIiwiaW5zdGFsbGVkTW9kdWxlcyIsIl9fd2VicGFja19yZXF1aXJlX18iLCJtb2R1bGVJZCIsIm1vZHVsZSIsImkiLCJsIiwiY2FsbCIsIm0iLCJjIiwiZCIsIm8iLCJkZWZpbmVQcm9wZXJ0eSIsImNvbmZpZ3VyYWJsZSIsImVudW1lcmFibGUiLCJnZXQiLCJuIiwiX19lc01vZHVsZSIsImdldERlZmF1bHQiLCJnZXRNb2R1bGVFeHBvcnRzIiwib2JqZWN0IiwicHJvcGVydHkiLCJoYXNPd25Qcm9wZXJ0eSIsInAiLCJzIiwiZyIsIkZ1bmN0aW9uIiwiZXZhbCIsImUiLCJ3aW5kb3ciLCJnbG9iYWwiLCJiYXNlNjQiLCJpZWVlNzU0IiwiQnVmZmVyIiwiU2xvd0J1ZmZlciIsIklOU1BFQ1RfTUFYX0JZVEVTIiwiVFlQRURfQVJSQVlfU1VQUE9SVCIsInR5cGVkQXJyYXlTdXBwb3J0Iiwia01heExlbmd0aCIsImFyciIsIlVpbnQ4QXJyYXkiLCJfX3Byb3RvX18iLCJmb28iLCJzdWJhcnJheSIsImJ5dGVMZW5ndGgiLCJjcmVhdGVCdWZmZXIiLCJ0aGF0IiwiUmFuZ2VFcnJvciIsImFyZyIsImVuY29kaW5nT3JPZmZzZXQiLCJhbGxvY1Vuc2FmZSIsImZyb20iLCJwb29sU2l6ZSIsIl9hdWdtZW50IiwiVHlwZUVycm9yIiwiQXJyYXlCdWZmZXIiLCJmcm9tQXJyYXlCdWZmZXIiLCJmcm9tU3RyaW5nIiwiZnJvbU9iamVjdCIsIlN5bWJvbCIsInNwZWNpZXMiLCJhc3NlcnRTaXplIiwic2l6ZSIsImFsbG9jIiwiZmlsbCIsImVuY29kaW5nIiwiY2hlY2tlZCIsImFsbG9jVW5zYWZlU2xvdyIsInN0cmluZyIsImlzRW5jb2RpbmciLCJhY3R1YWwiLCJ3cml0ZSIsImZyb21BcnJheUxpa2UiLCJhcnJheSIsImJ5dGVPZmZzZXQiLCJpc0J1ZmZlciIsImxlbiIsImNvcHkiLCJidWZmZXIiLCJpc25hbiIsInRvU3RyaW5nIiwiYiIsIl9pc0J1ZmZlciIsImNvbXBhcmUiLCJhIiwieCIsInkiLCJNYXRoIiwibWluIiwiY29uY2F0IiwibGlzdCIsInBvcyIsImJ1ZiIsImlzVmlldyIsImxvd2VyZWRDYXNlIiwidXRmOFRvQnl0ZXMiLCJiYXNlNjRUb0J5dGVzIiwic2xvd1RvU3RyaW5nIiwic3RhcnQiLCJlbmQiLCJoZXhTbGljZSIsInV0ZjhTbGljZSIsImFzY2lpU2xpY2UiLCJsYXRpbjFTbGljZSIsImJhc2U2NFNsaWNlIiwidXRmMTZsZVNsaWNlIiwic3dhcCIsInN3YXAxNiIsInN3YXAzMiIsInN3YXA2NCIsImFyZ3VtZW50cyIsImFwcGx5IiwiZXF1YWxzIiwiaW5zcGVjdCIsInN0ciIsIm1heCIsIm1hdGNoIiwiam9pbiIsInRhcmdldCIsInRoaXNTdGFydCIsInRoaXNFbmQiLCJ0aGlzQ29weSIsInRhcmdldENvcHkiLCJiaWRpcmVjdGlvbmFsSW5kZXhPZiIsInZhbCIsImRpciIsImlzTmFOIiwiYXJyYXlJbmRleE9mIiwiaW5kZXhPZiIsImxhc3RJbmRleE9mIiwiaW5kZXhTaXplIiwiYXJyTGVuZ3RoIiwidmFsTGVuZ3RoIiwicmVhZCIsInJlYWRVSW50MTZCRSIsImZvdW5kSW5kZXgiLCJmb3VuZCIsImoiLCJpbmNsdWRlcyIsImhleFdyaXRlIiwib2Zmc2V0IiwiTnVtYmVyIiwicmVtYWluaW5nIiwic3RyTGVuIiwicGFyc2VkIiwicGFyc2VJbnQiLCJzdWJzdHIiLCJ1dGY4V3JpdGUiLCJibGl0QnVmZmVyIiwiYXNjaWlXcml0ZSIsImFzY2lpVG9CeXRlcyIsImxhdGluMVdyaXRlIiwiYmFzZTY0V3JpdGUiLCJ1Y3MyV3JpdGUiLCJ1dGYxNmxlVG9CeXRlcyIsImlzRmluaXRlIiwidG9KU09OIiwiX2FyciIsImZyb21CeXRlQXJyYXkiLCJyZXMiLCJmaXJzdEJ5dGUiLCJjb2RlUG9pbnQiLCJieXRlc1BlclNlcXVlbmNlIiwic2Vjb25kQnl0ZSIsInRoaXJkQnl0ZSIsImZvdXJ0aEJ5dGUiLCJ0ZW1wQ29kZVBvaW50IiwiZGVjb2RlQ29kZVBvaW50c0FycmF5IiwiTUFYX0FSR1VNRU5UU19MRU5HVEgiLCJjb2RlUG9pbnRzIiwiZnJvbUNoYXJDb2RlIiwicmV0Iiwib3V0IiwidG9IZXgiLCJieXRlcyIsIm5ld0J1ZiIsInNsaWNlTGVuIiwiY2hlY2tPZmZzZXQiLCJleHQiLCJyZWFkVUludExFIiwibm9Bc3NlcnQiLCJtdWwiLCJyZWFkVUludEJFIiwicmVhZFVJbnQ4IiwicmVhZFVJbnQxNkxFIiwicmVhZFVJbnQzMkxFIiwicmVhZFVJbnQzMkJFIiwicmVhZEludExFIiwicG93IiwicmVhZEludEJFIiwicmVhZEludDgiLCJyZWFkSW50MTZMRSIsInJlYWRJbnQxNkJFIiwicmVhZEludDMyTEUiLCJyZWFkSW50MzJCRSIsInJlYWRGbG9hdExFIiwicmVhZEZsb2F0QkUiLCJyZWFkRG91YmxlTEUiLCJyZWFkRG91YmxlQkUiLCJjaGVja0ludCIsIndyaXRlVUludExFIiwibWF4Qnl0ZXMiLCJ3cml0ZVVJbnRCRSIsIndyaXRlVUludDgiLCJmbG9vciIsIm9iamVjdFdyaXRlVUludDE2IiwibGl0dGxlRW5kaWFuIiwid3JpdGVVSW50MTZMRSIsIndyaXRlVUludDE2QkUiLCJvYmplY3RXcml0ZVVJbnQzMiIsIndyaXRlVUludDMyTEUiLCJ3cml0ZVVJbnQzMkJFIiwid3JpdGVJbnRMRSIsImxpbWl0Iiwic3ViIiwid3JpdGVJbnRCRSIsIndyaXRlSW50OCIsIndyaXRlSW50MTZMRSIsIndyaXRlSW50MTZCRSIsIndyaXRlSW50MzJMRSIsIndyaXRlSW50MzJCRSIsImNoZWNrSUVFRTc1NCIsIndyaXRlRmxvYXQiLCJ3cml0ZUZsb2F0TEUiLCJ3cml0ZUZsb2F0QkUiLCJ3cml0ZURvdWJsZSIsIndyaXRlRG91YmxlTEUiLCJ3cml0ZURvdWJsZUJFIiwidGFyZ2V0U3RhcnQiLCJzZXQiLCJjb2RlIiwiY2hhckNvZGVBdCIsIklOVkFMSURfQkFTRTY0X1JFIiwiYmFzZTY0Y2xlYW4iLCJzdHJpbmd0cmltIiwidHJpbSIsInVuaXRzIiwiSW5maW5pdHkiLCJsZWFkU3Vycm9nYXRlIiwiYnl0ZUFycmF5IiwiaGkiLCJsbyIsInRvQnl0ZUFycmF5Iiwic3JjIiwiZHN0IiwiZmFjdG9yeSIsImxvbmciLCJjb21tb25qc0dsb2JhbCIsInNlbGYiLCJjcmVhdGVDb21tb25qc01vZHVsZSIsImZuIiwiZ2V0Q2pzRXhwb3J0RnJvbU5hbWVzcGFjZSIsIk1hcCIsIl9rZXlzIiwiX3ZhbHVlcyIsImVudHJ5IiwidiIsImNsZWFyIiwic3BsaWNlIiwiZW50cmllcyIsImluZGV4IiwibmV4dCIsImRvbmUiLCJmb3JFYWNoIiwiY2FsbGJhY2siLCJoYXMiLCJrZXlzIiwidmFsdWVzIiwibWFwXzEiLCJ0b0V4dGVuZGVkSlNPTiIsIm9wdGlvbnMiLCJyZWxheGVkIiwidG9OdW1iZXIiLCIkbnVtYmVyTG9uZyIsImZyb21FeHRlbmRlZEpTT04iLCJkb2MiLCJyZXN1bHQiLCJsb25nXzEiLCJfY2xhc3NDYWxsQ2hlY2siLCJpbnN0YW5jZSIsIkNvbnN0cnVjdG9yIiwiX2RlZmluZVByb3BlcnRpZXMiLCJwcm9wcyIsImRlc2NyaXB0b3IiLCJ3cml0YWJsZSIsIl9jcmVhdGVDbGFzcyIsInByb3RvUHJvcHMiLCJzdGF0aWNQcm9wcyIsIkRvdWJsZSIsInZhbHVlT2YiLCIkbnVtYmVyRG91YmxlIiwicGFyc2VGbG9hdCIsImRvdWJsZV8xIiwiX3R5cGVvZiIsIl90eXBlb2YyIiwiaXRlcmF0b3IiLCJfY2xhc3NDYWxsQ2hlY2skMSIsIl9kZWZpbmVQcm9wZXJ0aWVzJDEiLCJfY3JlYXRlQ2xhc3MkMSIsIl9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuIiwiX2Fzc2VydFRoaXNJbml0aWFsaXplZCIsIlJlZmVyZW5jZUVycm9yIiwiX2dldFByb3RvdHlwZU9mIiwic2V0UHJvdG90eXBlT2YiLCJnZXRQcm90b3R5cGVPZiIsIl9pbmhlcml0cyIsInN1YkNsYXNzIiwic3VwZXJDbGFzcyIsImNyZWF0ZSIsIl9zZXRQcm90b3R5cGVPZiIsIlRpbWVzdGFtcCIsIl9Mb25nIiwibG93IiwiaGlnaCIsIl90aGlzIiwiaXNMb25nIiwiJHRpbWVzdGFtcCIsInQiLCJmcm9tSW50IiwiZnJvbU51bWJlciIsImZyb21CaXRzIiwibG93Qml0cyIsImhpZ2hCaXRzIiwib3B0X3JhZGl4IiwidGltZXN0YW1wIiwiZW1wdHkiLCJlbXB0eSQxIiwicmVxdWlyZSQkMCIsIm5vcm1hbGl6ZWRGdW5jdGlvblN0cmluZyIsImluc2VjdXJlUmFuZG9tQnl0ZXMiLCJyYW5kb20iLCJyYW5kb21CeXRlcyIsImNyeXB0byIsImdldFJhbmRvbVZhbHVlcyIsInV0aWxzIiwic2V0VGltZW91dCIsImNsZWFyVGltZW91dCIsInBlcmZvcm1hbmNlIiwicGVyZm9ybWFuY2VOb3ciLCJub3ciLCJtb3pOb3ciLCJtc05vdyIsIm9Ob3ciLCJ3ZWJraXROb3ciLCJEYXRlIiwiZ2V0VGltZSIsImluaGVyaXRzIiwiY3RvciIsInN1cGVyQ3RvciIsInN1cGVyXyIsIlRlbXBDdG9yIiwiaW5oZXJpdHMkMSIsIl90eXBlb2YkMSIsImZvcm1hdFJlZ0V4cCIsImZvcm1hdCIsImYiLCJpc1N0cmluZyIsIm9iamVjdHMiLCJhcmdzIiwiSlNPTiIsInN0cmluZ2lmeSIsIl8iLCJpc051bGwiLCJpc09iamVjdCIsImRlcHJlY2F0ZSIsIm1zZyIsImlzVW5kZWZpbmVkIiwicHJvY2VzcyIsIndhcm5lZCIsImRlcHJlY2F0ZWQiLCJjb25zb2xlIiwiZXJyb3IiLCJkZWJ1Z3MiLCJkZWJ1Z0Vudmlyb24iLCJkZWJ1Z2xvZyIsInRvVXBwZXJDYXNlIiwiUmVnRXhwIiwidGVzdCIsInBpZCIsIm9wdHMiLCJjdHgiLCJzZWVuIiwic3R5bGl6ZSIsInN0eWxpemVOb0NvbG9yIiwiZGVwdGgiLCJjb2xvcnMiLCJpc0Jvb2xlYW4iLCJzaG93SGlkZGVuIiwiX2V4dGVuZCIsImN1c3RvbUluc3BlY3QiLCJzdHlsaXplV2l0aENvbG9yIiwiZm9ybWF0VmFsdWUiLCJzdHlsZXMiLCJzdHlsZVR5cGUiLCJzdHlsZSIsImFycmF5VG9IYXNoIiwiaGFzaCIsImlkeCIsInJlY3Vyc2VUaW1lcyIsImlzRnVuY3Rpb24iLCJwcmltaXRpdmUiLCJmb3JtYXRQcmltaXRpdmUiLCJ2aXNpYmxlS2V5cyIsImdldE93blByb3BlcnR5TmFtZXMiLCJpc0Vycm9yIiwiZm9ybWF0RXJyb3IiLCJpc1JlZ0V4cCIsImlzRGF0ZSIsImJhc2UiLCJicmFjZXMiLCJ0b1VUQ1N0cmluZyIsIm91dHB1dCIsImZvcm1hdEFycmF5IiwiZm9ybWF0UHJvcGVydHkiLCJwb3AiLCJyZWR1Y2VUb1NpbmdsZVN0cmluZyIsInNpbXBsZSIsImlzTnVtYmVyIiwiZGVzYyIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsInNwbGl0IiwibGluZSIsInJlZHVjZSIsInByZXYiLCJjdXIiLCJhciIsImlzTnVsbE9yVW5kZWZpbmVkIiwiaXNTeW1ib2wiLCJyZSIsIm9iamVjdFRvU3RyaW5nIiwiaXNQcmltaXRpdmUiLCJtYXliZUJ1ZiIsInBhZCIsIm1vbnRocyIsInRpbWVzdGFtcCQxIiwidGltZSIsImdldEhvdXJzIiwiZ2V0TWludXRlcyIsImdldFNlY29uZHMiLCJnZXREYXRlIiwiZ2V0TW9udGgiLCJsb2ciLCJvcmlnaW4iLCJhZGQiLCJwcm9wIiwidXRpbCIsInV0aWwkMSIsInV0aWwkMiIsIl9jbGFzc0NhbGxDaGVjayQyIiwiX2RlZmluZVByb3BlcnRpZXMkMiIsIl9jcmVhdGVDbGFzcyQyIiwiQnVmZmVyJDEiLCJyYW5kb21CeXRlcyQxIiwiZGVwcmVjYXRlJDEiLCJQUk9DRVNTX1VOSVFVRSIsImNoZWNrRm9ySGV4UmVnRXhwIiwiaGFzQnVmZmVyVHlwZSIsImVyciIsImhleFRhYmxlIiwiX2kiLCJkZWNvZGVMb29rdXAiLCJfQnVmZmVyIiwiY29udmVydFRvSGV4IiwibWFrZU9iamVjdElkRXJyb3IiLCJpbnZhbGlkU3RyaW5nIiwiaW52YWxpZENoYXJhY3RlciIsIk9iamVjdElkIiwiZ2VuZXJhdGUiLCJjYWNoZUhleFN0cmluZyIsIl9faWQiLCJ2YWxpZCIsImlzVmFsaWQiLCJjcmVhdGVGcm9tSGV4U3RyaW5nIiwidG9IZXhTdHJpbmciLCJoZXhTdHJpbmciLCJfaTIiLCJoZXhDaGFyIiwib3RoZXJJZCIsImdldFRpbWVzdGFtcCIsInNldFRpbWUiLCIkb2lkIiwiZ2V0SW5jIiwiaW5jIiwiYnVmZmVyJCQxIiwiY3JlYXRlUGsiLCJjcmVhdGVGcm9tVGltZSIsImdldF9pbmMiLCJjdXN0b20iLCJvYmplY3RpZCIsIl9jbGFzc0NhbGxDaGVjayQzIiwiX2RlZmluZVByb3BlcnRpZXMkMyIsIl9jcmVhdGVDbGFzcyQzIiwiYWxwaGFiZXRpemUiLCJzb3J0IiwiQlNPTlJlZ0V4cCIsInBhdHRlcm4iLCIkcmVndWxhckV4cHJlc3Npb24iLCJyZWdleHAiLCJfY2xhc3NDYWxsQ2hlY2skNCIsIl9kZWZpbmVQcm9wZXJ0aWVzJDQiLCJfY3JlYXRlQ2xhc3MkNCIsIkJTT05TeW1ib2wiLCIkc3ltYm9sIiwic3ltYm9sIiwiX2NsYXNzQ2FsbENoZWNrJDUiLCJfZGVmaW5lUHJvcGVydGllcyQ1IiwiX2NyZWF0ZUNsYXNzJDUiLCJJbnQzMiIsIiRudW1iZXJJbnQiLCJpbnRfMzIiLCJfY2xhc3NDYWxsQ2hlY2skNiIsIl9kZWZpbmVQcm9wZXJ0aWVzJDYiLCJfY3JlYXRlQ2xhc3MkNiIsIkNvZGUiLCJzY29wZSIsIiRjb2RlIiwiJHNjb3BlIiwiQnVmZmVyJDIiLCJQQVJTRV9TVFJJTkdfUkVHRVhQIiwiUEFSU0VfSU5GX1JFR0VYUCIsIlBBUlNFX05BTl9SRUdFWFAiLCJFWFBPTkVOVF9NQVgiLCJFWFBPTkVOVF9NSU4iLCJFWFBPTkVOVF9CSUFTIiwiTUFYX0RJR0lUUyIsIk5BTl9CVUZGRVIiLCJyZXZlcnNlIiwiSU5GX05FR0FUSVZFX0JVRkZFUiIsIklORl9QT1NJVElWRV9CVUZGRVIiLCJFWFBPTkVOVF9SRUdFWCIsImlzRGlnaXQiLCJkaXZpZGV1MTI4IiwiRElWSVNPUiIsIl9yZW0iLCJwYXJ0cyIsInF1b3RpZW50IiwicmVtIiwic2hpZnRMZWZ0IiwiZGl2IiwibW9kdWxvIiwibXVsdGlwbHk2NHgyIiwibGVmdCIsInJpZ2h0IiwibGVmdEhpZ2giLCJzaGlmdFJpZ2h0VW5zaWduZWQiLCJsZWZ0TG93IiwiZ2V0TG93Qml0cyIsInJpZ2h0SGlnaCIsInJpZ2h0TG93IiwicHJvZHVjdEhpZ2giLCJtdWx0aXBseSIsInByb2R1Y3RNaWQiLCJwcm9kdWN0TWlkMiIsInByb2R1Y3RMb3ciLCJsZXNzVGhhbiIsInVobGVmdCIsInVocmlnaHQiLCJ1bGxlZnQiLCJ1bHJpZ2h0IiwiaW52YWxpZEVyciIsIm1lc3NhZ2UiLCJEZWNpbWFsMTI4IiwiaXNOZWdhdGl2ZSIsInNhd1JhZGl4IiwiZm91bmROb25aZXJvIiwic2lnbmlmaWNhbnREaWdpdHMiLCJuRGlnaXRzUmVhZCIsIm5EaWdpdHMiLCJyYWRpeFBvc2l0aW9uIiwiZmlyc3ROb25aZXJvIiwiZGlnaXRzIiwibkRpZ2l0c1N0b3JlZCIsImRpZ2l0c0luc2VydCIsImZpcnN0RGlnaXQiLCJsYXN0RGlnaXQiLCJleHBvbmVudCIsInNpZ25pZmljYW5kSGlnaCIsInNpZ25pZmljYW5kTG93IiwiYmlhc2VkRXhwb25lbnQiLCJzdHJpbmdNYXRjaCIsImluZk1hdGNoIiwibmFuTWF0Y2giLCJ1bnNpZ25lZE51bWJlciIsImV4cFNpZ24iLCJleHBOdW1iZXIiLCJkaWdpdHNTdHJpbmciLCJfZGlnaXRzU3RyaW5nIiwiZW5kT2ZTdHJpbmciLCJyb3VuZERpZ2l0Iiwicm91bmRCaXQiLCJkSWR4IiwiX2RJZHgiLCJfZElkeDIiLCJzaWduaWZpY2FuZCIsImRlYyIsImFuZCIsIm9yIiwiQ09NQklOQVRJT05fTUFTSyIsIkVYUE9ORU5UX01BU0siLCJDT01CSU5BVElPTl9JTkZJTklUWSIsIkNPTUJJTkFUSU9OX05BTiIsIm1pZGgiLCJtaWRsIiwiY29tYmluYXRpb24iLCJiaWFzZWRfZXhwb25lbnQiLCJzaWduaWZpY2FuZF9kaWdpdHMiLCJzY2llbnRpZmljX2V4cG9uZW50IiwiaXNfemVybyIsInNpZ25pZmljYW5kX21zYiIsInNpZ25pZmljYW5kMTI4IiwiayIsIlpFUk8iLCJsZWFzdF9kaWdpdHMiLCJyYWRpeF9wb3NpdGlvbiIsIl9pMyIsIl9pNCIsIiRudW1iZXJEZWNpbWFsIiwiZGVjaW1hbDEyOCIsIl9jbGFzc0NhbGxDaGVjayQ3IiwiX2RlZmluZVByb3BlcnRpZXMkNyIsIl9jcmVhdGVDbGFzcyQ3IiwiTWluS2V5IiwiJG1pbktleSIsIm1pbl9rZXkiLCJfY2xhc3NDYWxsQ2hlY2skOCIsIl9kZWZpbmVQcm9wZXJ0aWVzJDgiLCJfY3JlYXRlQ2xhc3MkOCIsIk1heEtleSIsIiRtYXhLZXkiLCJtYXhfa2V5IiwiX2NsYXNzQ2FsbENoZWNrJDkiLCJfZGVmaW5lUHJvcGVydGllcyQ5IiwiX2NyZWF0ZUNsYXNzJDkiLCJEQlJlZiIsImNvbGxlY3Rpb24iLCJvaWQiLCJkYiIsImZpZWxkcyIsInNoaWZ0IiwiYXNzaWduIiwiJHJlZiIsIiRpZCIsIiRkYiIsImRiX3JlZiIsIl9jbGFzc0NhbGxDaGVjayRhIiwiX2RlZmluZVByb3BlcnRpZXMkYSIsIl9jcmVhdGVDbGFzcyRhIiwiQnVmZmVyJDMiLCJCaW5hcnkiLCJzdWJUeXBlIiwic3ViX3R5cGUiLCJCU09OX0JJTkFSWV9TVUJUWVBFX0RFRkFVTFQiLCJwb3NpdGlvbiIsIndyaXRlU3RyaW5nVG9BcnJheSIsIkJVRkZFUl9TSVpFIiwicHV0IiwiYnl0ZV92YWx1ZSIsImRlY29kZWRfYnl0ZSIsIl9idWZmZXIiLCJpc1VpbnQ4QXJyYXkiLCJhc1JhdyIsIm5ld0J1ZmZlciIsImNvbnZlcnRBcnJheXRvVXRmOEJpbmFyeVN0cmluZyIsImJhc2U2NFN0cmluZyIsIiRiaW5hcnkiLCJzdGFydEluZGV4IiwiZW5kSW5kZXgiLCJTVUJUWVBFX0RFRkFVTFQiLCJTVUJUWVBFX0ZVTkNUSU9OIiwiU1VCVFlQRV9CWVRFX0FSUkFZIiwiU1VCVFlQRV9VVUlEX09MRCIsIlNVQlRZUEVfVVVJRCIsIlNVQlRZUEVfTUQ1IiwiU1VCVFlQRV9VU0VSX0RFRklORUQiLCJiaW5hcnkiLCJjb25zdGFudHMiLCJCU09OX0lOVDMyX01BWCIsIkJTT05fSU5UMzJfTUlOIiwiQlNPTl9JTlQ2NF9NQVgiLCJCU09OX0lOVDY0X01JTiIsIkpTX0lOVF9NQVgiLCJKU19JTlRfTUlOIiwiQlNPTl9EQVRBX05VTUJFUiIsIkJTT05fREFUQV9TVFJJTkciLCJCU09OX0RBVEFfT0JKRUNUIiwiQlNPTl9EQVRBX0FSUkFZIiwiQlNPTl9EQVRBX0JJTkFSWSIsIkJTT05fREFUQV9VTkRFRklORUQiLCJCU09OX0RBVEFfT0lEIiwiQlNPTl9EQVRBX0JPT0xFQU4iLCJCU09OX0RBVEFfREFURSIsIkJTT05fREFUQV9OVUxMIiwiQlNPTl9EQVRBX1JFR0VYUCIsIkJTT05fREFUQV9EQlBPSU5URVIiLCJCU09OX0RBVEFfQ09ERSIsIkJTT05fREFUQV9TWU1CT0wiLCJCU09OX0RBVEFfQ09ERV9XX1NDT1BFIiwiQlNPTl9EQVRBX0lOVCIsIkJTT05fREFUQV9USU1FU1RBTVAiLCJCU09OX0RBVEFfTE9ORyIsIkJTT05fREFUQV9ERUNJTUFMMTI4IiwiQlNPTl9EQVRBX01JTl9LRVkiLCJCU09OX0RBVEFfTUFYX0tFWSIsIkJTT05fQklOQVJZX1NVQlRZUEVfRlVOQ1RJT04iLCJCU09OX0JJTkFSWV9TVUJUWVBFX0JZVEVfQVJSQVkiLCJCU09OX0JJTkFSWV9TVUJUWVBFX1VVSUQiLCJCU09OX0JJTkFSWV9TVUJUWVBFX01ENSIsIkJTT05fQklOQVJZX1NVQlRZUEVfVVNFUl9ERUZJTkVEIiwiX3R5cGVvZiQyIiwia2V5c1RvQ29kZWNzIiwiZGVzZXJpYWxpemVWYWx1ZSIsIiR1bmRlZmluZWQiLCJmaWx0ZXIiLCJzdGFydHNXaXRoIiwiJGRhdGUiLCJkYXRlIiwicGFyc2UiLCIkZGJQb2ludGVyIiwiZG9sbGFyS2V5cyIsInN0cmljdCIsInJlcGxhY2VyIiwic3BhY2UiLCJzZXJpYWxpemVBcnJheSIsInNlcmlhbGl6ZURvY3VtZW50Iiwic2VyaWFsaXplIiwiYnNvbiIsImRlc2VyaWFsaXplIiwiZWpzb24iLCJzZXJpYWxpemVWYWx1ZSIsImdldElTT1N0cmluZyIsImlzb1N0ciIsInRvSVNPU3RyaW5nIiwiZ2V0VVRDTWlsbGlzZWNvbmRzIiwiZGF0ZU51bSIsImluUmFuZ2UiLCJpbnQzMlJhbmdlIiwiaW50NjRSYW5nZSIsImZsYWdzIiwicngiLCJzb3VyY2UiLCJCU09OX1RZUEVfTUFQUElOR1MiLCJzdWJ0eXBlIiwibmFtZXNwYWNlIiwiTG9uZyIsImxvd18iLCJoaWdoXyIsInVuc2lnbmVkIiwidW5zaWduZWRfIiwiT2JqZWN0SUQiLCJic29udHlwZSIsIl9ic29udHlwZSIsIl9kb2MiLCJfZG9jMiIsIm1hcHBlciIsImV4dGVuZGVkX2pzb24iLCJGSVJTVF9CSVQiLCJGSVJTVF9UV09fQklUUyIsIkZJUlNUX1RIUkVFX0JJVFMiLCJGSVJTVF9GT1VSX0JJVFMiLCJGSVJTVF9GSVZFX0JJVFMiLCJUV09fQklUX0NIQVIiLCJUSFJFRV9CSVRfQ0hBUiIsIkZPVVJfQklUX0NIQVIiLCJDT05USU5VSU5HX0NIQVIiLCJ2YWxpZGF0ZVV0ZjgiLCJjb250aW51YXRpb24iLCJieXRlIiwidmFsaWRhdGVVdGY4XzEiLCJ2YWxpZGF0ZV91dGY4IiwiQnVmZmVyJDQiLCJ2YWxpZGF0ZVV0ZjgkMSIsIkpTX0lOVF9NQVhfTE9ORyIsIkpTX0lOVF9NSU5fTE9ORyIsImZ1bmN0aW9uQ2FjaGUiLCJkZXNlcmlhbGl6ZSQxIiwiYWxsb3dPYmplY3RTbWFsbGVyVGhhbkJ1ZmZlclNpemUiLCJkZXNlcmlhbGl6ZU9iamVjdCIsImV2YWxGdW5jdGlvbnMiLCJjYWNoZUZ1bmN0aW9ucyIsImNhY2hlRnVuY3Rpb25zQ3JjMzIiLCJjcmMzMiIsImZpZWxkc0FzUmF3IiwicmF3IiwiYnNvblJlZ0V4cCIsInByb21vdGVCdWZmZXJzIiwicHJvbW90ZUxvbmdzIiwicHJvbW90ZVZhbHVlcyIsImFycmF5SW5kZXgiLCJlbGVtZW50VHlwZSIsInN0cmluZ1NpemUiLCJfaW5kZXgiLCJvYmplY3RTaXplIiwiX2luZGV4MiIsIl9vYmplY3RTaXplIiwiYXJyYXlPcHRpb25zIiwic3RvcEluZGV4IiwiX2xvd0JpdHMiLCJfaGlnaEJpdHMiLCJsb25nJCQxIiwibGVzc1RoYW5PckVxdWFsIiwiZ3JlYXRlclRoYW5PckVxdWFsIiwiZGVjaW1hbDEyOCQkMSIsInRvT2JqZWN0IiwiYmluYXJ5U2l6ZSIsInRvdGFsQmluYXJ5U2l6ZSIsInJlZ0V4cE9wdGlvbnMiLCJvcHRpb25zQXJyYXkiLCJfc291cmNlIiwiX3JlZ0V4cE9wdGlvbnMiLCJfc3RyaW5nU2l6ZSIsIl9sb3dCaXRzMiIsIl9oaWdoQml0czIiLCJfc3RyaW5nU2l6ZTIiLCJmdW5jdGlvblN0cmluZyIsImlzb2xhdGVFdmFsV2l0aEhhc2giLCJpc29sYXRlRXZhbCIsInRvdGFsU2l6ZSIsIl9zdHJpbmdTaXplMyIsIl9mdW5jdGlvblN0cmluZyIsIl9pbmRleDMiLCJfb2JqZWN0U2l6ZTIiLCJzY29wZU9iamVjdCIsIl9oYXNoIiwiX3N0cmluZ1NpemU0Iiwib2lkQnVmZmVyIiwiX29pZCIsImJpbmQiLCJkZXNlcmlhbGl6ZXIiLCJyZWFkSUVFRTc1NCIsImVuZGlhbiIsIm1MZW4iLCJuQnl0ZXMiLCJiQkUiLCJlTGVuIiwiZU1heCIsImVCaWFzIiwibkJpdHMiLCJOYU4iLCJ3cml0ZUlFRUU3NTQiLCJydCIsImFicyIsIkxOMiIsImZsb2F0X3BhcnNlciIsIl90eXBlb2YkMyIsIkJ1ZmZlciQ1Iiwid3JpdGVJRUVFNzU0JDEiLCJub3JtYWxpemVkRnVuY3Rpb25TdHJpbmckMSIsInJlZ2V4cCQxIiwiaWdub3JlS2V5cyIsIlNldCIsImlzRGF0ZSQxIiwiaXNSZWdFeHAkMSIsInNlcmlhbGl6ZVN0cmluZyIsIm51bWJlck9mV3JpdHRlbkJ5dGVzIiwic2VyaWFsaXplTnVtYmVyIiwiX251bWJlck9mV3JpdHRlbkJ5dGVzIiwiX251bWJlck9mV3JpdHRlbkJ5dGVzMiIsImxvbmdWYWwiLCJnZXRIaWdoQml0cyIsIl9udW1iZXJPZldyaXR0ZW5CeXRlczMiLCJzZXJpYWxpemVOdWxsIiwic2VyaWFsaXplQm9vbGVhbiIsInNlcmlhbGl6ZURhdGUiLCJkYXRlSW5NaWxpcyIsInNlcmlhbGl6ZVJlZ0V4cCIsImlnbm9yZUNhc2UiLCJtdWx0aWxpbmUiLCJzZXJpYWxpemVCU09OUmVnRXhwIiwic2VyaWFsaXplTWluTWF4Iiwic2VyaWFsaXplT2JqZWN0SWQiLCJzZXJpYWxpemVCdWZmZXIiLCJzZXJpYWxpemVPYmplY3QiLCJjaGVja0tleXMiLCJzZXJpYWxpemVGdW5jdGlvbnMiLCJpZ25vcmVVbmRlZmluZWQiLCJwYXRoIiwic2VyaWFsaXplSW50byIsInNlcmlhbGl6ZURlY2ltYWwxMjgiLCJzZXJpYWxpemVMb25nIiwic2VyaWFsaXplSW50MzIiLCJzZXJpYWxpemVEb3VibGUiLCJzZXJpYWxpemVGdW5jdGlvbiIsInNlcmlhbGl6ZUNvZGUiLCJjb2RlU2l6ZSIsIl9udW1iZXJPZldyaXR0ZW5CeXRlczQiLCJzZXJpYWxpemVCaW5hcnkiLCJzZXJpYWxpemVTeW1ib2wiLCJzZXJpYWxpemVEQlJlZiIsInN0YXJ0aW5nSW5kZXgiLCJ0b0JTT04iLCJfa2V5IiwiX3ZhbHVlIiwiX3R5cGUiLCJfa2V5MiIsIl92YWx1ZTIiLCJfdHlwZTIiLCJzZXJpYWxpemVyIiwiX3R5cGVvZiQ0IiwiQnVmZmVyJDYiLCJub3JtYWxpemVkRnVuY3Rpb25TdHJpbmckMiIsImlzRGF0ZSQyIiwiY2FsY3VsYXRlT2JqZWN0U2l6ZSIsInRvdGFsTGVuZ3RoIiwiY2FsY3VsYXRlRWxlbWVudCIsIm9yZGVyZWRfdmFsdWVzIiwiY2FsY3VsYXRlX3NpemUiLCJCdWZmZXIkNyIsImVuc3VyZV9idWZmZXIiLCJlbnN1cmVCdWZmZXIiLCJwb3RlbnRpYWxCdWZmZXIiLCJCdWZmZXIkOCIsIk1BWFNJWkUiLCJidWZmZXIkMSIsInNldEludGVybmFsQnVmZmVyU2l6ZSIsInNlcmlhbGl6ZSQxIiwibWluSW50ZXJuYWxCdWZmZXJTaXplIiwic2VyaWFsaXphdGlvbkluZGV4IiwiZmluaXNoZWRCdWZmZXIiLCJzZXJpYWxpemVXaXRoQnVmZmVyQW5kSW5kZXgiLCJmaW5hbEJ1ZmZlciIsImRlc2VyaWFsaXplJDIiLCJjYWxjdWxhdGVPYmplY3RTaXplJDEiLCJkZXNlcmlhbGl6ZVN0cmVhbSIsIm51bWJlck9mRG9jdW1lbnRzIiwiZG9jdW1lbnRzIiwiZG9jU3RhcnRJbmRleCIsIkVKU09OIiwiYnNvbl8xIiwiYnNvbl8yIiwiYnNvbl8zIiwiYnNvbl80IiwiYnNvbl81IiwiYnNvbl82IiwiYnNvbl83IiwiYnNvbl84IiwiYnNvbl85IiwiYnNvbl8xMCIsImJzb25fMTEiLCJic29uXzEyIiwiYnNvbl8xMyIsImJzb25fMTQiLCJic29uXzE1IiwiYnNvbl8xNiIsImJzb25fMTciLCJic29uXzE4IiwiYnNvbl8xOSIsImJzb25fMjAiLCJic29uXzIxIiwiYnNvbl8yMiIsImJzb25fMjMiLCJic29uXzI0IiwiYnNvbl8yNSIsImJzb25fMjYiLCJic29uXzI3IiwiYnNvbl8yOCIsImJzb25fMjkiLCJic29uXzMwIiwiYnNvbl8zMSIsImJzb25fMzIiLCJic29uXzMzIiwiYnNvbl8zNCIsImJzb25fMzUiLCJic29uXzM2IiwiYnNvbl8zNyIsImJzb25fMzgiLCJic29uXzM5IiwiYnNvbl80MCIsImJzb25fNDEiLCJic29uXzQyIiwiYnNvbl80MyIsImJzb25fNDQiLCJic29uXzQ1IiwiYnNvbl80NiIsImJzb25fNDciLCJic29uXzQ4IiwiYnNvbl80OSIsImJzb25fNTAiLCJic29uXzUxIiwiYnNvbl81MiIsImJzb25fNTMiLCJic29uXzU0IiwibG9va3VwIiwicmV2TG9va3VwIiwiQXJyIiwiZ2V0TGVucyIsImI2NCIsInZhbGlkTGVuIiwicGxhY2VIb2xkZXJzTGVuIiwibGVucyIsIl9ieXRlTGVuZ3RoIiwidG1wIiwiY3VyQnl0ZSIsInRyaXBsZXRUb0Jhc2U2NCIsIm51bSIsImVuY29kZUNodW5rIiwidWludDgiLCJleHRyYUJ5dGVzIiwibWF4Q2h1bmtMZW5ndGgiLCJsZW4yIiwiaXNMRSIsIndhc20iLCJXZWJBc3NlbWJseSIsIkluc3RhbmNlIiwiTW9kdWxlIiwiX19pc0xvbmdfXyIsIklOVF9DQUNIRSIsIlVJTlRfQ0FDSEUiLCJjYWNoZWRPYmoiLCJjYWNoZSIsIlVaRVJPIiwiVFdPX1BXUl82NF9EQkwiLCJNQVhfVU5TSUdORURfVkFMVUUiLCJUV09fUFdSXzYzX0RCTCIsIk1JTl9WQUxVRSIsIk1BWF9WQUxVRSIsIm5lZyIsIlRXT19QV1JfMzJfREJMIiwicG93X2RibCIsInJhZGl4IiwicmFkaXhUb1Bvd2VyIiwicG93ZXIiLCJmcm9tVmFsdWUiLCJUV09fUFdSXzE2X0RCTCIsIlRXT19QV1JfMjRfREJMIiwiVFdPX1BXUl8yNCIsIk9ORSIsIlVPTkUiLCJORUdfT05FIiwiTG9uZ1Byb3RvdHlwZSIsInRvSW50IiwiaXNaZXJvIiwiZXEiLCJyYWRpeExvbmciLCJyZW0xIiwicmVtRGl2IiwiaW50dmFsIiwiZ2V0SGlnaEJpdHNVbnNpZ25lZCIsImdldExvd0JpdHNVbnNpZ25lZCIsImdldE51bUJpdHNBYnMiLCJiaXQiLCJlcXoiLCJpc1Bvc2l0aXZlIiwiaXNPZGQiLCJpc0V2ZW4iLCJvdGhlciIsIm5vdEVxdWFscyIsIm5lcSIsIm5lIiwiY29tcCIsImx0IiwibHRlIiwibGUiLCJncmVhdGVyVGhhbiIsImd0IiwiZ3RlIiwiZ2UiLCJ0aGlzTmVnIiwib3RoZXJOZWciLCJuZWdhdGUiLCJub3QiLCJhZGRlbmQiLCJhNDgiLCJhMzIiLCJhMTYiLCJhMDAiLCJiNDgiLCJiMzIiLCJiMTYiLCJiMDAiLCJjNDgiLCJjMzIiLCJjMTYiLCJjMDAiLCJzdWJ0cmFjdCIsInN1YnRyYWhlbmQiLCJtdWx0aXBsaWVyIiwiZ2V0X2hpZ2giLCJkaXZpZGUiLCJkaXZpc29yIiwiZGl2X3UiLCJkaXZfcyIsImFwcHJveCIsImhhbGZUaGlzIiwic2hyIiwic2hsIiwidG9VbnNpZ25lZCIsInNocnUiLCJsb2cyIiwiY2VpbCIsImRlbHRhIiwiYXBwcm94UmVzIiwiYXBwcm94UmVtIiwicmVtX3UiLCJyZW1fcyIsIm1vZCIsInhvciIsIm51bUJpdHMiLCJzaGlmdFJpZ2h0Iiwic2hyX3UiLCJ0b1NpZ25lZCIsInRvQnl0ZXMiLCJ0b0J5dGVzTEUiLCJ0b0J5dGVzQkUiLCJmcm9tQnl0ZXMiLCJmcm9tQnl0ZXNMRSIsImZyb21CeXRlc0JFIiwiQlNPTiIsIkJzb24iLCJTZGxQYWNrZXQiLCJlbmNyeXB0aW9uIiwiZnJhbWVUeXBlIiwiZnJhbWVJbmZvIiwiZGF0YVNpemUiLCJtZXNzYWdlSUQiLCJwYXlsb2FkIiwiYnl0ZXNUb1dyaXRlIiwiX3ZlcnNpb24iLCJfZW5jcnlwdGlvbiIsIl9mcmFtZVR5cGUiLCJfc2VydmljZVR5cGUiLCJfZnJhbWVJbmZvIiwiX3Nlc3Npb25JRCIsIl9kYXRhU2l6ZSIsIl9tZXNzYWdlSUQiLCJfcGF5bG9hZCIsIl9vZmZzZXQiLCJfYnl0ZXNUb1dyaXRlIiwiX2Jzb25QYXlsb2FkIiwiZ2V0VmVyc2lvbiIsImdldEVuY3J5cHRpb24iLCJnZXRTZXJ2aWNlVHlwZSIsImdldEZyYW1lSW5mbyIsImdldFNlc3Npb25JRCIsImdldE1lc3NhZ2VJRCIsImdldERhdGFTaXplIiwic2V0UGF5bG9hZCIsImdldFBheWxvYWQiLCJnZXRFbmNyeXB0aW9uQml0IiwiRU5DUllQVElPTl9NQVNLIiwiZ2V0RnJhbWVUeXBlIiwiY29uc3RydWN0UGFja2V0IiwiY29udHJvbEZyYW1lSW5mbyIsImRhdGFWaWV3IiwiZGF0YVZpZXdJbmRleCIsIkhFQURFUl9TSVpFIiwiSEVBREVSX1NJWkVfVjEiLCJ0b1BhY2tldCIsInB1dFRhZyIsInRhZyIsImdldFRhZyIsIkVYVFJBX1BBUkNFTF9EQVRBX0xFTkdUSCIsIlNFUlZJQ0VfVFlQRV9DT05UUk9MIiwiU0VSVklDRV9UWVBFX1JQQyIsIlNFUlZJQ0VfVFlQRV9QQ00iLCJTRVJWSUNFX1RZUEVfVklERU8iLCJTRVJWSUNFX1RZUEVfQlVMS19EQVRBIiwiRlJBTUVfSU5GT19IRUFSVF9CRUFUIiwiRlJBTUVfSU5GT19TVEFSVF9TRVJWSUNFIiwiRlJBTUVfSU5GT19TVEFSVF9TRVJWSUNFX0FDSyIsIkZSQU1FX0lORk9fU1RBUlRfU0VSVklDRV9OQUsiLCJGUkFNRV9JTkZPX0VORF9TRVJWSUNFIiwiRlJBTUVfSU5GT19FTkRfU0VSVklDRV9BQ0siLCJGUkFNRV9JTkZPX0VORF9TRVJWSUNFX05BSyIsIkZSQU1FX0lORk9fUkVHSVNURVJfU0VDT05EQVJZX1RSQU5TUE9SVCIsIkZSQU1FX0lORk9fUkVHSVNURVJfU0VDT05EQVJZX1RSQU5TUE9SVF9BQ0siLCJGUkFNRV9JTkZPX1JFR0lTVEVSX1NFQ09OREFSWV9UUkFOU1BPUlRfTkFLIiwiRlJBTUVfSU5GT19UUkFOU1BPUlRfRVZFTlRfVVBEQVRFIiwiRlJBTUVfSU5GT19TRVJWSUNFX0RBVEFfQUNLIiwiRlJBTUVfSU5GT19IRUFSVF9CRUFUX0FDSyIsIkZSQU1FX0lORk9fRklOQUxfQ09OTkVTQ1VUSVZFX0ZSQU1FIiwiRlJBTUVfSU5GT19SRVNFUlZFRCIsImJhc2U2NC5mcm9tQnl0ZUFycmF5IiwiaWVlZTc1NC5yZWFkIiwiaWVlZTc1NC53cml0ZSIsImJhc2U2NC50b0J5dGVBcnJheSIsIlRleHRFbmNvZGVyIiwiZW5jb2RlIiwiTGVuIiwicmVzUG9zIiwicmVzQXJyIiwicG9pbnQiLCJuZXh0Y29kZSIsIkpzb25ScGNNYXJzaGFsbGVyIiwibWFyc2hhbGwiLCJycGNTdHJ1Y3QiLCJqc29uQnl0ZXMiLCJwYXJhbWlmeSIsImpzb25PYmplY3QiLCJzdHJpbmdWZXJzaW9uIiwiX2VuY29kZSIsInVubWFyc2hhbGwiLCJqc29uU3RyaW5nIiwiX2RlY29kZSIsIkJpbmFyeUZyYW1lSGVhZGVyIiwiZnVuY3Rpb25JZCIsImpzb25TaXplIiwiX2Z1bmN0aW9uSWQiLCJfY29ycmVsYXRpb25JZCIsIl9qc29uU2l6ZSIsIl9qc29uRGF0YSIsImZyb21CaW5hcnlIZWFkZXIiLCJiaW5hcnlGcmFtZUhlYWRlckRhdGEiLCJiaW5hcnlGcmFtZUhlYWRlciIsImpzb25EYXRhU3RhcnQiLCJqc29uRGF0YUVuZCIsInNldEpzb25EYXRhIiwiYXNzZW1ibGVIZWFkZXJCeXRlcyIsInNldFJwY1R5cGUiLCJnZXRScGNUeXBlIiwic2V0RnVuY3Rpb25JZCIsImdldEZ1bmN0aW9uSWQiLCJzZXRKc29uU2l6ZSIsImdldEpzb25TaXplIiwiZ2V0SnNvbkRhdGEiLCJNZXNzYWdlRnJhbWVEaXNhc3NlbWJsZXIiLCJycGNSZXF1ZXN0IiwibWVzc2FnZUlkIiwibXR1IiwicGFja2V0Q2FsbGJhY2siLCJfcnBjUmVxdWVzdCIsIl9zZXNzaW9uSWQiLCJfbWVzc2FnZUlkIiwiX210dSIsIl9wYWNrZXRDYWxsYmFjayIsImJ1aWxkUlBDIiwiY2IiLCJkb1JlcXVlc3QiLCJfYnVpbGRSUENNYWluQnVmZmVyIiwicnBjQnVsa0RhdGEiLCJqc29uQnVmZmVyIiwiYmZoIiwiaGVhZGVyU2l6ZSIsImJ1bGtEYXRhU2l6ZSIsInRvdGFsTWVzc2FnZVNpemUiLCJtYWluQnVmZmVyIiwiZnJhbWVDb3VudCIsImZ1bGxQYWNrZXQiLCJfY29uc3RydWN0UGFja2V0IiwidmlldyIsIkRhdGFWaWV3Iiwic2V0VWludDMyIiwiZmlyc3RIZWFkZXIiLCJfYnVpbGRDb25zZWN1dGl2ZUZyYW1lcyIsInNkbFBhY2tldCIsImZyYW1lU2VxdWVuY2VOdW1iZXIiLCJjb3VudCIsImhlYWRlciIsIlRyYW5zcG9ydExpc3RlbmVyIiwiX29uVHJhbnNwb3J0RGlzY29ubmVjdGVkIiwiX29uUGFja2V0UmVjZWl2ZWQiLCJzZXRPblRyYW5zcG9ydERpc2Nvbm5lY3RlZCIsInNldE9uUGFja2V0UmVjZWl2ZWQiLCJvblRyYW5zcG9ydERpc2Nvbm5lY3RlZCIsIm9uUGFja2V0UmVjZWl2ZWQiLCJWZXJzaW9uIiwibWFqb3IiLCJtaW5vciIsInBhdGNoIiwic2V0TWFqb3IiLCJzZXRNaW5vciIsInNldFBhdGNoIiwiX21ham9yIiwiZ2V0TWFqb3IiLCJfbWlub3IiLCJnZXRNaW5vciIsIl9wYXRjaCIsImdldFBhdGNoIiwidmVyc2lvbnMiLCJpc05ld2VyVGhhbiIsIlNlcnZpY2VUeXBlIiwiUlBDIiwiQVVESU8iLCJWSURFTyIsIkhZQlJJRCIsIk1lc3NhZ2VGcmFtZUFzc2VtYmxlciIsIl9jYWxsYmFjayIsIl9hY2N1bXVsYXRvciIsIl90b3RhbENvbnNlY3V0aXZlRnJhbWVzIiwiX2NvbnNlY3V0aXZlRnJhbWVzSGFuZGxlZENvdW50IiwiX2NvbnNlY3V0aXZlRnJhbWVzRGF0YUxlbmd0aCIsImhhbmRsZUZyYW1lIiwiX2hhbmRsZU11bHRpRnJhbWVNZXNzYWdlIiwiX2hhbmRsZUZpcnN0RGF0YUZyYW1lIiwiZGF0YUxlbmd0aCIsIl9oYW5kbGVDb25zZWN1dGl2ZUZyYW1lIiwiZnJhbWVTZXF1ZW5jZSIsIndhcm4iLCJmaW5pc2hlZFNkbFBhY2tldCIsIkNvbnRyb2xGcmFtZVRhZ3MiLCJTdGFydFNlcnZpY2VBQ0tCYXNlIiwiTVRVIiwiTkFLQmFzZSIsIlJFSkVDVEVEX1BBUkFNUyIsIlN0YXJ0U2VydmljZVByb3RvY29sVmVyc2lvbiIsIlBST1RPQ09MX1ZFUlNJT04iLCJTdGFydFNlcnZpY2VIYXNoSWQiLCJIQVNIX0lEIiwiU3RhcnRTZXJ2aWNlRGltZW5zaW9ucyIsIkhFSUdIVCIsIldJRFRIIiwiU3RhcnRTZXJ2aWNlIiwiU3RhcnRTZXJ2aWNlQUNLIiwiU0VDT05EQVJZX1RSQU5TUE9SVFMiLCJBVURJT19TRVJWSUNFX1RSQU5TUE9SVFMiLCJWSURFT19TRVJWSUNFX1RSQU5TUE9SVFMiLCJBVVRIX1RPS0VOIiwiU3RhcnRTZXJ2aWNlTkFLIiwiRW5kU2VydmljZSIsIkVuZFNlcnZpY2VBQ0siLCJFbmRTZXJ2aWNlTkFLIiwiVHJhbnNwb3J0RXZlbnRVcGRhdGUiLCJUQ1BfSVBfQUREUkVTUyIsIlRDUF9QT1JUIiwiUmVnaXN0ZXJTZWNvbmRhcnlUcmFuc3BvcnQiLCJSZWdpc3RlclNlY29uZGFyeVRyYW5zcG9ydEFDSyIsIlJlZ2lzdGVyU2Vjb25kYXJ5VHJhbnNwb3J0TkFLIiwiUkVBU09OIiwiQXVkaW8iLCJWaWRlbyIsIlZJREVPX1BST1RPQ09MIiwiVklERU9fQ09ERUMiLCJCaXRDb252ZXJ0ZXIiLCJhcnJheUJ1ZmZlclRvSW50MzIiLCJnZXRVaW50MzIiLCJpbnQzMlRvQXJyYXlCdWZmZXIiLCJTZGxQYWNrZXRGYWN0b3J5IiwiY3JlYXRlSGVhcnRiZWF0QUNLIiwiY3JlYXRlRW5kU2Vzc2lvbiIsImhhc2hJRCIsImVuZFNlc3Npb24iLCJTb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzIiwic2V0U2hvcnRQcmVzc0F2YWlsYWJsZSIsImF2YWlsYWJsZSIsIktFWV9TSE9SVF9QUkVTU19BVkFJTEFCTEUiLCJnZXRTaG9ydFByZXNzQXZhaWxhYmxlIiwic2V0TG9uZ1ByZXNzQXZhaWxhYmxlIiwiS0VZX0xPTkdfUFJFU1NfQVZBSUxBQkxFIiwiZ2V0TG9uZ1ByZXNzQXZhaWxhYmxlIiwic2V0VXBEb3duQXZhaWxhYmxlIiwiS0VZX1VQX0RPV05fQVZBSUxBQkxFIiwiZ2V0VXBEb3duQXZhaWxhYmxlIiwic2V0SW1hZ2VTdXBwb3J0ZWQiLCJzdXBwb3J0ZWQiLCJLRVlfSU1BR0VfU1VQUE9SVEVEIiwiZ2V0SW1hZ2VTdXBwb3J0ZWQiLCJzZXRUZXh0U3VwcG9ydGVkIiwiS0VZX1RFWFRfU1VQUE9SVEVEIiwiZ2V0VGV4dFN1cHBvcnRlZCIsIlByZXJlY29yZGVkU3BlZWNoIiwiSEVMUF9KSU5HTEUiLCJJTklUSUFMX0pJTkdMRSIsIkxJU1RFTl9KSU5HTEUiLCJQT1NJVElWRV9KSU5HTEUiLCJORUdBVElWRV9KSU5HTEUiLCJQcmVzZXRCYW5rQ2FwYWJpbGl0aWVzIiwic2V0T25TY3JlZW5QcmVzZXRzQXZhaWxhYmxlIiwiS0VZX09OX1NDUkVFTl9QUkVTRVRTX0FWQUlMQUJMRSIsImdldE9uU2NyZWVuUHJlc2V0c0F2YWlsYWJsZSIsIlZlaGljbGVUeXBlIiwic2V0TWFrZSIsIm1ha2UiLCJLRVlfTUFLRSIsImdldE1ha2UiLCJzZXRNb2RlbCIsIm1vZGVsIiwiS0VZX01PREVMIiwiZ2V0TW9kZWwiLCJzZXRNb2RlbFllYXIiLCJ5ZWFyIiwiS0VZX01PREVMX1lFQVIiLCJnZXRNb2RlbFllYXIiLCJzZXRUcmltIiwiS0VZX1RSSU0iLCJnZXRUcmltIiwiSG1pWm9uZUNhcGFiaWxpdGllcyIsIkZST05UIiwiQkFDSyIsIk1lZGlhQ2xvY2tGb3JtYXQiLCJDTE9DSzEiLCJDTE9DSzIiLCJDTE9DSzMiLCJDTE9DS1RFWFQxIiwiQ0xPQ0tURVhUMiIsIkNMT0NLVEVYVDMiLCJDTE9DS1RFWFQ0IiwiSW1hZ2VSZXNvbHV0aW9uIiwic2V0UmVzb2x1dGlvbldpZHRoIiwid2lkdGgiLCJLRVlfUkVTT0xVVElPTl9XSURUSCIsImdldFJlc29sdXRpb25XaWR0aCIsInNldFJlc29sdXRpb25IZWlnaHQiLCJoZWlnaHQiLCJLRVlfUkVTT0xVVElPTl9IRUlHSFQiLCJnZXRSZXNvbHV0aW9uSGVpZ2h0IiwiVG91Y2hFdmVudENhcGFiaWxpdGllcyIsInNldFByZXNzQXZhaWxhYmxlIiwiS0VZX1BSRVNTX0FWQUlMQUJMRSIsImdldFByZXNzQXZhaWxhYmxlIiwic2V0TXVsdGlUb3VjaEF2YWlsYWJsZSIsIktFWV9NVUxUSV9UT1VDSF9BVkFJTEFCTEUiLCJnZXRNdWx0aVRvdWNoQXZhaWxhYmxlIiwic2V0RG91YmxlUHJlc3NBdmFpbGFibGUiLCJLRVlfRE9VQkxFX1BSRVNTX0FWQUlMQUJMRSIsImdldERvdWJsZVByZXNzQXZhaWxhYmxlIiwiU2NyZWVuUGFyYW1zIiwic2V0UmVzb2x1dGlvbiIsInJlc29sdXRpb24iLCJLRVlfUkVTT0xVVElPTiIsImdldFJlc29sdXRpb24iLCJzZXRUb3VjaEV2ZW50QXZhaWxhYmxlIiwiS0VZX1RPVUNIX0VWRU5UX0FWQUlMQUJMRSIsImdldFRvdWNoRXZlbnRBdmFpbGFibGUiLCJJbWFnZUZpZWxkTmFtZSIsInNvZnRCdXR0b25JbWFnZSIsImNob2ljZUltYWdlIiwiY2hvaWNlU2Vjb25kYXJ5SW1hZ2UiLCJ2ckhlbHBJdGVtIiwidHVybkljb24iLCJtZW51SWNvbiIsImNtZEljb24iLCJhcHBJY29uIiwiZ3JhcGhpYyIsInNlY29uZGFyeUdyYXBoaWMiLCJzaG93Q29uc3RhbnRUQlRJY29uIiwic2hvd0NvbnN0YW50VEJUTmV4dFR1cm5JY29uIiwibG9jYXRpb25JbWFnZSIsImFsZXJ0SWNvbiIsIkZpbGVUeXBlIiwiR1JBUEhJQ19CTVAiLCJHUkFQSElDX0pQRUciLCJHUkFQSElDX1BORyIsIkFVRElPX1dBVkUiLCJBVURJT19NUDMiLCJBVURJT19BQUMiLCJCSU5BUlkiLCJJbWFnZUZpZWxkIiwic2V0TmFtZSIsIktFWV9OQU1FIiwiZ2V0TmFtZSIsInNldEltYWdlVHlwZVN1cHBvcnRlZCIsIktFWV9JTUFHRV9UWVBFX1NVUFBPUlRFRCIsImdldEltYWdlVHlwZVN1cHBvcnRlZCIsInNldEltYWdlUmVzb2x1dGlvbiIsIktFWV9JTUFHRV9SRVNPTFVUSU9OIiwiZ2V0SW1hZ2VSZXNvbHV0aW9uIiwiRGlzcGxheVR5cGUiLCJDSUQiLCJUWVBFMiIsIlRZUEU1IiwiTkdOIiwiR0VOMl84X0RNQSIsIkdFTjJfNl9ETUEiLCJNRkQzIiwiTUZENCIsIk1GRDUiLCJHRU4zXzhfSU5DSCIsIlNETF9HRU5FUklDIiwiVGV4dEZpZWxkTmFtZSIsIm1haW5GaWVsZDEiLCJtYWluRmllbGQyIiwibWFpbkZpZWxkMyIsIm1haW5GaWVsZDQiLCJzdGF0dXNCYXIiLCJtZWRpYUNsb2NrIiwibWVkaWFUcmFjayIsInRlbXBsYXRlVGl0bGUiLCJhbGVydFRleHQxIiwiYWxlcnRUZXh0MiIsImFsZXJ0VGV4dDMiLCJzY3JvbGxhYmxlTWVzc2FnZUJvZHkiLCJpbml0aWFsSW50ZXJhY3Rpb25UZXh0IiwibmF2aWdhdGlvblRleHQxIiwibmF2aWdhdGlvblRleHQyIiwiRVRBIiwidG90YWxEaXN0YW5jZSIsImF1ZGlvUGFzc1RocnVEaXNwbGF5VGV4dDEiLCJhdWRpb1Bhc3NUaHJ1RGlzcGxheVRleHQyIiwic2xpZGVySGVhZGVyIiwic2xpZGVyRm9vdGVyIiwibWVudU5hbWUiLCJzZWNvbmRhcnlUZXh0IiwidGVydGlhcnlUZXh0IiwibWVudVRpdGxlIiwibG9jYXRpb25OYW1lIiwibG9jYXRpb25EZXNjcmlwdGlvbiIsImFkZHJlc3NMaW5lcyIsInBob25lTnVtYmVyIiwiQ2hhcmFjdGVyU2V0IiwiVFlQRTJTRVQiLCJUWVBFNVNFVCIsIkNJRDFTRVQiLCJDSUQyU0VUIiwiVGV4dEZpZWxkIiwic2V0Q2hhcmFjdGVyU2V0IiwiS0VZX0NIQVJBQ1RFUl9TRVQiLCJnZXRDaGFyYWN0ZXJTZXQiLCJzZXRXaWR0aCIsIktFWV9XSURUSCIsImdldFdpZHRoIiwic2V0Um93cyIsInJvd3MiLCJLRVlfUk9XUyIsImdldFJvd3MiLCJEaXNwbGF5Q2FwYWJpbGl0aWVzIiwic2V0RGlzcGxheVR5cGUiLCJLRVlfRElTUExBWV9UWVBFIiwiZ2V0RGlzcGxheVR5cGUiLCJzZXREaXNwbGF5TmFtZSIsIktFWV9ESVNQTEFZX05BTUUiLCJnZXREaXNwbGF5TmFtZSIsInNldFRleHRGaWVsZHMiLCJLRVlfVEVYVF9GSUVMRFMiLCJnZXRUZXh0RmllbGRzIiwic2V0SW1hZ2VGaWVsZHMiLCJLRVlfSU1BR0VfRklFTERTIiwiZ2V0SW1hZ2VGaWVsZHMiLCJzZXRNZWRpYUNsb2NrRm9ybWF0cyIsImZvcm1hdHMiLCJLRVlfTUVESUFfQ0xPQ0tfRk9STUFUUyIsImdldE1lZGlhQ2xvY2tGb3JtYXRzIiwic2V0R3JhcGhpY1N1cHBvcnRlZCIsIktFWV9HUkFQSElDX1NVUFBPUlRFRCIsImdldEdyYXBoaWNTdXBwb3J0ZWQiLCJzZXRUZW1wbGF0ZXNBdmFpbGFibGUiLCJLRVlfVEVNUExBVEVTX0FWQUlMQUJMRSIsImdldFRlbXBsYXRlc0F2YWlsYWJsZSIsInNldFNjcmVlblBhcmFtcyIsIktFWV9TQ1JFRU5fUEFSQU1TIiwiZ2V0U2NyZWVuUGFyYW1zIiwic2V0TnVtQ3VzdG9tUHJlc2V0c0F2YWlsYWJsZSIsIktFWV9OVU1fQ1VTVE9NX1BSRVNFVFNfQVZBSUxBQkxFIiwiZ2V0TnVtQ3VzdG9tUHJlc2V0c0F2YWlsYWJsZSIsIlNhbXBsaW5nUmF0ZSIsIlNhbXBsaW5nUmF0ZV84S0haIiwiU2FtcGxpbmdSYXRlXzE2S0haIiwiU2FtcGxpbmdSYXRlXzIyS0haIiwiU2FtcGxpbmdSYXRlXzQ0S0haIiwiQml0c1BlclNhbXBsZSIsIkJpdHNQZXJTYW1wbGVfOF9CSVQiLCJCaXRzUGVyU2FtcGxlXzE2X0JJVCIsIkF1ZGlvVHlwZSIsIlBDTSIsIkF1ZGlvUGFzc1RocnVDYXBhYmlsaXRpZXMiLCJzZXRTYW1wbGluZ1JhdGUiLCJyYXRlIiwiS0VZX1NBTVBMSU5HX1JBVEUiLCJnZXRTYW1wbGluZ1JhdGUiLCJzZXRCaXRzUGVyU2FtcGxlIiwic2FtcGxlIiwiS0VZX0JJVFNfUEVSX1NBTVBMRSIsImdldEJpdHNQZXJTYW1wbGUiLCJzZXRBdWRpb1R5cGUiLCJLRVlfQVVESU9fVFlQRSIsImdldEF1ZGlvVHlwZSIsIlZyQ2FwYWJpbGl0aWVzIiwiVlJfVEVYVCIsIkJ1dHRvbk5hbWUiLCJPSyIsIlBMQVlfUEFVU0UiLCJTRUVLTEVGVCIsIlNFRUtSSUdIVCIsIlRVTkVVUCIsIlRVTkVET1dOIiwiUFJFU0VUXzAiLCJQUkVTRVRfMSIsIlBSRVNFVF8yIiwiUFJFU0VUXzMiLCJQUkVTRVRfNCIsIlBSRVNFVF81IiwiUFJFU0VUXzYiLCJQUkVTRVRfNyIsIlBSRVNFVF84IiwiUFJFU0VUXzkiLCJDVVNUT01fQlVUVE9OIiwiU0VBUkNIIiwiQUNfTUFYIiwiQUMiLCJSRUNJUkNVTEFURSIsIkZBTl9VUCIsIkZBTl9ET1dOIiwiVEVNUF9VUCIsIlRFTVBfRE9XTiIsIkRFRlJPU1RfTUFYIiwiREVGUk9TVCIsIkRFRlJPU1RfUkVBUiIsIlVQUEVSX1ZFTlQiLCJMT1dFUl9WRU5UIiwiVk9MVU1FX1VQIiwiVk9MVU1FX0RPV04iLCJFSkVDVCIsIlNPVVJDRSIsIlNIVUZGTEUiLCJSRVBFQVQiLCJOQVZfQ0VOVEVSX0xPQ0FUSU9OIiwiTkFWX1pPT01fSU4iLCJOQVZfWk9PTV9PVVQiLCJOQVZfUEFOX1VQIiwiTkFWX1BBTl9VUF9SSUdIVCIsIk5BVl9QQU5fUklHSFQiLCJOQVZfUEFOX0RPV05fUklHSFQiLCJOQVZfUEFOX0RPV04iLCJOQVZfUEFOX0RPV05fTEVGVCIsIk5BVl9QQU5fTEVGVCIsIk5BVl9QQU5fVVBfTEVGVCIsIk5BVl9USUxUX1RPR0dMRSIsIk5BVl9ST1RBVEVfQ0xPQ0tXSVNFIiwiTkFWX1JPVEFURV9DT1VOVEVSQ0xPQ0tXSVNFIiwiTkFWX0hFQURJTkdfVE9HR0xFIiwiR3JpZCIsInNldENvbHVtbiIsImNvbCIsIktFWV9DT0xVTU4iLCJnZXRDb2x1bW4iLCJzZXRSb3ciLCJyb3ciLCJLRVlfUk9XIiwiZ2V0Um93Iiwic2V0TGV2ZWwiLCJsZXZlbCIsIktFWV9MRVZFTCIsImdldExldmVsIiwic2V0Q29sdW1uU3BhbiIsImNvbHNwYW4iLCJLRVlfQ09MVU1OX1NQQU4iLCJnZXRDb2x1bW5TcGFuIiwic2V0Um93U3BhbiIsInJvd3NwYW4iLCJLRVlfUk9XX1NQQU4iLCJnZXRSb3dTcGFuIiwic2V0TGV2ZWxTcGFuIiwibGV2ZWxzcGFuIiwiS0VZX0xFVkVMX1NQQU4iLCJnZXRMZXZlbFNwYW4iLCJNb2R1bGVJbmZvIiwic2V0TW9kdWxlSWQiLCJLRVlfTU9EVUxFX0lEIiwiZ2V0TW9kdWxlSWQiLCJzZXRMb2NhdGlvbiIsImxvY2F0aW9uIiwiS0VZX0xPQ0FUSU9OIiwiZ2V0TG9jYXRpb24iLCJzZXRTZXJ2aWNlQXJlYSIsImFyZWEiLCJLRVlfU0VSVklDRV9BUkVBIiwiZ2V0U2VydmljZUFyZWEiLCJzZXRBbGxvd011bHRpcGxlQWNjZXNzIiwiYWNjZXNzIiwiS0VZX0FMTE9XX01VTFRJUExFX0FDQ0VTUyIsImdldEFsbG93TXVsdGlwbGVBY2Nlc3MiLCJCdXR0b25DYXBhYmlsaXRpZXMiLCJzZXRNb2R1bGVJbmZvIiwiS0VZX01PRFVMRV9JTkZPIiwiZ2V0TW9kdWxlSW5mbyIsIkhNSUNhcGFiaWxpdGllcyIsInNldE5hdmlnYXRpb24iLCJuYXZpZ2F0aW9uIiwiS0VZX05BVklHQVRJT04iLCJnZXROYXZpZ2F0aW9uIiwic2V0UGhvbmVDYWxsIiwiS0VZX1BIT05FX0NBTEwiLCJnZXRQaG9uZUNhbGwiLCJzZXRWaWRlb1N0cmVhbWluZyIsInN0cmVhbWluZyIsIktFWV9WSURFT19TVFJFQU1JTkciLCJnZXRWaWRlb1N0cmVhbWluZyIsInNldFJlbW90ZUNvbnRyb2wiLCJjb250cm9sIiwiS0VZX1JFTU9URV9DT05UUk9MIiwiZ2V0UmVtb3RlQ29udHJvbCIsInNldEFwcFNlcnZpY2VzIiwic2VydmljZXMiLCJLRVlfQVBQX1NFUlZJQ0VTIiwiZ2V0QXBwU2VydmljZXMiLCJzZXREaXNwbGF5cyIsImRpc3BsYXlzIiwiS0VZX0RJU1BMQVlTIiwiZ2V0RGlzcGxheXMiLCJzZXRTZWF0TG9jYXRpb24iLCJLRVlfU0VBVF9MT0NBVElPTiIsImdldFNlYXRMb2NhdGlvbiIsIlJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UiLCJzZXRMYW5ndWFnZSIsImxhbmd1YWdlIiwiS0VZX0xBTkdVQUdFIiwiZ2V0TGFuZ3VhZ2UiLCJzZXRIbWlEaXNwbGF5TGFuZ3VhZ2UiLCJLRVlfSE1JX0RJU1BMQVlfTEFOR1VBR0UiLCJnZXRIbWlEaXNwbGF5TGFuZ3VhZ2UiLCJzZXREaXNwbGF5Q2FwYWJpbGl0aWVzIiwiY2FwYWJpbGl0aWVzIiwiS0VZX0RJU1BMQVlfQ0FQQUJJTElUSUVTIiwiZ2V0RGlzcGxheUNhcGFiaWxpdGllcyIsInNldEJ1dHRvbkNhcGFiaWxpdGllcyIsIktFWV9CVVRUT05fQ0FQQUJJTElUSUVTIiwiZ2V0QnV0dG9uQ2FwYWJpbGl0aWVzIiwic2V0U29mdEJ1dHRvbkNhcGFiaWxpdGllcyIsIktFWV9TT0ZUX0JVVFRPTl9DQVBBQklMSVRJRVMiLCJnZXRTb2Z0QnV0dG9uQ2FwYWJpbGl0aWVzIiwic2V0UHJlc2V0QmFua0NhcGFiaWxpdGllcyIsIktFWV9QUkVTRVRfQkFOS19DQVBBQklMSVRJRVMiLCJnZXRQcmVzZXRCYW5rQ2FwYWJpbGl0aWVzIiwic2V0SG1pWm9uZUNhcGFiaWxpdGllcyIsIktFWV9ITUlfWk9ORV9DQVBBQklMSVRJRVMiLCJnZXRIbWlab25lQ2FwYWJpbGl0aWVzIiwic2V0U3BlZWNoQ2FwYWJpbGl0aWVzIiwiS0VZX1NQRUVDSF9DQVBBQklMSVRJRVMiLCJnZXRTcGVlY2hDYXBhYmlsaXRpZXMiLCJzZXRQcmVyZWNvcmRlZFNwZWVjaCIsInNwZWVjaCIsIktFWV9QUkVSRUNPUkRFRF9TUEVFQ0giLCJnZXRQcmVyZWNvcmRlZFNwZWVjaCIsInNldFZyQ2FwYWJpbGl0aWVzIiwiS0VZX1ZSX0NBUEFCSUxJVElFUyIsImdldFZyQ2FwYWJpbGl0aWVzIiwic2V0QXVkaW9QYXNzVGhydUNhcGFiaWxpdGllcyIsIktFWV9BVURJT19QQVNTX1RIUlVfQ0FQQUJJTElUSUVTIiwiZ2V0QXVkaW9QYXNzVGhydUNhcGFiaWxpdGllcyIsInNldFBjbVN0cmVhbUNhcGFiaWxpdGllcyIsIktFWV9QQ01fU1RSRUFNX0NBUEFCSUxJVElFUyIsImdldFBjbVN0cmVhbUNhcGFiaWxpdGllcyIsInNldFZlaGljbGVUeXBlIiwiS0VZX1ZFSElDTEVfVFlQRSIsImdldFZlaGljbGVUeXBlIiwic2V0U3VwcG9ydGVkRGlhZ01vZGVzIiwibW9kZXMiLCJLRVlfU1VQUE9SVEVEX0RJQUdfTU9ERVMiLCJnZXRTdXBwb3J0ZWREaWFnTW9kZXMiLCJzZXRIbWlDYXBhYmlsaXRpZXMiLCJLRVlfSE1JX0NBUEFCSUxJVElFUyIsImdldEhtaUNhcGFiaWxpdGllcyIsInNldFNkbFZlcnNpb24iLCJLRVlfU0RMX1ZFUlNJT04iLCJnZXRTZGxWZXJzaW9uIiwic2V0U3lzdGVtU29mdHdhcmVWZXJzaW9uIiwiS0VZX1NZU1RFTV9TT0ZUV0FSRV9WRVJTSU9OIiwiZ2V0U3lzdGVtU29mdHdhcmVWZXJzaW9uIiwic2V0SWNvblJlc3VtZWQiLCJyZXN1bWVkIiwiS0VZX0lDT05fUkVTVU1FRCIsImdldEljb25SZXN1bWVkIiwiVW5yZWdpc3RlckFwcEludGVyZmFjZVJlc3BvbnNlIiwiV2luZG93VHlwZSIsIk1BSU4iLCJXSURHRVQiLCJzZXRXaW5kb3dJRCIsIktFWV9XSU5ET1dfSUQiLCJnZXRXaW5kb3dJRCIsInNldFdpbmRvd05hbWUiLCJLRVlfV0lORE9XX05BTUUiLCJnZXRXaW5kb3dOYW1lIiwic2V0QXNzb2NpYXRlZFNlcnZpY2VUeXBlIiwiS0VZX0FTU09DSUFURURfU0VSVklDRV9UWVBFIiwiZ2V0QXNzb2NpYXRlZFNlcnZpY2VUeXBlIiwic2V0RHVwbGljYXRlVXBkYXRlc0Zyb21XaW5kb3dJRCIsIktFWV9EVVBMSUNBVEVfVVBEQVRFU19GUk9NX1dJTkRPV19JRCIsImdldER1cGxpY2F0ZVVwZGF0ZXNGcm9tV2luZG93SUQiLCJDcmVhdGVXaW5kb3dSZXNwb25zZSIsIkRlbGV0ZVdpbmRvd1Jlc3BvbnNlIiwiSW1hZ2VUeXBlIiwiU1RBVElDIiwiRFlOQU1JQyIsIkltYWdlIiwic2V0VmFsdWUiLCJLRVlfVkFMVUUiLCJnZXRWYWx1ZSIsInNldEltYWdlVHlwZSIsIktFWV9JTUFHRV9UWVBFIiwiZ2V0SW1hZ2VUeXBlIiwic2V0SXNUZW1wbGF0ZSIsInRlbXBsYXRlIiwiS0VZX0lTX1RFTVBMQVRFIiwiZ2V0SXNUZW1wbGF0ZSIsIlZySGVscEl0ZW0iLCJzZXRJbWFnZSIsImltYWdlIiwiS0VZX0lNQUdFIiwiZ2V0SW1hZ2UiLCJzZXRQb3NpdGlvbiIsIktFWV9QT1NJVElPTiIsImdldFBvc2l0aW9uIiwiU2VhdExvY2F0aW9uIiwic2V0R3JpZCIsImdyaWQiLCJLRVlfR1JJRCIsImdldEdyaWQiLCJNZW51TGF5b3V0IiwiTElTVCIsIlRJTEVTIiwiS2V5Ym9hcmRMYXlvdXQiLCJRV0VSVFkiLCJRV0VSVFoiLCJBWkVSVFkiLCJLZXlwcmVzc01vZGUiLCJTSU5HTEVfS0VZUFJFU1MiLCJRVUVVRV9LRVlQUkVTU0VTIiwiUkVTRU5EX0NVUlJFTlRfRU5UUlkiLCJLZXlib2FyZFByb3BlcnRpZXMiLCJzZXRLZXlib2FyZExheW91dCIsImxheW91dCIsIktFWV9LRVlCT0FSRF9MQVlPVVQiLCJnZXRLZXlib2FyZExheW91dCIsInNldEtleXByZXNzTW9kZSIsIm1vZGUiLCJLRVlfS0VZUFJFU1NfTU9ERSIsImdldEtleXByZXNzTW9kZSIsInNldExpbWl0ZWRDaGFyYWN0ZXJMaXN0IiwiS0VZX0xJTUlURURfQ0hBUkFDVEVSX0xJU1QiLCJnZXRMaW1pdGVkQ2hhcmFjdGVyTGlzdCIsInNldEF1dG9Db21wbGV0ZVRleHQiLCJLRVlfQVVUT19DT01QTEVURV9URVhUIiwiZ2V0QXV0b0NvbXBsZXRlVGV4dCIsInNldEF1dG9Db21wbGV0ZUxpc3QiLCJLRVlfQVVUT19DT01QTEVURV9MSVNUIiwiZ2V0QXV0b0NvbXBsZXRlTGlzdCIsInNldFVzZXJMb2NhdGlvbiIsIktFWV9VU0VSX0xPQ0FUSU9OIiwiZ2V0VXNlckxvY2F0aW9uIiwic2V0SGVscFByb21wdCIsInByb21wdCIsIktFWV9IRUxQX1BST01QVCIsImdldEhlbHBQcm9tcHQiLCJzZXRUaW1lb3V0UHJvbXB0IiwiS0VZX1RJTUVPVVRfUFJPTVBUIiwiZ2V0VGltZW91dFByb21wdCIsInNldFZySGVscFRpdGxlIiwidGl0bGUiLCJLRVlfVlJfSEVMUF9USVRMRSIsImdldFZySGVscFRpdGxlIiwic2V0VnJIZWxwIiwiaGVscCIsIktFWV9WUl9IRUxQIiwiZ2V0VnJIZWxwIiwic2V0TWVudVRpdGxlIiwiS0VZX01FTlVfVElUTEUiLCJnZXRNZW51VGl0bGUiLCJzZXRNZW51SWNvbiIsIktFWV9NRU5VX0lDT04iLCJnZXRNZW51SWNvbiIsInNldEtleWJvYXJkUHJvcGVydGllcyIsInByb3BlcnRpZXMiLCJLRVlfS0VZQk9BUkRfUFJPUEVSVElFUyIsImdldEtleWJvYXJkUHJvcGVydGllcyIsInNldE1lbnVMYXlvdXQiLCJLRVlfTUVOVV9MQVlPVVQiLCJnZXRNZW51TGF5b3V0IiwiU2V0R2xvYmFsUHJvcGVydGllc1Jlc3BvbnNlIiwiR2xvYmFsUHJvcGVydHkiLCJVU0VSX0xPQ0FUSU9OIiwiSEVMUFBST01QVCIsIlRJTUVPVVRQUk9NUFQiLCJWUkhFTFBUSVRMRSIsIlZSSEVMUElURU1TIiwiTUVOVU5BTUUiLCJNRU5VSUNPTiIsIktFWUJPQVJEUFJPUEVSVElFUyIsInNldFByb3BlcnRpZXMiLCJLRVlfUFJPUEVSVElFUyIsImdldFByb3BlcnRpZXMiLCJSZXNldEdsb2JhbFByb3BlcnRpZXNSZXNwb25zZSIsIk1lbnVQYXJhbXMiLCJzZXRQYXJlbnRJRCIsIktFWV9QQVJFTlRfSUQiLCJnZXRQYXJlbnRJRCIsInNldE1lbnVOYW1lIiwiS0VZX01FTlVfTkFNRSIsImdldE1lbnVOYW1lIiwic2V0Q21kSUQiLCJLRVlfQ01EX0lEIiwiZ2V0Q21kSUQiLCJzZXRNZW51UGFyYW1zIiwiS0VZX01FTlVfUEFSQU1TIiwiZ2V0TWVudVBhcmFtcyIsInNldFZyQ29tbWFuZHMiLCJjb21tYW5kcyIsIktFWV9WUl9DT01NQU5EUyIsImdldFZyQ29tbWFuZHMiLCJzZXRDbWRJY29uIiwiS0VZX0NNRF9JQ09OIiwiZ2V0Q21kSWNvbiIsIkFkZENvbW1hbmRSZXNwb25zZSIsIkRlbGV0ZUNvbW1hbmRSZXNwb25zZSIsInNldE1lbnVJRCIsIktFWV9NRU5VX0lEIiwiZ2V0TWVudUlEIiwiQWRkU3ViTWVudVJlc3BvbnNlIiwiRGVsZXRlU3ViTWVudVJlc3BvbnNlIiwiU2hvd0FwcE1lbnVSZXNwb25zZSIsIkNob2ljZSIsInNldENob2ljZUlEIiwiS0VZX0NIT0lDRV9JRCIsImdldENob2ljZUlEIiwic2V0U2Vjb25kYXJ5VGV4dCIsIktFWV9TRUNPTkRBUllfVEVYVCIsImdldFNlY29uZGFyeVRleHQiLCJzZXRUZXJ0aWFyeVRleHQiLCJLRVlfVEVSVElBUllfVEVYVCIsImdldFRlcnRpYXJ5VGV4dCIsInNldFNlY29uZGFyeUltYWdlIiwiS0VZX1NFQ09OREFSWV9JTUFHRSIsImdldFNlY29uZGFyeUltYWdlIiwic2V0SW50ZXJhY3Rpb25DaG9pY2VTZXRJRCIsIktFWV9JTlRFUkFDVElPTl9DSE9JQ0VfU0VUX0lEIiwiZ2V0SW50ZXJhY3Rpb25DaG9pY2VTZXRJRCIsInNldENob2ljZVNldCIsIktFWV9DSE9JQ0VfU0VUIiwiZ2V0Q2hvaWNlU2V0IiwiQ3JlYXRlSW50ZXJhY3Rpb25DaG9pY2VTZXRSZXNwb25zZSIsIkxheW91dE1vZGUiLCJJQ09OX09OTFkiLCJJQ09OX1dJVEhfU0VBUkNIIiwiTElTVF9PTkxZIiwiTElTVF9XSVRIX1NFQVJDSCIsIktFWUJPQVJEIiwiSW50ZXJhY3Rpb25Nb2RlIiwiTUFOVUFMX09OTFkiLCJWUl9PTkxZIiwiQk9USCIsInNldEluaXRpYWxUZXh0IiwiS0VZX0lOSVRJQUxfVEVYVCIsImdldEluaXRpYWxUZXh0Iiwic2V0SW5pdGlhbFByb21wdCIsIktFWV9JTklUSUFMX1BST01QVCIsImdldEluaXRpYWxQcm9tcHQiLCJzZXRJbnRlcmFjdGlvbk1vZGUiLCJLRVlfSU5URVJBQ1RJT05fTU9ERSIsImdldEludGVyYWN0aW9uTW9kZSIsInNldEludGVyYWN0aW9uQ2hvaWNlU2V0SURMaXN0IiwiS0VZX0lOVEVSQUNUSU9OX0NIT0lDRV9TRVRfSURMSVNUIiwiZ2V0SW50ZXJhY3Rpb25DaG9pY2VTZXRJRExpc3QiLCJ0aW1lb3V0IiwiS0VZX1RJTUVPVVQiLCJnZXRUaW1lb3V0Iiwic2V0SW50ZXJhY3Rpb25MYXlvdXQiLCJLRVlfSU5URVJBQ1RJT05fTEFZT1VUIiwiZ2V0SW50ZXJhY3Rpb25MYXlvdXQiLCJzZXRDYW5jZWxJRCIsIktFWV9DQU5DRUxfSUQiLCJnZXRDYW5jZWxJRCIsIlRyaWdnZXJTb3VyY2UiLCJUU19NRU5VIiwiVFNfVlIiLCJUU19LRVlCT0FSRCIsIlBlcmZvcm1JbnRlcmFjdGlvblJlc3BvbnNlIiwic2V0TWFudWFsVGV4dEVudHJ5IiwiS0VZX01BTlVBTF9URVhUX0VOVFJZIiwiZ2V0TWFudWFsVGV4dEVudHJ5Iiwic2V0VHJpZ2dlclNvdXJjZSIsIktFWV9UUklHR0VSX1NPVVJDRSIsImdldFRyaWdnZXJTb3VyY2UiLCJEZWxldGVJbnRlcmFjdGlvbkNob2ljZVNldFJlc3BvbnNlIiwiU29mdEJ1dHRvblR5cGUiLCJTQlRfVEVYVCIsIlNCVF9JTUFHRSIsIlNCVF9CT1RIIiwiU3lzdGVtQWN0aW9uIiwiREVGQVVMVF9BQ1RJT04iLCJTVEVBTF9GT0NVUyIsIktFRVBfQ09OVEVYVCIsIlNvZnRCdXR0b24iLCJzZXRJc0hpZ2hsaWdodGVkIiwiaGlnaGxpZ2h0ZWQiLCJLRVlfSVNfSElHSExJR0hURUQiLCJnZXRJc0hpZ2hsaWdodGVkIiwic2V0U29mdEJ1dHRvbklEIiwiS0VZX1NPRlRfQlVUVE9OX0lEIiwiZ2V0U29mdEJ1dHRvbklEIiwic2V0U3lzdGVtQWN0aW9uIiwiYWN0aW9uIiwiS0VZX1NZU1RFTV9BQ1RJT04iLCJnZXRTeXN0ZW1BY3Rpb24iLCJzZXRBbGVydFRleHQxIiwidGV4dDEiLCJLRVlfQUxFUlRfVEVYVF8xIiwiZ2V0QWxlcnRUZXh0MSIsInNldEFsZXJ0VGV4dDIiLCJ0ZXh0MiIsIktFWV9BTEVSVF9URVhUXzIiLCJnZXRBbGVydFRleHQyIiwic2V0QWxlcnRUZXh0MyIsInRleHQzIiwiS0VZX0FMRVJUX1RFWFRfMyIsImdldEFsZXJ0VGV4dDMiLCJzZXRUdHNDaHVua3MiLCJjaHVua3MiLCJLRVlfVFRTX0NIVU5LUyIsImdldFR0c0NodW5rcyIsInNldER1cmF0aW9uIiwiZHVyYXRpb24iLCJLRVlfRFVSQVRJT04iLCJnZXREdXJhdGlvbiIsInNldFBsYXlUb25lIiwidG9uZSIsIktFWV9QTEFZX1RPTkUiLCJnZXRQbGF5VG9uZSIsInNldFByb2dyZXNzSW5kaWNhdG9yIiwiaW5kaWNhdG9yIiwiS0VZX1BST0dSRVNTX0lORElDQVRPUiIsImdldFByb2dyZXNzSW5kaWNhdG9yIiwic2V0U29mdEJ1dHRvbnMiLCJidXR0b25zIiwiS0VZX1NPRlRfQlVUVE9OUyIsImdldFNvZnRCdXR0b25zIiwic2V0QWxlcnRJY29uIiwiS0VZX0FMRVJUX0lDT04iLCJnZXRBbGVydEljb24iLCJBbGVydFJlc3BvbnNlIiwic2V0VHJ5QWdhaW5UaW1lIiwiS0VZX1RSWV9BR0FJTl9USU1FIiwiZ2V0VHJ5QWdhaW5UaW1lIiwiVGV4dEFsaWdubWVudCIsIkxFRlRfQUxJR05FRCIsIlJJR0hUX0FMSUdORUQiLCJDRU5URVJFRCIsIlRlbXBsYXRlQ29uZmlndXJhdGlvbiIsInNldFRlbXBsYXRlIiwiS0VZX1RFTVBMQVRFIiwiZ2V0VGVtcGxhdGUiLCJNZXRhZGF0YVR5cGUiLCJtZWRpYVRpdGxlIiwibWVkaWFBcnRpc3QiLCJtZWRpYUFsYnVtIiwibWVkaWFZZWFyIiwibWVkaWFHZW5yZSIsIm1lZGlhU3RhdGlvbiIsInJhdGluZyIsImN1cnJlbnRUZW1wZXJhdHVyZSIsIm1heGltdW1UZW1wZXJhdHVyZSIsIm1pbmltdW1UZW1wZXJhdHVyZSIsIndlYXRoZXJUZXJtIiwiaHVtaWRpdHkiLCJNZXRhZGF0YVRhZ3MiLCJzZXRNYWluRmllbGQxIiwiZmllbGQxIiwiS0VZX01BSU5fRklFTERfMSIsImdldE1haW5GaWVsZDEiLCJzZXRNYWluRmllbGQyIiwiZmllbGQyIiwiS0VZX01BSU5fRklFTERfMiIsImdldE1haW5GaWVsZDIiLCJzZXRNYWluRmllbGQzIiwiZmllbGQzIiwiS0VZX01BSU5fRklFTERfMyIsImdldE1haW5GaWVsZDMiLCJzZXRNYWluRmllbGQ0IiwiZmllbGQ0IiwiS0VZX01BSU5fRklFTERfNCIsImdldE1haW5GaWVsZDQiLCJzZXRBbGlnbm1lbnQiLCJhbGlnbm1lbnQiLCJLRVlfQUxJR05NRU5UIiwiZ2V0QWxpZ25tZW50Iiwic2V0U3RhdHVzQmFyIiwiYmFyIiwiS0VZX1NUQVRVU19CQVIiLCJnZXRTdGF0dXNCYXIiLCJzZXRNZWRpYUNsb2NrIiwiY2xvY2siLCJLRVlfTUVESUFfQ0xPQ0siLCJnZXRNZWRpYUNsb2NrIiwic2V0TWVkaWFUcmFjayIsInRyYWNrIiwiS0VZX01FRElBX1RSQUNLIiwiZ2V0TWVkaWFUcmFjayIsInNldEdyYXBoaWMiLCJLRVlfR1JBUEhJQyIsImdldEdyYXBoaWMiLCJzZXRTZWNvbmRhcnlHcmFwaGljIiwiS0VZX1NFQ09OREFSWV9HUkFQSElDIiwiZ2V0U2Vjb25kYXJ5R3JhcGhpYyIsInNldEN1c3RvbVByZXNldHMiLCJwcmVzZXRzIiwiS0VZX0NVU1RPTV9QUkVTRVRTIiwiZ2V0Q3VzdG9tUHJlc2V0cyIsInNldE1ldGFkYXRhVGFncyIsInRhZ3MiLCJLRVlfTUVUQURBVEFfVEFHUyIsImdldE1ldGFkYXRhVGFncyIsInNldFRlbXBsYXRlVGl0bGUiLCJLRVlfVEVNUExBVEVfVElUTEUiLCJnZXRUZW1wbGF0ZVRpdGxlIiwic2V0VGVtcGxhdGVDb25maWd1cmF0aW9uIiwiY29uZmlndXJhdGlvbiIsIktFWV9URU1QTEFURV9DT05GSUdVUkFUSU9OIiwiZ2V0VGVtcGxhdGVDb25maWd1cmF0aW9uIiwiU2hvd1Jlc3BvbnNlIiwiU3BlYWtSZXNwb25zZSIsIlN0YXJ0VGltZSIsInNldEhvdXJzIiwiaG91cnMiLCJLRVlfSE9VUlMiLCJzZXRNaW51dGVzIiwibWludXRlcyIsIktFWV9NSU5VVEVTIiwic2V0U2Vjb25kcyIsInNlY29uZHMiLCJLRVlfU0VDT05EUyIsIlVwZGF0ZU1vZGUiLCJDT1VOVFVQIiwiQ09VTlRET1dOIiwiUEFVU0UiLCJSRVNVTUUiLCJDTEVBUiIsIkF1ZGlvU3RyZWFtaW5nSW5kaWNhdG9yIiwiUExBWSIsIlNUT1AiLCJzZXRTdGFydFRpbWUiLCJLRVlfU1RBUlRfVElNRSIsImdldFN0YXJ0VGltZSIsInNldEVuZFRpbWUiLCJLRVlfRU5EX1RJTUUiLCJnZXRFbmRUaW1lIiwic2V0VXBkYXRlTW9kZSIsIktFWV9VUERBVEVfTU9ERSIsImdldFVwZGF0ZU1vZGUiLCJzZXRBdWRpb1N0cmVhbWluZ0luZGljYXRvciIsIktFWV9BVURJT19TVFJFQU1JTkdfSU5ESUNBVE9SIiwiZ2V0QXVkaW9TdHJlYW1pbmdJbmRpY2F0b3IiLCJTZXRNZWRpYUNsb2NrVGltZXJSZXNwb25zZSIsInNldEF1ZGlvUGFzc1RocnVEaXNwbGF5VGV4dDEiLCJLRVlfQVVESU9fUEFTU19USFJVX0RJU1BMQVlfVEVYVF8xIiwiZ2V0QXVkaW9QYXNzVGhydURpc3BsYXlUZXh0MSIsInNldEF1ZGlvUGFzc1RocnVEaXNwbGF5VGV4dDIiLCJLRVlfQVVESU9fUEFTU19USFJVX0RJU1BMQVlfVEVYVF8yIiwiZ2V0QXVkaW9QYXNzVGhydURpc3BsYXlUZXh0MiIsInNldE1heER1cmF0aW9uIiwiS0VZX01BWF9EVVJBVElPTiIsImdldE1heER1cmF0aW9uIiwic2V0TXV0ZUF1ZGlvIiwiYXVkaW8iLCJLRVlfTVVURV9BVURJTyIsImdldE11dGVBdWRpbyIsIlBlcmZvcm1BdWRpb1Bhc3NUaHJ1UmVzcG9uc2UiLCJFbmRBdWRpb1Bhc3NUaHJ1UmVzcG9uc2UiLCJzZXRCdXR0b25OYW1lIiwiS0VZX0JVVFRPTl9OQU1FIiwiZ2V0QnV0dG9uTmFtZSIsIlN1YnNjcmliZUJ1dHRvblJlc3BvbnNlIiwiVW5zdWJzY3JpYmVCdXR0b25SZXNwb25zZSIsInNldEdwcyIsImdwcyIsIktFWV9HUFMiLCJnZXRHcHMiLCJzZXRTcGVlZCIsInNwZWVkIiwiS0VZX1NQRUVEIiwiZ2V0U3BlZWQiLCJzZXRScG0iLCJycG0iLCJLRVlfUlBNIiwiZ2V0UnBtIiwic2V0RnVlbExldmVsIiwiS0VZX0ZVRUxfTEVWRUwiLCJnZXRGdWVsTGV2ZWwiLCJzZXRGdWVsTGV2ZWxfU3RhdGUiLCJsZXZlbF9zdGF0ZSIsIktFWV9GVUVMX0xFVkVMX1NUQVRFIiwiZ2V0RnVlbExldmVsX1N0YXRlIiwic2V0SW5zdGFudEZ1ZWxDb25zdW1wdGlvbiIsImNvbnN1bXB0aW9uIiwiS0VZX0lOU1RBTlRfRlVFTF9DT05TVU1QVElPTiIsImdldEluc3RhbnRGdWVsQ29uc3VtcHRpb24iLCJzZXRGdWVsUmFuZ2UiLCJyYW5nZSIsIktFWV9GVUVMX1JBTkdFIiwiZ2V0RnVlbFJhbmdlIiwic2V0RXh0ZXJuYWxUZW1wZXJhdHVyZSIsInRlbXBlcmF0dXJlIiwiS0VZX0VYVEVSTkFMX1RFTVBFUkFUVVJFIiwiZ2V0RXh0ZXJuYWxUZW1wZXJhdHVyZSIsInNldFR1cm5TaWduYWwiLCJzaWduYWwiLCJLRVlfVFVSTl9TSUdOQUwiLCJnZXRUdXJuU2lnbmFsIiwic2V0UHJuZGwiLCJwcm5kbCIsIktFWV9QUk5ETCIsImdldFBybmRsIiwic2V0VGlyZVByZXNzdXJlIiwicHJlc3N1cmUiLCJLRVlfVElSRV9QUkVTU1VSRSIsImdldFRpcmVQcmVzc3VyZSIsInNldE9kb21ldGVyIiwib2RvbWV0ZXIiLCJLRVlfT0RPTUVURVIiLCJnZXRPZG9tZXRlciIsInNldEJlbHRTdGF0dXMiLCJzdGF0dXMiLCJLRVlfQkVMVF9TVEFUVVMiLCJnZXRCZWx0U3RhdHVzIiwic2V0Qm9keUluZm9ybWF0aW9uIiwiaW5mb3JtYXRpb24iLCJLRVlfQk9EWV9JTkZPUk1BVElPTiIsImdldEJvZHlJbmZvcm1hdGlvbiIsInNldERldmljZVN0YXR1cyIsIktFWV9ERVZJQ0VfU1RBVFVTIiwiZ2V0RGV2aWNlU3RhdHVzIiwic2V0RHJpdmVyQnJha2luZyIsImJyYWtpbmciLCJLRVlfRFJJVkVSX0JSQUtJTkciLCJnZXREcml2ZXJCcmFraW5nIiwic2V0V2lwZXJTdGF0dXMiLCJLRVlfV0lQRVJfU1RBVFVTIiwiZ2V0V2lwZXJTdGF0dXMiLCJzZXRIZWFkTGFtcFN0YXR1cyIsIktFWV9IRUFEX0xBTVBfU1RBVFVTIiwiZ2V0SGVhZExhbXBTdGF0dXMiLCJzZXRFbmdpbmVUb3JxdWUiLCJ0b3JxdWUiLCJLRVlfRU5HSU5FX1RPUlFVRSIsImdldEVuZ2luZVRvcnF1ZSIsInNldEFjY1BlZGFsUG9zaXRpb24iLCJLRVlfQUNDX1BFREFMX1BPU0lUSU9OIiwiZ2V0QWNjUGVkYWxQb3NpdGlvbiIsInNldFN0ZWVyaW5nV2hlZWxBbmdsZSIsImFuZ2xlIiwiS0VZX1NURUVSSU5HX1dIRUVMX0FOR0xFIiwiZ2V0U3RlZXJpbmdXaGVlbEFuZ2xlIiwic2V0RW5naW5lT2lsTGlmZSIsImxpZmUiLCJLRVlfRU5HSU5FX09JTF9MSUZFIiwiZ2V0RW5naW5lT2lsTGlmZSIsInNldEVsZWN0cm9uaWNQYXJrQnJha2VTdGF0dXMiLCJLRVlfRUxFQ1RST05JQ19QQVJLX0JSQUtFX1NUQVRVUyIsImdldEVsZWN0cm9uaWNQYXJrQnJha2VTdGF0dXMiLCJzZXRDbG91ZEFwcFZlaGljbGVJRCIsIktFWV9DTE9VRF9BUFBfVkVISUNMRV9JRCIsImdldENsb3VkQXBwVmVoaWNsZUlEIiwic2V0RUNhbGxJbmZvIiwiS0VZX0VfQ0FMTF9JTkZPIiwiZ2V0RUNhbGxJbmZvIiwic2V0QWlyYmFnU3RhdHVzIiwiS0VZX0FJUkJBR19TVEFUVVMiLCJnZXRBaXJiYWdTdGF0dXMiLCJzZXRFbWVyZ2VuY3lFdmVudCIsImV2ZW50IiwiS0VZX0VNRVJHRU5DWV9FVkVOVCIsImdldEVtZXJnZW5jeUV2ZW50Iiwic2V0Q2x1c3Rlck1vZGVTdGF0dXMiLCJLRVlfQ0xVU1RFUl9NT0RFX1NUQVRVUyIsImdldENsdXN0ZXJNb2RlU3RhdHVzIiwic2V0TXlLZXkiLCJLRVlfTVlfS0VZIiwiZ2V0TXlLZXkiLCJWZWhpY2xlRGF0YVJlc3VsdENvZGUiLCJWRFJDX1NVQ0NFU1MiLCJWRFJDX1RSVU5DQVRFRF9EQVRBIiwiVkRSQ19ESVNBTExPV0VEIiwiVkRSQ19VU0VSX0RJU0FMTE9XRUQiLCJWRFJDX0lOVkFMSURfSUQiLCJWRFJDX0RBVEFfTk9UX0FWQUlMQUJMRSIsIlZEUkNfREFUQV9BTFJFQURZX1NVQlNDUklCRUQiLCJWRFJDX0RBVEFfTk9UX1NVQlNDUklCRUQiLCJWRFJDX0lHTk9SRUQiLCJWZWhpY2xlRGF0YVR5cGUiLCJWRUhJQ0xFREFUQV9HUFMiLCJWRUhJQ0xFREFUQV9TUEVFRCIsIlZFSElDTEVEQVRBX1JQTSIsIlZFSElDTEVEQVRBX0ZVRUxMRVZFTCIsIlZFSElDTEVEQVRBX0ZVRUxMRVZFTF9TVEFURSIsIlZFSElDTEVEQVRBX0ZVRUxDT05TVU1QVElPTiIsIlZFSElDTEVEQVRBX0VYVEVSTlRFTVAiLCJWRUhJQ0xFREFUQV9WSU4iLCJWRUhJQ0xFREFUQV9QUk5ETCIsIlZFSElDTEVEQVRBX1RJUkVQUkVTU1VSRSIsIlZFSElDTEVEQVRBX09ET01FVEVSIiwiVkVISUNMRURBVEFfQkVMVFNUQVRVUyIsIlZFSElDTEVEQVRBX0JPRFlJTkZPIiwiVkVISUNMRURBVEFfREVWSUNFU1RBVFVTIiwiVkVISUNMRURBVEFfRUNBTExJTkZPIiwiVkVISUNMRURBVEFfQUlSQkFHU1RBVFVTIiwiVkVISUNMRURBVEFfRU1FUkdFTkNZRVZFTlQiLCJWRUhJQ0xFREFUQV9DTFVTVEVSTU9ERVNUQVRVUyIsIlZFSElDTEVEQVRBX01ZS0VZIiwiVkVISUNMRURBVEFfQlJBS0lORyIsIlZFSElDTEVEQVRBX1dJUEVSU1RBVFVTIiwiVkVISUNMRURBVEFfSEVBRExBTVBTVEFUVVMiLCJWRUhJQ0xFREFUQV9CQVRUVk9MVEFHRSIsIlZFSElDTEVEQVRBX0VOR0lORVRPUlFVRSIsIlZFSElDTEVEQVRBX0FDQ1BFREFMIiwiVkVISUNMRURBVEFfU1RFRVJJTkdXSEVFTCIsIlZFSElDTEVEQVRBX1RVUk5TSUdOQUwiLCJWRUhJQ0xFREFUQV9GVUVMUkFOR0UiLCJWRUhJQ0xFREFUQV9FTkdJTkVPSUxMSUZFIiwiVkVISUNMRURBVEFfRUxFQ1RST05JQ1BBUktCUkFLRVNUQVRVUyIsIlZFSElDTEVEQVRBX0NMT1VEQVBQVkVISUNMRUlEIiwiVkVISUNMRURBVEFfT0VNX0NVU1RPTV9EQVRBIiwiVmVoaWNsZURhdGFSZXN1bHQiLCJzZXREYXRhVHlwZSIsIktFWV9EQVRBX1RZUEUiLCJnZXREYXRhVHlwZSIsInNldE9lbUN1c3RvbURhdGFUeXBlIiwiS0VZX09FTV9DVVNUT01fREFUQV9UWVBFIiwiZ2V0T2VtQ3VzdG9tRGF0YVR5cGUiLCJTdWJzY3JpYmVWZWhpY2xlRGF0YVJlc3BvbnNlIiwic2V0Q2x1c3Rlck1vZGVzIiwiS0VZX0NMVVNURVJfTU9ERVMiLCJnZXRDbHVzdGVyTW9kZXMiLCJVbnN1YnNjcmliZVZlaGljbGVEYXRhUmVzcG9uc2UiLCJzZXRWaW4iLCJ2aW4iLCJLRVlfVklOIiwiZ2V0VmluIiwiVmVoaWNsZURhdGFFdmVudFN0YXR1cyIsIlZERVNfTk9fRVZFTlQiLCJWREVTX05PIiwiVkRFU19ZRVMiLCJWREVTX05PVF9TVVBQT1JURUQiLCJWREVTX0ZBVUxUIiwiQWlyYmFnU3RhdHVzIiwic2V0RHJpdmVyQWlyYmFnRGVwbG95ZWQiLCJkZXBsb3llZCIsIktFWV9EUklWRVJfQUlSQkFHX0RFUExPWUVEIiwiZ2V0RHJpdmVyQWlyYmFnRGVwbG95ZWQiLCJzZXREcml2ZXJTaWRlQWlyYmFnRGVwbG95ZWQiLCJLRVlfRFJJVkVSX1NJREVfQUlSQkFHX0RFUExPWUVEIiwiZ2V0RHJpdmVyU2lkZUFpcmJhZ0RlcGxveWVkIiwic2V0RHJpdmVyQ3VydGFpbkFpcmJhZ0RlcGxveWVkIiwiS0VZX0RSSVZFUl9DVVJUQUlOX0FJUkJBR19ERVBMT1lFRCIsImdldERyaXZlckN1cnRhaW5BaXJiYWdEZXBsb3llZCIsInNldFBhc3NlbmdlckFpcmJhZ0RlcGxveWVkIiwiS0VZX1BBU1NFTkdFUl9BSVJCQUdfREVQTE9ZRUQiLCJnZXRQYXNzZW5nZXJBaXJiYWdEZXBsb3llZCIsInNldFBhc3NlbmdlckN1cnRhaW5BaXJiYWdEZXBsb3llZCIsIktFWV9QQVNTRU5HRVJfQ1VSVEFJTl9BSVJCQUdfREVQTE9ZRUQiLCJnZXRQYXNzZW5nZXJDdXJ0YWluQWlyYmFnRGVwbG95ZWQiLCJzZXREcml2ZXJLbmVlQWlyYmFnRGVwbG95ZWQiLCJLRVlfRFJJVkVSX0tORUVfQUlSQkFHX0RFUExPWUVEIiwiZ2V0RHJpdmVyS25lZUFpcmJhZ0RlcGxveWVkIiwic2V0UGFzc2VuZ2VyU2lkZUFpcmJhZ0RlcGxveWVkIiwiS0VZX1BBU1NFTkdFUl9TSURFX0FJUkJBR19ERVBMT1lFRCIsImdldFBhc3NlbmdlclNpZGVBaXJiYWdEZXBsb3llZCIsInNldFBhc3NlbmdlcktuZWVBaXJiYWdEZXBsb3llZCIsIktFWV9QQVNTRU5HRVJfS05FRV9BSVJCQUdfREVQTE9ZRUQiLCJnZXRQYXNzZW5nZXJLbmVlQWlyYmFnRGVwbG95ZWQiLCJQb3dlck1vZGVTdGF0dXMiLCJLRVlfT1VUIiwiS0VZX1JFQ0VOVExZX09VVCIsIktFWV9BUFBST1ZFRF8wIiwiUE9TVF9BQ0NFU09SWV8wIiwiQUNDRVNPUllfMSIsIlBPU1RfSUdOSVRJT05fMSIsIklHTklUSU9OX09OXzIiLCJSVU5OSU5HXzIiLCJDUkFOS18zIiwiQ2FyTW9kZVN0YXR1cyIsIkNNU19OT1JNQUwiLCJDTVNfRkFDVE9SWSIsIkNNU19UUkFOU1BPUlQiLCJDTVNfQ1JBU0giLCJQb3dlck1vZGVRdWFsaWZpY2F0aW9uU3RhdHVzIiwiUE9XRVJfTU9ERV9VTkRFRklORUQiLCJQT1dFUl9NT0RFX0VWQUxVQVRJT05fSU5fUFJPR1JFU1MiLCJOT1RfREVGSU5FRCIsIlBPV0VSX01PREVfT0siLCJDbHVzdGVyTW9kZVN0YXR1cyIsInNldFBvd2VyTW9kZUFjdGl2ZSIsImFjdGl2ZSIsIktFWV9QT1dFUl9NT0RFX0FDVElWRSIsImdldFBvd2VyTW9kZUFjdGl2ZSIsInNldFBvd2VyTW9kZVF1YWxpZmljYXRpb25TdGF0dXMiLCJLRVlfUE9XRVJfTU9ERV9RVUFMSUZJQ0FUSU9OX1NUQVRVUyIsImdldFBvd2VyTW9kZVF1YWxpZmljYXRpb25TdGF0dXMiLCJzZXRDYXJNb2RlU3RhdHVzIiwiS0VZX0NBUl9NT0RFX1NUQVRVUyIsImdldENhck1vZGVTdGF0dXMiLCJzZXRQb3dlck1vZGVTdGF0dXMiLCJLRVlfUE9XRVJfTU9ERV9TVEFUVVMiLCJnZXRQb3dlck1vZGVTdGF0dXMiLCJGdWVsQ3V0b2ZmU3RhdHVzIiwiRkNTX1RFUk1JTkFURV9GVUVMIiwiRkNTX05PUk1BTF9PUEVSQVRJT04iLCJGQ1NfRkFVTFQiLCJFbWVyZ2VuY3lFdmVudFR5cGUiLCJFRVRfTk9fRVZFTlQiLCJFRVRfRlJPTlRBTCIsIkVFVF9TSURFIiwiRUVUX1JFQVIiLCJFRVRfUk9MTE9WRVIiLCJFRVRfTk9UX1NVUFBPUlRFRCIsIkVFVF9GQVVMVCIsIkVtZXJnZW5jeUV2ZW50Iiwic2V0RW1lcmdlbmN5RXZlbnRUeXBlIiwiS0VZX0VNRVJHRU5DWV9FVkVOVF9UWVBFIiwiZ2V0RW1lcmdlbmN5RXZlbnRUeXBlIiwic2V0RnVlbEN1dG9mZlN0YXR1cyIsIktFWV9GVUVMX0NVVE9GRl9TVEFUVVMiLCJnZXRGdWVsQ3V0b2ZmU3RhdHVzIiwic2V0Um9sbG92ZXJFdmVudCIsIktFWV9ST0xMT1ZFUl9FVkVOVCIsImdldFJvbGxvdmVyRXZlbnQiLCJzZXRNYXhpbXVtQ2hhbmdlVmVsb2NpdHkiLCJ2ZWxvY2l0eSIsIktFWV9NQVhJTVVNX0NIQU5HRV9WRUxPQ0lUWSIsImdldE1heGltdW1DaGFuZ2VWZWxvY2l0eSIsInNldE11bHRpcGxlRXZlbnRzIiwiZXZlbnRzIiwiS0VZX01VTFRJUExFX0VWRU5UUyIsImdldE11bHRpcGxlRXZlbnRzIiwiVHVyblNpZ25hbCIsIk9GRiIsIkxFRlQiLCJSSUdIVCIsIkFtYmllbnRMaWdodFN0YXR1cyIsIk5JR0hUIiwiVFdJTElHSFRfMSIsIlRXSUxJR0hUXzIiLCJUV0lMSUdIVF8zIiwiVFdJTElHSFRfNCIsIkRBWSIsIkFMU19VTktOT1dOIiwiSU5WQUxJRCIsIkhlYWRMYW1wU3RhdHVzIiwic2V0TG93QmVhbXNPbiIsIm9uIiwiS0VZX0xPV19CRUFNU19PTiIsImdldExvd0JlYW1zT24iLCJzZXRIaWdoQmVhbXNPbiIsIktFWV9ISUdIX0JFQU1TX09OIiwiZ2V0SGlnaEJlYW1zT24iLCJzZXRBbWJpZW50TGlnaHRTZW5zb3JTdGF0dXMiLCJLRVlfQU1CSUVOVF9MSUdIVF9TRU5TT1JfU1RBVFVTIiwiZ2V0QW1iaWVudExpZ2h0U2Vuc29yU3RhdHVzIiwiUHJpbWFyeUF1ZGlvU291cmNlIiwiTk9fU09VUkNFX1NFTEVDVEVEIiwiQ0QiLCJVU0IiLCJVU0IyIiwiQkxVRVRPT1RIX1NURVJFT19CVFNUIiwiTElORV9JTiIsIklQT0QiLCJNT0JJTEVfQVBQIiwiQU0iLCJGTSIsIlhNIiwiREFCIiwiRGV2aWNlTGV2ZWxTdGF0dXMiLCJaRVJPX0xFVkVMX0JBUlMiLCJPTkVfTEVWRUxfQkFSUyIsIlRXT19MRVZFTF9CQVJTIiwiVEhSRUVfTEVWRUxfQkFSUyIsIkZPVVJfTEVWRUxfQkFSUyIsIk5PVF9QUk9WSURFRCIsIkRldmljZVN0YXR1cyIsInNldFZvaWNlUmVjT24iLCJLRVlfVk9JQ0VfUkVDX09OIiwiZ2V0Vm9pY2VSZWNPbiIsInNldEJ0SWNvbk9uIiwiS0VZX0JUX0lDT05fT04iLCJnZXRCdEljb25PbiIsInNldENhbGxBY3RpdmUiLCJLRVlfQ0FMTF9BQ1RJVkUiLCJnZXRDYWxsQWN0aXZlIiwic2V0UGhvbmVSb2FtaW5nIiwicm9hbWluZyIsIktFWV9QSE9ORV9ST0FNSU5HIiwiZ2V0UGhvbmVSb2FtaW5nIiwic2V0VGV4dE1zZ0F2YWlsYWJsZSIsIktFWV9URVhUX01TR19BVkFJTEFCTEUiLCJnZXRUZXh0TXNnQXZhaWxhYmxlIiwic2V0QmF0dExldmVsU3RhdHVzIiwiS0VZX0JBVFRfTEVWRUxfU1RBVFVTIiwiZ2V0QmF0dExldmVsU3RhdHVzIiwic2V0U3RlcmVvQXVkaW9PdXRwdXRNdXRlZCIsIm11dGVkIiwiS0VZX1NURVJFT19BVURJT19PVVRQVVRfTVVURUQiLCJnZXRTdGVyZW9BdWRpb091dHB1dE11dGVkIiwic2V0TW9ub0F1ZGlvT3V0cHV0TXV0ZWQiLCJLRVlfTU9OT19BVURJT19PVVRQVVRfTVVURUQiLCJnZXRNb25vQXVkaW9PdXRwdXRNdXRlZCIsInNldFNpZ25hbExldmVsU3RhdHVzIiwiS0VZX1NJR05BTF9MRVZFTF9TVEFUVVMiLCJnZXRTaWduYWxMZXZlbFN0YXR1cyIsInNldFByaW1hcnlBdWRpb1NvdXJjZSIsIktFWV9QUklNQVJZX0FVRElPX1NPVVJDRSIsImdldFByaW1hcnlBdWRpb1NvdXJjZSIsInNldEVDYWxsRXZlbnRBY3RpdmUiLCJLRVlfRV9DQUxMX0VWRU5UX0FDVElWRSIsImdldEVDYWxsRXZlbnRBY3RpdmUiLCJXaXBlclN0YXR1cyIsIkFVVE9fT0ZGIiwiT0ZGX01PVklORyIsIk1BTl9JTlRfT0ZGIiwiTUFOX0lOVF9PTiIsIk1BTl9MT1ciLCJNQU5fSElHSCIsIk1BTl9GTElDSyIsIldBU0giLCJBVVRPX0xPVyIsIkFVVE9fSElHSCIsIkNPVVJURVNZV0lQRSIsIkFVVE9fQURKVVNUIiwiU1RBTExFRCIsIk5PX0RBVEFfRVhJU1RTIiwiRWxlY3Ryb25pY1BhcmtCcmFrZVN0YXR1cyIsIkNMT1NFRCIsIlRSQU5TSVRJT04iLCJPUEVOIiwiRFJJVkVfQUNUSVZFIiwiRkFVTFQiLCJWZWhpY2xlRGF0YVN0YXR1cyIsIlZEU19OT19EQVRBX0VYSVNUUyIsIlZEU19PRkYiLCJWRFNfT04iLCJNeUtleSIsInNldEU5MTFPdmVycmlkZSIsImU5MTFvdmVycmlkZSIsIktFWV9FOTExT1ZFUlJJREUiLCJnZXRFOTExT3ZlcnJpZGUiLCJDb21wYXNzRGlyZWN0aW9uIiwiTk9SVEgiLCJOT1JUSFdFU1QiLCJXRVNUIiwiU09VVEhXRVNUIiwiU09VVEgiLCJTT1VUSEVBU1QiLCJFQVNUIiwiTk9SVEhFQVNUIiwiRGltZW5zaW9uIiwiRGltZW5zaW9uX05PX0ZJWCIsIkRpbWVuc2lvbl8yRCIsIkRpbWVuc2lvbl8zRCIsIkdQU0RhdGEiLCJzZXRMb25naXR1ZGVEZWdyZWVzIiwiZGVncmVlcyIsIktFWV9MT05HSVRVREVfREVHUkVFUyIsImdldExvbmdpdHVkZURlZ3JlZXMiLCJzZXRMYXRpdHVkZURlZ3JlZXMiLCJLRVlfTEFUSVRVREVfREVHUkVFUyIsImdldExhdGl0dWRlRGVncmVlcyIsInNldFV0Y1llYXIiLCJLRVlfVVRDX1lFQVIiLCJnZXRVdGNZZWFyIiwic2V0VXRjTW9udGgiLCJtb250aCIsIktFWV9VVENfTU9OVEgiLCJnZXRVdGNNb250aCIsInNldFV0Y0RheSIsImRheSIsIktFWV9VVENfREFZIiwiZ2V0VXRjRGF5Iiwic2V0VXRjSG91cnMiLCJLRVlfVVRDX0hPVVJTIiwiZ2V0VXRjSG91cnMiLCJzZXRVdGNNaW51dGVzIiwiS0VZX1VUQ19NSU5VVEVTIiwiZ2V0VXRjTWludXRlcyIsInNldFV0Y1NlY29uZHMiLCJLRVlfVVRDX1NFQ09ORFMiLCJnZXRVdGNTZWNvbmRzIiwic2V0Q29tcGFzc0RpcmVjdGlvbiIsImRpcmVjdGlvbiIsIktFWV9DT01QQVNTX0RJUkVDVElPTiIsImdldENvbXBhc3NEaXJlY3Rpb24iLCJzZXRQZG9wIiwicGRvcCIsIktFWV9QRE9QIiwiZ2V0UGRvcCIsInNldEhkb3AiLCJoZG9wIiwiS0VZX0hET1AiLCJnZXRIZG9wIiwic2V0VmRvcCIsInZkb3AiLCJLRVlfVkRPUCIsImdldFZkb3AiLCJzZXRBY3R1YWwiLCJLRVlfQUNUVUFMIiwiZ2V0QWN0dWFsIiwic2V0U2F0ZWxsaXRlcyIsInNhdGVsbGl0ZXMiLCJLRVlfU0FURUxMSVRFUyIsImdldFNhdGVsbGl0ZXMiLCJzZXREaW1lbnNpb24iLCJkaW1lbnNpb24iLCJLRVlfRElNRU5TSU9OIiwiZ2V0RGltZW5zaW9uIiwic2V0QWx0aXR1ZGUiLCJhbHRpdHVkZSIsIktFWV9BTFRJVFVERSIsImdldEFsdGl0dWRlIiwic2V0SGVhZGluZyIsImhlYWRpbmciLCJLRVlfSEVBRElORyIsImdldEhlYWRpbmciLCJzZXRTaGlmdGVkIiwic2hpZnRlZCIsIktFWV9TSElGVEVEIiwiZ2V0U2hpZnRlZCIsIlBSTkRMIiwiUEFSSyIsIlJFVkVSU0UiLCJORVVUUkFMIiwiRFJJVkUiLCJTUE9SVCIsIkxPV0dFQVIiLCJTRUNPTkQiLCJUSElSRCIsIkZPVVJUSCIsIkZJRlRIIiwiU0lYVEgiLCJTRVZFTlRIIiwiRUlHSFRIIiwiVU5LTk9XTiIsIkZ1ZWxUeXBlIiwiR0FTT0xJTkUiLCJESUVTRUwiLCJDTkciLCJMUEciLCJIWURST0dFTiIsIkJBVFRFUlkiLCJGdWVsUmFuZ2UiLCJzZXRSYW5nZSIsIktFWV9SQU5HRSIsImdldFJhbmdlIiwiVmVoaWNsZURhdGFOb3RpZmljYXRpb25TdGF0dXMiLCJWRE5TX05PVF9TVVBQT1JURUQiLCJWRE5TX05PUk1BTCIsIlZETlNfQUNUSVZFIiwiVkROU19OT1RfVVNFRCIsIkVDYWxsQ29uZmlybWF0aW9uU3RhdHVzIiwiRUNDU19OT1JNQUwiLCJFQ0NTX0NBTExfSU5fUFJPR1JFU1MiLCJFQ0NTX0NBTExfQ0FOQ0VMTEVEIiwiQ0FMTF9DT01QTEVURUQiLCJFQ0NTX0NBTExfVU5TVUNDRVNTRlVMIiwiRUNDU19FQ0FMTF9DT05GSUdVUkVEX09GRiIsIkVDQ1NfQ0FMTF9DT01QTEVURV9EVE1GX1RJTUVPVVQiLCJFQ2FsbEluZm8iLCJzZXRFQ2FsbE5vdGlmaWNhdGlvblN0YXR1cyIsIktFWV9FX0NBTExfTk9USUZJQ0FUSU9OX1NUQVRVUyIsImdldEVDYWxsTm90aWZpY2F0aW9uU3RhdHVzIiwic2V0QXV4RUNhbGxOb3RpZmljYXRpb25TdGF0dXMiLCJLRVlfQVVYX0VDQUxMX05PVElGSUNBVElPTl9TVEFUVVMiLCJnZXRBdXhFQ2FsbE5vdGlmaWNhdGlvblN0YXR1cyIsInNldEVDYWxsQ29uZmlybWF0aW9uU3RhdHVzIiwiS0VZX0VfQ0FMTF9DT05GSVJNQVRJT05fU1RBVFVTIiwiZ2V0RUNhbGxDb25maXJtYXRpb25TdGF0dXMiLCJCZWx0U3RhdHVzIiwic2V0RHJpdmVyQmVsdERlcGxveWVkIiwiS0VZX0RSSVZFUl9CRUxUX0RFUExPWUVEIiwiZ2V0RHJpdmVyQmVsdERlcGxveWVkIiwic2V0UGFzc2VuZ2VyQmVsdERlcGxveWVkIiwiS0VZX1BBU1NFTkdFUl9CRUxUX0RFUExPWUVEIiwiZ2V0UGFzc2VuZ2VyQmVsdERlcGxveWVkIiwic2V0UGFzc2VuZ2VyQnVja2xlQmVsdGVkIiwiYmVsdGVkIiwiS0VZX1BBU1NFTkdFUl9CVUNLTEVfQkVMVEVEIiwiZ2V0UGFzc2VuZ2VyQnVja2xlQmVsdGVkIiwic2V0RHJpdmVyQnVja2xlQmVsdGVkIiwiS0VZX0RSSVZFUl9CVUNLTEVfQkVMVEVEIiwiZ2V0RHJpdmVyQnVja2xlQmVsdGVkIiwic2V0TGVmdFJvdzJCdWNrbGVCZWx0ZWQiLCJLRVlfTEVGVF9ST1cyQlVDS0xFX0JFTFRFRCIsImdldExlZnRSb3cyQnVja2xlQmVsdGVkIiwic2V0UGFzc2VuZ2VyQ2hpbGREZXRlY3RlZCIsImRldGVjdGVkIiwiS0VZX1BBU1NFTkdFUl9DSElMRF9ERVRFQ1RFRCIsImdldFBhc3NlbmdlckNoaWxkRGV0ZWN0ZWQiLCJzZXRSaWdodFJvdzJCdWNrbGVCZWx0ZWQiLCJLRVlfUklHSFRfUk9XMkJVQ0tMRV9CRUxURUQiLCJnZXRSaWdodFJvdzJCdWNrbGVCZWx0ZWQiLCJzZXRNaWRkbGVSb3cyQnVja2xlQmVsdGVkIiwiS0VZX01JRERMRV9ST1cyQlVDS0xFX0JFTFRFRCIsImdldE1pZGRsZVJvdzJCdWNrbGVCZWx0ZWQiLCJzZXRNaWRkbGVSb3czQnVja2xlQmVsdGVkIiwiS0VZX01JRERMRV9ST1czQlVDS0xFX0JFTFRFRCIsImdldE1pZGRsZVJvdzNCdWNrbGVCZWx0ZWQiLCJzZXRMZWZ0Um93M0J1Y2tsZUJlbHRlZCIsIktFWV9MRUZUX1JPVzNCVUNLTEVfQkVMVEVEIiwiZ2V0TGVmdFJvdzNCdWNrbGVCZWx0ZWQiLCJzZXRSaWdodFJvdzNCdWNrbGVCZWx0ZWQiLCJLRVlfUklHSFRfUk9XM0JVQ0tMRV9CRUxURUQiLCJnZXRSaWdodFJvdzNCdWNrbGVCZWx0ZWQiLCJzZXRMZWZ0UmVhckluZmxhdGFibGVCZWx0ZWQiLCJLRVlfTEVGVF9SRUFSX0lORkxBVEFCTEVfQkVMVEVEIiwiZ2V0TGVmdFJlYXJJbmZsYXRhYmxlQmVsdGVkIiwic2V0UmlnaHRSZWFySW5mbGF0YWJsZUJlbHRlZCIsIktFWV9SSUdIVF9SRUFSX0lORkxBVEFCTEVfQkVMVEVEIiwiZ2V0UmlnaHRSZWFySW5mbGF0YWJsZUJlbHRlZCIsInNldE1pZGRsZVJvdzFCZWx0RGVwbG95ZWQiLCJLRVlfTUlERExFX1JPVzFCRUxUX0RFUExPWUVEIiwiZ2V0TWlkZGxlUm93MUJlbHREZXBsb3llZCIsInNldE1pZGRsZVJvdzFCdWNrbGVCZWx0ZWQiLCJLRVlfTUlERExFX1JPVzFCVUNLTEVfQkVMVEVEIiwiZ2V0TWlkZGxlUm93MUJ1Y2tsZUJlbHRlZCIsIkNvbXBvbmVudFZvbHVtZVN0YXR1cyIsIkNWU19VTktOT1dOIiwiQ1ZTX05PUk1BTCIsIkNWU19MT1ciLCJDVlNfRkFVTFQiLCJDVlNfQUxFUlQiLCJDVlNfTk9UX1NVUFBPUlRFRCIsIklnbml0aW9uU3RhdHVzIiwiSVNfVU5LTk9XTiIsIklTX09GRiIsIklTX0FDQ0VTU09SWSIsIklTX1JVTiIsIklTX1NUQVJUIiwiSVNfSU5WQUxJRCIsIklnbml0aW9uU3RhYmxlU3RhdHVzIiwiSUdOSVRJT05fU1dJVENIX05PVF9TVEFCTEUiLCJJR05JVElPTl9TV0lUQ0hfU1RBQkxFIiwiTUlTU0lOR19GUk9NX1RSQU5TTUlUVEVSIiwiQm9keUluZm9ybWF0aW9uIiwic2V0UGFya0JyYWtlQWN0aXZlIiwiS0VZX1BBUktfQlJBS0VfQUNUSVZFIiwiZ2V0UGFya0JyYWtlQWN0aXZlIiwic2V0SWduaXRpb25TdGFibGVTdGF0dXMiLCJLRVlfSUdOSVRJT05fU1RBQkxFX1NUQVRVUyIsImdldElnbml0aW9uU3RhYmxlU3RhdHVzIiwic2V0SWduaXRpb25TdGF0dXMiLCJLRVlfSUdOSVRJT05fU1RBVFVTIiwiZ2V0SWduaXRpb25TdGF0dXMiLCJzZXREcml2ZXJEb29yQWphciIsImFqYXIiLCJLRVlfRFJJVkVSX0RPT1JfQUpBUiIsImdldERyaXZlckRvb3JBamFyIiwic2V0UGFzc2VuZ2VyRG9vckFqYXIiLCJLRVlfUEFTU0VOR0VSX0RPT1JfQUpBUiIsImdldFBhc3NlbmdlckRvb3JBamFyIiwic2V0UmVhckxlZnREb29yQWphciIsIktFWV9SRUFSX0xFRlRfRE9PUl9BSkFSIiwiZ2V0UmVhckxlZnREb29yQWphciIsInNldFJlYXJSaWdodERvb3JBamFyIiwiS0VZX1JFQVJfUklHSFRfRE9PUl9BSkFSIiwiZ2V0UmVhclJpZ2h0RG9vckFqYXIiLCJUUE1TIiwiU1lTVEVNX0ZBVUxUIiwiU0VOU09SX0ZBVUxUIiwiTE9XIiwiU1lTVEVNX0FDVElWRSIsIlRSQUlOIiwiVFJBSU5JTkdfQ09NUExFVEUiLCJOT1RfVFJBSU5FRCIsIlNpbmdsZVRpcmVTdGF0dXMiLCJzZXRTdGF0dXMiLCJLRVlfU1RBVFVTIiwiZ2V0U3RhdHVzIiwic2V0VHBtcyIsInRwbXMiLCJLRVlfVFBNUyIsImdldFRwbXMiLCJzZXRQcmVzc3VyZSIsIktFWV9QUkVTU1VSRSIsImdldFByZXNzdXJlIiwiV2FybmluZ0xpZ2h0U3RhdHVzIiwiV0xTX09GRiIsIldMU19PTiIsIldMU19GTEFTSCIsIldMU19OT1RfVVNFRCIsIlRpcmVTdGF0dXMiLCJzZXRQcmVzc3VyZVRlbGx0YWxlIiwidGVsbHRhbGUiLCJLRVlfUFJFU1NVUkVfVEVMTFRBTEUiLCJnZXRQcmVzc3VyZVRlbGx0YWxlIiwic2V0TGVmdEZyb250IiwiZnJvbnQiLCJLRVlfTEVGVF9GUk9OVCIsImdldExlZnRGcm9udCIsInNldFJpZ2h0RnJvbnQiLCJLRVlfUklHSFRfRlJPTlQiLCJnZXRSaWdodEZyb250Iiwic2V0TGVmdFJlYXIiLCJyZWFyIiwiS0VZX0xFRlRfUkVBUiIsImdldExlZnRSZWFyIiwic2V0UmlnaHRSZWFyIiwiS0VZX1JJR0hUX1JFQVIiLCJnZXRSaWdodFJlYXIiLCJzZXRJbm5lckxlZnRSZWFyIiwiS0VZX0lOTkVSX0xFRlRfUkVBUiIsImdldElubmVyTGVmdFJlYXIiLCJzZXRJbm5lclJpZ2h0UmVhciIsIktFWV9JTk5FUl9SSUdIVF9SRUFSIiwiZ2V0SW5uZXJSaWdodFJlYXIiLCJHZXRWZWhpY2xlRGF0YVJlc3BvbnNlIiwic2V0RWN1TmFtZSIsIktFWV9FQ1VfTkFNRSIsImdldEVjdU5hbWUiLCJzZXREaWRMb2NhdGlvbiIsIktFWV9ESURfTE9DQVRJT04iLCJnZXREaWRMb2NhdGlvbiIsIkRJRFJlc3VsdCIsInNldERhdGEiLCJLRVlfREFUQSIsImdldERhdGEiLCJSZWFkRElEUmVzcG9uc2UiLCJzZXREaWRSZXN1bHQiLCJLRVlfRElEX1JFU1VMVCIsImdldERpZFJlc3VsdCIsInNldER0Y01hc2siLCJtYXNrIiwiS0VZX0RUQ19NQVNLIiwiZ2V0RHRjTWFzayIsIkdldERUQ3NSZXNwb25zZSIsInNldEVjdUhlYWRlciIsIktFWV9FQ1VfSEVBREVSIiwiZ2V0RWN1SGVhZGVyIiwic2V0RHRjIiwiZHRjIiwiS0VZX0RUQyIsImdldER0YyIsInNldFRhcmdldElEIiwiS0VZX1RBUkdFVF9JRCIsImdldFRhcmdldElEIiwic2V0TWVzc2FnZUxlbmd0aCIsIktFWV9NRVNTQUdFX0xFTkdUSCIsImdldE1lc3NhZ2VMZW5ndGgiLCJzZXRNZXNzYWdlRGF0YSIsIktFWV9NRVNTQUdFX0RBVEEiLCJnZXRNZXNzYWdlRGF0YSIsIkRpYWdub3N0aWNNZXNzYWdlUmVzcG9uc2UiLCJzZXRNZXNzYWdlRGF0YVJlc3VsdCIsIktFWV9NRVNTQUdFX0RBVEFfUkVTVUxUIiwiZ2V0TWVzc2FnZURhdGFSZXN1bHQiLCJzZXRTY3JvbGxhYmxlTWVzc2FnZUJvZHkiLCJib2R5IiwiS0VZX1NDUk9MTEFCTEVfTUVTU0FHRV9CT0RZIiwiZ2V0U2Nyb2xsYWJsZU1lc3NhZ2VCb2R5IiwiU2Nyb2xsYWJsZU1lc3NhZ2VSZXNwb25zZSIsInNldE51bVRpY2tzIiwidGlja3MiLCJLRVlfTlVNX1RJQ0tTIiwiZ2V0TnVtVGlja3MiLCJzZXRTbGlkZXJIZWFkZXIiLCJLRVlfU0xJREVSX0hFQURFUiIsImdldFNsaWRlckhlYWRlciIsInNldFNsaWRlckZvb3RlciIsImZvb3RlciIsIktFWV9TTElERVJfRk9PVEVSIiwiZ2V0U2xpZGVyRm9vdGVyIiwiU2xpZGVyUmVzcG9uc2UiLCJzZXRTbGlkZXJQb3NpdGlvbiIsIktFWV9TTElERVJfUE9TSVRJT04iLCJnZXRTbGlkZXJQb3NpdGlvbiIsInNldE5hdmlnYXRpb25UZXh0MSIsIktFWV9OQVZJR0FUSU9OX1RFWFRfMSIsImdldE5hdmlnYXRpb25UZXh0MSIsInNldE5hdmlnYXRpb25UZXh0MiIsIktFWV9OQVZJR0FUSU9OX1RFWFRfMiIsImdldE5hdmlnYXRpb25UZXh0MiIsInNldEV0YSIsImV0YSIsIktFWV9FVEEiLCJnZXRFdGEiLCJzZXRUaW1lVG9EZXN0aW5hdGlvbiIsImRlc3RpbmF0aW9uIiwiS0VZX1RJTUVfVE9fREVTVElOQVRJT04iLCJnZXRUaW1lVG9EZXN0aW5hdGlvbiIsInNldFRvdGFsRGlzdGFuY2UiLCJkaXN0YW5jZSIsIktFWV9UT1RBTF9ESVNUQU5DRSIsImdldFRvdGFsRGlzdGFuY2UiLCJzZXRUdXJuSWNvbiIsIktFWV9UVVJOX0lDT04iLCJnZXRUdXJuSWNvbiIsInNldE5leHRUdXJuSWNvbiIsIktFWV9ORVhUX1RVUk5fSUNPTiIsImdldE5leHRUdXJuSWNvbiIsInNldERpc3RhbmNlVG9NYW5ldXZlciIsIm1hbmV1dmVyIiwiS0VZX0RJU1RBTkNFX1RPX01BTkVVVkVSIiwiZ2V0RGlzdGFuY2VUb01hbmV1dmVyIiwic2V0RGlzdGFuY2VUb01hbmV1dmVyU2NhbGUiLCJzY2FsZSIsIktFWV9ESVNUQU5DRV9UT19NQU5FVVZFUl9TQ0FMRSIsImdldERpc3RhbmNlVG9NYW5ldXZlclNjYWxlIiwic2V0TWFuZXV2ZXJDb21wbGV0ZSIsImNvbXBsZXRlIiwiS0VZX01BTkVVVkVSX0NPTVBMRVRFIiwiZ2V0TWFuZXV2ZXJDb21wbGV0ZSIsIlNob3dDb25zdGFudFRCVFJlc3BvbnNlIiwiQWxlcnRNYW5ldXZlclJlc3BvbnNlIiwiVHVybiIsInNldE5hdmlnYXRpb25UZXh0IiwiS0VZX05BVklHQVRJT05fVEVYVCIsImdldE5hdmlnYXRpb25UZXh0Iiwic2V0VHVybkxpc3QiLCJLRVlfVFVSTl9MSVNUIiwiZ2V0VHVybkxpc3QiLCJVcGRhdGVUdXJuTGlzdFJlc3BvbnNlIiwiQ2hhbmdlUmVnaXN0cmF0aW9uUmVzcG9uc2UiLCJHZW5lcmljUmVzcG9uc2VSZXNwb25zZSIsInNldEZpbGVEYXRhIiwiZ2V0RmlsZURhdGEiLCJzZXRGaWxlTmFtZSIsIktFWV9GSUxFX05BTUUiLCJnZXRGaWxlTmFtZSIsInNldEZpbGVUeXBlIiwiS0VZX0ZJTEVfVFlQRSIsImdldEZpbGVUeXBlIiwic2V0UGVyc2lzdGVudEZpbGUiLCJmaWxlIiwiS0VZX1BFUlNJU1RFTlRfRklMRSIsImdldFBlcnNpc3RlbnRGaWxlIiwic2V0U3lzdGVtRmlsZSIsIktFWV9TWVNURU1fRklMRSIsImdldFN5c3RlbUZpbGUiLCJzZXRPZmZzZXQiLCJLRVlfT0ZGU0VUIiwiZ2V0T2Zmc2V0Iiwic2V0TGVuZ3RoIiwiS0VZX0xFTkdUSCIsImdldExlbmd0aCIsInNldENyYyIsImNyYyIsIktFWV9DUkMiLCJnZXRDcmMiLCJQdXRGaWxlUmVzcG9uc2UiLCJzZXRTcGFjZUF2YWlsYWJsZSIsIktFWV9TUEFDRV9BVkFJTEFCTEUiLCJnZXRTcGFjZUF2YWlsYWJsZSIsInNldEFwcFNlcnZpY2VJZCIsIktFWV9BUFBfU0VSVklDRV9JRCIsImdldEFwcFNlcnZpY2VJZCIsIkdldEZpbGVSZXNwb25zZSIsInNldFNkbEZpbGVOYW1lIiwiS0VZX1NETF9GSUxFX05BTUUiLCJnZXRTZGxGaWxlTmFtZSIsIkRlbGV0ZUZpbGVSZXNwb25zZSIsIkxpc3RGaWxlc1Jlc3BvbnNlIiwic2V0RmlsZW5hbWVzIiwiZmlsZW5hbWVzIiwiS0VZX0ZJTEVOQU1FUyIsImdldEZpbGVuYW1lcyIsIlNldEFwcEljb25SZXNwb25zZSIsInNldERpc3BsYXlMYXlvdXQiLCJLRVlfRElTUExBWV9MQVlPVVQiLCJnZXREaXNwbGF5TGF5b3V0IiwiU2V0RGlzcGxheUxheW91dFJlc3BvbnNlIiwiUmVxdWVzdFR5cGUiLCJIVFRQIiwiRklMRV9SRVNVTUUiLCJBVVRIX1JFUVVFU1QiLCJBVVRIX0NIQUxMRU5HRSIsIkFVVEhfQUNLIiwiUFJPUFJJRVRBUlkiLCJRVUVSWV9BUFBTIiwiTEFVTkNIX0FQUCIsIkxPQ0tfU0NSRUVOX0lDT05fVVJMIiwiVFJBRkZJQ19NRVNTQUdFX0NIQU5ORUwiLCJEUklWRVJfUFJPRklMRSIsIlZPSUNFX1NFQVJDSCIsIlBIT05FIiwiQ0xJTUFURSIsIlNFVFRJTkdTIiwiVkVISUNMRV9ESUFHTk9TVElDUyIsIkVNRVJHRU5DWSIsIkZPVEEiLCJPRU1fU1BFQ0lGSUMiLCJJQ09OX1VSTCIsInNldFJlcXVlc3RUeXBlIiwiS0VZX1JFUVVFU1RfVFlQRSIsImdldFJlcXVlc3RUeXBlIiwic2V0UmVxdWVzdFN1YlR5cGUiLCJLRVlfUkVRVUVTVF9TVUJfVFlQRSIsImdldFJlcXVlc3RTdWJUeXBlIiwiU3lzdGVtUmVxdWVzdFJlc3BvbnNlIiwiRGVsaXZlcnlNb2RlIiwiUFJPTVBUIiwiREVTVElOQVRJT04iLCJRVUVVRSIsIkRhdGVUaW1lIiwic2V0TWlsbGlzZWNvbmQiLCJtaWxsaXNlY29uZCIsIktFWV9NSUxMSVNFQ09ORCIsImdldE1pbGxpc2Vjb25kIiwic2V0U2Vjb25kIiwic2Vjb25kIiwiS0VZX1NFQ09ORCIsImdldFNlY29uZCIsInNldE1pbnV0ZSIsIm1pbnV0ZSIsIktFWV9NSU5VVEUiLCJnZXRNaW51dGUiLCJzZXRIb3VyIiwiaG91ciIsIktFWV9IT1VSIiwiZ2V0SG91ciIsInNldERheSIsIktFWV9EQVkiLCJnZXREYXkiLCJzZXRNb250aCIsIktFWV9NT05USCIsInNldFllYXIiLCJLRVlfWUVBUiIsImdldFllYXIiLCJzZXRUel9ob3VyIiwidHpfaG91ciIsIktFWV9UWl9IT1VSIiwiZ2V0VHpfaG91ciIsInNldFR6X21pbnV0ZSIsInR6X21pbnV0ZSIsIktFWV9UWl9NSU5VVEUiLCJnZXRUel9taW51dGUiLCJPQVNJU0FkZHJlc3MiLCJzZXRDb3VudHJ5TmFtZSIsIktFWV9DT1VOVFJZX05BTUUiLCJnZXRDb3VudHJ5TmFtZSIsInNldENvdW50cnlDb2RlIiwiS0VZX0NPVU5UUllfQ09ERSIsImdldENvdW50cnlDb2RlIiwic2V0UG9zdGFsQ29kZSIsIktFWV9QT1NUQUxfQ09ERSIsImdldFBvc3RhbENvZGUiLCJzZXRBZG1pbmlzdHJhdGl2ZUFyZWEiLCJLRVlfQURNSU5JU1RSQVRJVkVfQVJFQSIsImdldEFkbWluaXN0cmF0aXZlQXJlYSIsInNldFN1YkFkbWluaXN0cmF0aXZlQXJlYSIsIktFWV9TVUJfQURNSU5JU1RSQVRJVkVfQVJFQSIsImdldFN1YkFkbWluaXN0cmF0aXZlQXJlYSIsInNldExvY2FsaXR5IiwibG9jYWxpdHkiLCJLRVlfTE9DQUxJVFkiLCJnZXRMb2NhbGl0eSIsInNldFN1YkxvY2FsaXR5IiwiS0VZX1NVQl9MT0NBTElUWSIsImdldFN1YkxvY2FsaXR5Iiwic2V0VGhvcm91Z2hmYXJlIiwidGhvcm91Z2hmYXJlIiwiS0VZX1RIT1JPVUdIRkFSRSIsImdldFRob3JvdWdoZmFyZSIsInNldFN1YlRob3JvdWdoZmFyZSIsIktFWV9TVUJfVEhPUk9VR0hGQVJFIiwiZ2V0U3ViVGhvcm91Z2hmYXJlIiwic2V0TG9jYXRpb25OYW1lIiwiS0VZX0xPQ0FUSU9OX05BTUUiLCJnZXRMb2NhdGlvbk5hbWUiLCJzZXRMb2NhdGlvbkRlc2NyaXB0aW9uIiwiZGVzY3JpcHRpb24iLCJLRVlfTE9DQVRJT05fREVTQ1JJUFRJT04iLCJnZXRMb2NhdGlvbkRlc2NyaXB0aW9uIiwic2V0QWRkcmVzc0xpbmVzIiwibGluZXMiLCJLRVlfQUREUkVTU19MSU5FUyIsImdldEFkZHJlc3NMaW5lcyIsInNldFBob25lTnVtYmVyIiwibnVtYmVyIiwiS0VZX1BIT05FX05VTUJFUiIsImdldFBob25lTnVtYmVyIiwic2V0TG9jYXRpb25JbWFnZSIsIktFWV9MT0NBVElPTl9JTUFHRSIsImdldExvY2F0aW9uSW1hZ2UiLCJzZXRUaW1lU3RhbXAiLCJzdGFtcCIsIktFWV9USU1FX1NUQU1QIiwiZ2V0VGltZVN0YW1wIiwic2V0QWRkcmVzcyIsImFkZHJlc3MiLCJLRVlfQUREUkVTUyIsImdldEFkZHJlc3MiLCJzZXREZWxpdmVyeU1vZGUiLCJLRVlfREVMSVZFUllfTU9ERSIsImdldERlbGl2ZXJ5TW9kZSIsIlNlbmRMb2NhdGlvblJlc3BvbnNlIiwic2V0TnVtYmVyIiwiS0VZX05VTUJFUiIsImdldE51bWJlciIsIkRpYWxOdW1iZXJSZXNwb25zZSIsIkJ1dHRvblByZXNzTW9kZSIsIkxPTkciLCJTSE9SVCIsIk1vZHVsZVR5cGUiLCJSQURJTyIsIlNFQVQiLCJMSUdIVCIsIkhNSV9TRVRUSU5HUyIsInNldE1vZHVsZVR5cGUiLCJLRVlfTU9EVUxFX1RZUEUiLCJnZXRNb2R1bGVUeXBlIiwic2V0QnV0dG9uUHJlc3NNb2RlIiwiS0VZX0JVVFRPTl9QUkVTU19NT0RFIiwiZ2V0QnV0dG9uUHJlc3NNb2RlIiwiQnV0dG9uUHJlc3NSZXNwb25zZSIsInNldFN1YnNjcmliZSIsInN1YnNjcmliZSIsIktFWV9TVUJTQ1JJQkUiLCJnZXRTdWJzY3JpYmUiLCJEaXNwbGF5TW9kZSIsIkFVVE8iLCJEaXN0YW5jZVVuaXQiLCJNSUxFUyIsIktJTE9NRVRFUlMiLCJUZW1wZXJhdHVyZVVuaXQiLCJGQUhSRU5IRUlUIiwiQ0VMU0lVUyIsIkhNSVNldHRpbmdzQ29udHJvbERhdGEiLCJzZXREaXNwbGF5TW9kZSIsIktFWV9ESVNQTEFZX01PREUiLCJnZXREaXNwbGF5TW9kZSIsInNldFRlbXBlcmF0dXJlVW5pdCIsInVuaXQiLCJLRVlfVEVNUEVSQVRVUkVfVU5JVCIsImdldFRlbXBlcmF0dXJlVW5pdCIsInNldERpc3RhbmNlVW5pdCIsIktFWV9ESVNUQU5DRV9VTklUIiwiZ2V0RGlzdGFuY2VVbml0IiwiUmFkaW9CYW5kIiwiUmRzRGF0YSIsInNldFBTIiwicHMiLCJLRVlfUFMiLCJnZXRQUyIsInNldFJUIiwiS0VZX1JUIiwiZ2V0UlQiLCJzZXRDVCIsImN0IiwiS0VZX0NUIiwiZ2V0Q1QiLCJzZXRQSSIsInBpIiwiS0VZX1BJIiwiZ2V0UEkiLCJzZXRQVFkiLCJwdHkiLCJLRVlfUFRZIiwiZ2V0UFRZIiwic2V0VFAiLCJ0cCIsIktFWV9UUCIsImdldFRQIiwic2V0VEEiLCJ0YSIsIktFWV9UQSIsImdldFRBIiwic2V0UkVHIiwicmVnIiwiS0VZX1JFRyIsImdldFJFRyIsIlJhZGlvU3RhdGUiLCJBQ1FVSVJJTkciLCJBQ1FVSVJFRCIsIk1VTFRJQ0FTVCIsIk5PVF9GT1VORCIsIlN0YXRpb25JRE51bWJlciIsInNldEZjY0ZhY2lsaXR5SWQiLCJLRVlfRkNDX0ZBQ0lMSVRZX0lEIiwiZ2V0RmNjRmFjaWxpdHlJZCIsIlNpc0RhdGEiLCJzZXRTdGF0aW9uU2hvcnROYW1lIiwiS0VZX1NUQVRJT05fU0hPUlRfTkFNRSIsImdldFN0YXRpb25TaG9ydE5hbWUiLCJzZXRTdGF0aW9uSUROdW1iZXIiLCJLRVlfU1RBVElPTl9JRE5VTUJFUiIsImdldFN0YXRpb25JRE51bWJlciIsInNldFN0YXRpb25Mb25nTmFtZSIsIktFWV9TVEFUSU9OX0xPTkdfTkFNRSIsImdldFN0YXRpb25Mb25nTmFtZSIsInNldFN0YXRpb25Mb2NhdGlvbiIsIktFWV9TVEFUSU9OX0xPQ0FUSU9OIiwiZ2V0U3RhdGlvbkxvY2F0aW9uIiwic2V0U3RhdGlvbk1lc3NhZ2UiLCJLRVlfU1RBVElPTl9NRVNTQUdFIiwiZ2V0U3RhdGlvbk1lc3NhZ2UiLCJSYWRpb0NvbnRyb2xEYXRhIiwic2V0RnJlcXVlbmN5SW50ZWdlciIsImludGVnZXIiLCJLRVlfRlJFUVVFTkNZX0lOVEVHRVIiLCJnZXRGcmVxdWVuY3lJbnRlZ2VyIiwic2V0RnJlcXVlbmN5RnJhY3Rpb24iLCJmcmFjdGlvbiIsIktFWV9GUkVRVUVOQ1lfRlJBQ1RJT04iLCJnZXRGcmVxdWVuY3lGcmFjdGlvbiIsInNldEJhbmQiLCJiYW5kIiwiS0VZX0JBTkQiLCJnZXRCYW5kIiwic2V0UmRzRGF0YSIsIktFWV9SRFNfREFUQSIsImdldFJkc0RhdGEiLCJzZXRIZFJhZGlvRW5hYmxlIiwiZW5hYmxlIiwiS0VZX0hEX1JBRElPX0VOQUJMRSIsImdldEhkUmFkaW9FbmFibGUiLCJzZXRBdmFpbGFibGVIRHMiLCJkcyIsIktFWV9BVkFJTEFCTEVfSERTIiwiZ2V0QXZhaWxhYmxlSERzIiwic2V0QXZhaWxhYmxlSGRDaGFubmVscyIsImNoYW5uZWxzIiwiS0VZX0FWQUlMQUJMRV9IRF9DSEFOTkVMUyIsImdldEF2YWlsYWJsZUhkQ2hhbm5lbHMiLCJzZXRIZENoYW5uZWwiLCJjaGFubmVsIiwiS0VZX0hEX0NIQU5ORUwiLCJnZXRIZENoYW5uZWwiLCJzZXRTaWduYWxTdHJlbmd0aCIsInN0cmVuZ3RoIiwiS0VZX1NJR05BTF9TVFJFTkdUSCIsImdldFNpZ25hbFN0cmVuZ3RoIiwic2V0U2lnbmFsQ2hhbmdlVGhyZXNob2xkIiwidGhyZXNob2xkIiwiS0VZX1NJR05BTF9DSEFOR0VfVEhSRVNIT0xEIiwiZ2V0U2lnbmFsQ2hhbmdlVGhyZXNob2xkIiwic2V0UmFkaW9FbmFibGUiLCJLRVlfUkFESU9fRU5BQkxFIiwiZ2V0UmFkaW9FbmFibGUiLCJzZXRTdGF0ZSIsInN0YXRlIiwiS0VZX1NUQVRFIiwiZ2V0U3RhdGUiLCJzZXRTaXNEYXRhIiwiS0VZX1NJU19EQVRBIiwiZ2V0U2lzRGF0YSIsIlRlbXBlcmF0dXJlIiwic2V0VW5pdCIsIktFWV9VTklUIiwiZ2V0VW5pdCIsIlZlbnRpbGF0aW9uTW9kZSIsIlVQUEVSIiwiTE9XRVIiLCJOT05FIiwiRGVmcm9zdFpvbmUiLCJSRUFSIiwiQUxMIiwiQ2xpbWF0ZUNvbnRyb2xEYXRhIiwic2V0RmFuU3BlZWQiLCJLRVlfRkFOX1NQRUVEIiwiZ2V0RmFuU3BlZWQiLCJzZXRDdXJyZW50VGVtcGVyYXR1cmUiLCJLRVlfQ1VSUkVOVF9URU1QRVJBVFVSRSIsImdldEN1cnJlbnRUZW1wZXJhdHVyZSIsInNldERlc2lyZWRUZW1wZXJhdHVyZSIsIktFWV9ERVNJUkVEX1RFTVBFUkFUVVJFIiwiZ2V0RGVzaXJlZFRlbXBlcmF0dXJlIiwic2V0QWNFbmFibGUiLCJLRVlfQUNfRU5BQkxFIiwiZ2V0QWNFbmFibGUiLCJzZXRDaXJjdWxhdGVBaXJFbmFibGUiLCJLRVlfQ0lSQ1VMQVRFX0FJUl9FTkFCTEUiLCJnZXRDaXJjdWxhdGVBaXJFbmFibGUiLCJzZXRBdXRvTW9kZUVuYWJsZSIsIktFWV9BVVRPX01PREVfRU5BQkxFIiwiZ2V0QXV0b01vZGVFbmFibGUiLCJzZXREZWZyb3N0Wm9uZSIsInpvbmUiLCJLRVlfREVGUk9TVF9aT05FIiwiZ2V0RGVmcm9zdFpvbmUiLCJzZXREdWFsTW9kZUVuYWJsZSIsIktFWV9EVUFMX01PREVfRU5BQkxFIiwiZ2V0RHVhbE1vZGVFbmFibGUiLCJzZXRBY01heEVuYWJsZSIsIktFWV9BQ19NQVhfRU5BQkxFIiwiZ2V0QWNNYXhFbmFibGUiLCJzZXRWZW50aWxhdGlvbk1vZGUiLCJLRVlfVkVOVElMQVRJT05fTU9ERSIsImdldFZlbnRpbGF0aW9uTW9kZSIsInNldEhlYXRlZFN0ZWVyaW5nV2hlZWxFbmFibGUiLCJLRVlfSEVBVEVEX1NURUVSSU5HX1dIRUVMX0VOQUJMRSIsImdldEhlYXRlZFN0ZWVyaW5nV2hlZWxFbmFibGUiLCJzZXRIZWF0ZWRXaW5kc2hpZWxkRW5hYmxlIiwiS0VZX0hFQVRFRF9XSU5EU0hJRUxEX0VOQUJMRSIsImdldEhlYXRlZFdpbmRzaGllbGRFbmFibGUiLCJzZXRIZWF0ZWRSZWFyV2luZG93RW5hYmxlIiwiS0VZX0hFQVRFRF9SRUFSX1dJTkRPV19FTkFCTEUiLCJnZXRIZWF0ZWRSZWFyV2luZG93RW5hYmxlIiwic2V0SGVhdGVkTWlycm9yc0VuYWJsZSIsIktFWV9IRUFURURfTUlSUk9SU19FTkFCTEUiLCJnZXRIZWF0ZWRNaXJyb3JzRW5hYmxlIiwic2V0Q2xpbWF0ZUVuYWJsZSIsIktFWV9DTElNQVRFX0VOQUJMRSIsImdldENsaW1hdGVFbmFibGUiLCJFcXVhbGl6ZXJTZXR0aW5ncyIsInNldENoYW5uZWxJZCIsIktFWV9DSEFOTkVMX0lEIiwiZ2V0Q2hhbm5lbElkIiwic2V0Q2hhbm5lbE5hbWUiLCJLRVlfQ0hBTk5FTF9OQU1FIiwiZ2V0Q2hhbm5lbE5hbWUiLCJzZXRDaGFubmVsU2V0dGluZyIsInNldHRpbmciLCJLRVlfQ0hBTk5FTF9TRVRUSU5HIiwiZ2V0Q2hhbm5lbFNldHRpbmciLCJBdWRpb0NvbnRyb2xEYXRhIiwic2V0U291cmNlIiwiS0VZX1NPVVJDRSIsImdldFNvdXJjZSIsInNldEtlZXBDb250ZXh0IiwiY29udGV4dCIsIktFWV9LRUVQX0NPTlRFWFQiLCJnZXRLZWVwQ29udGV4dCIsInNldFZvbHVtZSIsInZvbHVtZSIsIktFWV9WT0xVTUUiLCJnZXRWb2x1bWUiLCJzZXRFcXVhbGl6ZXJTZXR0aW5ncyIsInNldHRpbmdzIiwiS0VZX0VRVUFMSVpFUl9TRVRUSU5HUyIsImdldEVxdWFsaXplclNldHRpbmdzIiwiTWFzc2FnZUN1c2hpb24iLCJUT1BfTFVNQkFSIiwiTUlERExFX0xVTUJBUiIsIkJPVFRPTV9MVU1CQVIiLCJCQUNLX0JPTFNURVJTIiwiU0VBVF9CT0xTVEVSUyIsIk1hc3NhZ2VDdXNoaW9uRmlybW5lc3MiLCJzZXRDdXNoaW9uIiwiY3VzaGlvbiIsIktFWV9DVVNISU9OIiwiZ2V0Q3VzaGlvbiIsInNldEZpcm1uZXNzIiwiZmlybW5lc3MiLCJLRVlfRklSTU5FU1MiLCJnZXRGaXJtbmVzcyIsIlN1cHBvcnRlZFNlYXQiLCJEUklWRVIiLCJGUk9OVF9QQVNTRU5HRVIiLCJTZWF0TWVtb3J5QWN0aW9uVHlwZSIsIlNBVkUiLCJSRVNUT1JFIiwiU2VhdE1lbW9yeUFjdGlvbiIsInNldElkIiwiS0VZX0lEIiwiZ2V0SWQiLCJzZXRMYWJlbCIsImxhYmVsIiwiS0VZX0xBQkVMIiwiZ2V0TGFiZWwiLCJzZXRBY3Rpb24iLCJLRVlfQUNUSU9OIiwiZ2V0QWN0aW9uIiwiTWFzc2FnZVpvbmUiLCJMVU1CQVIiLCJTRUFUX0NVU0hJT04iLCJNYXNzYWdlTW9kZSIsIkhJR0giLCJNYXNzYWdlTW9kZURhdGEiLCJzZXRNYXNzYWdlWm9uZSIsIktFWV9NQVNTQUdFX1pPTkUiLCJnZXRNYXNzYWdlWm9uZSIsInNldE1hc3NhZ2VNb2RlIiwiS0VZX01BU1NBR0VfTU9ERSIsImdldE1hc3NhZ2VNb2RlIiwiU2VhdENvbnRyb2xEYXRhIiwic2V0SGVhdGluZ0VuYWJsZWQiLCJlbmFibGVkIiwiS0VZX0hFQVRJTkdfRU5BQkxFRCIsImdldEhlYXRpbmdFbmFibGVkIiwic2V0Q29vbGluZ0VuYWJsZWQiLCJLRVlfQ09PTElOR19FTkFCTEVEIiwiZ2V0Q29vbGluZ0VuYWJsZWQiLCJzZXRIZWF0aW5nTGV2ZWwiLCJLRVlfSEVBVElOR19MRVZFTCIsImdldEhlYXRpbmdMZXZlbCIsInNldENvb2xpbmdMZXZlbCIsIktFWV9DT09MSU5HX0xFVkVMIiwiZ2V0Q29vbGluZ0xldmVsIiwic2V0SG9yaXpvbnRhbFBvc2l0aW9uIiwiS0VZX0hPUklaT05UQUxfUE9TSVRJT04iLCJnZXRIb3Jpem9udGFsUG9zaXRpb24iLCJzZXRWZXJ0aWNhbFBvc2l0aW9uIiwiS0VZX1ZFUlRJQ0FMX1BPU0lUSU9OIiwiZ2V0VmVydGljYWxQb3NpdGlvbiIsInNldEZyb250VmVydGljYWxQb3NpdGlvbiIsIktFWV9GUk9OVF9WRVJUSUNBTF9QT1NJVElPTiIsImdldEZyb250VmVydGljYWxQb3NpdGlvbiIsInNldEJhY2tWZXJ0aWNhbFBvc2l0aW9uIiwiS0VZX0JBQ0tfVkVSVElDQUxfUE9TSVRJT04iLCJnZXRCYWNrVmVydGljYWxQb3NpdGlvbiIsInNldEJhY2tUaWx0QW5nbGUiLCJLRVlfQkFDS19USUxUX0FOR0xFIiwiZ2V0QmFja1RpbHRBbmdsZSIsInNldEhlYWRTdXBwb3J0SG9yaXpvbnRhbFBvc2l0aW9uIiwiS0VZX0hFQURfU1VQUE9SVF9IT1JJWk9OVEFMX1BPU0lUSU9OIiwiZ2V0SGVhZFN1cHBvcnRIb3Jpem9udGFsUG9zaXRpb24iLCJzZXRIZWFkU3VwcG9ydFZlcnRpY2FsUG9zaXRpb24iLCJLRVlfSEVBRF9TVVBQT1JUX1ZFUlRJQ0FMX1BPU0lUSU9OIiwiZ2V0SGVhZFN1cHBvcnRWZXJ0aWNhbFBvc2l0aW9uIiwic2V0TWFzc2FnZUVuYWJsZWQiLCJLRVlfTUFTU0FHRV9FTkFCTEVEIiwiZ2V0TWFzc2FnZUVuYWJsZWQiLCJzZXRNYXNzYWdlQ3VzaGlvbkZpcm1uZXNzIiwiS0VZX01BU1NBR0VfQ1VTSElPTl9GSVJNTkVTUyIsImdldE1hc3NhZ2VDdXNoaW9uRmlybW5lc3MiLCJzZXRNZW1vcnkiLCJtZW1vcnkiLCJLRVlfTUVNT1JZIiwiZ2V0TWVtb3J5IiwiTGlnaHRTdGF0dXMiLCJPTiIsIlJBTVBfVVAiLCJSQU1QX0RPV04iLCJMaWdodE5hbWUiLCJGUk9OVF9MRUZUX0hJR0hfQkVBTSIsIkZST05UX1JJR0hUX0hJR0hfQkVBTSIsIkZST05UX0xFRlRfTE9XX0JFQU0iLCJGUk9OVF9SSUdIVF9MT1dfQkVBTSIsIkZST05UX0xFRlRfUEFSS0lOR19MSUdIVCIsIkZST05UX1JJR0hUX1BBUktJTkdfTElHSFQiLCJGUk9OVF9MRUZUX0ZPR19MSUdIVCIsIkZST05UX1JJR0hUX0ZPR19MSUdIVCIsIkZST05UX0xFRlRfREFZVElNRV9SVU5OSU5HX0xJR0hUIiwiRlJPTlRfUklHSFRfREFZVElNRV9SVU5OSU5HX0xJR0hUIiwiRlJPTlRfTEVGVF9UVVJOX0xJR0hUIiwiRlJPTlRfUklHSFRfVFVSTl9MSUdIVCIsIlJFQVJfTEVGVF9GT0dfTElHSFQiLCJSRUFSX1JJR0hUX0ZPR19MSUdIVCIsIlJFQVJfTEVGVF9UQUlMX0xJR0hUIiwiUkVBUl9SSUdIVF9UQUlMX0xJR0hUIiwiUkVBUl9MRUZUX0JSQUtFX0xJR0hUIiwiUkVBUl9SSUdIVF9CUkFLRV9MSUdIVCIsIlJFQVJfTEVGVF9UVVJOX0xJR0hUIiwiUkVBUl9SSUdIVF9UVVJOX0xJR0hUIiwiUkVBUl9SRUdJU1RSQVRJT05fUExBVEVfTElHSFQiLCJISUdIX0JFQU1TIiwiTE9XX0JFQU1TIiwiRk9HX0xJR0hUUyIsIlJVTk5JTkdfTElHSFRTIiwiUEFSS0lOR19MSUdIVFMiLCJCUkFLRV9MSUdIVFMiLCJSRUFSX1JFVkVSU0lOR19MSUdIVFMiLCJTSURFX01BUktFUl9MSUdIVFMiLCJMRUZUX1RVUk5fTElHSFRTIiwiUklHSFRfVFVSTl9MSUdIVFMiLCJIQVpBUkRfTElHSFRTIiwiUkVBUl9DQVJHT19MSUdIVFMiLCJSRUFSX1RSVUNLX0JFRF9MSUdIVFMiLCJSRUFSX1RSQUlMRVJfTElHSFRTIiwiTEVGVF9TUE9UX0xJR0hUUyIsIlJJR0hUX1NQT1RfTElHSFRTIiwiTEVGVF9QVURETEVfTElHSFRTIiwiUklHSFRfUFVERExFX0xJR0hUUyIsIkFNQklFTlRfTElHSFRTIiwiT1ZFUkhFQURfTElHSFRTIiwiUkVBRElOR19MSUdIVFMiLCJUUlVOS19MSUdIVFMiLCJFWFRFUklPUl9GUk9OVF9MSUdIVFMiLCJFWFRFUklPUl9SRUFSX0xJR0hUUyIsIkVYVEVSSU9SX0xFRlRfTElHSFRTIiwiRVhURVJJT1JfUklHSFRfTElHSFRTIiwiRVhURVJJT1JfQUxMX0xJR0hUUyIsIkxpZ2h0U3RhdGUiLCJzZXREZW5zaXR5IiwiZGVuc2l0eSIsIktFWV9ERU5TSVRZIiwiZ2V0RGVuc2l0eSIsInNldENvbG9yIiwiS0VZX0NPTE9SIiwiZ2V0Q29sb3IiLCJMaWdodENvbnRyb2xEYXRhIiwic2V0TGlnaHRTdGF0ZSIsIktFWV9MSUdIVF9TVEFURSIsImdldExpZ2h0U3RhdGUiLCJNb2R1bGVEYXRhIiwic2V0UmFkaW9Db250cm9sRGF0YSIsIktFWV9SQURJT19DT05UUk9MX0RBVEEiLCJnZXRSYWRpb0NvbnRyb2xEYXRhIiwic2V0Q2xpbWF0ZUNvbnRyb2xEYXRhIiwiS0VZX0NMSU1BVEVfQ09OVFJPTF9EQVRBIiwiZ2V0Q2xpbWF0ZUNvbnRyb2xEYXRhIiwic2V0U2VhdENvbnRyb2xEYXRhIiwiS0VZX1NFQVRfQ09OVFJPTF9EQVRBIiwiZ2V0U2VhdENvbnRyb2xEYXRhIiwic2V0QXVkaW9Db250cm9sRGF0YSIsIktFWV9BVURJT19DT05UUk9MX0RBVEEiLCJnZXRBdWRpb0NvbnRyb2xEYXRhIiwic2V0TGlnaHRDb250cm9sRGF0YSIsIktFWV9MSUdIVF9DT05UUk9MX0RBVEEiLCJnZXRMaWdodENvbnRyb2xEYXRhIiwic2V0SG1pU2V0dGluZ3NDb250cm9sRGF0YSIsIktFWV9ITUlfU0VUVElOR1NfQ09OVFJPTF9EQVRBIiwiZ2V0SG1pU2V0dGluZ3NDb250cm9sRGF0YSIsIkdldEludGVyaW9yVmVoaWNsZURhdGFSZXNwb25zZSIsInNldE1vZHVsZURhdGEiLCJLRVlfTU9EVUxFX0RBVEEiLCJnZXRNb2R1bGVEYXRhIiwic2V0SXNTdWJzY3JpYmVkIiwic3Vic2NyaWJlZCIsIktFWV9JU19TVUJTQ1JJQkVEIiwiZ2V0SXNTdWJzY3JpYmVkIiwic2V0TW9kdWxlSWRzIiwiaWRzIiwiS0VZX01PRFVMRV9JRFMiLCJnZXRNb2R1bGVJZHMiLCJHZXRJbnRlcmlvclZlaGljbGVEYXRhQ29uc2VudFJlc3BvbnNlIiwic2V0QWxsb3dlZCIsImFsbG93ZWQiLCJLRVlfQUxMT1dFRCIsImdldEFsbG93ZWQiLCJSZWxlYXNlSW50ZXJpb3JWZWhpY2xlRGF0YU1vZHVsZVJlc3BvbnNlIiwiU2V0SW50ZXJpb3JWZWhpY2xlRGF0YVJlc3BvbnNlIiwiU3Vic2NyaWJlV2F5UG9pbnRzUmVzcG9uc2UiLCJXYXlQb2ludFR5cGUiLCJzZXRXYXlQb2ludFR5cGUiLCJLRVlfV0FZX1BPSU5UX1RZUEUiLCJnZXRXYXlQb2ludFR5cGUiLCJDb29yZGluYXRlIiwiTG9jYXRpb25EZXRhaWxzIiwic2V0Q29vcmRpbmF0ZSIsImNvb3JkaW5hdGUiLCJLRVlfQ09PUkRJTkFURSIsImdldENvb3JkaW5hdGUiLCJzZXRTZWFyY2hBZGRyZXNzIiwiS0VZX1NFQVJDSF9BRERSRVNTIiwiZ2V0U2VhcmNoQWRkcmVzcyIsIkdldFdheVBvaW50c1Jlc3BvbnNlIiwic2V0V2F5UG9pbnRzIiwicG9pbnRzIiwiS0VZX1dBWV9QT0lOVFMiLCJnZXRXYXlQb2ludHMiLCJVbnN1YnNjcmliZVdheVBvaW50c1Jlc3BvbnNlIiwiU3lzdGVtQ2FwYWJpbGl0eVR5cGUiLCJQSE9ORV9DQUxMIiwiVklERU9fU1RSRUFNSU5HIiwiQVBQX1NFUlZJQ0VTIiwiU0VBVF9MT0NBVElPTiIsIkRJU1BMQVlTIiwic2V0U3lzdGVtQ2FwYWJpbGl0eVR5cGUiLCJLRVlfU1lTVEVNX0NBUEFCSUxJVFlfVFlQRSIsImdldFN5c3RlbUNhcGFiaWxpdHlUeXBlIiwiVmlkZW9TdHJlYW1pbmdDb2RlYyIsIkgyNjQiLCJIMjY1IiwiVGhlb3JhIiwiVlA4IiwiVlA5IiwiVmlkZW9TdHJlYW1pbmdQcm90b2NvbCIsIlJBVyIsIlJUUCIsIlJUU1AiLCJSVE1QIiwiV0VCTSIsIlZpZGVvU3RyZWFtaW5nRm9ybWF0Iiwic2V0UHJvdG9jb2wiLCJwcm90b2NvbCIsIktFWV9QUk9UT0NPTCIsImdldFByb3RvY29sIiwic2V0Q29kZWMiLCJjb2RlYyIsIktFWV9DT0RFQyIsImdldENvZGVjIiwiVmlkZW9TdHJlYW1pbmdDYXBhYmlsaXR5Iiwic2V0UHJlZmVycmVkUmVzb2x1dGlvbiIsIktFWV9QUkVGRVJSRURfUkVTT0xVVElPTiIsImdldFByZWZlcnJlZFJlc29sdXRpb24iLCJzZXRNYXhCaXRyYXRlIiwiYml0cmF0ZSIsIktFWV9NQVhfQklUUkFURSIsImdldE1heEJpdHJhdGUiLCJzZXRTdXBwb3J0ZWRGb3JtYXRzIiwiS0VZX1NVUFBPUlRFRF9GT1JNQVRTIiwiZ2V0U3VwcG9ydGVkRm9ybWF0cyIsInNldEhhcHRpY1NwYXRpYWxEYXRhU3VwcG9ydGVkIiwiS0VZX0hBUFRJQ19TUEFUSUFMX0RBVEFfU1VQUE9SVEVEIiwiZ2V0SGFwdGljU3BhdGlhbERhdGFTdXBwb3J0ZWQiLCJzZXREaWFnb25hbFNjcmVlblNpemUiLCJLRVlfRElBR09OQUxfU0NSRUVOX1NJWkUiLCJnZXREaWFnb25hbFNjcmVlblNpemUiLCJzZXRQaXhlbFBlckluY2giLCJpbmNoIiwiS0VZX1BJWEVMX1BFUl9JTkNIIiwiZ2V0UGl4ZWxQZXJJbmNoIiwic2V0U2NhbGUiLCJLRVlfU0NBTEUiLCJnZXRTY2FsZSIsIlBob25lQ2FwYWJpbGl0eSIsInNldERpYWxOdW1iZXJFbmFibGVkIiwiS0VZX0RJQUxfTlVNQkVSX0VOQUJMRUQiLCJnZXREaWFsTnVtYmVyRW5hYmxlZCIsIldpbmRvd1R5cGVDYXBhYmlsaXRpZXMiLCJzZXRNYXhpbXVtTnVtYmVyT2ZXaW5kb3dzIiwid2luZG93cyIsIktFWV9NQVhJTVVNX05VTUJFUl9PRl9XSU5ET1dTIiwiZ2V0TWF4aW11bU51bWJlck9mV2luZG93cyIsIldpbmRvd0NhcGFiaWxpdHkiLCJzZXRNZW51TGF5b3V0c0F2YWlsYWJsZSIsIktFWV9NRU5VX0xBWU9VVFNfQVZBSUxBQkxFIiwiZ2V0TWVudUxheW91dHNBdmFpbGFibGUiLCJEaXNwbGF5Q2FwYWJpbGl0eSIsInNldFdpbmRvd1R5cGVTdXBwb3J0ZWQiLCJLRVlfV0lORE9XX1RZUEVfU1VQUE9SVEVEIiwiZ2V0V2luZG93VHlwZVN1cHBvcnRlZCIsInNldFdpbmRvd0NhcGFiaWxpdGllcyIsIktFWV9XSU5ET1dfQ0FQQUJJTElUSUVTIiwiZ2V0V2luZG93Q2FwYWJpbGl0aWVzIiwiQXVkaW9Db250cm9sQ2FwYWJpbGl0aWVzIiwic2V0TW9kdWxlTmFtZSIsIktFWV9NT0RVTEVfTkFNRSIsImdldE1vZHVsZU5hbWUiLCJzZXRTb3VyY2VBdmFpbGFibGUiLCJLRVlfU09VUkNFX0FWQUlMQUJMRSIsImdldFNvdXJjZUF2YWlsYWJsZSIsInNldEtlZXBDb250ZXh0QXZhaWxhYmxlIiwiS0VZX0tFRVBfQ09OVEVYVF9BVkFJTEFCTEUiLCJnZXRLZWVwQ29udGV4dEF2YWlsYWJsZSIsInNldFZvbHVtZUF2YWlsYWJsZSIsIktFWV9WT0xVTUVfQVZBSUxBQkxFIiwiZ2V0Vm9sdW1lQXZhaWxhYmxlIiwic2V0RXF1YWxpemVyQXZhaWxhYmxlIiwiS0VZX0VRVUFMSVpFUl9BVkFJTEFCTEUiLCJnZXRFcXVhbGl6ZXJBdmFpbGFibGUiLCJzZXRFcXVhbGl6ZXJNYXhDaGFubmVsSWQiLCJLRVlfRVFVQUxJWkVSX01BWF9DSEFOTkVMX0lEIiwiZ2V0RXF1YWxpemVyTWF4Q2hhbm5lbElkIiwiTGlnaHRDYXBhYmlsaXRpZXMiLCJzZXRTdGF0dXNBdmFpbGFibGUiLCJLRVlfU1RBVFVTX0FWQUlMQUJMRSIsImdldFN0YXR1c0F2YWlsYWJsZSIsInNldERlbnNpdHlBdmFpbGFibGUiLCJLRVlfREVOU0lUWV9BVkFJTEFCTEUiLCJnZXREZW5zaXR5QXZhaWxhYmxlIiwic2V0UmdiQ29sb3JTcGFjZUF2YWlsYWJsZSIsIktFWV9SR0JfQ09MT1JfU1BBQ0VfQVZBSUxBQkxFIiwiZ2V0UmdiQ29sb3JTcGFjZUF2YWlsYWJsZSIsIkxpZ2h0Q29udHJvbENhcGFiaWxpdGllcyIsInNldFN1cHBvcnRlZExpZ2h0cyIsImxpZ2h0cyIsIktFWV9TVVBQT1JURURfTElHSFRTIiwiZ2V0U3VwcG9ydGVkTGlnaHRzIiwiQ2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMiLCJzZXRDdXJyZW50VGVtcGVyYXR1cmVBdmFpbGFibGUiLCJLRVlfQ1VSUkVOVF9URU1QRVJBVFVSRV9BVkFJTEFCTEUiLCJnZXRDdXJyZW50VGVtcGVyYXR1cmVBdmFpbGFibGUiLCJzZXRGYW5TcGVlZEF2YWlsYWJsZSIsIktFWV9GQU5fU1BFRURfQVZBSUxBQkxFIiwiZ2V0RmFuU3BlZWRBdmFpbGFibGUiLCJzZXREZXNpcmVkVGVtcGVyYXR1cmVBdmFpbGFibGUiLCJLRVlfREVTSVJFRF9URU1QRVJBVFVSRV9BVkFJTEFCTEUiLCJnZXREZXNpcmVkVGVtcGVyYXR1cmVBdmFpbGFibGUiLCJzZXRBY0VuYWJsZUF2YWlsYWJsZSIsIktFWV9BQ19FTkFCTEVfQVZBSUxBQkxFIiwiZ2V0QWNFbmFibGVBdmFpbGFibGUiLCJzZXRBY01heEVuYWJsZUF2YWlsYWJsZSIsIktFWV9BQ19NQVhfRU5BQkxFX0FWQUlMQUJMRSIsImdldEFjTWF4RW5hYmxlQXZhaWxhYmxlIiwic2V0Q2lyY3VsYXRlQWlyRW5hYmxlQXZhaWxhYmxlIiwiS0VZX0NJUkNVTEFURV9BSVJfRU5BQkxFX0FWQUlMQUJMRSIsImdldENpcmN1bGF0ZUFpckVuYWJsZUF2YWlsYWJsZSIsInNldEF1dG9Nb2RlRW5hYmxlQXZhaWxhYmxlIiwiS0VZX0FVVE9fTU9ERV9FTkFCTEVfQVZBSUxBQkxFIiwiZ2V0QXV0b01vZGVFbmFibGVBdmFpbGFibGUiLCJzZXREdWFsTW9kZUVuYWJsZUF2YWlsYWJsZSIsIktFWV9EVUFMX01PREVfRU5BQkxFX0FWQUlMQUJMRSIsImdldER1YWxNb2RlRW5hYmxlQXZhaWxhYmxlIiwic2V0RGVmcm9zdFpvbmVBdmFpbGFibGUiLCJLRVlfREVGUk9TVF9aT05FX0FWQUlMQUJMRSIsImdldERlZnJvc3Rab25lQXZhaWxhYmxlIiwic2V0VmVudGlsYXRpb25Nb2RlQXZhaWxhYmxlIiwiS0VZX1ZFTlRJTEFUSU9OX01PREVfQVZBSUxBQkxFIiwiZ2V0VmVudGlsYXRpb25Nb2RlQXZhaWxhYmxlIiwic2V0SGVhdGVkU3RlZXJpbmdXaGVlbEF2YWlsYWJsZSIsIktFWV9IRUFURURfU1RFRVJJTkdfV0hFRUxfQVZBSUxBQkxFIiwiZ2V0SGVhdGVkU3RlZXJpbmdXaGVlbEF2YWlsYWJsZSIsInNldEhlYXRlZFdpbmRzaGllbGRBdmFpbGFibGUiLCJLRVlfSEVBVEVEX1dJTkRTSElFTERfQVZBSUxBQkxFIiwiZ2V0SGVhdGVkV2luZHNoaWVsZEF2YWlsYWJsZSIsInNldEhlYXRlZFJlYXJXaW5kb3dBdmFpbGFibGUiLCJLRVlfSEVBVEVEX1JFQVJfV0lORE9XX0FWQUlMQUJMRSIsImdldEhlYXRlZFJlYXJXaW5kb3dBdmFpbGFibGUiLCJzZXRIZWF0ZWRNaXJyb3JzQXZhaWxhYmxlIiwiS0VZX0hFQVRFRF9NSVJST1JTX0FWQUlMQUJMRSIsImdldEhlYXRlZE1pcnJvcnNBdmFpbGFibGUiLCJzZXRDbGltYXRlRW5hYmxlQXZhaWxhYmxlIiwiS0VZX0NMSU1BVEVfRU5BQkxFX0FWQUlMQUJMRSIsImdldENsaW1hdGVFbmFibGVBdmFpbGFibGUiLCJTZWF0Q29udHJvbENhcGFiaWxpdGllcyIsInNldEhlYXRpbmdFbmFibGVkQXZhaWxhYmxlIiwiS0VZX0hFQVRJTkdfRU5BQkxFRF9BVkFJTEFCTEUiLCJnZXRIZWF0aW5nRW5hYmxlZEF2YWlsYWJsZSIsInNldENvb2xpbmdFbmFibGVkQXZhaWxhYmxlIiwiS0VZX0NPT0xJTkdfRU5BQkxFRF9BVkFJTEFCTEUiLCJnZXRDb29saW5nRW5hYmxlZEF2YWlsYWJsZSIsInNldEhlYXRpbmdMZXZlbEF2YWlsYWJsZSIsIktFWV9IRUFUSU5HX0xFVkVMX0FWQUlMQUJMRSIsImdldEhlYXRpbmdMZXZlbEF2YWlsYWJsZSIsInNldENvb2xpbmdMZXZlbEF2YWlsYWJsZSIsIktFWV9DT09MSU5HX0xFVkVMX0FWQUlMQUJMRSIsImdldENvb2xpbmdMZXZlbEF2YWlsYWJsZSIsInNldEhvcml6b250YWxQb3NpdGlvbkF2YWlsYWJsZSIsIktFWV9IT1JJWk9OVEFMX1BPU0lUSU9OX0FWQUlMQUJMRSIsImdldEhvcml6b250YWxQb3NpdGlvbkF2YWlsYWJsZSIsInNldFZlcnRpY2FsUG9zaXRpb25BdmFpbGFibGUiLCJLRVlfVkVSVElDQUxfUE9TSVRJT05fQVZBSUxBQkxFIiwiZ2V0VmVydGljYWxQb3NpdGlvbkF2YWlsYWJsZSIsInNldEZyb250VmVydGljYWxQb3NpdGlvbkF2YWlsYWJsZSIsIktFWV9GUk9OVF9WRVJUSUNBTF9QT1NJVElPTl9BVkFJTEFCTEUiLCJnZXRGcm9udFZlcnRpY2FsUG9zaXRpb25BdmFpbGFibGUiLCJzZXRCYWNrVmVydGljYWxQb3NpdGlvbkF2YWlsYWJsZSIsIktFWV9CQUNLX1ZFUlRJQ0FMX1BPU0lUSU9OX0FWQUlMQUJMRSIsImdldEJhY2tWZXJ0aWNhbFBvc2l0aW9uQXZhaWxhYmxlIiwic2V0QmFja1RpbHRBbmdsZUF2YWlsYWJsZSIsIktFWV9CQUNLX1RJTFRfQU5HTEVfQVZBSUxBQkxFIiwiZ2V0QmFja1RpbHRBbmdsZUF2YWlsYWJsZSIsInNldEhlYWRTdXBwb3J0SG9yaXpvbnRhbFBvc2l0aW9uQXZhaWxhYmxlIiwiS0VZX0hFQURfU1VQUE9SVF9IT1JJWk9OVEFMX1BPU0lUSU9OX0FWQUlMQUJMRSIsImdldEhlYWRTdXBwb3J0SG9yaXpvbnRhbFBvc2l0aW9uQXZhaWxhYmxlIiwic2V0SGVhZFN1cHBvcnRWZXJ0aWNhbFBvc2l0aW9uQXZhaWxhYmxlIiwiS0VZX0hFQURfU1VQUE9SVF9WRVJUSUNBTF9QT1NJVElPTl9BVkFJTEFCTEUiLCJnZXRIZWFkU3VwcG9ydFZlcnRpY2FsUG9zaXRpb25BdmFpbGFibGUiLCJzZXRNYXNzYWdlRW5hYmxlZEF2YWlsYWJsZSIsIktFWV9NQVNTQUdFX0VOQUJMRURfQVZBSUxBQkxFIiwiZ2V0TWFzc2FnZUVuYWJsZWRBdmFpbGFibGUiLCJzZXRNYXNzYWdlTW9kZUF2YWlsYWJsZSIsIktFWV9NQVNTQUdFX01PREVfQVZBSUxBQkxFIiwiZ2V0TWFzc2FnZU1vZGVBdmFpbGFibGUiLCJzZXRNYXNzYWdlQ3VzaGlvbkZpcm1uZXNzQXZhaWxhYmxlIiwiS0VZX01BU1NBR0VfQ1VTSElPTl9GSVJNTkVTU19BVkFJTEFCTEUiLCJnZXRNYXNzYWdlQ3VzaGlvbkZpcm1uZXNzQXZhaWxhYmxlIiwic2V0TWVtb3J5QXZhaWxhYmxlIiwiS0VZX01FTU9SWV9BVkFJTEFCTEUiLCJnZXRNZW1vcnlBdmFpbGFibGUiLCJSYWRpb0NvbnRyb2xDYXBhYmlsaXRpZXMiLCJzZXRSYWRpb0VuYWJsZUF2YWlsYWJsZSIsIktFWV9SQURJT19FTkFCTEVfQVZBSUxBQkxFIiwiZ2V0UmFkaW9FbmFibGVBdmFpbGFibGUiLCJzZXRSYWRpb0JhbmRBdmFpbGFibGUiLCJLRVlfUkFESU9fQkFORF9BVkFJTEFCTEUiLCJnZXRSYWRpb0JhbmRBdmFpbGFibGUiLCJzZXRSYWRpb0ZyZXF1ZW5jeUF2YWlsYWJsZSIsIktFWV9SQURJT19GUkVRVUVOQ1lfQVZBSUxBQkxFIiwiZ2V0UmFkaW9GcmVxdWVuY3lBdmFpbGFibGUiLCJzZXRIZENoYW5uZWxBdmFpbGFibGUiLCJLRVlfSERfQ0hBTk5FTF9BVkFJTEFCTEUiLCJnZXRIZENoYW5uZWxBdmFpbGFibGUiLCJzZXRSZHNEYXRhQXZhaWxhYmxlIiwiS0VZX1JEU19EQVRBX0FWQUlMQUJMRSIsImdldFJkc0RhdGFBdmFpbGFibGUiLCJzZXRBdmFpbGFibGVIRHNBdmFpbGFibGUiLCJLRVlfQVZBSUxBQkxFX0hEU19BVkFJTEFCTEUiLCJnZXRBdmFpbGFibGVIRHNBdmFpbGFibGUiLCJzZXRBdmFpbGFibGVIZENoYW5uZWxzQXZhaWxhYmxlIiwiS0VZX0FWQUlMQUJMRV9IRF9DSEFOTkVMU19BVkFJTEFCTEUiLCJnZXRBdmFpbGFibGVIZENoYW5uZWxzQXZhaWxhYmxlIiwic2V0U3RhdGVBdmFpbGFibGUiLCJLRVlfU1RBVEVfQVZBSUxBQkxFIiwiZ2V0U3RhdGVBdmFpbGFibGUiLCJzZXRTaWduYWxTdHJlbmd0aEF2YWlsYWJsZSIsIktFWV9TSUdOQUxfU1RSRU5HVEhfQVZBSUxBQkxFIiwiZ2V0U2lnbmFsU3RyZW5ndGhBdmFpbGFibGUiLCJzZXRTaWduYWxDaGFuZ2VUaHJlc2hvbGRBdmFpbGFibGUiLCJLRVlfU0lHTkFMX0NIQU5HRV9USFJFU0hPTERfQVZBSUxBQkxFIiwiZ2V0U2lnbmFsQ2hhbmdlVGhyZXNob2xkQXZhaWxhYmxlIiwic2V0U2lzRGF0YUF2YWlsYWJsZSIsIktFWV9TSVNfREFUQV9BVkFJTEFCTEUiLCJnZXRTaXNEYXRhQXZhaWxhYmxlIiwic2V0SGRSYWRpb0VuYWJsZUF2YWlsYWJsZSIsIktFWV9IRF9SQURJT19FTkFCTEVfQVZBSUxBQkxFIiwiZ2V0SGRSYWRpb0VuYWJsZUF2YWlsYWJsZSIsInNldFNpcml1c3htUmFkaW9BdmFpbGFibGUiLCJLRVlfU0lSSVVTWE1fUkFESU9fQVZBSUxBQkxFIiwiZ2V0U2lyaXVzeG1SYWRpb0F2YWlsYWJsZSIsIkhNSVNldHRpbmdzQ29udHJvbENhcGFiaWxpdGllcyIsInNldERpc3RhbmNlVW5pdEF2YWlsYWJsZSIsIktFWV9ESVNUQU5DRV9VTklUX0FWQUlMQUJMRSIsImdldERpc3RhbmNlVW5pdEF2YWlsYWJsZSIsInNldFRlbXBlcmF0dXJlVW5pdEF2YWlsYWJsZSIsIktFWV9URU1QRVJBVFVSRV9VTklUX0FWQUlMQUJMRSIsImdldFRlbXBlcmF0dXJlVW5pdEF2YWlsYWJsZSIsInNldERpc3BsYXlNb2RlVW5pdEF2YWlsYWJsZSIsIktFWV9ESVNQTEFZX01PREVfVU5JVF9BVkFJTEFCTEUiLCJnZXREaXNwbGF5TW9kZVVuaXRBdmFpbGFibGUiLCJSZW1vdGVDb250cm9sQ2FwYWJpbGl0aWVzIiwic2V0Q2xpbWF0ZUNvbnRyb2xDYXBhYmlsaXRpZXMiLCJLRVlfQ0xJTUFURV9DT05UUk9MX0NBUEFCSUxJVElFUyIsImdldENsaW1hdGVDb250cm9sQ2FwYWJpbGl0aWVzIiwic2V0UmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzIiwiS0VZX1JBRElPX0NPTlRST0xfQ0FQQUJJTElUSUVTIiwiZ2V0UmFkaW9Db250cm9sQ2FwYWJpbGl0aWVzIiwic2V0QXVkaW9Db250cm9sQ2FwYWJpbGl0aWVzIiwiS0VZX0FVRElPX0NPTlRST0xfQ0FQQUJJTElUSUVTIiwiZ2V0QXVkaW9Db250cm9sQ2FwYWJpbGl0aWVzIiwic2V0SG1pU2V0dGluZ3NDb250cm9sQ2FwYWJpbGl0aWVzIiwiS0VZX0hNSV9TRVRUSU5HU19DT05UUk9MX0NBUEFCSUxJVElFUyIsImdldEhtaVNldHRpbmdzQ29udHJvbENhcGFiaWxpdGllcyIsInNldExpZ2h0Q29udHJvbENhcGFiaWxpdGllcyIsIktFWV9MSUdIVF9DT05UUk9MX0NBUEFCSUxJVElFUyIsImdldExpZ2h0Q29udHJvbENhcGFiaWxpdGllcyIsInNldFNlYXRDb250cm9sQ2FwYWJpbGl0aWVzIiwiS0VZX1NFQVRfQ09OVFJPTF9DQVBBQklMSVRJRVMiLCJnZXRTZWF0Q29udHJvbENhcGFiaWxpdGllcyIsIlNlYXRMb2NhdGlvbkNhcGFiaWxpdHkiLCJzZXRDb2x1bW5zIiwiY29sdW1ucyIsIktFWV9DT0xVTU5TIiwiZ2V0Q29sdW1ucyIsInNldExldmVscyIsImxldmVscyIsIktFWV9MRVZFTFMiLCJnZXRMZXZlbHMiLCJzZXRTZWF0cyIsInNlYXRzIiwiS0VZX1NFQVRTIiwiZ2V0U2VhdHMiLCJTZXJ2aWNlVXBkYXRlUmVhc29uIiwiUFVCTElTSEVEIiwiUkVNT1ZFRCIsIkFDVElWQVRFRCIsIkRFQUNUSVZBVEVEIiwiTUFOSUZFU1RfVVBEQVRFIiwiTmF2aWdhdGlvblNlcnZpY2VNYW5pZmVzdCIsInNldEFjY2VwdHNXYXlQb2ludHMiLCJLRVlfQUNDRVBUU19XQVlfUE9JTlRTIiwiZ2V0QWNjZXB0c1dheVBvaW50cyIsIldlYXRoZXJTZXJ2aWNlTWFuaWZlc3QiLCJzZXRDdXJyZW50Rm9yZWNhc3RTdXBwb3J0ZWQiLCJLRVlfQ1VSUkVOVF9GT1JFQ0FTVF9TVVBQT1JURUQiLCJnZXRDdXJyZW50Rm9yZWNhc3RTdXBwb3J0ZWQiLCJzZXRNYXhNdWx0aWRheUZvcmVjYXN0QW1vdW50IiwiYW1vdW50IiwiS0VZX01BWF9NVUxUSURBWV9GT1JFQ0FTVF9BTU9VTlQiLCJnZXRNYXhNdWx0aWRheUZvcmVjYXN0QW1vdW50Iiwic2V0TWF4SG91cmx5Rm9yZWNhc3RBbW91bnQiLCJLRVlfTUFYX0hPVVJMWV9GT1JFQ0FTVF9BTU9VTlQiLCJnZXRNYXhIb3VybHlGb3JlY2FzdEFtb3VudCIsInNldE1heE1pbnV0ZWx5Rm9yZWNhc3RBbW91bnQiLCJLRVlfTUFYX01JTlVURUxZX0ZPUkVDQVNUX0FNT1VOVCIsImdldE1heE1pbnV0ZWx5Rm9yZWNhc3RBbW91bnQiLCJzZXRXZWF0aGVyRm9yTG9jYXRpb25TdXBwb3J0ZWQiLCJLRVlfV0VBVEhFUl9GT1JfTE9DQVRJT05fU1VQUE9SVEVEIiwiZ2V0V2VhdGhlckZvckxvY2F0aW9uU3VwcG9ydGVkIiwiTWVkaWFTZXJ2aWNlTWFuaWZlc3QiLCJBcHBTZXJ2aWNlTWFuaWZlc3QiLCJzZXRTZXJ2aWNlTmFtZSIsIktFWV9TRVJWSUNFX05BTUUiLCJnZXRTZXJ2aWNlTmFtZSIsInNldFNlcnZpY2VUeXBlIiwiS0VZX1NFUlZJQ0VfVFlQRSIsInNldFNlcnZpY2VJY29uIiwiS0VZX1NFUlZJQ0VfSUNPTiIsImdldFNlcnZpY2VJY29uIiwic2V0QWxsb3dBcHBDb25zdW1lcnMiLCJjb25zdW1lcnMiLCJLRVlfQUxMT1dfQVBQX0NPTlNVTUVSUyIsImdldEFsbG93QXBwQ29uc3VtZXJzIiwic2V0UnBjU3BlY1ZlcnNpb24iLCJLRVlfUlBDX1NQRUNfVkVSU0lPTiIsImdldFJwY1NwZWNWZXJzaW9uIiwic2V0SGFuZGxlZFJQQ3MiLCJjcyIsIktFWV9IQU5ETEVEX1JQQ1MiLCJnZXRIYW5kbGVkUlBDcyIsInNldE1lZGlhU2VydmljZU1hbmlmZXN0IiwibWFuaWZlc3QiLCJLRVlfTUVESUFfU0VSVklDRV9NQU5JRkVTVCIsImdldE1lZGlhU2VydmljZU1hbmlmZXN0Iiwic2V0V2VhdGhlclNlcnZpY2VNYW5pZmVzdCIsIktFWV9XRUFUSEVSX1NFUlZJQ0VfTUFOSUZFU1QiLCJnZXRXZWF0aGVyU2VydmljZU1hbmlmZXN0Iiwic2V0TmF2aWdhdGlvblNlcnZpY2VNYW5pZmVzdCIsIktFWV9OQVZJR0FUSU9OX1NFUlZJQ0VfTUFOSUZFU1QiLCJnZXROYXZpZ2F0aW9uU2VydmljZU1hbmlmZXN0IiwiQXBwU2VydmljZVJlY29yZCIsInNldFNlcnZpY2VJRCIsIktFWV9TRVJWSUNFX0lEIiwiZ2V0U2VydmljZUlEIiwic2V0U2VydmljZU1hbmlmZXN0IiwiS0VZX1NFUlZJQ0VfTUFOSUZFU1QiLCJnZXRTZXJ2aWNlTWFuaWZlc3QiLCJzZXRTZXJ2aWNlUHVibGlzaGVkIiwicHVibGlzaGVkIiwiS0VZX1NFUlZJQ0VfUFVCTElTSEVEIiwiZ2V0U2VydmljZVB1Ymxpc2hlZCIsInNldFNlcnZpY2VBY3RpdmUiLCJLRVlfU0VSVklDRV9BQ1RJVkUiLCJnZXRTZXJ2aWNlQWN0aXZlIiwiQXBwU2VydmljZUNhcGFiaWxpdHkiLCJzZXRVcGRhdGVSZWFzb24iLCJLRVlfVVBEQVRFX1JFQVNPTiIsImdldFVwZGF0ZVJlYXNvbiIsInNldFVwZGF0ZWRBcHBTZXJ2aWNlUmVjb3JkIiwicmVjb3JkIiwiS0VZX1VQREFURURfQVBQX1NFUlZJQ0VfUkVDT1JEIiwiZ2V0VXBkYXRlZEFwcFNlcnZpY2VSZWNvcmQiLCJBcHBTZXJ2aWNlc0NhcGFiaWxpdGllcyIsIk5hdmlnYXRpb25DYXBhYmlsaXR5Iiwic2V0U2VuZExvY2F0aW9uRW5hYmxlZCIsIktFWV9TRU5EX0xPQ0FUSU9OX0VOQUJMRUQiLCJnZXRTZW5kTG9jYXRpb25FbmFibGVkIiwic2V0R2V0V2F5UG9pbnRzRW5hYmxlZCIsIktFWV9HRVRfV0FZX1BPSU5UU19FTkFCTEVEIiwiZ2V0R2V0V2F5UG9pbnRzRW5hYmxlZCIsIlN5c3RlbUNhcGFiaWxpdHkiLCJzZXROYXZpZ2F0aW9uQ2FwYWJpbGl0eSIsImNhcGFiaWxpdHkiLCJLRVlfTkFWSUdBVElPTl9DQVBBQklMSVRZIiwiZ2V0TmF2aWdhdGlvbkNhcGFiaWxpdHkiLCJzZXRQaG9uZUNhcGFiaWxpdHkiLCJLRVlfUEhPTkVfQ0FQQUJJTElUWSIsImdldFBob25lQ2FwYWJpbGl0eSIsInNldFZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eSIsIktFWV9WSURFT19TVFJFQU1JTkdfQ0FQQUJJTElUWSIsImdldFZpZGVvU3RyZWFtaW5nQ2FwYWJpbGl0eSIsInNldFJlbW90ZUNvbnRyb2xDYXBhYmlsaXR5IiwiS0VZX1JFTU9URV9DT05UUk9MX0NBUEFCSUxJVFkiLCJnZXRSZW1vdGVDb250cm9sQ2FwYWJpbGl0eSIsInNldEFwcFNlcnZpY2VzQ2FwYWJpbGl0aWVzIiwiS0VZX0FQUF9TRVJWSUNFU19DQVBBQklMSVRJRVMiLCJnZXRBcHBTZXJ2aWNlc0NhcGFiaWxpdGllcyIsInNldFNlYXRMb2NhdGlvbkNhcGFiaWxpdHkiLCJLRVlfU0VBVF9MT0NBVElPTl9DQVBBQklMSVRZIiwiZ2V0U2VhdExvY2F0aW9uQ2FwYWJpbGl0eSIsIkdldFN5c3RlbUNhcGFiaWxpdHlSZXNwb25zZSIsInNldFN5c3RlbUNhcGFiaWxpdHkiLCJLRVlfU1lTVEVNX0NBUEFCSUxJVFkiLCJnZXRTeXN0ZW1DYXBhYmlsaXR5IiwiUmVjdGFuZ2xlIiwic2V0WCIsIktFWV9YIiwiZ2V0WCIsInNldFkiLCJLRVlfWSIsImdldFkiLCJzZXRIZWlnaHQiLCJLRVlfSEVJR0hUIiwiZ2V0SGVpZ2h0IiwiSGFwdGljUmVjdCIsInNldFJlY3QiLCJyZWN0IiwiS0VZX1JFQ1QiLCJnZXRSZWN0Iiwic2V0SGFwdGljUmVjdERhdGEiLCJLRVlfSEFQVElDX1JFQ1RfREFUQSIsImdldEhhcHRpY1JlY3REYXRhIiwiU2VuZEhhcHRpY0RhdGFSZXNwb25zZSIsIkh5YnJpZEFwcFByZWZlcmVuY2UiLCJNT0JJTEUiLCJDTE9VRCIsIkNsb3VkQXBwUHJvcGVydGllcyIsInNldE5pY2tuYW1lcyIsIm5pY2tuYW1lcyIsIktFWV9OSUNLTkFNRVMiLCJnZXROaWNrbmFtZXMiLCJzZXRBcHBJRCIsImdldEFwcElEIiwic2V0RW5hYmxlZCIsIktFWV9FTkFCTEVEIiwiZ2V0RW5hYmxlZCIsInNldEF1dGhUb2tlbiIsInRva2VuIiwiS0VZX0FVVEhfVE9LRU4iLCJnZXRBdXRoVG9rZW4iLCJzZXRDbG91ZFRyYW5zcG9ydFR5cGUiLCJLRVlfQ0xPVURfVFJBTlNQT1JUX1RZUEUiLCJnZXRDbG91ZFRyYW5zcG9ydFR5cGUiLCJzZXRIeWJyaWRBcHBQcmVmZXJlbmNlIiwicHJlZmVyZW5jZSIsIktFWV9IWUJSSURfQVBQX1BSRUZFUkVOQ0UiLCJnZXRIeWJyaWRBcHBQcmVmZXJlbmNlIiwic2V0RW5kcG9pbnQiLCJlbmRwb2ludCIsIktFWV9FTkRQT0lOVCIsImdldEVuZHBvaW50IiwiU2V0Q2xvdWRBcHBQcm9wZXJ0aWVzUmVzcG9uc2UiLCJHZXRDbG91ZEFwcFByb3BlcnRpZXNSZXNwb25zZSIsInNldEFwcFNlcnZpY2VNYW5pZmVzdCIsIktFWV9BUFBfU0VSVklDRV9NQU5JRkVTVCIsImdldEFwcFNlcnZpY2VNYW5pZmVzdCIsIlB1Ymxpc2hBcHBTZXJ2aWNlUmVzcG9uc2UiLCJzZXRBcHBTZXJ2aWNlUmVjb3JkIiwiS0VZX0FQUF9TRVJWSUNFX1JFQ09SRCIsImdldEFwcFNlcnZpY2VSZWNvcmQiLCJVbnB1Ymxpc2hBcHBTZXJ2aWNlUmVzcG9uc2UiLCJOYXZpZ2F0aW9uSnVuY3Rpb24iLCJSRUdVTEFSIiwiQklGVVJDQVRJT04iLCJNVUxUSV9DQVJSSUFHRVdBWSIsIlJPVU5EQUJPVVQiLCJUUkFWRVJTQUJMRV9ST1VOREFCT1VUIiwiSlVHSEFORExFIiwiQUxMX1dBWV9ZSUVMRCIsIlRVUk5fQVJPVU5EIiwiRGlyZWN0aW9uIiwiTmF2aWdhdGlvbkFjdGlvbiIsIlRVUk4iLCJFWElUIiwiU1RBWSIsIk1FUkdFIiwiRkVSUlkiLCJDQVJfU0hVVFRMRV9UUkFJTiIsIldBWVBPSU5UIiwiTmF2aWdhdGlvbkluc3RydWN0aW9uIiwic2V0TG9jYXRpb25EZXRhaWxzIiwiZGV0YWlscyIsIktFWV9MT0NBVElPTl9ERVRBSUxTIiwiZ2V0TG9jYXRpb25EZXRhaWxzIiwic2V0QmVhcmluZyIsImJlYXJpbmciLCJLRVlfQkVBUklORyIsImdldEJlYXJpbmciLCJzZXRKdW5jdGlvblR5cGUiLCJLRVlfSlVOQ1RJT05fVFlQRSIsImdldEp1bmN0aW9uVHlwZSIsInNldERyaXZpbmdTaWRlIiwic2lkZSIsIktFWV9EUklWSU5HX1NJREUiLCJnZXREcml2aW5nU2lkZSIsInNldERldGFpbHMiLCJLRVlfREVUQUlMUyIsImdldERldGFpbHMiLCJOYXZpZ2F0aW9uU2VydmljZURhdGEiLCJzZXRPcmlnaW4iLCJLRVlfT1JJR0lOIiwiZ2V0T3JpZ2luIiwic2V0RGVzdGluYXRpb24iLCJLRVlfREVTVElOQVRJT04iLCJnZXREZXN0aW5hdGlvbiIsInNldERlc3RpbmF0aW9uRVRBIiwiS0VZX0RFU1RJTkFUSU9OX0VUQSIsImdldERlc3RpbmF0aW9uRVRBIiwic2V0SW5zdHJ1Y3Rpb25zIiwiaW5zdHJ1Y3Rpb25zIiwiS0VZX0lOU1RSVUNUSU9OUyIsImdldEluc3RydWN0aW9ucyIsInNldE5leHRJbnN0cnVjdGlvbkVUQSIsIktFWV9ORVhUX0lOU1RSVUNUSU9OX0VUQSIsImdldE5leHRJbnN0cnVjdGlvbkVUQSIsInNldE5leHRJbnN0cnVjdGlvbkRpc3RhbmNlIiwiS0VZX05FWFRfSU5TVFJVQ1RJT05fRElTVEFOQ0UiLCJnZXROZXh0SW5zdHJ1Y3Rpb25EaXN0YW5jZSIsInNldE5leHRJbnN0cnVjdGlvbkRpc3RhbmNlU2NhbGUiLCJLRVlfTkVYVF9JTlNUUlVDVElPTl9ESVNUQU5DRV9TQ0FMRSIsImdldE5leHRJbnN0cnVjdGlvbkRpc3RhbmNlU2NhbGUiLCJzZXRQcm9tcHQiLCJLRVlfUFJPTVBUIiwiZ2V0UHJvbXB0IiwiTWVkaWFUeXBlIiwiTVVTSUMiLCJQT0RDQVNUIiwiQVVESU9CT09LIiwiT1RIRVIiLCJNZWRpYVNlcnZpY2VEYXRhIiwic2V0TWVkaWFUeXBlIiwiS0VZX01FRElBX1RZUEUiLCJnZXRNZWRpYVR5cGUiLCJzZXRNZWRpYVRpdGxlIiwiS0VZX01FRElBX1RJVExFIiwiZ2V0TWVkaWFUaXRsZSIsInNldE1lZGlhQXJ0aXN0IiwiYXJ0aXN0IiwiS0VZX01FRElBX0FSVElTVCIsImdldE1lZGlhQXJ0aXN0Iiwic2V0TWVkaWFBbGJ1bSIsImFsYnVtIiwiS0VZX01FRElBX0FMQlVNIiwiZ2V0TWVkaWFBbGJ1bSIsInNldFBsYXlsaXN0TmFtZSIsIktFWV9QTEFZTElTVF9OQU1FIiwiZ2V0UGxheWxpc3ROYW1lIiwic2V0SXNFeHBsaWNpdCIsImV4cGxpY2l0IiwiS0VZX0lTX0VYUExJQ0lUIiwiZ2V0SXNFeHBsaWNpdCIsInNldFRyYWNrUGxheWJhY2tQcm9ncmVzcyIsInByb2dyZXNzIiwiS0VZX1RSQUNLX1BMQVlCQUNLX1BST0dSRVNTIiwiZ2V0VHJhY2tQbGF5YmFja1Byb2dyZXNzIiwic2V0VHJhY2tQbGF5YmFja0R1cmF0aW9uIiwiS0VZX1RSQUNLX1BMQVlCQUNLX0RVUkFUSU9OIiwiZ2V0VHJhY2tQbGF5YmFja0R1cmF0aW9uIiwic2V0UXVldWVQbGF5YmFja1Byb2dyZXNzIiwiS0VZX1FVRVVFX1BMQVlCQUNLX1BST0dSRVNTIiwiZ2V0UXVldWVQbGF5YmFja1Byb2dyZXNzIiwic2V0UXVldWVQbGF5YmFja0R1cmF0aW9uIiwiS0VZX1FVRVVFX1BMQVlCQUNLX0RVUkFUSU9OIiwiZ2V0UXVldWVQbGF5YmFja0R1cmF0aW9uIiwic2V0UXVldWVDdXJyZW50VHJhY2tOdW1iZXIiLCJLRVlfUVVFVUVfQ1VSUkVOVF9UUkFDS19OVU1CRVIiLCJnZXRRdWV1ZUN1cnJlbnRUcmFja051bWJlciIsInNldFF1ZXVlVG90YWxUcmFja0NvdW50IiwiS0VZX1FVRVVFX1RPVEFMX1RSQUNLX0NPVU5UIiwiZ2V0UXVldWVUb3RhbFRyYWNrQ291bnQiLCJzZXRNZWRpYUltYWdlIiwiS0VZX01FRElBX0lNQUdFIiwiZ2V0TWVkaWFJbWFnZSIsIldlYXRoZXJEYXRhIiwic2V0VGVtcGVyYXR1cmVIaWdoIiwiS0VZX1RFTVBFUkFUVVJFX0hJR0giLCJnZXRUZW1wZXJhdHVyZUhpZ2giLCJzZXRUZW1wZXJhdHVyZUxvdyIsIktFWV9URU1QRVJBVFVSRV9MT1ciLCJnZXRUZW1wZXJhdHVyZUxvdyIsInNldEFwcGFyZW50VGVtcGVyYXR1cmUiLCJLRVlfQVBQQVJFTlRfVEVNUEVSQVRVUkUiLCJnZXRBcHBhcmVudFRlbXBlcmF0dXJlIiwic2V0QXBwYXJlbnRUZW1wZXJhdHVyZUhpZ2giLCJLRVlfQVBQQVJFTlRfVEVNUEVSQVRVUkVfSElHSCIsImdldEFwcGFyZW50VGVtcGVyYXR1cmVIaWdoIiwic2V0QXBwYXJlbnRUZW1wZXJhdHVyZUxvdyIsIktFWV9BUFBBUkVOVF9URU1QRVJBVFVSRV9MT1ciLCJnZXRBcHBhcmVudFRlbXBlcmF0dXJlTG93Iiwic2V0V2VhdGhlclN1bW1hcnkiLCJzdW1tYXJ5IiwiS0VZX1dFQVRIRVJfU1VNTUFSWSIsImdldFdlYXRoZXJTdW1tYXJ5IiwiS0VZX1RJTUUiLCJzZXRIdW1pZGl0eSIsIktFWV9IVU1JRElUWSIsImdldEh1bWlkaXR5Iiwic2V0Q2xvdWRDb3ZlciIsImNvdmVyIiwiS0VZX0NMT1VEX0NPVkVSIiwiZ2V0Q2xvdWRDb3ZlciIsInNldE1vb25QaGFzZSIsInBoYXNlIiwiS0VZX01PT05fUEhBU0UiLCJnZXRNb29uUGhhc2UiLCJzZXRXaW5kQmVhcmluZyIsIktFWV9XSU5EX0JFQVJJTkciLCJnZXRXaW5kQmVhcmluZyIsInNldFdpbmRHdXN0IiwiZ3VzdCIsIktFWV9XSU5EX0dVU1QiLCJnZXRXaW5kR3VzdCIsInNldFdpbmRTcGVlZCIsIktFWV9XSU5EX1NQRUVEIiwiZ2V0V2luZFNwZWVkIiwic2V0TmVhcmVzdFN0b3JtQmVhcmluZyIsIktFWV9ORUFSRVNUX1NUT1JNX0JFQVJJTkciLCJnZXROZWFyZXN0U3Rvcm1CZWFyaW5nIiwic2V0TmVhcmVzdFN0b3JtRGlzdGFuY2UiLCJLRVlfTkVBUkVTVF9TVE9STV9ESVNUQU5DRSIsImdldE5lYXJlc3RTdG9ybURpc3RhbmNlIiwic2V0UHJlY2lwQWNjdW11bGF0aW9uIiwiYWNjdW11bGF0aW9uIiwiS0VZX1BSRUNJUF9BQ0NVTVVMQVRJT04iLCJnZXRQcmVjaXBBY2N1bXVsYXRpb24iLCJzZXRQcmVjaXBJbnRlbnNpdHkiLCJpbnRlbnNpdHkiLCJLRVlfUFJFQ0lQX0lOVEVOU0lUWSIsImdldFByZWNpcEludGVuc2l0eSIsInNldFByZWNpcFByb2JhYmlsaXR5IiwicHJvYmFiaWxpdHkiLCJLRVlfUFJFQ0lQX1BST0JBQklMSVRZIiwiZ2V0UHJlY2lwUHJvYmFiaWxpdHkiLCJzZXRQcmVjaXBUeXBlIiwiS0VZX1BSRUNJUF9UWVBFIiwiZ2V0UHJlY2lwVHlwZSIsInNldFZpc2liaWxpdHkiLCJ2aXNpYmlsaXR5IiwiS0VZX1ZJU0lCSUxJVFkiLCJnZXRWaXNpYmlsaXR5Iiwic2V0V2VhdGhlckljb24iLCJLRVlfV0VBVEhFUl9JQ09OIiwiZ2V0V2VhdGhlckljb24iLCJXZWF0aGVyQWxlcnQiLCJzZXRUaXRsZSIsIktFWV9USVRMRSIsImdldFRpdGxlIiwic2V0U3VtbWFyeSIsIktFWV9TVU1NQVJZIiwiZ2V0U3VtbWFyeSIsInNldEV4cGlyZXMiLCJleHBpcmVzIiwiS0VZX0VYUElSRVMiLCJnZXRFeHBpcmVzIiwic2V0UmVnaW9ucyIsInJlZ2lvbnMiLCJLRVlfUkVHSU9OUyIsImdldFJlZ2lvbnMiLCJzZXRTZXZlcml0eSIsInNldmVyaXR5IiwiS0VZX1NFVkVSSVRZIiwiZ2V0U2V2ZXJpdHkiLCJzZXRUaW1lSXNzdWVkIiwiaXNzdWVkIiwiS0VZX1RJTUVfSVNTVUVEIiwiZ2V0VGltZUlzc3VlZCIsIldlYXRoZXJTZXJ2aWNlRGF0YSIsInNldEN1cnJlbnRGb3JlY2FzdCIsImZvcmVjYXN0IiwiS0VZX0NVUlJFTlRfRk9SRUNBU1QiLCJnZXRDdXJyZW50Rm9yZWNhc3QiLCJzZXRNaW51dGVGb3JlY2FzdCIsIktFWV9NSU5VVEVfRk9SRUNBU1QiLCJnZXRNaW51dGVGb3JlY2FzdCIsInNldEhvdXJseUZvcmVjYXN0IiwiS0VZX0hPVVJMWV9GT1JFQ0FTVCIsImdldEhvdXJseUZvcmVjYXN0Iiwic2V0TXVsdGlkYXlGb3JlY2FzdCIsIktFWV9NVUxUSURBWV9GT1JFQ0FTVCIsImdldE11bHRpZGF5Rm9yZWNhc3QiLCJzZXRBbGVydHMiLCJhbGVydHMiLCJLRVlfQUxFUlRTIiwiZ2V0QWxlcnRzIiwiQXBwU2VydmljZURhdGEiLCJzZXRNZWRpYVNlcnZpY2VEYXRhIiwiS0VZX01FRElBX1NFUlZJQ0VfREFUQSIsImdldE1lZGlhU2VydmljZURhdGEiLCJzZXRXZWF0aGVyU2VydmljZURhdGEiLCJLRVlfV0VBVEhFUl9TRVJWSUNFX0RBVEEiLCJnZXRXZWF0aGVyU2VydmljZURhdGEiLCJzZXROYXZpZ2F0aW9uU2VydmljZURhdGEiLCJLRVlfTkFWSUdBVElPTl9TRVJWSUNFX0RBVEEiLCJnZXROYXZpZ2F0aW9uU2VydmljZURhdGEiLCJHZXRBcHBTZXJ2aWNlRGF0YVJlc3BvbnNlIiwic2V0U2VydmljZURhdGEiLCJLRVlfU0VSVklDRV9EQVRBIiwiZ2V0U2VydmljZURhdGEiLCJzZXRTZXJ2aWNlVXJpIiwidXJpIiwiS0VZX1NFUlZJQ0VfVVJJIiwiZ2V0U2VydmljZVVyaSIsInNldE9yaWdpbkFwcCIsImFwcCIsIktFWV9PUklHSU5fQVBQIiwiZ2V0T3JpZ2luQXBwIiwic2V0UmVxdWVzdFNlcnZpY2VBY3RpdmUiLCJLRVlfUkVRVUVTVF9TRVJWSUNFX0FDVElWRSIsImdldFJlcXVlc3RTZXJ2aWNlQWN0aXZlIiwiUGVyZm9ybUFwcFNlcnZpY2VJbnRlcmFjdGlvblJlc3BvbnNlIiwic2V0U2VydmljZVNwZWNpZmljUmVzdWx0IiwiS0VZX1NFUlZJQ0VfU1BFQ0lGSUNfUkVTVUxUIiwiZ2V0U2VydmljZVNwZWNpZmljUmVzdWx0Iiwic2V0RnVuY3Rpb25JRCIsIktFWV9GVU5DVElPTl9JRCIsImdldEZ1bmN0aW9uSUQiLCJDYW5jZWxJbnRlcmFjdGlvblJlc3BvbnNlIiwiQ2xvc2VBcHBsaWNhdGlvblJlc3BvbnNlIiwiU3lzdGVtQ29udGV4dCIsIlNZU0NUWFRfTUFJTiIsIlNZU0NUWFRfVlJTRVNTSU9OIiwiU1lTQ1RYVF9NRU5VIiwiU1lTQ1RYVF9ITUlfT0JTQ1VSRUQiLCJTWVNDVFhUX0FMRVJUIiwiUnBjTm90aWZpY2F0aW9uIiwiQXVkaW9TdHJlYW1pbmdTdGF0ZSIsIkFVRElCTEUiLCJBVFRFTlVBVEVEIiwiTk9UX0FVRElCTEUiLCJITUlMZXZlbCIsIkhNSV9GVUxMIiwiSE1JX0xJTUlURUQiLCJITUlfQkFDS0dST1VORCIsIkhNSV9OT05FIiwiVmlkZW9TdHJlYW1pbmdTdGF0ZSIsIlNUUkVBTUFCTEUiLCJOT1RfU1RSRUFNQUJMRSIsInNldEhtaUxldmVsIiwiS0VZX0hNSV9MRVZFTCIsImdldEhtaUxldmVsIiwic2V0QXVkaW9TdHJlYW1pbmdTdGF0ZSIsIktFWV9BVURJT19TVFJFQU1JTkdfU1RBVEUiLCJnZXRBdWRpb1N0cmVhbWluZ1N0YXRlIiwic2V0U3lzdGVtQ29udGV4dCIsIktFWV9TWVNURU1fQ09OVEVYVCIsImdldFN5c3RlbUNvbnRleHQiLCJzZXRWaWRlb1N0cmVhbWluZ1N0YXRlIiwiS0VZX1ZJREVPX1NUUkVBTUlOR19TVEFURSIsImdldFZpZGVvU3RyZWFtaW5nU3RhdGUiLCJBcHBJbnRlcmZhY2VVbnJlZ2lzdGVyZWRSZWFzb24iLCJJR05JVElPTl9PRkYiLCJCTFVFVE9PVEhfT0ZGIiwiVVNCX0RJU0NPTk5FQ1RFRCIsIlJFUVVFU1RfV0hJTEVfSU5fTk9ORV9ITUlfTEVWRUwiLCJUT09fTUFOWV9SRVFVRVNUUyIsIkRSSVZFUl9ESVNUUkFDVElPTl9WSU9MQVRJT04iLCJMQU5HVUFHRV9DSEFOR0UiLCJNQVNURVJfUkVTRVQiLCJGQUNUT1JZX0RFRkFVTFRTIiwiQVBQX1VOQVVUSE9SSVpFRCIsIlBST1RPQ09MX1ZJT0xBVElPTiIsIlVOU1VQUE9SVEVEX0hNSV9SRVNPVVJDRSIsInNldFJlYXNvbiIsIktFWV9SRUFTT04iLCJnZXRSZWFzb24iLCJCdXR0b25FdmVudE1vZGUiLCJCVVRUT05VUCIsIkJVVFRPTkRPV04iLCJzZXRCdXR0b25FdmVudE1vZGUiLCJLRVlfQlVUVE9OX0VWRU5UX01PREUiLCJnZXRCdXR0b25FdmVudE1vZGUiLCJzZXRDdXN0b21CdXR0b25JRCIsIktFWV9DVVNUT01fQlVUVE9OX0lEIiwiZ2V0Q3VzdG9tQnV0dG9uSUQiLCJUQlRTdGF0ZSIsIlJPVVRFX1VQREFURV9SRVFVRVNUIiwiUk9VVEVfQUNDRVBURUQiLCJST1VURV9SRUZVU0VEIiwiUk9VVEVfQ0FOQ0VMTEVEIiwiRVRBX1JFUVVFU1QiLCJORVhUX1RVUk5fUkVRVUVTVCIsIlJPVVRFX1NUQVRVU19SRVFVRVNUIiwiUk9VVEVfU1VNTUFSWV9SRVFVRVNUIiwiVFJJUF9TVEFUVVNfUkVRVUVTVCIsIlJPVVRFX1VQREFURV9SRVFVRVNUX1RJTUVPVVQiLCJEcml2ZXJEaXN0cmFjdGlvblN0YXRlIiwiRERfT04iLCJERF9PRkYiLCJzZXRMb2NrU2NyZWVuRGlzbWlzc2FsRW5hYmxlZCIsIktFWV9MT0NLX1NDUkVFTl9ESVNNSVNTQUxfRU5BQkxFRCIsImdldExvY2tTY3JlZW5EaXNtaXNzYWxFbmFibGVkIiwic2V0TG9ja1NjcmVlbkRpc21pc3NhbFdhcm5pbmciLCJ3YXJuaW5nIiwiS0VZX0xPQ0tfU0NSRUVOX0RJU01JU1NBTF9XQVJOSU5HIiwiZ2V0TG9ja1NjcmVlbkRpc21pc3NhbFdhcm5pbmciLCJITUlQZXJtaXNzaW9ucyIsInNldFVzZXJEaXNhbGxvd2VkIiwiZGlzYWxsb3dlZCIsIktFWV9VU0VSX0RJU0FMTE9XRUQiLCJnZXRVc2VyRGlzYWxsb3dlZCIsIlBhcmFtZXRlclBlcm1pc3Npb25zIiwiUGVybWlzc2lvbkl0ZW0iLCJzZXRScGNOYW1lIiwiS0VZX1JQQ19OQU1FIiwiZ2V0UnBjTmFtZSIsInNldEhtaVBlcm1pc3Npb25zIiwicGVybWlzc2lvbnMiLCJLRVlfSE1JX1BFUk1JU1NJT05TIiwiZ2V0SG1pUGVybWlzc2lvbnMiLCJzZXRQYXJhbWV0ZXJQZXJtaXNzaW9ucyIsIktFWV9QQVJBTUVURVJfUEVSTUlTU0lPTlMiLCJnZXRQYXJhbWV0ZXJQZXJtaXNzaW9ucyIsInNldFJlcXVpcmVFbmNyeXB0aW9uIiwiS0VZX1JFUVVJUkVfRU5DUllQVElPTiIsImdldFJlcXVpcmVFbmNyeXB0aW9uIiwic2V0UGVybWlzc2lvbkl0ZW0iLCJLRVlfUEVSTUlTU0lPTl9JVEVNIiwiZ2V0UGVybWlzc2lvbkl0ZW0iLCJLZXlib2FyZEV2ZW50IiwiS0VZUFJFU1MiLCJFTlRSWV9TVUJNSVRURUQiLCJFTlRSWV9WT0lDRSIsIkVOVFJZX0NBTkNFTExFRCIsIkVOVFJZX0FCT1JURUQiLCJzZXRFdmVudCIsIktFWV9FVkVOVCIsImdldEV2ZW50IiwiVG91Y2hDb29yZCIsIlRvdWNoRXZlbnQiLCJzZXRUcyIsInRzIiwiS0VZX1RTIiwiZ2V0VHMiLCJzZXRDIiwiS0VZX0MiLCJnZXRDIiwiVG91Y2hUeXBlIiwiQkVHSU4iLCJNT1ZFIiwiRU5EIiwiQ0FOQ0VMIiwic2V0VXJsIiwidXJsIiwiS0VZX1VSTCIsImdldFVybCIsInNldEFsbG9jYXRlZE1vZHVsZXMiLCJLRVlfQUxMT0NBVEVEX01PRFVMRVMiLCJnZXRBbGxvY2F0ZWRNb2R1bGVzIiwic2V0RnJlZU1vZHVsZXMiLCJLRVlfRlJFRV9NT0RVTEVTIiwiZ2V0RnJlZU1vZHVsZXMiLCJFbmNvZGVkU3luY1BEYXRhUmVzcG9uc2UiLCJzZXRVUkwiLCJnZXRVUkwiLCJScGNDcmVhdG9yIiwiY29uc3RydWN0IiwicnBjTmFtZSIsImpzb25EYXRhIiwiU2RsUHJvdG9jb2xCYXNlIiwiYmFzZVRyYW5zcG9ydENvbmZpZyIsInNkbFByb3RvY29sTGlzdGVuZXIiLCJfYmFzZVRyYW5zcG9ydENvbmZpZyIsIl9zZGxQcm90b2NvbExpc3RlbmVyIiwiX3RyYW5zcG9ydE1hbmFnZXIiLCJyZXNldCIsIl9jcmVhdGVUcmFuc3BvcnRMaXN0ZW5lciIsIl9wcm90b2NvbFZlcnNpb24iLCJfaGVhZGVyU2l6ZSIsIlYxX0hFQURFUl9TSVpFIiwiX3NlcnZpY2VTdGF0dXMiLCJfbXR1cyIsIlYxX1YyX01UVV9TSVpFIiwiX2hhc2hJRCIsIl9tZXNzYWdlRnJhbWVBc3NlbWJsZXJzIiwic2V0VHJhbnNwb3J0TWFuYWdlciIsIm1hbmFnZXIiLCJzdGFydFNlcnZpY2UiLCJfdHJhbnNwb3J0TGlzdGVuZXIiLCJfaGFuZGxlVHJhbnNwb3J0Q29ubmVjdGVkIiwiX2hhbmRsZVBhY2tldFJlY2VpdmVkIiwicHJvdG9jb2xWZXJzaW9uIiwiTUFYX1BST1RPQ09MX1ZFUlNJT04iLCJzZW5kUGFja2V0IiwidmlkZW9TdHJlYW1pbmdQYXJhbWV0ZXJzIiwiZGVzaXJlZFJlc29sdXRpb24iLCJkZXNpcmVkRm9ybWF0IiwiZ2V0Rm9ybWF0IiwiZ2V0TXR1IiwicmV0VmFsIiwiaXNDb25uZWN0ZWQiLCJnZXRQcm90b2NvbFZlcnNpb24iLCJfc2V0VmVyc2lvbiIsIlYyX0hFQURFUl9TSVpFIiwiVjNfVjRfTVRVX1NJWkUiLCJfZ2V0TmV4dE1lc3NhZ2VJRCIsInNlbmRScGMiLCJfaGFuZGxlQ29udHJvbFBhY2tldCIsIm1lc3NhZ2VGcmFtZUFzc2VtYmxlciIsIl9nZXRNZXNzYWdlRnJhbWVBc3NlbWJsZXIiLCJfaGFuZGxlT25NZXNzYWdlQXNzZW1ibGVkIiwiX2hhbmRsZVJQQ1BhY2tldCIsIl9oYW5kbGVQcm90b2NvbEhlYXJ0YmVhdCIsIl9oYW5kbGVQcm90b2NvbEhlYXJ0YmVhdEFDSyIsIl9oYW5kbGVTdGFydFNlcnZpY2VBQ0siLCJfaGFuZGxlU3RhcnRTZXJ2aWNlTkFLIiwiX2hhbmRsZUVuZFNlcnZpY2VBQ0siLCJfaGFuZGxlRW5kU2VydmljZSIsIl9oYW5kbGVFbmRTZXJ2aWNlTkFLIiwiaGVhcnRiZWF0IiwibXR1VGFnIiwiTkFWIiwiYWNjZXB0ZWRSZXNvbHV0aW9uIiwiYWNjZXB0ZWRGb3JtYXQiLCJhZ3JlZWRWaWRlb1BhcmFtcyIsInNldEZvcm1hdCIsIl9oYW5kbGVTZXJ2aWNlRW5kZWQiLCJyZWplY3RlZFRhZyIsInJlamVjdGVkUGFyYW1zIiwiZW5kU2VydmljZSIsIlRyYW5zcG9ydFR5cGUiLCJXRUJTT0NLRVRfQ0xJRU5UIiwiV0VCU09DS0VUX1NFUlZFUiIsIkNVU1RPTSIsIlNkbFBzbSIsIl9zdGF0ZSIsIlNUQVJUX1NUQVRFIiwiX2NvbnRyb2xGcmFtZUluZm8iLCJfZHVtcFNpemUiLCJfZGF0YUxlbmd0aCIsImdldEZvcm1lZFBhY2tldCIsIkZJTklTSEVEX1NUQVRFIiwiaGFuZGxlQnl0ZSIsIl90cmFuc2l0aW9uT25JbnB1dCIsIkVSUk9SX1NUQVRFIiwicmF3Qnl0ZSIsIlZFUlNJT05fTUFTSyIsIkZSQU1FX1RZUEVfTUFTSyIsIlNFUlZJQ0VfVFlQRV9TVEFURSIsIkNPTlRST0xfRlJBTUVfSU5GT19TVEFURSIsIlNFU1NJT05fSURfU1RBVEUiLCJEQVRBX1NJWkVfMV9TVEFURSIsIkRBVEFfU0laRV8yX1NUQVRFIiwiREFUQV9TSVpFXzNfU1RBVEUiLCJEQVRBX1NJWkVfNF9TVEFURSIsIkRBVEFfUFVNUF9TVEFURSIsIkZJUlNUX0ZSQU1FX0RBVEFfU0laRSIsIk1FU1NBR0VfMV9TVEFURSIsIk1FU1NBR0VfMl9TVEFURSIsIk1FU1NBR0VfM19TVEFURSIsIk1FU1NBR0VfNF9TVEFURSIsIlRyYW5zcG9ydEJhc2UiLCJ0cmFuc3BvcnRDYWxsYmFjayIsIl9zZGxQc20iLCJfdHJhbnNwb3J0Q2FsbGJhY2siLCJzdG9wIiwic2V0VHJhbnNwb3J0Q2FsbGJhY2siLCJXZWJTb2NrZXRDbGllbnQiLCJjb25maWciLCJfcXVldWUiLCJfaXNSdW5uaW5nIiwiX3dzVXJsIiwiZ2V0SG9zdCIsImdldFBvcnQiLCJfd3MiLCJfaW5pdCIsIldlYlNvY2tldCIsIm9ub3BlbiIsIm9uQ29ubmVjdGlvbkVzdGFibGlzaGVkIiwib25lcnJvciIsIm9ubWVzc2FnZSIsIl9oYW5kbGVJbmNvbWluZyIsIm9uY2xvc2UiLCJvbkNvbm5lY3Rpb25UZXJtaW5hdGVkIiwiY2xvc2UiLCJwYWNrZXQiLCJzZW5kIiwiX211bHRpQnl0ZUhhbmRsZXIiLCJtc2dEYXRhIiwiUmVzcG9uc2UiLCJhcnJheUJ1ZmZlciIsInRoZW4iLCJfaGFuZGxlQnl0ZSIsImlzRmluaXNoZWQiLCJUcmFuc3BvcnRDYWxsYmFjayIsIl9vbkNvbm5lY3Rpb25Fc3RhYmxpc2hlZCIsIl9vbkNvbm5lY3Rpb25UZXJtaW5hdGVkIiwic2V0T25Db25uZWN0aW9uRXN0YWJsaXNoZWQiLCJzZXRPbkNvbm5lY3Rpb25UZXJtaW5hdGVkIiwiVHJhbnNwb3J0TWFuYWdlckJhc2UiLCJ0cmFuc3BvcnRMaXN0ZW5lciIsIl90cmFuc3BvcnQiLCJfaXNDb25uZWN0ZWQiLCJnZXRUcmFuc3BvcnRUeXBlIiwiZ2V0VHJhbnNwb3J0IiwidHJhbnNwb3J0VHlwZSIsIlNzbENvbmZpZyIsInBlbUNlcnRpZmljYXRlIiwicHJpdmF0ZUtleSIsInBhc3N3b3JkIiwiX3BlbUNlcnRpZmljYXRlIiwiX3ByaXZhdGVLZXkiLCJfcGFzc3dvcmQiLCJnZXRQZW1DZXJ0aWZpY2F0ZSIsImdldFByaXZhdGVLZXkiLCJnZXRQYXNzd29yZCIsInJlcXVpcmUkJDEiLCJyZXF1aXJlJCQyIiwiV2ViU29ja2V0U2VydmVyIiwiZ2V0U3NsQ29uZmlnIiwic2VydmVyIiwiaHR0cHMiLCJjcmVhdGVTZXJ2ZXIiLCJjZXJ0IiwicGFzc3BocmFzZSIsIlNlcnZlciIsImxpc3RlbiIsInBvcnQiLCJjb25uZWN0aW9uIiwiX2hhbmRsZU1lc3NhZ2UiLCJlcnJvckV2ZW50IiwiaXNBbGl2ZSIsImdldENvbm5lY3Rpb25Mb3N0VGltZW91dCIsInNldEludGVydmFsIiwiY2xpZW50cyIsImVhY2giLCJjbGllbnQiLCJ0ZXJtaW5hdGUiLCJwaW5nIiwicmVhZHlTdGF0ZSIsInN0YXRlUHJvZ3Jlc3MiLCJtZXNzYWdlSW5kZXgiLCJUcmFuc3BvcnRNYW5hZ2VyIiwiU2RsUHJvdG9jb2wiLCJTZXJ2aWNlTGlzdGVuZXJNYXAiLCJfbGlzdGVuZXJzIiwiYWRkTGlzdGVuZXIiLCJzZXJ2aWNlTGlzdGVuZXIiLCJyZW1vdmVMaXN0ZW5lciIsImxpc3RlbmVyQXJyYXkiLCJyZW1vdmVkIiwic2VuZEV2ZW50U2VydmljZVN0YXJ0ZWQiLCJzZXNzaW9uIiwic2VuZEV2ZW50U2VydmljZUVuZGVkIiwic2VuZEV2ZW50U2VydmljZUVycm9yIiwib25TZXJ2aWNlRXJyb3IiLCJERUZBVUxUX1BST1RPQ09MIiwiREVGQVVMVF9DT0RFQyIsIkRFRkFVTFRfV0lEVEgiLCJERUZBVUxUX0hFSUdIVCIsIkRFRkFVTFRfREVOU0lUWSIsIkRFRkFVTFRfRlJBTUVSQVRFIiwiREVGQVVMVF9CSVRSQVRFIiwiREVGQVVMVF9JTlRFUlZBTCIsIkRFRkFVTFRfU0NBTEUiLCJWaWRlb1N0cmVhbWluZ1BhcmFtZXRlcnMiLCJkaXNwbGF5RGVuc2l0eSIsImZyYW1lUmF0ZSIsImludGVydmFsIiwiX2Rpc3BsYXlEZW5zaXR5IiwiX2ZyYW1lUmF0ZSIsIl9iaXRyYXRlIiwiX2ludGVydmFsIiwiX3Jlc29sdXRpb24iLCJfZm9ybWF0IiwidXBkYXRlIiwic2V0RGlzcGxheURlbnNpdHkiLCJnZXREaXNwbGF5RGVuc2l0eSIsInNldEZyYW1lUmF0ZSIsImdldEZyYW1lUmF0ZSIsInNldEJpdHJhdGUiLCJnZXRCaXRyYXRlIiwiZ2V0SW50ZXJ2YWwiLCJTZGxTZXNzaW9uIiwic2RsU2Vzc2lvbkxpc3RlbmVyIiwiX3Nlc3Npb25IYXNoSWQiLCJfc2RsU2Vzc2lvbkxpc3RlbmVyIiwiX3NlcnZpY2VMaXN0ZW5lcnMiLCJfc2V0dXBTZGxQcm90b2NvbExpc3RlbmVyIiwiX3NkbFByb3RvY29sIiwiZ2V0Q3VycmVudFRyYW5zcG9ydFR5cGUiLCJnZXRJc0Nvbm5lY3RlZCIsImdldFNlc3Npb25IYXNoSWQiLCJhZGRTZXJ2aWNlTGlzdGVuZXIiLCJzZGxTZXJ2aWNlTGlzdGVuZXIiLCJyZW1vdmVTZXJ2aWNlTGlzdGVuZXIiLCJnZXRTZXJ2aWNlTGlzdGVuZXJzIiwic2V0RGVzaXJlZFZpZGVvUGFyYW1zIiwiX2Rlc2lyZWRWaWRlb1BhcmFtcyIsIlNkbFNlc3Npb25MaXN0ZW5lciIsImNvcnJlbGF0aW9uSSIsIkFycmF5VG9vbHMiLCJhcnJheVJlbW92ZSIsImVsZSIsIkxpZmVjeWNsZU1hbmFnZXIiLCJhcHBDb25maWciLCJsaWZlY3ljbGVMaXN0ZW5lciIsIl9hcHBDb25maWciLCJfbGlmZWN5Y2xlTGlzdGVuZXIiLCJfc2RsU2Vzc2lvbiIsIl9jcmVhdGVTZXNzaW9uTGlzdGVuZXIiLCJfY3VycmVudEhNSVN0YXR1cyIsIl9maXJzdFRpbWVGdWxsIiwiX3Jlc3BvbnNlTGlzdGVuZXJzIiwiX21heENvcnJlbGF0aW9uSWQiLCJfcnBjTGlzdGVuZXJzIiwic2Vzc2lvbkxpc3RlbmVyIiwic2VuZFJwY01lc3NhZ2UiLCJfY3JlYXRlUmVnaXN0ZXJBcHBJbnRlcmZhY2UiLCJfaGFuZGxlUnBjIiwiZnVuY3Rpb25JRCIsInJlc29sdmUiLCJfc2V0dXBJbnRlcm5hbFJwY0xpc3RlbmVycyIsImFkZFJwY0xpc3RlbmVyIiwicnBjTGlzdGVuZXIiLCJyZW1vdmVScGNMaXN0ZW5lciIsImdldFJlZ2lzdGVyQXBwSW50ZXJmYWNlUmVzcG9uc2UiLCJfcmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZSIsInJlZ2lzdGVyQXBwSW50ZXJmYWNlIiwiTUFYX1JQQ19WRVJTSU9OIiwiUkVHSVNURVJfQVBQX0lOVEVSRkFDRV9DT1JSRUxBVElPTl9JRCIsIl9ycGNMaXN0ZW5lciIsIl9wcm9jZXNzUmFpUmVzcG9uc2UiLCJzaG91bGRJbml0IiwicmVnaXN0ZXJBcHBJbnRlcmZhY2VSZXNwb25zZSIsIm1zZ1ZlcnNpb24iLCJVTlJFR0lTVEVSX0FQUF9JTlRFUkZBQ0VfQ09SUkVMQVRJT05fSUQiLCJBcHBTZXJ2aWNlVHlwZSIsIldFQVRIRVIiLCJNYWludGVuYW5jZU1vZGVTdGF0dXMiLCJNTVNfTk9STUFMIiwiTU1TX05FQVIiLCJNTVNfQUNUSVZFIiwiTU1TX0ZFQVRVUkVfTk9UX1BSRVNFTlQiLCJQZXJtaXNzaW9uU3RhdHVzIiwiUFNfQUxMT1dFRCIsIlBTX0RJU0FMTE9XRUQiLCJQU19VU0VSX0RJU0FMTE9XRUQiLCJQU19VU0VSX0NPTlNFTlRfUEVORElORyIsIlByZWRlZmluZWRMYXlvdXQiLCJOT05fTUVESUEiLCJPTlNDUkVFTl9QUkVTRVRTIiwiTkFWX0ZVTExTQ1JFRU5fTUFQIiwiTkFWX0xJU1QiLCJOQVZfS0VZQk9BUkQiLCJHUkFQSElDX1dJVEhfVEVYVCIsIlRFWFRfV0lUSF9HUkFQSElDIiwiVElMRVNfT05MWSIsIlRFWFRCVVRUT05TX09OTFkiLCJHUkFQSElDX1dJVEhfVElMRVMiLCJUSUxFU19XSVRIX0dSQVBISUMiLCJHUkFQSElDX1dJVEhfVEVYVF9BTkRfU09GVEJVVFRPTlMiLCJURVhUX0FORF9TT0ZUQlVUVE9OU19XSVRIX0dSQVBISUMiLCJHUkFQSElDX1dJVEhfVEVYVEJVVFRPTlMiLCJURVhUQlVUVE9OU19XSVRIX0dSQVBISUMiLCJMQVJHRV9HUkFQSElDX1dJVEhfU09GVEJVVFRPTlMiLCJET1VCTEVfR1JBUEhJQ19XSVRIX1NPRlRCVVRUT05TIiwiTEFSR0VfR1JBUEhJQ19PTkxZIiwiUHJlZGVmaW5lZFdpbmRvd3MiLCJERUZBVUxUX1dJTkRPVyIsIlBSSU1BUllfV0lER0VUIiwiVGltZXJNb2RlIiwiVVAiLCJET1dOIiwiVmVoaWNsZURhdGFBY3RpdmVTdGF0dXMiLCJWREFTX0lOQUNUSVZFX05PVF9DT05GSVJNRUQiLCJWREFTX0lOQUNUSVZFX0NPTkZJUk1FRCIsIlZEQVNfQUNUSVZFX05PVF9DT05GSVJNRUQiLCJWREFTX0FDVElWRV9DT05GSVJNRUQiLCJWREFTX0ZBVUxUIiwibWVzc2FnZVR5cGUiLCJyZXF1ZXN0IiwicmVzcG9uc2UiLCJub3RpZmljYXRpb24iLCJTZGxTZXJ2aWNlTGlzdGVuZXIiLCJfb25TZXJ2aWNlRXJyb3IiLCJzZXRPblNlcnZpY2VFcnJvciIsIkN1c3RvbVRyYW5zcG9ydCIsIm9uU2VuZFBhY2tldCIsIm9uQnl0ZUJ1ZmZlclJlY2VpdmVkIiwic2RsUHNtIiwiVHJhbnNwb3J0Q29uZmlnQmFzZSIsIl90cmFuc3BvcnRUeXBlIiwiQ3VzdG9tVHJhbnNwb3J0Q29uZmlnIiwiY3VzdG9tVHJhbnNwb3J0IiwiX2N1c3RvbVRyYW5zcG9ydCIsIldlYlNvY2tldENsaWVudENvbmZpZyIsImhvc3QiLCJfaG9zdCIsIl9wb3J0IiwiVHJhbnNwb3J0UmVjb3JkIiwiX2FkZHJlc3MiLCJXZWJTb2NrZXRTZXJ2ZXJDb25maWciLCJjb25uZWN0aW9uTG9zdFRpbWVvdXQiLCJzc2xDb25maWciLCJfY29ubmVjdGlvbkxvc3RUaW1lb3V0IiwiX3NzbENvbmZpZyIsIlNETCIsImxpZmVjeWNsZSIsImVudW1zIiwicnBjIiwibWVzc2FnZXMiLCJzdHJ1Y3RzIiwidmlkZW8iLCJ0cmFuc3BvcnQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztJQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBZ0NBO0lBQ0E7SUFFQSxNQUFNQSxTQUFOLENBQWdCO0lBQ1o7OztJQUdBQyxFQUFBQSxXQUFXLEdBQUk7SUFDWCxTQUFLQyxnQkFBTCxHQUF3QixJQUF4QjtJQUNBLFNBQUtDLE1BQUwsR0FBYyxJQUFkO0lBQ0EsU0FBS0MsUUFBTCxHQUFnQixJQUFoQjtJQUNBLFNBQUtDLFNBQUwsR0FBaUIsSUFBakI7SUFDQSxTQUFLQyxTQUFMLEdBQWlCLElBQWpCO0lBQ0EsU0FBS0MsYUFBTCxH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QyxFQUM2QyxDQUQ3QyxFQUNnRCxDQURoRCxFQUNtRCxDQURuRCxFQUNzRCxDQUR0RCxFQUN5RCxHQUR6RCxFQUM4RCxDQUQ5RCxFQUNpRSxFQURqRSxFQUNxRSxDQURyRSxFQUN3RSxFQUR4RSxFQUM0RSxDQUQ1RSxFQUMrRSxFQUQvRSxFQUNtRixDQURuRixFQUNzRixDQUR0RixFQUN5RixHQUR6RixFQUM4RixHQUQ5RixFQUNtRyxHQURuRyxFQUN3RyxDQUR4RyxFQUMyRyxDQUQzRyxFQUM4RyxDQUQ5RyxFQUNpSCxHQURqSCxFQUNzSCxHQUR0SCxFQUMySCxHQUQzSCxFQUNnSSxFQURoSSxFQUNvSSxHQURwSSxFQUN5SSxDQUR6SSxFQUM0SSxDQUQ1SSxFQUMrSSxDQUQvSSxFQUNrSixHQURsSixFQUN1SixHQUR2SixFQUM0SixHQUQ1SixFQUNpSyxFQURqSyxFQUNxSyxHQURySyxFQUMwSyxDQUQxSyxFQUM2SyxDQUQ3SyxFQUNnTCxDQURoTCxFQUNtTCxHQURuTCxFQUN3TCxHQUR4TCxFQUM2TCxHQUQ3TCxFQUNrTSxFQURsTSxFQUNzTSxHQUR0TSxFQUMyTSxDQUQzTSxFQUM4TSxDQUQ5TSxFQUNpTixDQURqTixFQUNvTixHQURwTixFQUN5TixHQUR6TixFQUM4TixHQUQ5TixFQUNtTyxFQURuTyxFQUN1TyxHQUR2TyxFQUM0TyxDQUQ1TyxFQUMrTyxDQUQvTyxFQUNrUCxDQURsUCxFQUNxUCxHQURyUCxFQUMwUCxHQUQxUCxFQUMrUCxHQUQvUCxFQUNvUSxFQURwUSxFQUN3USxHQUR4USxFQUM2USxHQUQ3USxFQUNrUixHQURsUixFQUN1UixHQUR2UixFQUM0UixDQUQ1UixFQUMrUixDQUQvUixFQUNrUyxFQURsUyxFQUNzUyxHQUR0UyxFQUMyUyxDQUQzUyxFQUM4UyxDQUQ5UyxFQUNpVCxDQURqVCxFQUNvVCxDQURwVCxFQUN1VCxFQUR2VCxFQUMyVCxDQUQzVCxFQUM4VCxFQUQ5VCxFQUNrVSxFQURsVSxFQUNzVSxDQUR0VSxFQUN5VSxDQUR6VSxFQUM0VSxHQUQ1VSxFQUNpVixFQURq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Rzs7SUFFSDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsRUFBRSxZQUFZLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsR0FBRyxFQUFDOztJQUV4RTtJQUNBLEVBQUUsR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLFlBQVksRUFBQzs7SUFFM0M7SUFDQSxFQUFFLENBQUMsR0FBRyxZQUFZLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsSUFBRzs7SUFFdEMsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFDOztJQUVYLEVBQUUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUU7SUFDNUMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxTQUFTLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxTQUFTLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUM7SUFDdEssSUFBSSxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxFQUFFLElBQUksS0FBSTtJQUNqQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxLQUFJO0lB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LEVBQUUsSUFBSSxFQUFFLElBQUksSUFBSSxLQUFLLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFDO0lBQ2xFLEVBQUUsSUFBSSxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxNQUFNLEdBQUcsQ0FBQyxFQUFDO0lBQ2pDLEVBQUUsSUFBSSxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUM7SUFDdkIsRUFBRSxJQUFJLENBQUMsR0FBRyxLQUFLLEdBQUcsQ0FBQyxLQUFLLEtBQUssS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLEtBQUssR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBQzs7SUFFN0QsRUFBRSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUM7O0lBRXpCLEVBQUUsSUFBSSxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxLQUFLLFFBQVEsRUFBRTtJQUMxQyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUM7SUFDNUIsSUFBSSxDQUFDLEdBQUcsS0FBSTtJQUNaLEdBQUcsTUFBTTtJQUNULElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFDO0lBQzlDLElBQUksSUFBSSxLQUFLLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUU7SUFDM0MsTUFBTSxDQUFDLEdBQUU7SUFDVCxNQUFNLENBQUMsSUFBSSxFQUFDO0lBQ1osS0FBSztJQUNMLElBQUksSUFBSSxDQUFDLEdBQUcsS0FBSyxJQUFJLENBQUMsRUFBRTtJQUN4QixNQUFNLEtBQUssSUFBSSxFQUFFLEdBQUcsRUFBQztJQUNyQixLQUFLLE1BQU07SUFDWCxNQUFNLEtBQUssSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssRUFBQztJQUMxQyxLQUFLO0lBQ0wsSUFBSSxJQUFJLEtBQUssR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFO0lBQ3hCLE1BQU0sQ0FBQyxHQUFFO0lBQ1QsTUFBTSxDQUFDLElBQUksRUFBQztJQUNaLEtBQUs7O0lBRUwsSUFBSSxJQUFJLENBQUMsR0FBRyxLQUFLLElBQUksSUFBSSxFQUFFO0lBQzNCLE1BQU0sQ0FBQyxHQUFHLEVBQUM7SUFDWCxNQUFNLENBQUMsR0FBRyxLQUFJO0lBQ2QsS0FBSyxNQUFNLElBQUksQ0FBQyxHQUFHLEtBQUssSUFBSSxDQUFDLEVBQUU7SUFDL0IsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUM7SUFDN0MsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLE1BQUs7SUFDbkIsS0FBSyxNQUFNO0lBQ1gsTUFBTSxDQUFDLEdBQUcsS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEtBQUssR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUM7SUFDNUQsTUFBTSxDQUFDLEdBQUcsRUFBQztJQUNYLEtBQUs7SUFDTCxHQUFHOztJQUVILEVBQUUsT0FBTyxJQUFJLElBQUksQ0FBQyxFQUFFLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxHQUFHLEVBQUUsSUFBSSxJQUFJLENBQUMsRUFBRSxFQUFFOztJQUVsRixFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxJQUFJLElBQUksRUFBQztJQUNyQixFQUFFLElBQUksSUFBSSxLQUFJO0lBQ2QsRUFBRSxPQUFPLElBQUksR0FBRyxDQUFDLEVBQUUsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEdBQUcsRUFBRSxJQUFJLElBQUksQ0FBQyxFQUFFLEVBQUU7O0lBRWpGLEVBQUUsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUc7SUFDbkMsQ0FBQzs7SUNwRkQsSUFBSSxRQUFRLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQzs7QUFFM0Isa0JBQWUsS0FBSyxDQUFDLE9BQU8sSUFBSSxVQUFVLEdBQUcsRUFBRTtJQUMvQyxFQUFFLE9BQU8sUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxnQkFBZ0IsQ0FBQztJQUNoRCxDQUFDLENBQUM7O0lDU0ssSUFBSSxpQkFBaUIsR0FBRyxHQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQTBCakMsTUFBTSxDQUFDLG1CQUFtQixHQUFHcG5DLFFBQU0sQ0FBQyxtQkFBbUIsS0FBSyxTQUFTO1FBQ2pFQSxRQUFNLENBQUMsbUJBQW1CO1FBQzFCLEtBQUk7O0lBd0JSLFNBQVMsVUFBVSxJQUFJO01BQ3JCLE9BQU8sTUFBTSxDQUFDLG1CQUFtQjtVQUM3QixVQUFVO1VBQ1YsVUFBVTtLQUNmOztJQUVELFNBQVMsWUFBWSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUU7TUFDbkMsSUFBSSxVQUFVLEVBQUUsR0FBRyxNQUFNLEVBQUU7UUFDekIsTUFBTSxJQUFJLFVBQVUsQ0FBQyw0QkFBNEIsQ0FBQztPQUNuRDtNQUNELElBQUksTUFBTSxDQUFDLG1CQUFtQixFQUFFOztRQUU5QixJQUFJLEdBQUcsSUFBSSxVQUFVLENBQUMsTUFBTSxFQUFDO1FBQzdCLElBQUksQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLFVBQVM7T0FDbEMsTUFBTTs7UUFFTCxJQUFJLElBQUksS0FBSyxJQUFJLEVBQUU7VUFDakIsSUFBSSxHQUFHLElBQUksTUFBTSxDQUFDLE1BQU0sRUFBQztTQUMxQjtRQUNELElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTTtPQUNyQjs7TUFFRCxPQUFPLElBQUk7S0FDWjs7Ozs7Ozs7Ozs7O0FBWUQsSUFBTyxTQUFTLE1BQU0sRUFBRSxHQUFHLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxFQUFFO01BQ3JELElBQUksQ0FBQyxNQUFNLENBQUMsbUJBQW1CLElBQUksRUFBRSxJQUFJLFlBQVksTUFBTSxDQUFDLEVBQUU7UUFDNUQsT0FBTyxJQUFJLE1BQU0sQ0FBQyxHQUFHLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDO09BQ2pEOzs7TUFHRCxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsRUFBRTtRQUMzQixJQUFJLE9BQU8sZ0JBQWdCLEtBQUssUUFBUSxFQUFFO1VBQ3hDLE1BQU0sSUFBSSxLQUFLO1lBQ2IsbUVBQW1FO1dBQ3BFO1NBQ0Y7UUFDRCxPQUFPLFdBQVcsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDO09BQzlCO01BQ0QsT0FBTyxJQUFJLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLENBQUM7S0FDakQ7O0lBRUQsTUFBTSxDQUFDLFFBQVEsR0FBRyxLQUFJOzs7SUFHdEIsTUFBTSxDQUFDLFFBQVEsR0FBRyxVQUFVLEdBQUcsRUFBRTtNQUMvQixHQUFHLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQyxVQUFTO01BQ2hDLE9BQU8sR0FBRztNQUNYOztJQUVELFNBQVMsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxFQUFFO01BQ3BELElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFO1FBQzdCLE1BQU0sSUFBSSxTQUFTLENBQUMsdUNBQXVDLENBQUM7T0FDN0Q7O01BRUQsSUFBSSxPQUFPLFdBQVcsS0FBSyxXQUFXLElBQUksS0FBSyxZQUFZLFdBQVcsRUFBRTtRQUN0RSxPQUFPLGVBQWUsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sQ0FBQztPQUM5RDs7TUFFRCxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRTtRQUM3QixPQUFPLFVBQVUsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLGdCQUFnQixDQUFDO09BQ2pEOztNQUVELE9BQU8sVUFBVSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUM7S0FDL0I7Ozs7Ozs7Ozs7SUFVRCxNQUFNLENBQUMsSUFBSSxHQUFHLFVBQVUsS0FBSyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sRUFBRTtNQUN2RCxPQUFPLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sQ0FBQztNQUNuRDs7SUFFRCxJQUFJLE1BQU0sQ0FBQyxtQkFBbUIsRUFBRTtNQUM5QixNQUFNLENBQUMsU0FBUyxDQUFDLFNBQVMsR0FBRyxVQUFVLENBQUMsVUFBUztNQUNqRCxNQUFNLENBQUMsU0FBUyxHQUFHLFdBQVU7S0FTOUI7O0lBRUQsU0FBUyxVQUFVLEVBQUUsSUFBSSxFQUFFO01BQ3pCLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxFQUFFO1FBQzVCLE1BQU0sSUFBSSxTQUFTLENBQUMsa0NBQWtDLENBQUM7T0FDeEQsTUFBTSxJQUFJLElBQUksR0FBRyxDQUFDLEVBQUU7UUFDbkIsTUFBTSxJQUFJLFVBQVUsQ0FBQyxzQ0FBc0MsQ0FBQztPQUM3RDtLQUNGOztJQUVELFNBQVMsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTtNQUMxQyxVQUFVLENBQUMsSUFBSSxFQUFDO01BQ2hCLElBQUksSUFBSSxJQUFJLENBQUMsRUFBRTtRQUNiLE9BQU8sWUFBWSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUM7T0FDaEM7TUFDRCxJQUFJLElBQUksS0FBSyxTQUFTLEVBQUU7Ozs7UUFJdEIsT0FBTyxPQUFPLFFBQVEsS0FBSyxRQUFRO1lBQy9CLFlBQVksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7WUFDN0MsWUFBWSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO09BQ3hDO01BQ0QsT0FBTyxZQUFZLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQztLQUNoQzs7Ozs7O0lBTUQsTUFBTSxDQUFDLEtBQUssR0FBRyxVQUFVLElBQUksRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO01BQzdDLE9BQU8sS0FBSyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLFFBQVEsQ0FBQztNQUN6Qzs7SUFFRCxTQUFTLFdBQVcsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFO01BQ2hDLFVBQVUsQ0FBQyxJQUFJLEVBQUM7TUFDaEIsSUFBSSxHQUFHLFlBQVksQ0FBQyxJQUFJLEVBQUUsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBQztNQUMzRCxJQUFJLENBQUMsTUFBTSxDQUFDLG1CQUFtQixFQUFFO1FBQy9CLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLEVBQUUsRUFBRSxDQUFDLEVBQUU7VUFDN0IsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUM7U0FDWjtPQUNGO01BQ0QsT0FBTyxJQUFJO0tBQ1o7Ozs7O0lBS0QsTUFBTSxDQUFDLFdBQVcsR0FBRyxVQUFVLElBQUksRUFBRTtNQUNuQyxPQUFPLFdBQVcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDO01BQy9COzs7O0lBSUQsTUFBTSxDQUFDLGVBQWUsR0FBRyxVQUFVLElBQUksRUFBRTtNQUN2QyxPQUFPLFdBQVcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDO01BQy9COztJQUVELFNBQVMsVUFBVSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFO01BQzNDLElBQUksT0FBTyxRQUFRLEtBQUssUUFBUSxJQUFJLFFBQVEsS0FBSyxFQUFFLEVBQUU7UUFDbkQsUUFBUSxHQUFHLE9BQU07T0FDbEI7O01BRUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEVBQUU7UUFDaEMsTUFBTSxJQUFJLFNBQVMsQ0FBQyw0Q0FBNEMsQ0FBQztPQUNsRTs7TUFFRCxJQUFJLE1BQU0sR0FBRyxVQUFVLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxHQUFHLEVBQUM7TUFDN0MsSUFBSSxHQUFHLFlBQVksQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFDOztNQUVqQyxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUM7O01BRXpDLElBQUksTUFBTSxLQUFLLE1BQU0sRUFBRTs7OztRQUlyQixJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFDO09BQzdCOztNQUVELE9BQU8sSUFBSTtLQUNaOztJQUVELFNBQVMsYUFBYSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUU7TUFDbkMsSUFBSSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBQztNQUM3RCxJQUFJLEdBQUcsWUFBWSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUM7TUFDakMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFO1FBQ2xDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBRztPQUN6QjtNQUNELE9BQU8sSUFBSTtLQUNaOztJQUVELFNBQVMsZUFBZSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRTtNQUN6RCxLQUFLLENBQUMsV0FBVTs7TUFFaEIsSUFBSSxVQUFVLEdBQUcsQ0FBQyxJQUFJLEtBQUssQ0FBQyxVQUFVLEdBQUcsVUFBVSxFQUFFO1FBQ25ELE1BQU0sSUFBSSxVQUFVLENBQUMsNkJBQTZCLENBQUM7T0FDcEQ7O01BRUQsSUFBSSxLQUFLLENBQUMsVUFBVSxHQUFHLFVBQVUsSUFBSSxNQUFNLElBQUksQ0FBQyxDQUFDLEVBQUU7UUFDakQsTUFBTSxJQUFJLFVBQVUsQ0FBQyw2QkFBNkIsQ0FBQztPQUNwRDs7TUFFRCxJQUFJLFVBQVUsS0FBSyxTQUFTLElBQUksTUFBTSxLQUFLLFNBQVMsRUFBRTtRQUNwRCxLQUFLLEdBQUcsSUFBSSxVQUFVLENBQUMsS0FBSyxFQUFDO09BQzlCLE1BQU0sSUFBSSxNQUFNLEtBQUssU0FBUyxFQUFFO1FBQy9CLEtBQUssR0FBRyxJQUFJLFVBQVUsQ0FBQyxLQUFLLEVBQUUsVUFBVSxFQUFDO09BQzFDLE1BQU07UUFDTCxLQUFLLEdBQUcsSUFBSSxVQUFVLENBQUMsS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUM7T0FDbEQ7O01BRUQsSUFBSSxNQUFNLENBQUMsbUJBQW1CLEVBQUU7O1FBRTlCLElBQUksR0FBRyxNQUFLO1FBQ1osSUFBSSxDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUMsVUFBUztPQUNsQyxNQUFNOztRQUVMLElBQUksR0FBRyxhQUFhLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBQztPQUNsQztNQUNELE9BQU8sSUFBSTtLQUNaOztJQUVELFNBQVMsVUFBVSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUU7TUFDOUIsSUFBSSxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsRUFBRTtRQUN6QixJQUFJLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUM7UUFDakMsSUFBSSxHQUFHLFlBQVksQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFDOztRQUU5QixJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO1VBQ3JCLE9BQU8sSUFBSTtTQUNaOztRQUVELEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFDO1FBQ3pCLE9BQU8sSUFBSTtPQUNaOztNQUVELElBQUksR0FBRyxFQUFFO1FBQ1AsSUFBSSxDQUFDLE9BQU8sV0FBVyxLQUFLLFdBQVc7WUFDbkMsR0FBRyxDQUFDLE1BQU0sWUFBWSxXQUFXLEtBQUssUUFBUSxJQUFJLEdBQUcsRUFBRTtVQUN6RCxJQUFJLE9BQU8sR0FBRyxDQUFDLE1BQU0sS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUN2RCxPQUFPLFlBQVksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1dBQzdCO1VBQ0QsT0FBTyxhQUFhLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQztTQUNoQzs7UUFFRCxJQUFJLEdBQUcsQ0FBQyxJQUFJLEtBQUssUUFBUSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUU7VUFDOUMsT0FBTyxhQUFhLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUM7U0FDckM7T0FDRjs7TUFFRCxNQUFNLElBQUksU0FBUyxDQUFDLG9GQUFvRixDQUFDO0tBQzFHOztJQUVELFNBQVMsT0FBTyxFQUFFLE1BQU0sRUFBRTs7O01BR3hCLElBQUksTUFBTSxJQUFJLFVBQVUsRUFBRSxFQUFFO1FBQzFCLE1BQU0sSUFBSSxVQUFVLENBQUMsaURBQWlEOzZCQUNqRCxVQUFVLEdBQUcsVUFBVSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxHQUFHLFFBQVEsQ0FBQztPQUN4RTtNQUNELE9BQU8sTUFBTSxHQUFHLENBQUM7S0FDbEI7SUFRRCxNQUFNLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztJQUMzQixTQUFTLGdCQUFnQixFQUFFLENBQUMsRUFBRTtNQUM1QixPQUFPLENBQUMsRUFBRSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQUM7S0FDcEM7O0lBRUQsTUFBTSxDQUFDLE9BQU8sR0FBRyxTQUFTLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO01BQ3ZDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxFQUFFO1FBQ2hELE1BQU0sSUFBSSxTQUFTLENBQUMsMkJBQTJCLENBQUM7T0FDakQ7O01BRUQsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLE9BQU8sQ0FBQzs7TUFFckIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU07TUFDaEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU07O01BRWhCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFO1FBQ2xELElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtVQUNqQixDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBQztVQUNSLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFDO1VBQ1IsS0FBSztTQUNOO09BQ0Y7O01BRUQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO01BQ3BCLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxPQUFPLENBQUM7TUFDbkIsT0FBTyxDQUFDO01BQ1Q7O0lBRUQsTUFBTSxDQUFDLFVBQVUsR0FBRyxTQUFTLFVBQVUsRUFBRSxRQUFRLEVBQUU7TUFDakQsUUFBUSxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsV0FBVyxFQUFFO1FBQ3BDLEtBQUssS0FBSyxDQUFDO1FBQ1gsS0FBSyxNQUFNLENBQUM7UUFDWixLQUFLLE9BQU8sQ0FBQztRQUNiLEtBQUssT0FBTyxDQUFDO1FBQ2IsS0FBSyxRQUFRLENBQUM7UUFDZCxLQUFLLFFBQVEsQ0FBQztRQUNkLEtBQUssUUFBUSxDQUFDO1FBQ2QsS0FBSyxNQUFNLENBQUM7UUFDWixLQUFLLE9BQU8sQ0FBQztRQUNiLEtBQUssU0FBUyxDQUFDO1FBQ2YsS0FBSyxVQUFVO1VBQ2IsT0FBTyxJQUFJO1FBQ2I7VUFDRSxPQUFPLEtBQUs7T0FDZjtNQUNGOztJQUVELE1BQU0sQ0FBQyxNQUFNLEdBQUcsU0FBUyxNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRTtNQUM3QyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFO1FBQ2xCLE1BQU0sSUFBSSxTQUFTLENBQUMsNkNBQTZDLENBQUM7T0FDbkU7O01BRUQsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtRQUNyQixPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO09BQ3ZCOztNQUVELElBQUksRUFBQztNQUNMLElBQUksTUFBTSxLQUFLLFNBQVMsRUFBRTtRQUN4QixNQUFNLEdBQUcsRUFBQztRQUNWLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRTtVQUNoQyxNQUFNLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU07U0FDekI7T0FDRjs7TUFFRCxJQUFJLE1BQU0sR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBQztNQUN2QyxJQUFJLEdBQUcsR0FBRyxFQUFDO01BQ1gsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxFQUFFO1FBQ2hDLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLEVBQUM7UUFDakIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxFQUFFO1VBQzFCLE1BQU0sSUFBSSxTQUFTLENBQUMsNkNBQTZDLENBQUM7U0FDbkU7UUFDRCxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUM7UUFDckIsR0FBRyxJQUFJLEdBQUcsQ0FBQyxPQUFNO09BQ2xCO01BQ0QsT0FBTyxNQUFNO01BQ2Q7O0lBRUQsU0FBUyxVQUFVLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRTtNQUNyQyxJQUFJLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxFQUFFO1FBQzVCLE9BQU8sTUFBTSxDQUFDLE1BQU07T0FDckI7TUFDRCxJQUFJLE9BQU8sV0FBVyxLQUFLLFdBQVcsSUFBSSxPQUFPLFdBQVcsQ0FBQyxNQUFNLEtBQUssVUFBVTtXQUM3RSxXQUFXLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLE1BQU0sWUFBWSxXQUFXLENBQUMsRUFBRTtRQUNqRSxPQUFPLE1BQU0sQ0FBQyxVQUFVO09BQ3pCO01BQ0QsSUFBSSxPQUFPLE1BQU0sS0FBSyxRQUFRLEVBQUU7UUFDOUIsTUFBTSxHQUFHLEVBQUUsR0FBRyxPQUFNO09BQ3JCOztNQUVELElBQUksR0FBRyxHQUFHLE1BQU0sQ0FBQyxPQUFNO01BQ3ZCLElBQUksR0FBRyxLQUFLLENBQUMsRUFBRSxPQUFPLENBQUM7OztNQUd2QixJQUFJLFdBQVcsR0FBRyxNQUFLO01BQ3ZCLFNBQVM7UUFDUCxRQUFRLFFBQVE7VUFDZCxLQUFLLE9BQU8sQ0FBQztVQUNiLEtBQUssUUFBUSxDQUFDO1VBQ2QsS0FBSyxRQUFRO1lBQ1gsT0FBTyxHQUFHO1VBQ1osS0FBSyxNQUFNLENBQUM7VUFDWixLQUFLLE9BQU8sQ0FBQztVQUNiLEtBQUssU0FBUztZQUNaLE9BQU8sV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU07VUFDbkMsS0FBSyxNQUFNLENBQUM7VUFDWixLQUFLLE9BQU8sQ0FBQztVQUNiLEtBQUssU0FBUyxDQUFDO1VBQ2YsS0FBSyxVQUFVO1lBQ2IsT0FBTyxHQUFHLEdBQUcsQ0FBQztVQUNoQixLQUFLLEtBQUs7WUFDUixPQUFPLEdBQUcsS0FBSyxDQUFDO1VBQ2xCLEtBQUssUUFBUTtZQUNYLE9BQU8sYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU07VUFDckM7WUFDRSxJQUFJLFdBQVcsRUFBRSxPQUFPLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNO1lBQ2xELFFBQVEsR0FBRyxDQUFDLEVBQUUsR0FBRyxRQUFRLEVBQUUsV0FBVyxHQUFFO1lBQ3hDLFdBQVcsR0FBRyxLQUFJO1NBQ3JCO09BQ0Y7S0FDRjtJQUNELE1BQU0sQ0FBQyxVQUFVLEdBQUcsV0FBVTs7SUFFOUIsU0FBUyxZQUFZLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUU7TUFDM0MsSUFBSSxXQUFXLEdBQUcsTUFBSzs7Ozs7Ozs7O01BU3ZCLElBQUksS0FBSyxLQUFLLFNBQVMsSUFBSSxLQUFLLEdBQUcsQ0FBQyxFQUFFO1FBQ3BDLEtBQUssR0FBRyxFQUFDO09BQ1Y7OztNQUdELElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUU7UUFDdkIsT0FBTyxFQUFFO09BQ1Y7O01BRUQsSUFBSSxHQUFHLEtBQUssU0FBUyxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFO1FBQzFDLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTTtPQUNsQjs7TUFFRCxJQUFJLEdBQUcsSUFBSSxDQUFDLEVBQUU7UUFDWixPQUFPLEVBQUU7T0FDVjs7O01BR0QsR0FBRyxNQUFNLEVBQUM7TUFDVixLQUFLLE1BQU0sRUFBQzs7TUFFWixJQUFJLEdBQUcsSUFBSSxLQUFLLEVBQUU7UUFDaEIsT0FBTyxFQUFFO09BQ1Y7O01BRUQsSUFBSSxDQUFDLFFBQVEsRUFBRSxRQUFRLEdBQUcsT0FBTTs7TUFFaEMsT0FBTyxJQUFJLEVBQUU7UUFDWCxRQUFRLFFBQVE7VUFDZCxLQUFLLEtBQUs7WUFDUixPQUFPLFFBQVEsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQzs7VUFFbkMsS0FBSyxNQUFNLENBQUM7VUFDWixLQUFLLE9BQU87WUFDVixPQUFPLFNBQVMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQzs7VUFFcEMsS0FBSyxPQUFPO1lBQ1YsT0FBTyxVQUFVLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUM7O1VBRXJDLEtBQUssUUFBUSxDQUFDO1VBQ2QsS0FBSyxRQUFRO1lBQ1gsT0FBTyxXQUFXLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUM7O1VBRXRDLEtBQUssUUFBUTtZQUNYLE9BQU8sV0FBVyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsR0FBRyxDQUFDOztVQUV0QyxLQUFLLE1BQU0sQ0FBQztVQUNaLEtBQUssT0FBTyxDQUFDO1VBQ2IsS0FBSyxTQUFTLENBQUM7VUFDZixLQUFLLFVBQVU7WUFDYixPQUFPLFlBQVksQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQzs7VUFFdkM7WUFDRSxJQUFJLFdBQVcsRUFBRSxNQUFNLElBQUksU0FBUyxDQUFDLG9CQUFvQixHQUFHLFFBQVEsQ0FBQztZQUNyRSxRQUFRLEdBQUcsQ0FBQyxRQUFRLEdBQUcsRUFBRSxFQUFFLFdBQVcsR0FBRTtZQUN4QyxXQUFXLEdBQUcsS0FBSTtTQUNyQjtPQUNGO0tBQ0Y7Ozs7SUFJRCxNQUFNLENBQUMsU0FBUyxDQUFDLFNBQVMsR0FBRyxLQUFJOztJQUVqQyxTQUFTLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtNQUN0QixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFDO01BQ1osQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUM7TUFDWCxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBQztLQUNUOztJQUVELE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLFNBQVMsTUFBTSxJQUFJO01BQzNDLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFNO01BQ3JCLElBQUksR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUU7UUFDakIsTUFBTSxJQUFJLFVBQVUsQ0FBQywyQ0FBMkMsQ0FBQztPQUNsRTtNQUNELEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRTtRQUMvQixJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFDO09BQ3JCO01BQ0QsT0FBTyxJQUFJO01BQ1o7O0lBRUQsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsU0FBUyxNQUFNLElBQUk7TUFDM0MsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU07TUFDckIsSUFBSSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRTtRQUNqQixNQUFNLElBQUksVUFBVSxDQUFDLDJDQUEyQyxDQUFDO09BQ2xFO01BQ0QsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFO1FBQy9CLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUM7UUFDcEIsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUM7T0FDekI7TUFDRCxPQUFPLElBQUk7TUFDWjs7SUFFRCxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxTQUFTLE1BQU0sSUFBSTtNQUMzQyxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTTtNQUNyQixJQUFJLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFO1FBQ2pCLE1BQU0sSUFBSSxVQUFVLENBQUMsMkNBQTJDLENBQUM7T0FDbEU7TUFDRCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUU7UUFDL0IsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBQztRQUNwQixJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBQztRQUN4QixJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBQztRQUN4QixJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBQztPQUN6QjtNQUNELE9BQU8sSUFBSTtNQUNaOztJQUVELE1BQU0sQ0FBQyxTQUFTLENBQUMsUUFBUSxHQUFHLFNBQVMsUUFBUSxJQUFJO01BQy9DLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBQztNQUM1QixJQUFJLE1BQU0sS0FBSyxDQUFDLEVBQUUsT0FBTyxFQUFFO01BQzNCLElBQUksU0FBUyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsT0FBTyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxNQUFNLENBQUM7TUFDN0QsT0FBTyxZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxTQUFTLENBQUM7TUFDM0M7O0lBRUQsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsU0FBUyxNQUFNLEVBQUUsQ0FBQyxFQUFFO01BQzVDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLElBQUksU0FBUyxDQUFDLDJCQUEyQixDQUFDO01BQzFFLElBQUksSUFBSSxLQUFLLENBQUMsRUFBRSxPQUFPLElBQUk7TUFDM0IsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDO01BQ3JDOztJQUVELE1BQU0sQ0FBQyxTQUFTLENBQUMsT0FBTyxHQUFHLFNBQVMsT0FBTyxJQUFJO01BQzdDLElBQUksR0FBRyxHQUFHLEdBQUU7TUFDWixJQUFJLEdBQUcsR0FBRyxrQkFBaUI7TUFDM0IsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtRQUNuQixHQUFHLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFDO1FBQzNELElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxHQUFHLEVBQUUsR0FBRyxJQUFJLFFBQU87T0FDdEM7TUFDRCxPQUFPLFVBQVUsR0FBRyxHQUFHLEdBQUcsR0FBRztNQUM5Qjs7SUFFRCxNQUFNLENBQUMsU0FBUyxDQUFDLE9BQU8sR0FBRyxTQUFTLE9BQU8sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFO01BQ25GLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsRUFBRTtRQUM3QixNQUFNLElBQUksU0FBUyxDQUFDLDJCQUEyQixDQUFDO09BQ2pEOztNQUVELElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRTtRQUN2QixLQUFLLEdBQUcsRUFBQztPQUNWO01BQ0QsSUFBSSxHQUFHLEtBQUssU0FBUyxFQUFFO1FBQ3JCLEdBQUcsR0FBRyxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sR0FBRyxFQUFDO09BQ2pDO01BQ0QsSUFBSSxTQUFTLEtBQUssU0FBUyxFQUFFO1FBQzNCLFNBQVMsR0FBRyxFQUFDO09BQ2Q7TUFDRCxJQUFJLE9BQU8sS0FBSyxTQUFTLEVBQUU7UUFDekIsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFNO09BQ3RCOztNQUVELElBQUksS0FBSyxHQUFHLENBQUMsSUFBSSxHQUFHLEdBQUcsTUFBTSxDQUFDLE1BQU0sSUFBSSxTQUFTLEdBQUcsQ0FBQyxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFO1FBQzlFLE1BQU0sSUFBSSxVQUFVLENBQUMsb0JBQW9CLENBQUM7T0FDM0M7O01BRUQsSUFBSSxTQUFTLElBQUksT0FBTyxJQUFJLEtBQUssSUFBSSxHQUFHLEVBQUU7UUFDeEMsT0FBTyxDQUFDO09BQ1Q7TUFDRCxJQUFJLFNBQVMsSUFBSSxPQUFPLEVBQUU7UUFDeEIsT0FBTyxDQUFDLENBQUM7T0FDVjtNQUNELElBQUksS0FBSyxJQUFJLEdBQUcsRUFBRTtRQUNoQixPQUFPLENBQUM7T0FDVDs7TUFFRCxLQUFLLE1BQU0sRUFBQztNQUNaLEdBQUcsTUFBTSxFQUFDO01BQ1YsU0FBUyxNQUFNLEVBQUM7TUFDaEIsT0FBTyxNQUFNLEVBQUM7O01BRWQsSUFBSSxJQUFJLEtBQUssTUFBTSxFQUFFLE9BQU8sQ0FBQzs7TUFFN0IsSUFBSSxDQUFDLEdBQUcsT0FBTyxHQUFHLFVBQVM7TUFDM0IsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLE1BQUs7TUFDbkIsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFDOztNQUV4QixJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUM7TUFDN0MsSUFBSSxVQUFVLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFDOztNQUV6QyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFO1FBQzVCLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRTtVQUNqQyxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsRUFBQztVQUNmLENBQUMsR0FBRyxVQUFVLENBQUMsQ0FBQyxFQUFDO1VBQ2pCLEtBQUs7U0FDTjtPQUNGOztNQUVELElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztNQUNwQixJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsT0FBTyxDQUFDO01BQ25CLE9BQU8sQ0FBQztNQUNUOzs7Ozs7Ozs7OztJQVdELFNBQVMsb0JBQW9CLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRTs7TUFFckUsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQzs7O01BR2xDLElBQUksT0FBTyxVQUFVLEtBQUssUUFBUSxFQUFFO1FBQ2xDLFFBQVEsR0FBRyxXQUFVO1FBQ3JCLFVBQVUsR0FBRyxFQUFDO09BQ2YsTUFBTSxJQUFJLFVBQVUsR0FBRyxVQUFVLEVBQUU7UUFDbEMsVUFBVSxHQUFHLFdBQVU7T0FDeEIsTUFBTSxJQUFJLFVBQVUsR0FBRyxDQUFDLFVBQVUsRUFBRTtRQUNuQyxVQUFVLEdBQUcsQ0FBQyxXQUFVO09BQ3pCO01BQ0QsVUFBVSxHQUFHLENBQUMsV0FBVTtNQUN4QixJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUMsRUFBRTs7UUFFckIsVUFBVSxHQUFHLEdBQUcsR0FBRyxDQUFDLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUM7T0FDM0M7OztNQUdELElBQUksVUFBVSxHQUFHLENBQUMsRUFBRSxVQUFVLEdBQUcsTUFBTSxDQUFDLE1BQU0sR0FBRyxXQUFVO01BQzNELElBQUksVUFBVSxJQUFJLE1BQU0sQ0FBQyxNQUFNLEVBQUU7UUFDL0IsSUFBSSxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUM7YUFDYixVQUFVLEdBQUcsTUFBTSxDQUFDLE1BQU0sR0FBRyxFQUFDO09BQ3BDLE1BQU0sSUFBSSxVQUFVLEdBQUcsQ0FBQyxFQUFFO1FBQ3pCLElBQUksR0FBRyxFQUFFLFVBQVUsR0FBRyxFQUFDO2FBQ2xCLE9BQU8sQ0FBQyxDQUFDO09BQ2Y7OztNQUdELElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxFQUFFO1FBQzNCLEdBQUcsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxRQUFRLEVBQUM7T0FDakM7OztNQUdELElBQUksZ0JBQWdCLENBQUMsR0FBRyxDQUFDLEVBQUU7O1FBRXpCLElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7VUFDcEIsT0FBTyxDQUFDLENBQUM7U0FDVjtRQUNELE9BQU8sWUFBWSxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxHQUFHLENBQUM7T0FDNUQsTUFBTSxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsRUFBRTtRQUNsQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEtBQUk7UUFDaEIsSUFBSSxNQUFNLENBQUMsbUJBQW1CO1lBQzFCLE9BQU8sVUFBVSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEtBQUssVUFBVSxFQUFFO1VBQ3RELElBQUksR0FBRyxFQUFFO1lBQ1AsT0FBTyxVQUFVLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRSxVQUFVLENBQUM7V0FDbEUsTUFBTTtZQUNMLE9BQU8sVUFBVSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsVUFBVSxDQUFDO1dBQ3RFO1NBQ0Y7UUFDRCxPQUFPLFlBQVksQ0FBQyxNQUFNLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLEdBQUcsQ0FBQztPQUNoRTs7TUFFRCxNQUFNLElBQUksU0FBUyxDQUFDLHNDQUFzQyxDQUFDO0tBQzVEOztJQUVELFNBQVMsWUFBWSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7TUFDMUQsSUFBSSxTQUFTLEdBQUcsRUFBQztNQUNqQixJQUFJLFNBQVMsR0FBRyxHQUFHLENBQUMsT0FBTTtNQUMxQixJQUFJLFNBQVMsR0FBRyxHQUFHLENBQUMsT0FBTTs7TUFFMUIsSUFBSSxRQUFRLEtBQUssU0FBUyxFQUFFO1FBQzFCLFFBQVEsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsV0FBVyxHQUFFO1FBQ3pDLElBQUksUUFBUSxLQUFLLE1BQU0sSUFBSSxRQUFRLEtBQUssT0FBTztZQUMzQyxRQUFRLEtBQUssU0FBUyxJQUFJLFFBQVEsS0FBSyxVQUFVLEVBQUU7VUFDckQsSUFBSSxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUNwQyxPQUFPLENBQUMsQ0FBQztXQUNWO1VBQ0QsU0FBUyxHQUFHLEVBQUM7VUFDYixTQUFTLElBQUksRUFBQztVQUNkLFNBQVMsSUFBSSxFQUFDO1VBQ2QsVUFBVSxJQUFJLEVBQUM7U0FDaEI7T0FDRjs7TUFFRCxTQUFTLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFO1FBQ3JCLElBQUksU0FBUyxLQUFLLENBQUMsRUFBRTtVQUNuQixPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUM7U0FDZCxNQUFNO1VBQ0wsT0FBTyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUM7U0FDdkM7T0FDRjs7TUFFRCxJQUFJLEVBQUM7TUFDTCxJQUFJLEdBQUcsRUFBRTtRQUNQLElBQUksVUFBVSxHQUFHLENBQUMsRUFBQztRQUNuQixLQUFLLENBQUMsR0FBRyxVQUFVLEVBQUUsQ0FBQyxHQUFHLFNBQVMsRUFBRSxDQUFDLEVBQUUsRUFBRTtVQUN2QyxJQUFJLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLEdBQUcsRUFBRSxVQUFVLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxVQUFVLENBQUMsRUFBRTtZQUN0RSxJQUFJLFVBQVUsS0FBSyxDQUFDLENBQUMsRUFBRSxVQUFVLEdBQUcsRUFBQztZQUNyQyxJQUFJLENBQUMsR0FBRyxVQUFVLEdBQUcsQ0FBQyxLQUFLLFNBQVMsRUFBRSxPQUFPLFVBQVUsR0FBRyxTQUFTO1dBQ3BFLE1BQU07WUFDTCxJQUFJLFVBQVUsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLFdBQVU7WUFDMUMsVUFBVSxHQUFHLENBQUMsRUFBQztXQUNoQjtTQUNGO09BQ0YsTUFBTTtRQUNMLElBQUksVUFBVSxHQUFHLFNBQVMsR0FBRyxTQUFTLEVBQUUsVUFBVSxHQUFHLFNBQVMsR0FBRyxVQUFTO1FBQzFFLEtBQUssQ0FBQyxHQUFHLFVBQVUsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO1VBQ2hDLElBQUksS0FBSyxHQUFHLEtBQUk7VUFDaEIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFNBQVMsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNsQyxJQUFJLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUU7Y0FDckMsS0FBSyxHQUFHLE1BQUs7Y0FDYixLQUFLO2FBQ047V0FDRjtVQUNELElBQUksS0FBSyxFQUFFLE9BQU8sQ0FBQztTQUNwQjtPQUNGOztNQUVELE9BQU8sQ0FBQyxDQUFDO0tBQ1Y7O0lBRUQsTUFBTSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEdBQUcsU0FBUyxRQUFRLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUU7TUFDeEUsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxVQUFVLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO01BQ3REOztJQUVELE1BQU0sQ0FBQyxTQUFTLENBQUMsT0FBTyxHQUFHLFNBQVMsT0FBTyxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFO01BQ3RFLE9BQU8sb0JBQW9CLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQztNQUNuRTs7SUFFRCxNQUFNLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxTQUFTLFdBQVcsRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRTtNQUM5RSxPQUFPLG9CQUFvQixDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxLQUFLLENBQUM7TUFDcEU7O0lBRUQsU0FBUyxRQUFRLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFO01BQzlDLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksRUFBQztNQUM1QixJQUFJLFNBQVMsR0FBRyxHQUFHLENBQUMsTUFBTSxHQUFHLE9BQU07TUFDbkMsSUFBSSxDQUFDLE1BQU0sRUFBRTtRQUNYLE1BQU0sR0FBRyxVQUFTO09BQ25CLE1BQU07UUFDTCxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBQztRQUN2QixJQUFJLE1BQU0sR0FBRyxTQUFTLEVBQUU7VUFDdEIsTUFBTSxHQUFHLFVBQVM7U0FDbkI7T0FDRjs7O01BR0QsSUFBSSxNQUFNLEdBQUcsTUFBTSxDQUFDLE9BQU07TUFDMUIsSUFBSSxNQUFNLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxNQUFNLElBQUksU0FBUyxDQUFDLG9CQUFvQixDQUFDOztNQUUvRCxJQUFJLE1BQU0sR0FBRyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1FBQ3ZCLE1BQU0sR0FBRyxNQUFNLEdBQUcsRUFBQztPQUNwQjtNQUNELEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLEVBQUUsRUFBRSxDQUFDLEVBQUU7UUFDL0IsSUFBSSxNQUFNLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUM7UUFDbEQsSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsT0FBTyxDQUFDO1FBQzNCLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEdBQUcsT0FBTTtPQUN6QjtNQUNELE9BQU8sQ0FBQztLQUNUOztJQUVELFNBQVMsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRTtNQUMvQyxPQUFPLFVBQVUsQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUM7S0FDakY7O0lBRUQsU0FBUyxVQUFVLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFO01BQ2hELE9BQU8sVUFBVSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQztLQUM3RDs7SUFFRCxTQUFTLFdBQVcsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUU7TUFDakQsT0FBTyxVQUFVLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDO0tBQy9DOztJQUVELFNBQVMsV0FBVyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRTtNQUNqRCxPQUFPLFVBQVUsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUM7S0FDOUQ7O0lBRUQsU0FBUyxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFO01BQy9DLE9BQU8sVUFBVSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQztLQUNwRjs7SUFFRCxNQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxTQUFTLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUU7O01BRXpFLElBQUksTUFBTSxLQUFLLFNBQVMsRUFBRTtRQUN4QixRQUFRLEdBQUcsT0FBTTtRQUNqQixNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU07UUFDcEIsTUFBTSxHQUFHLEVBQUM7O09BRVgsTUFBTSxJQUFJLE1BQU0sS0FBSyxTQUFTLElBQUksT0FBTyxNQUFNLEtBQUssUUFBUSxFQUFFO1FBQzdELFFBQVEsR0FBRyxPQUFNO1FBQ2pCLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTTtRQUNwQixNQUFNLEdBQUcsRUFBQzs7T0FFWCxNQUFNLElBQUksUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFO1FBQzNCLE1BQU0sR0FBRyxNQUFNLEdBQUcsRUFBQztRQUNuQixJQUFJLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRTtVQUNwQixNQUFNLEdBQUcsTUFBTSxHQUFHLEVBQUM7VUFDbkIsSUFBSSxRQUFRLEtBQUssU0FBUyxFQUFFLFFBQVEsR0FBRyxPQUFNO1NBQzlDLE1BQU07VUFDTCxRQUFRLEdBQUcsT0FBTTtVQUNqQixNQUFNLEdBQUcsVUFBUztTQUNuQjs7T0FFRixNQUFNO1FBQ0wsTUFBTSxJQUFJLEtBQUs7VUFDYix5RUFBeUU7U0FDMUU7T0FDRjs7TUFFRCxJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLE9BQU07TUFDcEMsSUFBSSxNQUFNLEtBQUssU0FBUyxJQUFJLE1BQU0sR0FBRyxTQUFTLEVBQUUsTUFBTSxHQUFHLFVBQVM7O01BRWxFLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsS0FBSyxNQUFNLEdBQUcsQ0FBQyxJQUFJLE1BQU0sR0FBRyxDQUFDLENBQUMsS0FBSyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRTtRQUM3RSxNQUFNLElBQUksVUFBVSxDQUFDLHdDQUF3QyxDQUFDO09BQy9EOztNQUVELElBQUksQ0FBQyxRQUFRLEVBQUUsUUFBUSxHQUFHLE9BQU07O01BRWhDLElBQUksV0FBVyxHQUFHLE1BQUs7TUFDdkIsU0FBUztRQUNQLFFBQVEsUUFBUTtVQUNkLEtBQUssS0FBSztZQUNSLE9BQU8sUUFBUSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQzs7VUFFL0MsS0FBSyxNQUFNLENBQUM7VUFDWixLQUFLLE9BQU87WUFDVixPQUFPLFNBQVMsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUM7O1VBRWhELEtBQUssT0FBTztZQUNWLE9BQU8sVUFBVSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQzs7VUFFakQsS0FBSyxRQUFRLENBQUM7VUFDZCxLQUFLLFFBQVE7WUFDWCxPQUFPLFdBQVcsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUM7O1VBRWxELEtBQUssUUFBUTs7WUFFWCxPQUFPLFdBQVcsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUM7O1VBRWxELEtBQUssTUFBTSxDQUFDO1VBQ1osS0FBSyxPQUFPLENBQUM7VUFDYixLQUFLLFNBQVMsQ0FBQztVQUNmLEtBQUssVUFBVTtZQUNiLE9BQU8sU0FBUyxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQzs7VUFFaEQ7WUFDRSxJQUFJLFdBQVcsRUFBRSxNQUFNLElBQUksU0FBUyxDQUFDLG9CQUFvQixHQUFHLFFBQVEsQ0FBQztZQUNyRSxRQUFRLEdBQUcsQ0FBQyxFQUFFLEdBQUcsUUFBUSxFQUFFLFdBQVcsR0FBRTtZQUN4QyxXQUFXLEdBQUcsS0FBSTtTQUNyQjtPQUNGO01BQ0Y7O0lBRUQsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsU0FBUyxNQUFNLElBQUk7TUFDM0MsT0FBTztRQUNMLElBQUksRUFBRSxRQUFRO1FBQ2QsSUFBSSxFQUFFLEtBQUssQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLElBQUksRUFBRSxDQUFDLENBQUM7T0FDdkQ7TUFDRjs7SUFFRCxTQUFTLFdBQVcsRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRTtNQUNyQyxJQUFJLEtBQUssS0FBSyxDQUFDLElBQUksR0FBRyxLQUFLLEdBQUcsQ0FBQyxNQUFNLEVBQUU7UUFDckMsT0FBT3FuQyxhQUFvQixDQUFDLEdBQUcsQ0FBQztPQUNqQyxNQUFNO1FBQ0wsT0FBT0EsYUFBb0IsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztPQUNuRDtLQUNGOztJQUVELFNBQVMsU0FBUyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFO01BQ25DLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFDO01BQy9CLElBQUksR0FBRyxHQUFHLEdBQUU7O01BRVosSUFBSSxDQUFDLEdBQUcsTUFBSztNQUNiLE9BQU8sQ0FBQyxHQUFHLEdBQUcsRUFBRTtRQUNkLElBQUksU0FBUyxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUM7UUFDdEIsSUFBSSxTQUFTLEdBQUcsS0FBSTtRQUNwQixJQUFJLGdCQUFnQixHQUFHLENBQUMsU0FBUyxHQUFHLElBQUksSUFBSSxDQUFDO1lBQ3pDLENBQUMsU0FBUyxHQUFHLElBQUksSUFBSSxDQUFDO1lBQ3RCLENBQUMsU0FBUyxHQUFHLElBQUksSUFBSSxDQUFDO1lBQ3RCLEVBQUM7O1FBRUwsSUFBSSxDQUFDLEdBQUcsZ0JBQWdCLElBQUksR0FBRyxFQUFFO1VBQy9CLElBQUksVUFBVSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsY0FBYTs7VUFFcEQsUUFBUSxnQkFBZ0I7WUFDdEIsS0FBSyxDQUFDO2NBQ0osSUFBSSxTQUFTLEdBQUcsSUFBSSxFQUFFO2dCQUNwQixTQUFTLEdBQUcsVUFBUztlQUN0QjtjQUNELEtBQUs7WUFDUCxLQUFLLENBQUM7Y0FDSixVQUFVLEdBQUcsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUM7Y0FDdkIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLE1BQU0sSUFBSSxFQUFFO2dCQUNoQyxhQUFhLEdBQUcsQ0FBQyxTQUFTLEdBQUcsSUFBSSxLQUFLLEdBQUcsSUFBSSxVQUFVLEdBQUcsSUFBSSxFQUFDO2dCQUMvRCxJQUFJLGFBQWEsR0FBRyxJQUFJLEVBQUU7a0JBQ3hCLFNBQVMsR0FBRyxjQUFhO2lCQUMxQjtlQUNGO2NBQ0QsS0FBSztZQUNQLEtBQUssQ0FBQztjQUNKLFVBQVUsR0FBRyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBQztjQUN2QixTQUFTLEdBQUcsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUM7Y0FDdEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLE1BQU0sSUFBSSxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksTUFBTSxJQUFJLEVBQUU7Z0JBQy9ELGFBQWEsR0FBRyxDQUFDLFNBQVMsR0FBRyxHQUFHLEtBQUssR0FBRyxHQUFHLENBQUMsVUFBVSxHQUFHLElBQUksS0FBSyxHQUFHLElBQUksU0FBUyxHQUFHLElBQUksRUFBQztnQkFDMUYsSUFBSSxhQUFhLEdBQUcsS0FBSyxLQUFLLGFBQWEsR0FBRyxNQUFNLElBQUksYUFBYSxHQUFHLE1BQU0sQ0FBQyxFQUFFO2tCQUMvRSxTQUFTLEdBQUcsY0FBYTtpQkFDMUI7ZUFDRjtjQUNELEtBQUs7WUFDUCxLQUFLLENBQUM7Y0FDSixVQUFVLEdBQUcsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUM7Y0FDdkIsU0FBUyxHQUFHLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFDO2NBQ3RCLFVBQVUsR0FBRyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBQztjQUN2QixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksTUFBTSxJQUFJLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxNQUFNLElBQUksSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLE1BQU0sSUFBSSxFQUFFO2dCQUMvRixhQUFhLEdBQUcsQ0FBQyxTQUFTLEdBQUcsR0FBRyxLQUFLLElBQUksR0FBRyxDQUFDLFVBQVUsR0FBRyxJQUFJLEtBQUssR0FBRyxHQUFHLENBQUMsU0FBUyxHQUFHLElBQUksS0FBSyxHQUFHLElBQUksVUFBVSxHQUFHLElBQUksRUFBQztnQkFDeEgsSUFBSSxhQUFhLEdBQUcsTUFBTSxJQUFJLGFBQWEsR0FBRyxRQUFRLEVBQUU7a0JBQ3RELFNBQVMsR0FBRyxjQUFhO2lCQUMxQjtlQUNGO1dBQ0o7U0FDRjs7UUFFRCxJQUFJLFNBQVMsS0FBSyxJQUFJLEVBQUU7OztVQUd0QixTQUFTLEdBQUcsT0FBTTtVQUNsQixnQkFBZ0IsR0FBRyxFQUFDO1NBQ3JCLE1BQU0sSUFBSSxTQUFTLEdBQUcsTUFBTSxFQUFFOztVQUU3QixTQUFTLElBQUksUUFBTztVQUNwQixHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsS0FBSyxFQUFFLEdBQUcsS0FBSyxHQUFHLE1BQU0sRUFBQztVQUMzQyxTQUFTLEdBQUcsTUFBTSxHQUFHLFNBQVMsR0FBRyxNQUFLO1NBQ3ZDOztRQUVELEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFDO1FBQ25CLENBQUMsSUFBSSxpQkFBZ0I7T0FDdEI7O01BRUQsT0FBTyxxQkFBcUIsQ0FBQyxHQUFHLENBQUM7S0FDbEM7Ozs7O0lBS0QsSUFBSSxvQkFBb0IsR0FBRyxPQUFNOztJQUVqQyxTQUFTLHFCQUFxQixFQUFFLFVBQVUsRUFBRTtNQUMxQyxJQUFJLEdBQUcsR0FBRyxVQUFVLENBQUMsT0FBTTtNQUMzQixJQUFJLEdBQUcsSUFBSSxvQkFBb0IsRUFBRTtRQUMvQixPQUFPLE1BQU0sQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUM7T0FDckQ7OztNQUdELElBQUksR0FBRyxHQUFHLEdBQUU7TUFDWixJQUFJLENBQUMsR0FBRyxFQUFDO01BQ1QsT0FBTyxDQUFDLEdBQUcsR0FBRyxFQUFFO1FBQ2QsR0FBRyxJQUFJLE1BQU0sQ0FBQyxZQUFZLENBQUMsS0FBSztVQUM5QixNQUFNO1VBQ04sVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLG9CQUFvQixDQUFDO1VBQy9DO09BQ0Y7TUFDRCxPQUFPLEdBQUc7S0FDWDs7SUFFRCxTQUFTLFVBQVUsRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRTtNQUNwQyxJQUFJLEdBQUcsR0FBRyxHQUFFO01BQ1osR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUM7O01BRS9CLEtBQUssSUFBSSxDQUFDLEdBQUcsS0FBSyxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUU7UUFDaEMsR0FBRyxJQUFJLE1BQU0sQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBQztPQUMxQztNQUNELE9BQU8sR0FBRztLQUNYOztJQUVELFNBQVMsV0FBVyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFO01BQ3JDLElBQUksR0FBRyxHQUFHLEdBQUU7TUFDWixHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBQzs7TUFFL0IsS0FBSyxJQUFJLENBQUMsR0FBRyxLQUFLLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRTtRQUNoQyxHQUFHLElBQUksTUFBTSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUM7T0FDbkM7TUFDRCxPQUFPLEdBQUc7S0FDWDs7SUFFRCxTQUFTLFFBQVEsRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRTtNQUNsQyxJQUFJLEdBQUcsR0FBRyxHQUFHLENBQUMsT0FBTTs7TUFFcEIsSUFBSSxDQUFDLEtBQUssSUFBSSxLQUFLLEdBQUcsQ0FBQyxFQUFFLEtBQUssR0FBRyxFQUFDO01BQ2xDLElBQUksQ0FBQyxHQUFHLElBQUksR0FBRyxHQUFHLENBQUMsSUFBSSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxJQUFHOztNQUUzQyxJQUFJLEdBQUcsR0FBRyxHQUFFO01BQ1osS0FBSyxJQUFJLENBQUMsR0FBRyxLQUFLLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRTtRQUNoQyxHQUFHLElBQUksS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBQztPQUNyQjtNQUNELE9BQU8sR0FBRztLQUNYOztJQUVELFNBQVMsWUFBWSxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFO01BQ3RDLElBQUksS0FBSyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBQztNQUNqQyxJQUFJLEdBQUcsR0FBRyxHQUFFO01BQ1osS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRTtRQUN4QyxHQUFHLElBQUksTUFBTSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLEVBQUM7T0FDMUQ7TUFDRCxPQUFPLEdBQUc7S0FDWDs7SUFFRCxNQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxTQUFTLEtBQUssRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFO01BQ25ELElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFNO01BQ3JCLEtBQUssR0FBRyxDQUFDLENBQUMsTUFBSztNQUNmLEdBQUcsR0FBRyxHQUFHLEtBQUssU0FBUyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsSUFBRzs7TUFFckMsSUFBSSxLQUFLLEdBQUcsQ0FBQyxFQUFFO1FBQ2IsS0FBSyxJQUFJLElBQUc7UUFDWixJQUFJLEtBQUssR0FBRyxDQUFDLEVBQUUsS0FBSyxHQUFHLEVBQUM7T0FDekIsTUFBTSxJQUFJLEtBQUssR0FBRyxHQUFHLEVBQUU7UUFDdEIsS0FBSyxHQUFHLElBQUc7T0FDWjs7TUFFRCxJQUFJLEdBQUcsR0FBRyxDQUFDLEVBQUU7UUFDWCxHQUFHLElBQUksSUFBRztRQUNWLElBQUksR0FBRyxHQUFHLENBQUMsRUFBRSxHQUFHLEdBQUcsRUFBQztPQUNyQixNQUFNLElBQUksR0FBRyxHQUFHLEdBQUcsRUFBRTtRQUNwQixHQUFHLEdBQUcsSUFBRztPQUNWOztNQUVELElBQUksR0FBRyxHQUFHLEtBQUssRUFBRSxHQUFHLEdBQUcsTUFBSzs7TUFFNUIsSUFBSSxPQUFNO01BQ1YsSUFBSSxNQUFNLENBQUMsbUJBQW1CLEVBQUU7UUFDOUIsTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBQztRQUNsQyxNQUFNLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQyxVQUFTO09BQ3BDLE1BQU07UUFDTCxJQUFJLFFBQVEsR0FBRyxHQUFHLEdBQUcsTUFBSztRQUMxQixNQUFNLEdBQUcsSUFBSSxNQUFNLENBQUMsUUFBUSxFQUFFLFNBQVMsRUFBQztRQUN4QyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsUUFBUSxFQUFFLEVBQUUsQ0FBQyxFQUFFO1VBQ2pDLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUssRUFBQztTQUM1QjtPQUNGOztNQUVELE9BQU8sTUFBTTtNQUNkOzs7OztJQUtELFNBQVMsV0FBVyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFO01BQ3pDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxNQUFNLEdBQUcsQ0FBQyxFQUFFLE1BQU0sSUFBSSxVQUFVLENBQUMsb0JBQW9CLENBQUM7TUFDaEYsSUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLE1BQU0sRUFBRSxNQUFNLElBQUksVUFBVSxDQUFDLHVDQUF1QyxDQUFDO0tBQ3pGOztJQUVELE1BQU0sQ0FBQyxTQUFTLENBQUMsVUFBVSxHQUFHLFNBQVMsVUFBVSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFO01BQy9FLE1BQU0sR0FBRyxNQUFNLEdBQUcsRUFBQztNQUNuQixVQUFVLEdBQUcsVUFBVSxHQUFHLEVBQUM7TUFDM0IsSUFBSSxDQUFDLFFBQVEsRUFBRSxXQUFXLENBQUMsTUFBTSxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFDOztNQUUzRCxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFDO01BQ3RCLElBQUksR0FBRyxHQUFHLEVBQUM7TUFDWCxJQUFJLENBQUMsR0FBRyxFQUFDO01BQ1QsT0FBTyxFQUFFLENBQUMsR0FBRyxVQUFVLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxFQUFFO1FBQ3pDLEdBQUcsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUc7T0FDOUI7O01BRUQsT0FBTyxHQUFHO01BQ1g7O0lBRUQsTUFBTSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEdBQUcsU0FBUyxVQUFVLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUU7TUFDL0UsTUFBTSxHQUFHLE1BQU0sR0FBRyxFQUFDO01BQ25CLFVBQVUsR0FBRyxVQUFVLEdBQUcsRUFBQztNQUMzQixJQUFJLENBQUMsUUFBUSxFQUFFO1FBQ2IsV0FBVyxDQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBQztPQUM3Qzs7TUFFRCxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsVUFBVSxFQUFDO01BQ3JDLElBQUksR0FBRyxHQUFHLEVBQUM7TUFDWCxPQUFPLFVBQVUsR0FBRyxDQUFDLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxFQUFFO1FBQ3ZDLEdBQUcsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsVUFBVSxDQUFDLEdBQUcsSUFBRztPQUN6Qzs7TUFFRCxPQUFPLEdBQUc7TUFDWDs7SUFFRCxNQUFNLENBQUMsU0FBUyxDQUFDLFNBQVMsR0FBRyxTQUFTLFNBQVMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFO01BQ2pFLElBQUksQ0FBQyxRQUFRLEVBQUUsV0FBVyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBQztNQUNsRCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7TUFDcEI7O0lBRUQsTUFBTSxDQUFDLFNBQVMsQ0FBQyxZQUFZLEdBQUcsU0FBUyxZQUFZLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRTtNQUN2RSxJQUFJLENBQUMsUUFBUSxFQUFFLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUM7TUFDbEQsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7TUFDOUM7O0lBRUQsTUFBTSxDQUFDLFNBQVMsQ0FBQyxZQUFZLEdBQUcsU0FBUyxZQUFZLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRTtNQUN2RSxJQUFJLENBQUMsUUFBUSxFQUFFLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUM7TUFDbEQsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7TUFDOUM7O0lBRUQsTUFBTSxDQUFDLFNBQVMsQ0FBQyxZQUFZLEdBQUcsU0FBUyxZQUFZLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRTtNQUN2RSxJQUFJLENBQUMsUUFBUSxFQUFFLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUM7O01BRWxELE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7V0FDaEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7V0FDdEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7V0FDdkIsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUM7TUFDbkM7O0lBRUQsTUFBTSxDQUFDLFNBQVMsQ0FBQyxZQUFZLEdBQUcsU0FBUyxZQUFZLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRTtNQUN2RSxJQUFJLENBQUMsUUFBUSxFQUFFLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUM7O01BRWxELE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsU0FBUztTQUM3QixDQUFDLElBQUksQ0FB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RCxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUU7U0FDdkIsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7U0FDdkIsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDdEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztNQUNyQjs7SUFFRCxNQUFNLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxTQUFTLFdBQVcsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFO01BQ3JFLElBQUksQ0FBQyxRQUFRLEVBQUUsV0FBVyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBQztNQUNsRCxPQUFPQyxJQUFZLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztNQUMvQzs7SUFFRCxNQUFNLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxTQUFTLFdBQVcsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFO01BQ3JFLElBQUksQ0FBQyxRQUFRLEVBQUUsV0FBVyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBQztNQUNsRCxPQUFPQSxJQUFZLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztNQUNoRDs7SUFFRCxNQUFNLENBQUMsU0FBUyxDQUFDLFlBQVksR0FBRyxTQUFTLFlBQVksRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFO01BQ3ZFLElBQUksQ0FBQyxRQUFRLEVBQUUsV0FBVyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBQztNQUNsRCxPQUFPQSxJQUFZLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztNQUMvQzs7SUFFRCxNQUFNLENBQUMsU0FBUyxDQUFDLFlBQVksR0FB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 diff --git a/package-lock.json b/package-lock.json index 197a33da..e56ef6d1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "sdl_javascript_suite", - "version": "0.1.0", + "version": "0.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1578,6 +1578,12 @@ "babel-helper-is-void-0": "^0.4.3" } }, + "babel-plugin-transform-async-to-promises": { + "version": "0.8.15", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-promises/-/babel-plugin-transform-async-to-promises-0.8.15.tgz", + "integrity": "sha512-fDXP68ZqcinZO2WCiimCL9zhGjGXOnn3D33zvbh+yheZ/qOrNVVDDIBtAaM3Faz8TRvQzHiRKsu3hfrBAhEncQ==", + "dev": true + }, "babel-plugin-transform-inline-consecutive-adds": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.4.3.tgz", diff --git a/package.json b/package.json index 7ec875ad..07b98342 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "devDependencies": { "@babel/preset-env": "^7.7.1", "babel-minify-webpack-plugin": "^0.3.1", + "babel-plugin-transform-async-to-promises": "^0.8.15", "bson": "^4.0.2", "chai": "^4.2.0", "eslint": "^6.6.0", diff --git a/rollup.config.js b/rollup.config.js index 810f0e1b..48a71540 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -22,6 +22,7 @@ export default [{ // Vanilla JS source commonjs(), babel({ exclude: 'node_modules/**', // only transpile our source code + plugins: ["babel-plugin-transform-async-to-promises"] // convert async/await syntax }), uglify(), ], @@ -42,6 +43,7 @@ export default [{ // Vanilla JS source commonjs(), babel({ exclude: 'node_modules/**', // only transpile our source code + plugins: ["babel-plugin-transform-async-to-promises"] // convert async/await syntax }), ], external: ['ws', 'https']